From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from rock.gnat.com (rock.gnat.com [IPv6:2620:20:4000:0:a9e:1ff:fe9b:1d1]) by sourceware.org (Postfix) with ESMTP id 18B5A3857C4A for ; Sat, 15 Aug 2020 16:40:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 18B5A3857C4A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oliva@adacore.com Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id B419F563EC; Sat, 15 Aug 2020 12:40:02 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id tr5oxVQo2ULU; Sat, 15 Aug 2020 12:40:02 -0400 (EDT) Received: from free.home (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id 0FF89563EB; Sat, 15 Aug 2020 12:40:01 -0400 (EDT) Received: from livre.home (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 07FGdoxL164838 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sat, 15 Aug 2020 13:39:51 -0300 From: Alexandre Oliva To: Iain Sandoe Cc: Nathan Sidwell , Eric Botcazou , gcc-patches@gcc.gnu.org, joseph@codesourcery.com Subject: Re: [PATCH] introduce attribute exalias Organization: Free thinker, does not speak for AdaCore References: <13ed4563-33bb-f9b5-4b63-0cf0eebf6034@acm.org> <3BCD58FE-BB29-49EA-BBEF-1FF4ADCAB7CA@sandoe.co.uk> Errors-To: aoliva@lxoliva.fsfla.org Date: Sat, 15 Aug 2020 13:39:49 -0300 In-Reply-To: <3BCD58FE-BB29-49EA-BBEF-1FF4ADCAB7CA@sandoe.co.uk> (Iain Sandoe's message of "Sat, 15 Aug 2020 10:22:30 +0100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-5.3 required=5.0 tests=BAYES_00, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Aug 2020 16:40:04 -0000 On Aug 15, 2020, Iain Sandoe wrote: > * if the target ABI does not support symbol aliases, then this facility = cannot > be used. True. I'm surprised there are modern platforms that don't. What is it that stands in the way? Lack of support for .set in the assembler? If that's the case, couldn't it possibly be worked around by setting multiple global labels at the same spot? I'm pretty sure setting multiple labels at the same address is used and relied on quite often. > will exclude the GCC targets without symbol aliases from Ada. It's not so dire. Developers for alias-deprived systems would have to use the mangled names instead. That would be a little painful, but not even close to making the language unavailable. > * The process shifts the onus on representation to the exporter and thus= there > can now be 3 library vendors who all thought =E2=80=9CMY_FOO_FUNC=E2= =80=9D was the > best representation for an export - these will now clash in the =E2=80= =9Cshorthand=E2=80=9D > namespace, although their C++ mangling might well not. Using this to disqualify the new feature would also disqualify regular aliases, that could be used for just the same purpose of making symbols available under chosen names: extern "C" typeof(foo::func) __attribute__((__alias__(""))) MY_FOO_FUNC; Now, this concern appears to be focused on binary-only libraries. Since we haven't seen vendors rush to make their library internals available under shorter aliases, polluting the symbolic namespace, I see little reason for concern about this possibility. When it comes to binary-only libraries, the ABI is often set in stone, and it's up to users to figure out the symbol names in the ABI and use them. If they vary across target platforms, that's inconvenient, but nothing new. I expect this feature to be used and useful within multi-language projects, particularly when using, as part of their interfaces, shorthand typedefs whose encoding varies depending on the platform. E.g., consider a function or a template instantiation that takes a int64_t parameter. Depending on whether int64_t maps to long or long long, you get different encodings, thus references using the symbol name have to be adjusted depending on what type stdint.h maps int64_t to. > * it=E2=80=99s not universally usable without =E2=80=9Crebuilding the wo= rld=E2=80=9D and having access to > source for everything you might want to import You mean it does not bring improvements to situations in which you can't introduce nicknames for third-party symbols. You then figure out and import the mangled names and move on. > * what happens for templates and overloads - presumably the Ada import h= as > add the relevant (albeit abbreviated) decorations? They don't matter to the proposed design. The reason they come up for you is that you have a completely different solution in mind that requires this kind of resolution. The one I'm proposing attaches the extra aliases directly to the target language entity, be it one of the overloads of a member function, be it a specialization of a template function. > * One can=E2=80=99t have an arbitrary re-name; it has to be supported by= the target > assembler (not that this is a new constraint, but it prevents the expo= rted > name from being an exact representation of the human-readable C++ inte= rface > in general). *nod*. It couldn't be a target for alias attributes otherwise, and I found that a desirable property to make the new feature useful even for standalone C++. > =E2=80=94=E2=80=94 are there other possibilites to solve the underlying i= ssue? > C++ mangled names have some proven good properties: > * they convey all the relevant information about the interface > * they are standardized, and work between implementations from different > =E2=80=98vendors=E2=80=99 or OSS compilers on the same platform. > * they are not going to clash. * they require so much symbolic information that in order to perform mangling you pretty much have to #include all of the relevant C++ headers. Consider typedefs, templates with partial or explicit specializations, default template arguments, besides the possibility of varying definitions across platforms. > what about annotating the import pragma in some way such that the platform > mangling is applied by the compiler? That would indeed be desirable, but it is unfortunately not viable. Consider you have to figure out the correct mangling for this: foo::bar::f Is foo a namespace, a canonical class name, or a typedef? (maybe even a using declaration, or even something brought into the global namespace by a using directive) If it's a typedef, what's the canonical name? (it could be a template instantiation) bar is clearly a template type, so you "just" need enough symbolic information to be able to mangle std::iostream&, std::string, u64, g::h. For u64, you just have to look at stdint.h to see which of the C++-defined types is maps to. g::h is a mystery. It could be a type, a function, a member function, a variable, a data member... There could be any subsequent template parameters using defaults. Even if we were to simplify this (and make it inconvenient for the user) requiring no defaults to be relied on, that wouldn't get you much farther. Finally, we get to f. We can assume it's not a template type, nor a template member function, so it would have to be (assuming a well-formed symbolic reference) a static or non-static data member, a static or non-static member function, a typedef, a nested type; possibly a template instantiation, using defaults?). It could even name an overload set, so you might want to require a parameter list, and an explicit template parameter list. We could then require all of this symbolic information, in the form of type, variable and function declarations, including partial and explicit specializations, and the transitive closure thereof. How would you get all of this symbolic information to the compiler of the Ada unit importing such C++ symbols? Parsing C++ headers? Requiring users to bring the relevant declarations into the Ada program? Searching the symbol tables of object files that would have to have alreayd been compiled, looking for a match? None of these are good. Extracting symbolic information from C++ headers (=C3=A0-la -fdump-ada-spec, but with a *lot* more symbolic info) in a first pass, and referencing that in your imports. Viable, a *lot* of work, and also a big doh! -fdump-ada-spec would already get you the Imports with the mangled names. This feature is for when you don't want to go through all this trouble, and would rather reference a few C++ symbols directly in your target-independent sources. > it=E2=80=99s nice when an attribute reads in the source to tell you its p= urpose. *exporting* is heavily overloaded, so I've been avoiding it. One thing the proposed feature does NOT do is to make the alias more visible than the original symbol. If it's internal, hidden or protected, or even if it's local, it won't get exported. You could use it, and then another alias declaration referencing it, to get it exported, if you wish, but that was enough of a reason for me to stay away from the term "export". > *** right now Darwin fails silently (there doesn=E2=80=99t seem to be the= usual error > that the target doesn=E2=80=99t support that kind of alias). Hmm, thanks, I will make sure there's some more verbose failure mode if we can't find a way for something akin to an alias to be usable there. --=20 Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ Free Software Activist GNU Toolchain Engineer