erichkeane created this revision.

As we know, MSVC is pretty relaxed when it comes to 'typename'.  Clang so far 
does a pretty darn good job of permitting the behavior, however there was 1 
missed case that compiles in MSVC (as of 2015), but not in clang.  I've updated 
the test for similar ones that also/still pass, but were not tested.

  template<typename T>
  struct S { 
    typedef int TD;
  };
  template<class TMP>
  void foo() {
    S<TMP>::TD varname =0;
  }
  
  void foo2(){
    foo<int>();
  }

The above was previously an error in clang in -fms-compatibility mode.  This 
patch alters the parser in MSVC mode to correctly assume the 'typename' above 
where necessary.


https://reviews.llvm.org/D29401

Files:
  lib/Parse/ParseStmt.cpp
  test/SemaCXX/MicrosoftCompatibility.cpp


Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp
+++ lib/Parse/ParseStmt.cpp
@@ -183,7 +183,8 @@
 
     // Look up the identifier, and typo-correct it to a keyword if it's not
     // found.
-    if (Next.isNot(tok::coloncolon)) {
+    if (Next.isNot(tok::coloncolon) && (!getLangOpts().MSVCCompat ||
+        Next.isNot(tok::less))) {
       // Try to limit which sets of keywords should be included in typo
       // correction based on what the next token is.
       if (TryAnnotateName(/*IsAddressOfOperand*/ false,
Index: test/SemaCXX/MicrosoftCompatibility.cpp
===================================================================
--- test/SemaCXX/MicrosoftCompatibility.cpp
+++ test/SemaCXX/MicrosoftCompatibility.cpp
@@ -218,6 +218,9 @@
 void function_missing_typename(const T::Type param)// expected-warning 
{{missing 'typename' prior to dependent type name}}
 {
     const T::Type var = 2; // expected-warning {{missing 'typename' prior to 
dependent type name}}
+    const A<T>::TYPE var2 = 2; // expected-warning {{missing 'typename' prior 
to dependent type name}}
+    A<T>::TYPE var3 = 2; // expected-warning {{missing 'typename' prior to 
dependent type name}}
+    MissingTypename::A<T>::TYPE var4 = 2; // expected-warning {{missing 
'typename' prior to dependent type name}}
 }
 
 template void function_missing_typename<D>(const D::Type param);


Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp
+++ lib/Parse/ParseStmt.cpp
@@ -183,7 +183,8 @@
 
     // Look up the identifier, and typo-correct it to a keyword if it's not
     // found.
-    if (Next.isNot(tok::coloncolon)) {
+    if (Next.isNot(tok::coloncolon) && (!getLangOpts().MSVCCompat ||
+        Next.isNot(tok::less))) {
       // Try to limit which sets of keywords should be included in typo
       // correction based on what the next token is.
       if (TryAnnotateName(/*IsAddressOfOperand*/ false,
Index: test/SemaCXX/MicrosoftCompatibility.cpp
===================================================================
--- test/SemaCXX/MicrosoftCompatibility.cpp
+++ test/SemaCXX/MicrosoftCompatibility.cpp
@@ -218,6 +218,9 @@
 void function_missing_typename(const T::Type param)// expected-warning {{missing 'typename' prior to dependent type name}}
 {
     const T::Type var = 2; // expected-warning {{missing 'typename' prior to dependent type name}}
+    const A<T>::TYPE var2 = 2; // expected-warning {{missing 'typename' prior to dependent type name}}
+    A<T>::TYPE var3 = 2; // expected-warning {{missing 'typename' prior to dependent type name}}
+    MissingTypename::A<T>::TYPE var4 = 2; // expected-warning {{missing 'typename' prior to dependent type name}}
 }
 
 template void function_missing_typename<D>(const D::Type param);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to