Implement parsing for explicit instantiations of class templates, e.g.,
template class X<int>;
This also cleans up the propagation of template information through
declaration parsing, which is used to improve some diagnostics.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71608 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 9d7d9d4..cdf84bf 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -234,14 +234,8 @@
DeclPtrTy SingleDecl;
switch (Tok.getKind()) {
case tok::kw_template:
- if (NextToken().isNot(tok::less)) {
- SingleDecl = ParseExplicitInstantiation(DeclEnd);
- break;
- }
- // Fall through for template declarations and specializations
-
case tok::kw_export:
- SingleDecl = ParseTemplateDeclarationOrSpecialization(Context, DeclEnd);
+ SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
break;
case tok::kw_namespace:
SingleDecl = ParseNamespace(Context, DeclEnd);
@@ -521,7 +515,7 @@
/// other pieces of declspec after it, it returns true.
///
bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
- TemplateParameterLists *TemplateParams,
+ const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS) {
assert(Tok.is(tok::identifier) && "should have identifier");
@@ -576,7 +570,7 @@
if (TagKind == tok::kw_enum)
ParseEnumSpecifier(Loc, DS, AS);
else
- ParseClassSpecifier(TagKind, Loc, DS, TemplateParams, AS);
+ ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS);
return true;
}
}
@@ -622,7 +616,7 @@
///
void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
- TemplateParameterLists *TemplateParams,
+ const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS) {
DS.SetRangeStart(Tok.getLocation());
while (1) {
@@ -686,7 +680,7 @@
// typename.
if (TypeRep == 0) {
ConsumeToken(); // Eat the scope spec so the identifier is current.
- if (ParseImplicitInt(DS, &SS, TemplateParams, AS)) continue;
+ if (ParseImplicitInt(DS, &SS, TemplateInfo, AS)) continue;
goto DoneWithDeclSpec;
}
@@ -748,7 +742,7 @@
// If this is not a typedef name, don't parse it as part of the declspec,
// it must be an implicit int or an error.
if (TypeRep == 0) {
- if (ParseImplicitInt(DS, 0, TemplateParams, AS)) continue;
+ if (ParseImplicitInt(DS, 0, TemplateInfo, AS)) continue;
goto DoneWithDeclSpec;
}
@@ -934,7 +928,7 @@
case tok::kw_union: {
tok::TokenKind Kind = Tok.getKind();
ConsumeToken();
- ParseClassSpecifier(Kind, Loc, DS, TemplateParams, AS);
+ ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS);
continue;
}
@@ -1047,7 +1041,7 @@
/// [OBJC] typedef-name objc-protocol-refs[opt] [TODO]
bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
const char *&PrevSpec,
- TemplateParameterLists *TemplateParams){
+ const ParsedTemplateInfo &TemplateInfo) {
SourceLocation Loc = Tok.getLocation();
switch (Tok.getKind()) {
@@ -1056,7 +1050,7 @@
// Annotate typenames and C++ scope specifiers. If we get one, just
// recurse to handle whatever we get.
if (TryAnnotateTypeOrScopeToken())
- return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec,TemplateParams);
+ return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, TemplateInfo);
// Otherwise, not a type specifier.
return false;
case tok::coloncolon: // ::foo::bar
@@ -1067,7 +1061,7 @@
// Annotate typenames and C++ scope specifiers. If we get one, just
// recurse to handle whatever we get.
if (TryAnnotateTypeOrScopeToken())
- return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec,TemplateParams);
+ return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, TemplateInfo);
// Otherwise, not a type specifier.
return false;
@@ -1156,7 +1150,7 @@
case tok::kw_union: {
tok::TokenKind Kind = Tok.getKind();
ConsumeToken();
- ParseClassSpecifier(Kind, Loc, DS, TemplateParams);
+ ParseClassSpecifier(Kind, Loc, DS, TemplateInfo);
return true;
}