aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-05-12 23:25:50 +0000
committerDouglas Gregor <dgregor@apple.com>2009-05-12 23:25:50 +0000
commit4d9a16f36d3b768672d50e6d02000f982ae448d7 (patch)
treed25cf10b1f7bd1f93a5559c45ac95dc915781d70 /lib/Parse/ParseDecl.cpp
parent05fa629c9f61ae62bef5315344c840fe3d239328 (diff)
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
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r--lib/Parse/ParseDecl.cpp28
1 files changed, 11 insertions, 17 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 9d7d9d400f..cdf84bfad6 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -234,14 +234,8 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
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 @@ static bool isValidAfterIdentifierInDeclarator(const Token &T) {
/// 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 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
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 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
///
void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
- TemplateParameterLists *TemplateParams,
+ const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS) {
DS.SetRangeStart(Tok.getLocation());
while (1) {
@@ -686,7 +680,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// 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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// 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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
/// [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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
// 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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
// 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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
case tok::kw_union: {
tok::TokenKind Kind = Tok.getKind();
ConsumeToken();
- ParseClassSpecifier(Kind, Loc, DS, TemplateParams);
+ ParseClassSpecifier(Kind, Loc, DS, TemplateInfo);
return true;
}