diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-03-31 00:43:58 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-03-31 00:43:58 +0000 |
commit | c45c232440dfafedca1a3773b904fb42609b1b19 (patch) | |
tree | 8fc8ee76514079ac19b30b1200dddedd6f74dece /lib/Parse | |
parent | af3e72285238369c2ea4ebd40a1c9a87bd3eabb7 (diff) |
Parsing and AST representation for dependent template names that occur
within nested-name-specifiers, e.g., for the "apply" in
typename MetaFun::template apply<T1, T2>::type
At present, we can't instantiate these nested-name-specifiers, so our
testing is sketchy.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68081 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/MinimalAction.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 36 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 12 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 2 |
6 files changed, 30 insertions, 30 deletions
diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp index e99e96a7dc..fcbf4eea94 100644 --- a/lib/Parse/MinimalAction.cpp +++ b/lib/Parse/MinimalAction.cpp @@ -134,7 +134,7 @@ bool MinimalAction::isCurrentClassName(const IdentifierInfo &, Scope *, } TemplateNameKind -MinimalAction::isTemplateName(IdentifierInfo &II, Scope *S, +MinimalAction::isTemplateName(const IdentifierInfo &II, Scope *S, TemplateTy &TemplateDecl, const CXXScopeSpec *SS) { return TNK_Non_template; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index f80afe3f4b..11658d4c50 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -513,7 +513,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, Token Next = NextToken(); if (Next.is(tok::annot_template_id) && static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue()) - ->Kind == TNK_Class_template) { + ->Kind == TNK_Type_template) { // We have a qualified template-id, e.g., N::A<int> CXXScopeSpec SS; ParseOptionalCXXScopeSpecifier(SS); @@ -640,7 +640,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, case tok::annot_template_id: { TemplateIdAnnotation *TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); - if (TemplateId->Kind != TNK_Class_template) { + if (TemplateId->Kind != TNK_Type_template) { // This template-id does not refer to a type name, so we're // done with the type-specifiers. goto DoneWithDeclSpec; diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index fdfc7315a8..663fea5096 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -307,7 +307,7 @@ Parser::TypeTy *Parser::ParseClassName(SourceLocation &EndLocation, if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); - if (TemplateId->Kind == TNK_Class_template) { + if (TemplateId->Kind == TNK_Type_template) { if (AnnotateTemplateIdTokenAsType(SS)) return 0; @@ -419,7 +419,7 @@ void Parser::ParseClassSpecifier(DeclSpec &DS, TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); NameLoc = ConsumeToken(); - if (TemplateId->Kind != TNK_Class_template) { + if (TemplateId->Kind != TNK_Type_template) { // The template-name in the simple-template-id refers to // something other than a class template. Give an appropriate // error message and skip to the ';'. diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 4d419bbd87..2c6963a05f 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -92,9 +92,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) { Tok.is(tok::kw_template)) { // Parse the optional 'template' keyword, then make sure we have // 'identifier <' after it. - SourceLocation TemplateKWLoc; if (Tok.is(tok::kw_template)) { - TemplateKWLoc = ConsumeToken(); + SourceLocation TemplateKWLoc = ConsumeToken(); if (Tok.isNot(tok::identifier)) { Diag(Tok.getLocation(), @@ -110,20 +109,20 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) { << SourceRange(TemplateKWLoc, Tok.getLocation()); break; } - } - else { - // FIXME: If the nested-name-specifier thus far is dependent, - // we need to break out of here, because this '<' is taken as - // an operator and not as part of a simple-template-id. + + TemplateTy Template + = Actions.ActOnDependentTemplateName(TemplateKWLoc, + *Tok.getIdentifierInfo(), + Tok.getLocation(), + SS); + AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, + &SS, TemplateKWLoc, false); + continue; } TemplateTy Template; - TemplateNameKind TNK = TNK_Non_template; - // FIXME: If the nested-name-specifier thus far is dependent, - // set TNK = TNK_Dependent_template_name and skip the - // "isTemplateName" check. - TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(), - CurScope, Template, &SS); + TemplateNameKind TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(), + CurScope, Template, &SS); if (TNK) { // We have found a template name, so annotate this this token // with a template-id annotation. We do not permit the @@ -131,7 +130,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) { // because some clients (e.g., the parsing of class template // specializations) still want to see the original template-id // token. - AnnotateTemplateIdToken(Template, TNK, &SS, TemplateKWLoc, false); + AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(), false); continue; } } @@ -142,12 +141,13 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) { // simple-template-id '::' // // So we need to check whether the simple-template-id is of the - // right kind (it should name a type), and then convert it into - // a type within the nested-name-specifier. + // right kind (it should name a type or be dependent), and then + // convert it into a type within the nested-name-specifier. TemplateIdAnnotation *TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); - if (TemplateId->Kind == TNK_Class_template) { + if (TemplateId->Kind == TNK_Type_template || + TemplateId->Kind == TNK_Dependent_template_name) { if (AnnotateTemplateIdTokenAsType(&SS)) SS.clear(); @@ -172,7 +172,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) { SS.setEndLoc(CCLoc); continue; } else - assert(false && "FIXME: Only class template names supported here"); + assert(false && "FIXME: Only type template names supported here"); } // We don't have any tokens that form the beginning of a diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 8eda694864..45d148e38b 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -531,8 +531,7 @@ void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, return; // Build the annotation token. - // FIXME: Not just for class templates! - if (TNK == TNK_Class_template && AllowTypeAnnotation) { + if (TNK == TNK_Type_template && AllowTypeAnnotation) { Action::TypeResult Type = Actions.ActOnTemplateIdType(Template, TemplateNameLoc, LAngleLoc, TemplateArgsPtr, @@ -550,8 +549,8 @@ void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, else Tok.setLocation(TemplateNameLoc); } else { - // This is a function template. We'll be building a template-id - // annotation token. + // Build a template-id annotation token that can be processed + // later. Tok.setKind(tok::annot_template_id); TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Allocate(TemplateArgs.size()); @@ -595,8 +594,9 @@ bool Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) { TemplateIdAnnotation *TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); - assert(TemplateId->Kind == TNK_Class_template && - "Only works for class templates"); + assert((TemplateId->Kind == TNK_Type_template || + TemplateId->Kind == TNK_Dependent_template_name) && + "Only works for type and dependent templates"); ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateId->getTemplateArgs(), diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index a101aaa732..56e217a329 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -901,7 +901,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() { if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); - if (TemplateId->Kind == TNK_Class_template) { + if (TemplateId->Kind == TNK_Type_template) { // A template-id that refers to a type was parsed into a // template-id annotation in a context where we weren't allowed // to produce a type annotation token. Update the template-id |