Function template specializations

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.
Many thanks,
Vassil

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 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

implicit_template_decls.diff (533 Bytes)