aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-05-14 22:43:34 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-05-14 22:43:34 +0000
commit23756776eadfd8bbddf5d120d4c191ef9e50d209 (patch)
tree82ced400d4f87ef65ec550071ad3d02676d97fd1 /lib/Parse/Parser.cpp
parent45246a7fc00f07bba9a34a3f13c0af72a05f95be (diff)
Recover properly from a redundant 'typename' before a non-nested name. This is
permitted as a Microsoft extension. Patch by William Wilson! (Plus some minor tweaking by me.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156786 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/Parser.cpp')
-rw-r--r--lib/Parse/Parser.cpp22
1 files changed, 17 insertions, 5 deletions
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 955f4558f8..ad283fa57a 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -1248,7 +1248,8 @@ TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) {
bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)
|| Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope)
- || Tok.is(tok::kw_decltype)) && "Cannot be a type or scope token!");
+ || Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id))
+ && "Cannot be a type or scope token!");
if (Tok.is(tok::kw_typename)) {
// Parse a C++ typename-specifier, e.g., "typename T::type".
@@ -1264,10 +1265,21 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
0, /*IsTypename*/true))
return true;
if (!SS.isSet()) {
- if (getLangOpts().MicrosoftExt)
- Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename);
- else
- Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
+ if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
+ // Attempt to recover by skipping the invalid 'typename'
+ if (!TryAnnotateTypeOrScopeToken(EnteringContext, NeedType) &&
+ Tok.isAnnotation()) {
+ unsigned DiagID = diag::err_expected_qualified_after_typename;
+ // MS compatibility: MSVC permits using known types with typename.
+ // e.g. "typedef typename T* pointer_type"
+ if (getLangOpts().MicrosoftExt)
+ DiagID = diag::warn_expected_qualified_after_typename;
+ Diag(Tok.getLocation(), DiagID);
+ return false;
+ }
+ }
+
+ Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
return true;
}