diff options
-rw-r--r-- | include/clang/Parse/Parser.h | 8 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 15 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 3 | ||||
-rw-r--r-- | test/SemaTemplate/explicit-instantiation.cpp | 8 |
4 files changed, 24 insertions, 10 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 293c46d1e2..e3ca12af9f 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -2119,9 +2119,11 @@ private: bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs); ParsedTemplateArgument ParseTemplateTemplateArgument(); ParsedTemplateArgument ParseTemplateArgument(); - Decl *ParseExplicitInstantiation(SourceLocation ExternLoc, - SourceLocation TemplateLoc, - SourceLocation &DeclEnd); + Decl *ParseExplicitInstantiation(unsigned Context, + SourceLocation ExternLoc, + SourceLocation TemplateLoc, + SourceLocation &DeclEnd, + AccessSpecifier AS = AS_none); //===--------------------------------------------------------------------===// // Modules diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 9343f5b733..4f2f49c804 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -31,8 +31,9 @@ Parser::ParseDeclarationStartingWithTemplate(unsigned Context, ObjCDeclContextSwitch ObjCDC(*this); if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) { - return ParseExplicitInstantiation(SourceLocation(), ConsumeToken(), - DeclEnd); + return ParseExplicitInstantiation(Context, + SourceLocation(), ConsumeToken(), + DeclEnd, AS); } return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS, AccessAttrs); @@ -1107,17 +1108,19 @@ Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) { /// 'extern' [opt] 'template' declaration /// /// Note that the 'extern' is a GNU extension and C++0x feature. -Decl *Parser::ParseExplicitInstantiation(SourceLocation ExternLoc, +Decl *Parser::ParseExplicitInstantiation(unsigned Context, + SourceLocation ExternLoc, SourceLocation TemplateLoc, - SourceLocation &DeclEnd) { + SourceLocation &DeclEnd, + AccessSpecifier AS) { // This isn't really required here. ParsingDeclRAIIObject ParsingTemplateParams(*this); - return ParseSingleDeclarationAfterTemplate(Declarator::FileContext, + return ParseSingleDeclarationAfterTemplate(Context, ParsedTemplateInfo(ExternLoc, TemplateLoc), ParsingTemplateParams, - DeclEnd, AS_none); + DeclEnd, AS); } SourceRange Parser::ParsedTemplateInfo::getSourceRange() const { diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index c57711dbc6..b2de1046fd 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -656,7 +656,8 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc); SourceLocation DeclEnd; return Actions.ConvertDeclToDeclGroup( - ParseExplicitInstantiation(ExternLoc, TemplateLoc, DeclEnd)); + ParseExplicitInstantiation(Declarator::FileContext, + ExternLoc, TemplateLoc, DeclEnd)); } // FIXME: Detect C++ linkage specifications here? goto dont_know; diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp index dae5c36b70..13d76befe2 100644 --- a/test/SemaTemplate/explicit-instantiation.cpp +++ b/test/SemaTemplate/explicit-instantiation.cpp @@ -97,3 +97,11 @@ namespace PR7622 { // expected-error{{expected member name or ';' after declaration specifiers}} template struct basic_streambuf<int>; } + +// Test that we do not crash. +class TC1 { + class TC2 { + template // FIXME: error here. + void foo() { } + }; +}; |