r184634 - 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.
Larisse Voufo
lvoufo at google.com
Sat Jun 22 06:56:11 PDT 2013
Author: lvoufo
Date: Sat Jun 22 08:56:11 2013
New Revision: 184634
URL: http://llvm.org/viewvc/llvm-project?rev=184634&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=184634&r1=184633&r2=184634&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sat Jun 22 08:56:11 2013
@@ -595,6 +595,9 @@ def err_explicit_instantiation_with_defi
def err_template_defn_explicit_instantiation : Error<
"%select{function|class}0 cannot be defined in an explicit instantiation; if this "
"declaration is meant to be a %select{function|class}0 definition, remove the 'template' keyword">;
+def err_friend_explicit_instantiation : Error<
+ "friend cannot be declared in an explicit instantiation; if this "
+ "declaration is meant to be a friend declaration, remove the 'template' keyword">;
def err_explicit_instantiation_enum : Error<
"enumerations cannot be explicitly instantiated">;
def err_expected_template_parameter : Error<"expected template parameter">;
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=184634&r1=184633&r2=184634&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sat Jun 22 08:56:11 2013
@@ -1465,7 +1465,6 @@ void Parser::ParseClassSpecifier(tok::To
// 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::To
// 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::To
// recover by ignoring the 'template' keyword.
Diag(Tok, diag::err_template_defn_explicit_instantiation)
<< 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
+ TemplateParams = 0;
}
bool IsDependent = false;
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=184634&r1=184633&r2=184634&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Sat Jun 22 08:56:11 2013
@@ -242,6 +242,8 @@ Parser::ParseSingleDeclarationAfterTempl
// If the declarator-id is not a template-id, issue a diagnostic and
// recover by ignoring the 'template' keyword.
Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
+ return ParseFunctionDefinition(DeclaratorInfo, ParsedTemplateInfo(),
+ &LateParsedAttrs);
} else {
SourceLocation LAngleLoc
= PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
@@ -251,24 +253,21 @@ Parser::ParseSingleDeclarationAfterTempl
<< FixItHint::CreateInsertion(LAngleLoc, "<>");
// Recover as if it were an explicit specialization.
- TemplateParameterLists ParamLists;
- SmallVector<Decl*, 4> TemplateParams;
- ParamLists.push_back(
- TemplateParameterList::Create(Actions.getASTContext(),
- TemplateInfo.TemplateLoc,
- LAngleLoc,
- (NamedDecl**)TemplateParams.data(),
- TemplateParams.size(), LAngleLoc));
+ TemplateParameterLists FakedParamLists;
+ FakedParamLists.push_back(
+ Actions.ActOnTemplateParameterList(0, SourceLocation(),
+ TemplateInfo.TemplateLoc,
+ LAngleLoc, 0, 0, LAngleLoc));
return ParseFunctionDefinition(DeclaratorInfo,
- ParsedTemplateInfo(&ParamLists,
+ ParsedTemplateInfo(&FakedParamLists,
/*isSpecialization=*/true,
/*LastParamListWasEmpty=*/true),
&LateParsedAttrs);
}
}
return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo,
- &LateParsedAttrs);
+ &LateParsedAttrs);
}
// Parse this declaration.
More information about the cfe-commits
mailing list