[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