[cfe-dev] On instantiations of template declarations.

Douglas Gregor dgregor at apple.com
Tue Jun 1 08:44:56 PDT 2010


On Jun 1, 2010, at 7:38 AM, Enea Zaffanella wrote:
> Consider now the following variant, where we have a static data member:
> 
> template <typename T>
> struct A { static int a; };
> 
> template <typename T>
> int A<T>::a = 0;
> 
> A<int> si;
> A<double> sd;
> 
> void bar() {
>   sd.a = 13;
> }
> 
> Here, we have two implicit instantiations of the template A.
> Each of those declares the corresponding static data member.
> For one of those (A<double>), we also have an implicit instantiation of 
> the *definition* of the static data member A<double>::a.
> This implicit definition is reachable starting from the implicit 
> declaration using method:
> 
>   VarDecl* VarDecl::getOutOfLineDefinition();
>   If this is a static data member, find its out-of-line definition.
> 
> Strangely, the very same implicit definition is also listed in the 
> context of the translation unit. This can be seen when dumping the AST, 
> just after the definition of function bar():
> 
> ===================
> [...]
> void bar() (CompoundStmt 0x2151fb0 <var_template.cc:10:12, line:12:1>
>   (BinaryOperator 0x216be70 <line:11:3, col:10> 'int' '='
>     (MemberExpr 0x216bdf0 <col:3, col:6> 'int' .a 0x216b160
>       (DeclRefExpr 0x216bdb0 <col:3> 'A<double>':'struct A<double>' 
> Var='sd' 0x216ae10))
>     (IntegerLiteral 0x216be30 <col:10> 'int' 13)))
> 
> 
> static int a = (IntegerLiteral 0x216a8d0 <var_template.cc:5:15> 'int' 0)
> ;
> ===================
> 
> So, finally, our question is: why such a difference?
> 
> That is, why does the translation unit context contains these 
> (implicitly instantiated) definitions of static data members?
> It was not containing the (implicitly instantiated) specialization of 
> the class template ... or of its methods.

Definitely a bug. Implicit instantiations should not show up in the translation unit context.

> Moreover, why there is not in the VarDecl object corresponding to
>   template <typename T> int A<T>::a = 0;
> a method for extracting all of its specializations, similarly to what is 
> done for class and function templates? That is, something like
> 
>   llvm::FoldingSet<VarDecl>& getSpecializations();


We're trying to save memory. One can find the specialization for a static data member just be looking up the name in the instantiation of its class.

	- Doug



More information about the cfe-dev mailing list