summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-05-03 18:35:10 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-05-03 18:35:10 +0000
commit7c9856deb32130fe8a249020cfe95816a4e77d2f (patch)
tree3ad3c8f993e0d197b0cb5a89748669870fc14eac /clang/lib
parentfd23782c26b216f3a03dfaacec750ea711176a35 (diff)
downloadbcm5719-llvm-7c9856deb32130fe8a249020cfe95816a4e77d2f.tar.gz
bcm5719-llvm-7c9856deb32130fe8a249020cfe95816a4e77d2f.zip
When parsing a template friend declaration we dropped the template
parameters on the floor in certain cases: class X { template <typename T> friend typename A<T>::Foo; }; This was parsed as a *non* template friend declaration some how, and received an ExtWarn. Fixing the parser to actually provide the template parameters to the freestanding declaration parse triggers the code which specifically looks for such constructs and hard errors on them. Along the way, this prevents us from trying to instantiate constructs like the above inside of a outer template. This is important as loosing the template parameters means we don't have a well formed declaration and template instantiation will be unable to rebuild the AST. That fixes a crash in the GCC test suite. llvm-svn: 130772
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp2
-rw-r--r--clang/lib/Sema/SemaDecl.cpp12
2 files changed, 12 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 8c0aa1ba694..596778dbd32 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1547,7 +1547,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if (Tok.is(tok::semi)) {
ConsumeToken();
Decl *TheDecl =
- Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS);
+ Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams);
DS.complete(TheDecl);
return;
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7214988bdaf..975a9635748 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2132,6 +2132,16 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
/// no declarator (e.g. "struct foo;") is parsed.
Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
DeclSpec &DS) {
+ return ParsedFreeStandingDeclSpec(S, AS, DS,
+ MultiTemplateParamsArg(*this, 0, 0));
+}
+
+/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+/// no declarator (e.g. "struct foo;") is parsed. It also accopts template
+/// parameters to cope with template friend declarations.
+Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
+ DeclSpec &DS,
+ MultiTemplateParamsArg TemplateParams) {
Decl *TagD = 0;
TagDecl *Tag = 0;
if (DS.getTypeSpecType() == DeclSpec::TST_class ||
@@ -2163,7 +2173,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
// whatever routines created it handled the friendship aspect.
if (TagD && !Tag)
return 0;
- return ActOnFriendTypeDecl(S, DS, MultiTemplateParamsArg(*this, 0, 0));
+ return ActOnFriendTypeDecl(S, DS, TemplateParams);
}
// Track whether we warned about the fact that there aren't any
OpenPOWER on IntegriCloud