diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-05-12 23:25:50 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-05-12 23:25:50 +0000 |
commit | 1b57ff32a828c485f5b685ffe02e2effa79f405a (patch) | |
tree | 79d0cd3dbd5bff8a94b409d94fd36b947fb3b6e3 /clang/lib/Parse/ParseTemplate.cpp | |
parent | e83b560e0687b83a118ee352a93bc10014153248 (diff) | |
download | bcm5719-llvm-1b57ff32a828c485f5b685ffe02e2effa79f405a.tar.gz bcm5719-llvm-1b57ff32a828c485f5b685ffe02e2effa79f405a.zip |
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.
llvm-svn: 71608
Diffstat (limited to 'clang/lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 22d11779ab3..490f2769e12 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -18,6 +18,18 @@ #include "AstGuard.h" using namespace clang; +/// \brief Parse a template declaration, explicit instantiation, or +/// explicit specialization. +Parser::DeclPtrTy +Parser::ParseDeclarationStartingWithTemplate(unsigned Context, + SourceLocation &DeclEnd, + AccessSpecifier AS) { + if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) + return ParseExplicitInstantiation(ConsumeToken(), DeclEnd); + + return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS); +} + /// \brief Parse a template declaration or an explicit specialization. /// /// Template declarations include one or more template parameter lists @@ -64,6 +76,7 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, // defining A<T>::B receives just the inner template parameter list // (and retrieves the outer template parameter list from its // context). + bool isSpecialiation = true; TemplateParameterLists ParamLists; do { // Consume the 'export', if any. @@ -87,6 +100,9 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, ParseTemplateParameters(ParamLists.size(), TemplateParams, LAngleLoc, RAngleLoc); + if (!TemplateParams.empty()) + isSpecialiation = false; + ParamLists.push_back( Actions.ActOnTemplateParameterList(ParamLists.size(), ExportLoc, TemplateLoc, LAngleLoc, @@ -95,8 +111,9 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, } while (Tok.is(tok::kw_export) || Tok.is(tok::kw_template)); // Parse the actual template declaration. - return ParseSingleDeclarationAfterTemplate(Context, &ParamLists, - SourceLocation(), + return ParseSingleDeclarationAfterTemplate(Context, + ParsedTemplateInfo(&ParamLists, + isSpecialiation), DeclEnd, AS); } @@ -123,14 +140,16 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, Parser::DeclPtrTy Parser::ParseSingleDeclarationAfterTemplate( unsigned Context, - TemplateParameterLists *TemplateParams, - SourceLocation TemplateLoc, + const ParsedTemplateInfo &TemplateInfo, SourceLocation &DeclEnd, AccessSpecifier AS) { + assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && + "Template information required"); + // Parse the declaration specifiers. DeclSpec DS; // FIXME: Pass TemplateLoc through for explicit template instantiations - ParseDeclarationSpecifiers(DS, TemplateParams, AS); + ParseDeclarationSpecifiers(DS, TemplateInfo, AS); if (Tok.is(tok::semi)) { DeclEnd = ConsumeToken(); @@ -156,7 +175,7 @@ Parser::ParseSingleDeclarationAfterTemplate( if (Tok.is(tok::comma)) { Diag(Tok, diag::err_multiple_template_declarators) - << (TemplateParams == 0); + << (int)TemplateInfo.Kind; SkipUntil(tok::semi, true, false); return ThisDecl; } @@ -785,11 +804,10 @@ Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs, /// /// explicit-instantiation: /// 'template' declaration -Parser::DeclPtrTy Parser::ParseExplicitInstantiation(SourceLocation &DeclEnd) { - assert(Tok.is(tok::kw_template) && NextToken().isNot(tok::less) && - "Token does not start an explicit instantiation."); - - SourceLocation TemplateLoc = ConsumeToken(); - return ParseSingleDeclarationAfterTemplate(Declarator::FileContext, 0, - TemplateLoc, DeclEnd, AS_none); +Parser::DeclPtrTy +Parser::ParseExplicitInstantiation(SourceLocation TemplateLoc, + SourceLocation &DeclEnd) { + return ParseSingleDeclarationAfterTemplate(Declarator::FileContext, + ParsedTemplateInfo(TemplateLoc), + DeclEnd, AS_none); } |