[cfe-commits] r156786 - in /cfe/trunk: lib/Parse/Parser.cpp test/Parser/MicrosoftExtensions.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Mon May 14 15:43:34 PDT 2012
Author: rsmith
Date: Mon May 14 17:43:34 2012
New Revision: 156786
URL: http://llvm.org/viewvc/llvm-project?rev=156786&view=rev
Log:
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.)
Modified:
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/test/Parser/MicrosoftExtensions.cpp
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=156786&r1=156785&r2=156786&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon May 14 17:43:34 2012
@@ -1248,7 +1248,8 @@
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 @@
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;
}
Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=156786&r1=156785&r2=156786&view=diff
==============================================================================
--- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Mon May 14 17:43:34 2012
@@ -151,11 +151,24 @@
class AAAA { };
+template <typename T>
+class SimpleTemplate {};
+
template <class T>
void redundant_typename() {
typename T t;// expected-warning {{expected a qualified name after 'typename'}}
typename AAAA a;// expected-warning {{expected a qualified name after 'typename'}}
+
t = 3;
+
+ typedef typename T* pointerT;// expected-warning {{expected a qualified name after 'typename'}}
+ typedef typename SimpleTemplate<int> templateT;// expected-warning {{expected a qualified name after 'typename'}}
+
+ pointerT pT = &t;
+ *pT = 4;
+
+ int var;
+ int k = typename var;// expected-error {{expected a qualified name after 'typename'}}
}
More information about the cfe-commits
mailing list