r189867 - Parser: support Microsoft syntax for 'typename typedef'

David Majnemer david.majnemer at gmail.com
Tue Sep 3 15:36:22 PDT 2013


Author: majnemer
Date: Tue Sep  3 17:36:22 2013
New Revision: 189867

URL: http://llvm.org/viewvc/llvm-project?rev=189867&view=rev
Log:
Parser: support Microsoft syntax for 'typename typedef'

Summary:
Transform the token sequence for:
typename typedef T U;

to:
typename T typedef U;

Raise a diagnostic when this happens but only if we succeeded handling
the typename.

Reviewers: rsmith, rnk

Reviewed By: rsmith

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D1433

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=189867&r1=189866&r2=189867&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Sep  3 17:36:22 2013
@@ -1480,6 +1480,23 @@ bool Parser::TryAnnotateTypeOrScopeToken
           && "Cannot be a type or scope token!");
 
   if (Tok.is(tok::kw_typename)) {
+    // MSVC lets you do stuff like:
+    //   typename typedef T_::D D;
+    //
+    // We will consume the typedef token here and put it back after we have
+    // parsed the first identifier, transforming it into something more like:
+    //   typename T_::D typedef D;
+    if (getLangOpts().MicrosoftMode && NextToken().is(tok::kw_typedef)) {
+      Token TypedefToken;
+      PP.Lex(TypedefToken);
+      bool Result = TryAnnotateTypeOrScopeToken(EnteringContext, NeedType);
+      PP.EnterToken(Tok);
+      Tok = TypedefToken;
+      if (!Result)
+        Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename);
+      return Result;
+    }
+
     // Parse a C++ typename-specifier, e.g., "typename T::type".
     //
     //   typename-specifier:
@@ -1498,7 +1515,7 @@ bool Parser::TryAnnotateTypeOrScopeToken
         // Attempt to recover by skipping the invalid 'typename'
         if (Tok.is(tok::annot_decltype) ||
             (!TryAnnotateTypeOrScopeToken(EnteringContext, NeedType) &&
-            Tok.isAnnotation())) {
+             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"

Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=189867&r1=189866&r2=189867&view=diff
==============================================================================
--- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Tue Sep  3 17:36:22 2013
@@ -152,7 +152,9 @@ void missing_template_keyword(){
 
 
 
-class AAAA { };
+class AAAA {
+   typedef int D;
+};
 
 template <typename T>
 class SimpleTemplate {};
@@ -174,6 +176,12 @@ void redundant_typename() {
    int k = typename var;// expected-error {{expected a qualified name after 'typename'}}
 }
 
+template <typename T>
+struct TypenameWrongPlace {
+  typename typedef T::D D;// expected-warning {{expected a qualified name after 'typename'}}
+};
+
+extern TypenameWrongPlace<AAAA> PR16925;
 
 __interface MicrosoftInterface;
 __interface MicrosoftInterface {





More information about the cfe-commits mailing list