!standard 7.18 07-01-15 SI99-0016-1/03 !standard 15.27 !class binding interpretation 06-07-19 !status work item 06-07-19 !status received 06-07-19 !priority High !difficulty Medium !qualifier Omission !subject Correct Corresponding_Body !summary If Generic_Macro_Expansion_Supported is False, Corresponding_Body does not return an expanded body, rather it returns Nil_Element (even if the generic has been compiled). !question What does ASIS.Implementation_Permissions.Generic_Macro_Expansion_Supported mean? In particular, what does it mean if it is False? Corresponding_Body (15.27) says that the expanded body for an instance is always returned, but such a thing would not exist for a shared generic implementation. !recommendation (See summary.) !wording In 7.8, change: Returns True if the implementation expands {the bodies of generic instantiations} [generics using macros] to support[s] queries. Note: Implementations are required to support expansion of specifications. In 15.27, change: Returns a Nil_Element if the body of the generic has not yet been compiled or inserted into the Ada Environment Context. {Also returns a Nil_Element if Generic_Macro_Expansion_Supported returns False.} !discussion Ada has always supported implementations that shared generic bodies. ASIS seems to support such implementations with the Generic_Macro_Expansion_Supported flag. However, there is no semantics defined in the rest of the Standard that explains what this flag means. But there are obvious cases where the semantics of ASIS appears to require generic macro expansion, such as Corresponding_Body. Macro expansion of bodies should not be required in the syntax interface; Corresponding_Body should be able to return Nil_Element for all instantations where the body is shared. !appendix From: Private e-mail of mid-July, 2006 [Editor's note: Following is a conversation between Randy Brukardt and Pascal Leroy on this topic, included by permission.] [From the Porto minutes on SI-12:] A side discussion erupts about macro expansion of generics. This shouldn’t be required of implementations that support code sharing of bodies, but the definition of normalized instantiations seems to require it. We find an implementation permission function that queries whether it is supported (Generic_Macro_Expansion_Supported), but there is no definition of what it means if it returns False. That ought to be fixed somehow. Arguably, the blanket permission to return Nil_Element covers it, but that permission makes portable use of ASIS very difficult — it probably should be reduced. (And the semantic interface will have no such permission.) [RLB] Shouldn’t there be an action item here? No one has one in my notes. [PHL] I wouldn’t bother until we have a clearer view of what’s in the semantic interface. It seems to me that, in the semantic interface, all the implicit entities defined by the language should be accessible, and that includes expanded bodies (see 12.3(12)). For an implementation that shares generic bodies the compiler may not create such a copy, but ASIS would still have to simulate it somehow. Not very different from predefined operators, for instance: the compiler may or may not represent them explicitly, but they must be accessible using the semantic interface. [RLB] I guess I disagree. The problem remains even if the use of the "Normalized" parameter is made obsolete. These routines do not return anything like the semantic data structures; they return the syntax structures expanded. This makes no sense (it's a mixture of semantic and syntactic information) and something has to be done. I don't see any way to make this meaningful. Moreover, there is a general problem here that ASIS seems to imply that a compiler should just return whatever it has available, which is death for portability. There needs to be clear requirements on which items need to be available syntactically and which are not -- that's missing from the standard currently. *Someone* needs to do this!!! [PHL] Did you just volunteer? ;-) The “general problem” that you mention really has to do with the syntactic/semantic confusion in the interface. I agree that it’s a killer for portability, but I am hoping that it will go away once we have a semantic interface. My view is this: for the syntactic part of the interface, ASIS returns whatever is available in the source, and that’s well defined; for the semantic part, ASIS always returns “something” and that includes implicit subprograms, class-wide and base types, generic expansions, etc. [RLB] This a tough problem and it really only has to do with the syntactic interface. (Although it would be good to figure out what Generic_Macro_Expansion_Supported means in any case.) The problem is a strict view like the one you suggest above (and what I would implement, at most) is likely to be incompatible with existing implementations (and more importantly, programs). The old rules allowed them to construct implicit stuff, and programs are likely to depend on that stuff existing in the way that their current implementation supports. To the extent that we tie these rules down, we might break programs that expected implicit stuff to exist. (Of course, if these are source processing programs, we'll probably fix problems...) I guess I'd feel better if there was an SI spelling out these issues, even if there isn't a solution. Otherwise, there is a significant danger that the whole thing will get forgotten and not addressed. So I suppose I'm volunteering to write a mostly empty SI. Thoughts?? [PHL] My belief is that there are actually few programs out there that go beyond syntax analysis, largely because it's so hard. I remember attending presentations at SIGAda or Ada Europe in the past few years where people explained that they didn't use ASIS because ASIS didn't provide the right interface for their problem. I didn't understand why at the time, but now I do. In all instances that I remember they ended up tweaking the GNAT front end. If that's true, cleaning up the interfaces would be a service to users and would fix more bugs than it would create. Yes, a mostly empty SI explaining the problems would be good. Feel free to borrow from our discussion. **************************************************************** From: Private e-mail of January, 2007 [Editor's note: Following is a conversation between Randy Brukardt and Pascal Leroy on this topic, included by permission.] [PHL] I guess I have to some extent come to agree with your point of view: the expanded body, with the replicated statements and so on, doesn’t belong in the semantic domain, because we want the semantic domain to only contain declarations (implicit or explicit). My latest greatest idea is this: in order to analyze expanded bodies, you need a pair (instance_id, element_in_generic). The instance_id you get, you guessed it, from the instance (assume that it’s some private type distinct from element). You use the existing interfaces to traverse the (syntactic) body of the generic until you find an element of interest. If you want to make a query to the semantic domain (eg, what declaration is denoted by this name?), it would use the instance_id to take into account the actual/formal parameter substitutions and return you the declaration in the instance body. In the case of children of generics you’d probably need several instance ids to guide you to the “right” place. Since we wouldn’t add extra parameters to the semantic queries just for generic bodies, we would need some way to establish a global “instance context” to be used by all the queries. Note that this would also work for instance specs, btw. [RLB] I agree that there shouldn't be an "expanded" body; no such thing exists in the Ada semantics (at least not in any visible way). Any attempt to provide one is going to cause all kinds of anomalies. I like your approach better, although the magic context isn't very appealing. Perhaps there is some way to include that in a special kind of element (they're pretty general, after all, don't have to be just syntax). ****************************************************************