diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-09-24 23:14:47 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-09-24 23:14:47 +0000 |
commit | b9aa6b214c8fbc3e081dde575eef1f0913d48bdc (patch) | |
tree | 77bf753a91b1d025823f3adc0a285c0d973beab9 /lib/Sema/SemaDecl.cpp | |
parent | 119fa68eb1394a2653bb651dc5c1cf294cbbdbda (diff) |
WIP implementation of explicit function template specialization. This
first implementation recognizes when a function declaration is an
explicit function template specialization (based on the presence of a
template<> header), performs template argument deduction + ambiguity
resolution to determine which template is being specialized, and hooks
There are many caveats here:
- We completely and totally drop any explicitly-specified template
arguments on the floor
- We don't diagnose any of the extra semantic things that we should
diagnose.
- I haven't looked to see that we're getting the right linkage for
explicit specializations
On a happy note, this silences a bunch of errors that show up in
libstdc++'s <iostream>, although Clang still can't get through the
entire header.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82728 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ec27814870..c9983a8f73 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1794,9 +1794,11 @@ Sema::HandleDeclarator(Scope *S, Declarator &D, if (New == 0) return DeclPtrTy(); - // If this has an identifier and is not an invalid redeclaration, - // add it to the scope stack. - if (Name && !(Redeclaration && New->isInvalidDecl())) + // If this has an identifier and is not an invalid redeclaration or + // function template specialization, add it to the scope stack. + if (Name && !(Redeclaration && New->isInvalidDecl()) && + !(isa<FunctionDecl>(New) && + cast<FunctionDecl>(New)->isFunctionTemplateSpecialization())) PushOnScopeChains(New, S); return DeclPtrTy::make(New); @@ -2516,6 +2518,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // Match up the template parameter lists with the scope specifier, then // determine whether we have a template or a template specialization. FunctionTemplateDecl *FunctionTemplate = 0; + bool isFunctionTemplateSpecialization = false; if (TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( D.getDeclSpec().getSourceRange().getBegin(), @@ -2536,13 +2539,14 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, FunctionTemplate->setLexicalDeclContext(CurContext); NewFD->setDescribedFunctionTemplate(FunctionTemplate); } else { - // FIXME: Handle function template specializations + // This is a function template specialization. + isFunctionTemplateSpecialization = true; } // FIXME: Free this memory properly. TemplateParamLists.release(); } - + // C++ [dcl.fct.spec]p5: // The virtual specifier shall only be used in declarations of // nonstatic class member functions that appear within a @@ -2678,6 +2682,18 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, isOutOfScopePreviousDeclaration(PrevDecl, DC, Context))) PrevDecl = 0; + // FIXME: If the declarator has a template argument list but + // isFunctionTemplateSpecialization is false, this is a function template + // specialization but the user forgot the "template<>" header. Complain about + // the missing template<> header and set isFunctionTemplateSpecialization. + + if (isFunctionTemplateSpecialization && + CheckFunctionTemplateSpecialization(NewFD, + /*FIXME:*/false, SourceLocation(), + 0, 0, SourceLocation(), + PrevDecl)) + NewFD->setInvalidDecl(); + // Perform semantic checking on the function declaration. bool OverloadableAttrRequired = false; // FIXME: HACK! CheckFunctionDeclaration(NewFD, PrevDecl, Redeclaration, |