[cfe-dev] Function template specializations

Vassil Vassilev vvasilev at cern.ch
Tue Dec 10 15:03:59 PST 2013


On 12/10/13 9:02 PM, Richard Smith wrote:
> On Tue, Dec 10, 2013 at 4:48 AM, Vassil Vassilev 
> <vasil.georgiev.vasilev at cern.ch 
> <mailto:vasil.georgiev.vasilev at cern.ch>> wrote:
>
>     Hi,
>       IIUC when clang instantiates a function template it 'injects' a
>     canonical declaration so that it can register it as a template
>     specialization in the list of specializations. Is there any way to
>     distinguish between implicitly 'injected' one and a forward
>     declaration of the same. Eg:
>
>       template<typename T> T f(){ return T();} template<> int f() {
>     return 0;} // here clang will inject a canonical declaration
>     implicitly IIUC
>       template<typename T> T f(){ return T();} template<> int f();
>     template<> int f() { return 0;} // and here it won't because it
>     was forward declared:
>
>       So my question is given the template specialization definition
>     could I distinguish between the both cases.
>
>
> Ideally we shouldn't generate this extra "bonus" declaration, but in 
> practice it's very useful (for detecting mismatches between the 
> specialization and the template, for instance). One way to distinguish 
> these cases is to compare source locations; if you get two 
> redeclarations of the same function template declaration at the same 
> location, the first one was the implicit one.
>
> I'd take a patch to mark the implicitly-injected declaration with the 
> 'Implicit' flag; that would give a much nicer way to detect this.
I didn't like the idea with comparing the source locations, because it 
looks fragile to me.

I am attaching the diff making the canonical decls for the 
instantiations implicit. There are 3 failing tests with the patch and 1 
without. Looks like I got bad revision set. I will retry tomorrow with 
newer llvm and clang to verify. I might be able to produce a better 
patch and more intrusive though (please note that I am not an expert in 
this):

template<typename T> T f(){ return T();} template<> int f(); template<> 
int f() { return 0;}
Is there any reason why in the case of seeing the forward template 
declaration of f to not 'canonicalize' it and add it as a template 
specialization? Then the code around 
SemaTemplateInstantiateDecl.cpp:1195 (with slight modifications) will 
kick in and the redundant declaration could be avoided.

Vassil

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131211/06ce8aad/attachment.html>
-------------- next part --------------
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp	(revision 196959)
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp	(working copy)
@@ -1251,6 +1251,7 @@
                            D->isInlineSpecified(), D->hasWrittenPrototype(),
                            D->isConstexpr());
   Function->setRangeEnd(D->getSourceRange().getEnd());
+  Function->setImplicit();
 
   if (D->isInlined())
     Function->setImplicitlyInline();


More information about the cfe-dev mailing list