summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-07-22 23:48:44 +0000
committerDouglas Gregor <dgregor@apple.com>2009-07-22 23:48:44 +0000
commite93e46c69096c8f6ad9e61578955d60a0de59f1d (patch)
tree3559b7c80967b179542bc71ed1c1029a9f5a3abc /clang/lib/Sema/SemaDecl.cpp
parentd2aeef0703f6c752b7215e551ce219e2971b42e3 (diff)
downloadbcm5719-llvm-e93e46c69096c8f6ad9e61578955d60a0de59f1d.tar.gz
bcm5719-llvm-e93e46c69096c8f6ad9e61578955d60a0de59f1d.zip
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. llvm-svn: 76820
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2e280f58cb5..d9c1224b435 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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;
OpenPOWER on IntegriCloud