Author: hans
Date: Tue Jun  3 19:18:41 2014
New Revision: 210141

URL: http://llvm.org/viewvc/llvm-project?rev=210141&view=rev
Log:
Downgrade "definition of dllimport static field" error to warning for class 
templates (PR19902)

This allows us to compile the following kind of code, which occurs in MSVC
headers:

  template <typename> struct S {
    __declspec(dllimport) static int x;
  };
  template <typename T> int S<T>::x;

The definition works similarly to a dllimport inline function definition and
gets available_externally linkage.

Differential Revision: http://reviews.llvm.org/D3998

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

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=210141&r1=210140&r2=210141&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jun  3 19:18:41 
2014
@@ -2109,6 +2109,9 @@ def err_attribute_dllimport_data_definit
   "definition of dllimport data">;
 def err_attribute_dllimport_static_field_definition : Error<
   "definition of dllimport static field not allowed">;
+def warn_attribute_dllimport_static_field_definition : Warning<
+  "definition of dllimport static field">,
+  InGroup<DiagGroup<"dllimport-static-field-def">>;
 def err_attribute_dll_member_of_dll_class : Error<
   "attribute %q0 cannot be applied to member of %q1 class">;
 def err_attribute_weakref_not_static : Error<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=210141&r1=210140&r2=210141&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jun  3 19:18:41 2014
@@ -9061,10 +9061,19 @@ Sema::FinalizeDeclaration(Decl *ThisDecl
   if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) {
     if (VD->isStaticDataMember() && VD->isOutOfLine() &&
         VD->isThisDeclarationADefinition()) {
+      // We allow definitions of dllimport class template static data members
+      // with a warning.
+      bool IsClassTemplateMember =
+          cast<CXXRecordDecl>(VD->getFirstDecl()->getDeclContext())
+              ->getDescribedClassTemplate();
+
       Diag(VD->getLocation(),
-           diag::err_attribute_dllimport_static_field_definition);
+           IsClassTemplateMember
+               ? diag::warn_attribute_dllimport_static_field_definition
+               : diag::err_attribute_dllimport_static_field_definition);
       Diag(IA->getLocation(), diag::note_attribute);
-      VD->setInvalidDecl();
+      if (!IsClassTemplateMember)
+        VD->setInvalidDecl();
     }
   }
 

Modified: cfe/trunk/test/CodeGenCXX/dllimport.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport.cpp?rev=210141&r1=210140&r2=210141&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllimport.cpp Tue Jun  3 19:18:41 2014
@@ -571,6 +571,15 @@ namespace Vtordisp {
   template class C<char>;
 }
 
+namespace ClassTemplateStaticDef {
+  template <typename T> struct __declspec(dllimport) S {
+    static int x;
+  };
+  template <typename T> int S<T>::x;
+  // CHECK-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = 
available_externally dllimport global i32 0
+  int f() { return S<int>::x; }
+}
+
 
//===----------------------------------------------------------------------===//
 // Negative checks
 
//===----------------------------------------------------------------------===//

Modified: cfe/trunk/test/SemaCXX/dllimport.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllimport.cpp?rev=210141&r1=210140&r2=210141&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/dllimport.cpp (original)
+++ cfe/trunk/test/SemaCXX/dllimport.cpp Tue Jun  3 19:18:41 2014
@@ -816,9 +816,9 @@ template<typename T>        void ImportC
 template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() 
{}
 template<typename T>        void ImportClassTmplMembers<T>::staticInlineDecl() 
{}
 
-template<typename T>        int  ImportClassTmplMembers<T>::StaticFieldDef; // 
expected-error{{definition of dllimport static field not allowed}}
-template<typename T> const  int  
ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // 
expected-error{{definition of dllimport static field not allowed}}
-template<typename T> constexpr int 
ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-error{{definition of 
dllimport static field not allowed}}
+template<typename T>        int  ImportClassTmplMembers<T>::StaticFieldDef; // 
expected-warning{{definition of dllimport static field}}
+template<typename T> const  int  
ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // 
expected-warning{{definition of dllimport static field}}
+template<typename T> constexpr int 
ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition 
of dllimport static field}}
 
 
 // Redeclarations cannot add dllimport.
@@ -853,13 +853,13 @@ template<typename T> __declspec(dllimpor
 template<typename T> __declspec(dllimport)        void 
CTMR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 
'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
 
 template<typename T> __declspec(dllimport)        int  CTMR<T>::StaticField = 
1;       // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 
'dllimport' attribute}}
-                                                                               
        // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                               
        // expected-warning@-1{{definition of dllimport static field}}
                                                                                
        // expected-note@-2{{attribute is here}}
 template<typename T> __declspec(dllimport) const  int  
CTMR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 
'CTMR::StaticConstField' cannot add 'dllimport' attribute}}
-                                                                               
        // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                               
        // expected-warning@-1{{definition of dllimport static field}}
                                                                                
        // expected-note@-2{{attribute is here}}
 template<typename T> __declspec(dllimport) constexpr int 
CTMR<T>::ConstexprField;      // expected-error{{redeclaration of 
'CTMR::ConstexprField' cannot add 'dllimport' attribute}}
-                                                                               
        // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                               
        // expected-warning@-1{{definition of dllimport static field}}
                                                                                
        // expected-note@-2{{attribute is here}}
 
 
@@ -901,9 +901,9 @@ template<typename T> template<typename U
 template<typename T> template<typename U>        void 
ImportClsTmplMemTmpl<T>::staticInlineDecl() {}
 
 #if __has_feature(cxx_variable_templates)
-template<typename T> template<typename U>        int  
ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-error{{definition of 
dllimport static field not allowed}}
-template<typename T> template<typename U> const  int  
ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-error{{definition 
of dllimport static field not allowed}}
-template<typename T> template<typename U> constexpr int 
ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-error{{definition of 
dllimport static field not allowed}}
+template<typename T> template<typename U>        int  
ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of 
dllimport static field}}
+template<typename T> template<typename U> const  int  
ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // 
expected-warning{{definition of dllimport static field}}
+template<typename T> template<typename U> constexpr int 
ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-warning{{definition of 
dllimport static field}}
 #endif // __has_feature(cxx_variable_templates)
 
 
@@ -935,13 +935,13 @@ template<typename T> template<typename U
 
 #if __has_feature(cxx_variable_templates)
 template<typename T> template<typename U> __declspec(dllimport)        int  
CTMTR<T>::StaticField = 1;       // expected-error{{redeclaration of 
'CTMTR::StaticField' cannot add 'dllimport' attribute}}
-                                                                               
                              // expected-error@-1{{definition of dllimport 
static field not allowed}}
+                                                                               
                              // expected-warning@-1{{definition of dllimport 
static field}}
                                                                                
                              // expected-note@-2{{attribute is here}}
 template<typename T> template<typename U> __declspec(dllimport) const  int  
CTMTR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 
'CTMTR::StaticConstField' cannot add 'dllimport' attribute}}
-                                                                               
                              // expected-error@-1{{definition of dllimport 
static field not allowed}}
+                                                                               
                              // expected-warning@-1{{definition of dllimport 
static field}}
                                                                                
                              // expected-note@-2{{attribute is here}}
 template<typename T> template<typename U> __declspec(dllimport) constexpr int 
CTMTR<T>::ConstexprField;      // expected-error{{redeclaration of 
'CTMTR::ConstexprField' cannot add 'dllimport' attribute}}
-                                                                               
                              // expected-error@-1{{definition of dllimport 
static field not allowed}}
+                                                                               
                              // expected-warning@-1{{definition of dllimport 
static field}}
                                                                                
                              // expected-note@-2{{attribute is here}}
 #endif // __has_feature(cxx_variable_templates)
 
@@ -976,3 +976,10 @@ class __declspec(dllexport) ExportClassW
   void __declspec(dllimport) foo();
   void __declspec(dllexport) bar();
 };
+
+namespace ImportedExplicitSpecialization {
+template <typename T> struct S { static int x; };
+template <typename T> int S<T>::x = sizeof(T);
+template <> struct __declspec(dllimport) S<int> { static int x; }; // 
expected-note{{attribute is here}}
+int S<int>::x = -1; // expected-error{{definition of dllimport static field 
not allowed}}
+}


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to