diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-07-22 23:48:44 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-07-22 23:48:44 +0000 |
commit | 7cdbc5832084f45721693dfb1d93284c3e08efee (patch) | |
tree | 1c31b6a6580709273dc40913ee491c7f44e86eaa /lib/Sema | |
parent | 6016cb2d1e99960675e4c4bb97f6f4ecdff97818 (diff) |
Implement support for out-of-line definitions of the class members of class
templates, e.g.,
template<typename T>
struct Outer {
struct Inner;
};
template<typename T>
struct Outer<T>::Inner {
// ...
};
Implementing this feature required some extensions to ActOnTag, which
now takes a set of template parameter lists, and is the precursor to
removing the ActOnClassTemplate function from the parser Action
interface. The reason for this approach is simple: the parser cannot
tell the difference between a class template definition and the
definition of a member of a class template; both have template
parameter lists, and semantic analysis determines what that template
parameter list means.
There is still some cleanup to do with ActOnTag and
ActOnClassTemplate. This commit provides the basic functionality we
need, however.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76820 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 27 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 3 |
4 files changed, 29 insertions, 4 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 7daf3f90a8..78d64b53c0 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -522,6 +522,7 @@ public: SourceLocation KWLoc, const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, AccessSpecifier AS, + MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl); virtual void ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart, diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index cf73725e7f..be1a1103b3 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -213,7 +213,7 @@ bool Sema::RequireCompleteDeclContext(const CXXScopeSpec &SS) { if (!SS.isSet() || SS.isInvalid()) return false; - DeclContext *DC = computeDeclContext(SS); + DeclContext *DC = computeDeclContext(SS, true); if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { // If we're currently defining this type, then lookup into the // type is okay: don't complain that it isn't complete yet. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 2e280f58cb..d9c1224b43 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1866,14 +1866,14 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, } else { // There is an extraneous 'template<>' for this variable. Complain // about it, but allow the declaration of the variable. - Diag(TemplateParams->getTemplateLoc(), diag::err_template_variable) + Diag(TemplateParams->getTemplateLoc(), + diag::err_template_variable_noparams) << II << SourceRange(TemplateParams->getTemplateLoc(), TemplateParams->getRAngleLoc()); } } - // The variable can not NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(), II, R, SC, // FIXME: Move to DeclGroup... @@ -3522,6 +3522,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, AccessSpecifier AS, + MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl) { // If this is not a definition, it must have a name. assert((Name != 0 || TK == TK_Definition) && @@ -3537,6 +3538,28 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, case DeclSpec::TST_enum: Kind = TagDecl::TK_enum; break; } + if (TK != TK_Reference) { + if (TemplateParameterList *TemplateParams + = MatchTemplateParametersToScopeSpecifier(KWLoc, SS, + (TemplateParameterList**)TemplateParameterLists.get(), + TemplateParameterLists.size())) { + if (TemplateParams->size() > 0) { + // This is a declaration or definition of a class template (which may + // be a member of another template). + OwnedDecl = false; + DeclResult Result = ActOnClassTemplate(S, TagSpec, TK, KWLoc, + SS, Name, NameLoc, Attr, + move(TemplateParameterLists), + AS); + return Result.get(); + } else { + // FIXME: diagnose the extraneous 'template<>', once we recover + // slightly better in ParseTemplate.cpp from bogus template + // parameters. + } + } + } + DeclContext *SearchDC = CurContext; DeclContext *DC = CurContext; NamedDecl *PrevDecl = 0; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 5f772bc22c..981b8508c5 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2895,7 +2895,8 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, bool Owned = false; DeclPtrTy TagD = ActOnTag(S, TagSpec, Action::TK_Reference, - KWLoc, SS, Name, NameLoc, Attr, AS_none, Owned); + KWLoc, SS, Name, NameLoc, Attr, AS_none, + MultiTemplateParamsArg(*this, 0, 0), Owned); if (!TagD) return true; |