[cfe-commits] r129425 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp test/SemaCXX/MicrosoftExtensions.cpp

Francois Pichet pichet2000 at gmail.com
Tue Apr 12 19:38:49 PDT 2011


Author: fpichet
Date: Tue Apr 12 21:38:49 2011
New Revision: 129425

URL: http://llvm.org/viewvc/llvm-project?rev=129425&view=rev
Log:
In Microsoft mode, within class scope, if a CXXScopeSpec's type is equal to the type of one of the base classes then downgrade the missing typename error to a warning. Up to now this is the only case I found where MSVC doesn't require "typename" at class scope. Really strange!
This fixes 1 error when parsing the MSVC 2008 header files.
Example:

template<class T> class A {
public:
  typedef int TYPE;
};
template<class T> class B : public A<T> {
public:
  A<T>::TYPE a; // no typename required because A<T> is a base class.
};

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=129425&r1=129424&r2=129425&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Apr 12 21:38:49 2011
@@ -1946,6 +1946,8 @@
     "referenced member %0 is declared here">;
 def err_typename_missing : Error<
   "missing 'typename' prior to dependent type name '%0%1'">;
+def war_typename_missing : ExtWarn<
+  "missing 'typename' prior to dependent type name '%0%1'">;
 def ext_typename_outside_of_template : ExtWarn<
   "'typename' occurs outside of a template">, InGroup<CXX0x>;
 def err_typename_refers_to_using_value_decl : Error<

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=129425&r1=129424&r2=129425&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Apr 12 21:38:49 2011
@@ -799,6 +799,7 @@
                          ParsedType ObjectType = ParsedType(),
                          bool WantNontrivialTypeSourceInfo = false);
   TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
+  bool isMicrosoftMissingTypename(const CXXScopeSpec *SS);
   bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
                                SourceLocation IILoc,
                                Scope *S,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=129425&r1=129424&r2=129425&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Apr 12 21:38:49 2011
@@ -250,6 +250,33 @@
   return DeclSpec::TST_unspecified;
 }
 
+/// isMicrosoftMissingTypename - In Microsoft mode, within class scope,
+/// if a CXXScopeSpec's type is equal to the type of one of the base classes
+/// then downgrade the missing typename error to a warning.
+/// This is needed for MSVC compatibility; Example:
+/// @code
+/// template<class T> class A {
+/// public:
+///   typedef int TYPE;
+/// };
+/// template<class T> class B : public A<T> {
+/// public:
+///   A<T>::TYPE a; // no typename required because A<T> is a base class.
+/// };
+/// @endcode
+bool Sema::isMicrosoftMissingTypename(const CXXScopeSpec *SS) {
+  if (CurContext->isRecord()) {
+    const Type* Ty = SS->getScopeRep()->getAsType();
+
+    CXXRecordDecl *RD = cast<CXXRecordDecl>(CurContext);
+    for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
+          BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base)
+      if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base->getType()))
+        return true;
+  } 
+  return false;
+}
+
 bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, 
                                    SourceLocation IILoc,
                                    Scope *S,
@@ -327,7 +354,11 @@
     Diag(IILoc, diag::err_typename_nested_not_found) 
       << &II << DC << SS->getRange();
   else if (isDependentScopeSpecifier(*SS)) {
-    Diag(SS->getRange().getBegin(), diag::err_typename_missing)
+    unsigned DiagID = diag::err_typename_missing;
+    if (getLangOptions().Microsoft && isMicrosoftMissingTypename(SS))
+      DiagID = diag::war_typename_missing;
+
+    Diag(SS->getRange().getBegin(), DiagID)
       << (NestedNameSpecifier *)SS->getScopeRep() << II.getName()
       << SourceRange(SS->getRange().getBegin(), IILoc)
       << FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename ");

Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=129425&r1=129424&r2=129425&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Tue Apr 12 21:38:49 2011
@@ -136,3 +136,35 @@
 template <class T>
 void BB<T>::f(int g = 0) { } // expected-warning {{redefinition of default argument}}
 
+
+namespace MissingTypename {
+
+template<class T> class A {
+public:
+	 typedef int TYPE;
+};
+
+template<class T> class B {
+public:
+	 typedef int TYPE;
+};
+
+
+template<class T, class U>
+class C : private A<T>, public B<U> {
+public:
+   typedef A<T> Base1;
+   typedef B<U> Base2;
+   typedef A<U> Base3;
+
+   A<T>::TYPE a1; // expected-warning {{missing 'typename' prior to dependent type name}}
+   Base1::TYPE a2; // expected-warning {{missing 'typename' prior to dependent type name}}
+
+   B<U>::TYPE a3; // expected-warning {{missing 'typename' prior to dependent type name}}
+   Base2::TYPE a4; // expected-warning {{missing 'typename' prior to dependent type name}}
+
+   A<U>::TYPE a5; // expected-error {{missing 'typename' prior to dependent type name}}
+   Base3::TYPE a6; // expected-error {{missing 'typename' prior to dependent type name}}
+ };
+
+}
\ No newline at end of file





More information about the cfe-commits mailing list