ipr: Bodies of the mapping expressions (and Variable Templates)
IPR uses mapping expression to represent functions and templates. A mapping has a parameter list, type and a body.
The parameter_list of the mapping hosts a homogeneous scope/region that holds parameter declarations. Body of the function mapping is a block that takes an enclosing region (parameter_list scope/region) in its constructor.
Similarly, for a class template, the body of a mapping is an ipr::impl::Class that takes the enclosing region in its constructor.
For a function template, the body is a mapping expression for a function. Function mapping takes enclosing region in its constructor.
From the ipr interface, we have a couple of alternatives on how to represent the body of the mapping. Option 1 is to use the actual expression that will become the body/initializer of the entity after substitution. Option 2 is to create a full fledged declaration and to make it the body of the mapping.
Template Kind | Option 1 | Option 2 |
---|---|---|
Function template | Function Mapping Expr | ipr::Fundecl |
Class Template | Class (Type) | ipr::Typedecl |
Alias Template | Type | ipr::Alias (Decl) |
Variable Template | ??? | ipr::Var (Decl) |
While Option 2 is possible from the perspective of ipr interface. It is cannot be created using ipr::impl as it exists today. To create a declaration, we have to have a heterogeneous scope in which to create it. We don’t have it. The enclosing scope of the body of the mapping is a homogenous parameter scope.
Option 1 is feasible for function, class and alias templates, but, does not have a node (that is not a declaration) that can represent the body of the mapping for a variable template.
Option 2 would need a resolution of where ipr::Fundecl, ipr::Typedecl, ipr::Alias or ipr::Var will be stored.
One alternative how option 2 can be addressed is to add a storage for declarations that can be bodies of templates (ipr::impl::Var at the minimum, or all four flavors) and host them in the master_decl_data<ipr::Template>
template<>
struct master_decl_data<ipr::Template>
: basic_decl_data<ipr::Template>, overload_entry {
using Base = basic_decl_data<ipr::Template>;
// The declaration that is considered to be the definition.
Optional<ipr::Template> def { };
Optional<ipr::Linkage> langlinkage { };
const ipr::Template* primary;
const ipr::Region* home;
// The overload set that contains this master declaration. It
// shall be set at the time the node for the master declaration
// is created.
impl::Overload* overload;
// Sequence of specializations
decl_sequence specs;
// +++++++++++ ????????
decl_factory<ipr::Var> vars;
// ++++++++++++++????
master_decl_data(impl::Overload*, const ipr::Type&);
};
Option 2 is a bit wasteful. We do not need entire declaration machinery that deals with overloads and master declarations, since every declaration that is a body of the mapping is unique to that mapping, since it refers to parameters of that particular mapping.
Making Option 1 work for all template kinds needs some kind of node to represent a body of a variable template. Essentially a pair (type and initializer).
About this issue
- Original URL
- State: open
- Created 3 years ago
- Comments: 18 (17 by maintainers)
On 2/25/2021 4:23 PM, Gabriel Dos Reis wrote:
That’s a key design idea - without that, we get lost in obscure language/WG21 details.