aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-01-12 21:28:44 +0000
committerDouglas Gregor <dgregor@apple.com>2010-01-12 21:28:44 +0000
commit84d0a19828599e8623223632d59447fd498999cf (patch)
tree3812778b563c064aae7c1a594abdc3e32e748790 /lib/Parse/ParseDeclCXX.cpp
parent7ef655a78863c0a7550bfe51174b9c340ab1dce0 (diff)
Improve recovery for template-ids whose template-name doesn't actually
name a template, when they occur in a base-specifier. This is one of the (few) places where we know for sure that an identifier followed by a '<' must be a template name, so we can diagnose and recover well: test/SemaTemplate/dependent-base-classes.cpp:9:16: error: missing 'template' keyword prior to dependent template name 'T::apply' struct X1 : T::apply<U> { }; // expected-error{{missing 'template' ... ^ template test/SemaTemplate/dependent-base-classes.cpp:12:13: error: unknown template name 'vector' struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}} ^ 2 diagnostics generated. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93257 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r--lib/Parse/ParseDeclCXX.cpp51
1 files changed, 45 insertions, 6 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 61a494193c..90040c54bf 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -490,18 +490,57 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
return true;
}
+ IdentifierInfo *Id = Tok.getIdentifierInfo();
+ SourceLocation IdLoc = ConsumeToken();
+
+ if (Tok.is(tok::less)) {
+ // It looks the user intended to write a template-id here, but the
+ // template-name was wrong. Try to fix that.
+ TemplateNameKind TNK = TNK_Type_template;
+ TemplateTy Template;
+ if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, CurScope,
+ SS, Template, TNK)) {
+ Diag(IdLoc, diag::err_unknown_template_name)
+ << Id;
+ }
+
+ if (!Template)
+ return true;
+
+ // Form the template name
+ UnqualifiedId TemplateName;
+ TemplateName.setIdentifier(Id, IdLoc);
+
+ // Parse the full template-id, then turn it into a type.
+ if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName,
+ SourceLocation(), true))
+ return true;
+ if (TNK == TNK_Dependent_template_name)
+ AnnotateTemplateIdTokenAsType(SS);
+
+ // If we didn't end up with a typename token, there's nothing more we
+ // can do.
+ if (Tok.isNot(tok::annot_typename))
+ return true;
+
+ // Retrieve the type from the annotation token, consume that token, and
+ // return.
+ EndLocation = Tok.getAnnotationEndLoc();
+ TypeTy *Type = Tok.getAnnotationValue();
+ ConsumeToken();
+ return Type;
+ }
+
// We have an identifier; check whether it is actually a type.
- TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(),
- Tok.getLocation(), CurScope, SS,
- true);
- if (!Type) {
- Diag(Tok, DestrExpected ? diag::err_destructor_class_name
+ TypeTy *Type = Actions.getTypeName(*Id, IdLoc, CurScope, SS, true);
+ if (!Type) {
+ Diag(IdLoc, DestrExpected ? diag::err_destructor_class_name
: diag::err_expected_class_name);
return true;
}
// Consume the identifier.
- EndLocation = ConsumeToken();
+ EndLocation = IdLoc;
return Type;
}