diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-07-21 23:53:31 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-07-21 23:53:31 +0000 |
commit | f59a56e180bf54528d7d1d5afa68fcc13300965a (patch) | |
tree | df0ccbf20fb79ddbd0b8939afcf838bfb16be0a2 /lib/Sema/SemaDecl.cpp | |
parent | 3502deee1a93e86a97fb22df1cdb512c5a643dd6 (diff) |
Basic parsing and semantic analysis for out-of-line definitions of the
member functions of class templates, e.g.,
template<typename T>
struct X {
void f(T);
};
template<typename T> X<T>::f(T) { /* ... */ }
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76692 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 4674327e6c..283033bd7c 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -707,8 +707,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old); const CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New); if (OldMethod && NewMethod && - OldMethod->getLexicalDeclContext() == - NewMethod->getLexicalDeclContext()) { + NewMethod->getLexicalDeclContext()->isRecord()) { // -- Member function declarations with the same name and the // same parameter types cannot be overloaded if any of them // is a static member function declaration. @@ -1445,7 +1444,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D, NameKind == LookupRedeclarationWithLinkage, D.getIdentifierLoc()); } else { // Something like "int foo::x;" - DC = computeDeclContext(D.getCXXScopeSpec()); + DC = computeDeclContext(D.getCXXScopeSpec(), true); // FIXME: RequireCompleteDeclContext(D.getCXXScopeSpec()); ? PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true); @@ -2191,14 +2190,15 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // from the semantic context. NewFD->setLexicalDeclContext(CurContext); - // If there is a template parameter list, then we are dealing with a - // template declaration or specialization. + // Match up the template parameter lists with the scope specifier, then + // determine whether we have a template or a template specialization. FunctionTemplateDecl *FunctionTemplate = 0; - if (TemplateParamLists.size()) { - // FIXME: member templates! - TemplateParameterList *TemplateParams - = static_cast<TemplateParameterList *>(*TemplateParamLists.release()); - + if (TemplateParameterList *TemplateParams + = MatchTemplateParametersToScopeSpecifier( + D.getDeclSpec().getSourceRange().getBegin(), + D.getCXXScopeSpec(), + (TemplateParameterList**)TemplateParamLists.release(), + TemplateParamLists.size())) { if (TemplateParams->size() > 0) { // This is a function template FunctionTemplate = FunctionTemplateDecl::Create(Context, CurContext, @@ -2210,6 +2210,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // FIXME: Handle function template specializations } } + // C++ [dcl.fct.spec]p5: // The virtual specifier shall only be used in declarations of @@ -3517,7 +3518,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, if (RequireCompleteDeclContext(SS)) return DeclPtrTy::make((Decl *)0); - DC = computeDeclContext(SS); + DC = computeDeclContext(SS, true); SearchDC = DC; // Look-up name inside 'foo::'. PrevDecl |