summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorLarisse Voufo <lvoufo@google.com>2013-06-22 13:56:11 +0000
committerLarisse Voufo <lvoufo@google.com>2013-06-22 13:56:11 +0000
commitb9bbaba6b14b7c11554ffe2467e2508402545a39 (patch)
treed6557e6ec0d86799df29e18b9c4526bf6de8bede /clang/lib/Parse/ParseDeclCXX.cpp
parentb5ab36002022e35ce2e583930c9eaa0b091903a2 (diff)
downloadbcm5719-llvm-b9bbaba6b14b7c11554ffe2467e2508402545a39.tar.gz
bcm5719-llvm-b9bbaba6b14b7c11554ffe2467e2508402545a39.zip
Instantiation bug fix extension (cf. r184503) -- minor code fixes, including a typo that caused a runtime assertion after firing diagnosis for class definitions, with the 'template' keyword as template header, in friend declarations.
llvm-svn: 184634
Diffstat (limited to 'clang/lib/Parse/ParseDeclCXX.cpp')
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp50
1 files changed, 30 insertions, 20 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 68d8e6ba4d0..9ba13141712 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1465,7 +1465,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// This is an explicit specialization or a class template
// partial specialization.
TemplateParameterLists FakedParamLists;
-
if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
// This looks like an explicit instantiation, because we have
// something like
@@ -1475,25 +1474,35 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// but it actually has a definition. Most likely, this was
// meant to be an explicit specialization, but the user forgot
// the '<>' after 'template'.
- assert(TUK == Sema::TUK_Definition && "Expected a definition here");
-
- SourceLocation LAngleLoc
- = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
- Diag(TemplateId->TemplateNameLoc,
- diag::err_explicit_instantiation_with_definition)
- << SourceRange(TemplateInfo.TemplateLoc)
- << FixItHint::CreateInsertion(LAngleLoc, "<>");
-
- // Create a fake template parameter list that contains only
- // "template<>", so that we treat this construct as a class
- // template specialization.
- FakedParamLists.push_back(
- Actions.ActOnTemplateParameterList(0, SourceLocation(),
- TemplateInfo.TemplateLoc,
- LAngleLoc,
- 0, 0,
- LAngleLoc));
- TemplateParams = &FakedParamLists;
+ // It this is friend declaration however, since it cannot have a
+ // template header, it is most likely that the user meant to
+ // remove the 'template' keyword.
+ assert((TUK == Sema::TUK_Definition || TUK == Sema::TUK_Friend) &&
+ "Expected a definition here");
+
+ if (TUK == Sema::TUK_Friend) {
+ Diag(DS.getFriendSpecLoc(),
+ diag::err_friend_explicit_instantiation);
+ TemplateParams = 0;
+ } else {
+ SourceLocation LAngleLoc
+ = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
+ Diag(TemplateId->TemplateNameLoc,
+ diag::err_explicit_instantiation_with_definition)
+ << SourceRange(TemplateInfo.TemplateLoc)
+ << FixItHint::CreateInsertion(LAngleLoc, "<>");
+
+ // Create a fake template parameter list that contains only
+ // "template<>", so that we treat this construct as a class
+ // template specialization.
+ FakedParamLists.push_back(
+ Actions.ActOnTemplateParameterList(0, SourceLocation(),
+ TemplateInfo.TemplateLoc,
+ LAngleLoc,
+ 0, 0,
+ LAngleLoc));
+ TemplateParams = &FakedParamLists;
+ }
}
// Build the class template specialization.
@@ -1546,6 +1555,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// recover by ignoring the 'template' keyword.
Diag(Tok, diag::err_template_defn_explicit_instantiation)
<< 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
+ TemplateParams = 0;
}
bool IsDependent = false;
OpenPOWER on IntegriCloud