aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-31 00:43:58 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-31 00:43:58 +0000
commitc45c232440dfafedca1a3773b904fb42609b1b19 (patch)
tree8fc8ee76514079ac19b30b1200dddedd6f74dece /lib/Parse
parentaf3e72285238369c2ea4ebd40a1c9a87bd3eabb7 (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.cpp2
-rw-r--r--lib/Parse/ParseDecl.cpp4
-rw-r--r--lib/Parse/ParseDeclCXX.cpp4
-rw-r--r--lib/Parse/ParseExprCXX.cpp36
-rw-r--r--lib/Parse/ParseTemplate.cpp12
-rw-r--r--lib/Parse/Parser.cpp2
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