r201947 - Reorganize and improve semantic tests for dllexport/import

Nico Rieck nico.rieck at gmail.com
Sat Feb 22 11:47:31 PST 2014


Author: nrieck
Date: Sat Feb 22 13:47:30 2014
New Revision: 201947

URL: http://llvm.org/viewvc/llvm-project?rev=201947&view=rev
Log:
Reorganize and improve semantic tests for dllexport/import

Added:
    cfe/trunk/test/Sema/dllexport.c
    cfe/trunk/test/Sema/dllimport.c
    cfe/trunk/test/SemaCXX/dllexport.cpp
    cfe/trunk/test/SemaCXX/dllimport.cpp
Removed:
    cfe/trunk/test/Sema/dllimport-dllexport.c
Modified:
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Rewriter/dllimport-typedef.c

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=201947&r1=201946&r2=201947&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sat Feb 22 13:47:30 2014
@@ -3786,7 +3786,7 @@ static void handleX86ForceAlignArgPointe
 DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
                                         unsigned AttrSpellingListIndex) {
   if (D->hasAttr<DLLExportAttr>()) {
-    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "dllimport";
+    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'dllimport'";
     return NULL;
   }
 
@@ -3834,7 +3834,7 @@ static void handleDLLImportAttr(Sema &S,
 DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
                                         unsigned AttrSpellingListIndex) {
   if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
-    Diag(Import->getLocation(), diag::warn_attribute_ignored) << "dllimport";
+    Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
     D->dropAttr<DLLImportAttr>();
   }
 

Modified: cfe/trunk/test/Rewriter/dllimport-typedef.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/dllimport-typedef.c?rev=201947&r1=201946&r2=201947&view=diff
==============================================================================
--- cfe/trunk/test/Rewriter/dllimport-typedef.c (original)
+++ cfe/trunk/test/Rewriter/dllimport-typedef.c Sat Feb 22 13:47:30 2014
@@ -10,7 +10,7 @@ typedef __declspec(dllimport) int CB(voi
 void bar() { return 1; }
 
 // CHECK-NEG: error: void function 'bar' should not return a value
-// CHECK-NEG: 1 error generated
+// CHECK-NEG: {{^}}1 error generated
 // CHECK-POS: warning: 'dllimport' attribute only applies to variables and functions
 // CHECK-POS: error: void function 'bar' should not return a value
 // CHECK-POS: 1 warning and 1 error generated

Added: cfe/trunk/test/Sema/dllexport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllexport.c?rev=201947&view=auto
==============================================================================
--- cfe/trunk/test/Sema/dllexport.c (added)
+++ cfe/trunk/test/Sema/dllexport.c Sat Feb 22 13:47:30 2014
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c99 %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c11 %s
+// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c11 %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c99 %s
+
+// Invalid usage.
+__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+enum __declspec(dllexport) Enum { EnumVal }; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+struct __declspec(dllexport) Record {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Export declaration.
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// dllexport implies a definition.
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+__declspec(dllexport) int GlobalInit1 = 1;
+int __declspec(dllexport) GlobalInit2 = 1;
+
+// Declare, then export definition.
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Export in local scope.
+void functionScope() {
+  __declspec(dllexport) extern int ExternLocalVarDecl;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Export function declaration. Check different placements.
+__attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllexport)      void decl1B();
+
+void __attribute__((dllexport)) decl2A();
+void __declspec(dllexport)      decl2B();
+
+// Export function definition.
+__declspec(dllexport) void def() {}
+
+// Export inline function.
+__declspec(dllexport) inline void inlineFunc1() {} // expected-warning{{'dllexport' attribute ignored}}
+extern void inlineFunc1();
+
+inline void __attribute__((dllexport)) inlineFunc2() {} // expected-warning{{'dllexport' attribute ignored}}
+extern void inlineFunc2();
+
+// Redeclarations
+__declspec(dllexport) void redecl1();
+__declspec(dllexport) void redecl1();
+
+__declspec(dllexport) void redecl2();
+                      void redecl2();
+
+__declspec(dllexport) void redecl3();
+                      void redecl3() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over dllimport if both are specified.
+__attribute__((dllimport, dllexport))       extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport))       extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
+
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport)        int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport)        int PrecedenceGlobalRedecl2;
+
+void __attribute__((dllimport, dllexport))       precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __attribute__((dllexport, dllimport))       precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) precedenceRedecl1() {}
+
+void __declspec(dllexport) precedenceRedecl2();
+void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}

Removed: cfe/trunk/test/Sema/dllimport-dllexport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllimport-dllexport.c?rev=201946&view=auto
==============================================================================
--- cfe/trunk/test/Sema/dllimport-dllexport.c (original)
+++ cfe/trunk/test/Sema/dllimport-dllexport.c (removed)
@@ -1,48 +0,0 @@
-// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify %s
-
-inline void __attribute__((dllexport)) foo1(){} // expected-warning{{'dllexport' attribute ignored}}
-inline void __attribute__((dllimport)) foo2(){} // expected-warning{{'dllimport' attribute ignored}}
-
-void __attribute__((dllimport)) foo3(){} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
-
-void __attribute__((dllimport, dllexport)) foo4(); // expected-warning{{dllimport attribute ignored}}
-
-void __attribute__((dllexport)) foo5();
-void __attribute__((dllimport)) foo5(); // expected-warning{{dllimport attribute ignored}}
-
-typedef int __attribute__((dllexport)) type6; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-
-typedef int __attribute__((dllimport)) type7; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-
-void __attribute__((dllimport)) foo6();
-void foo6(){} // expected-warning {{'foo6' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-
-// PR6269
-inline void __declspec(dllexport) foo7(){} // expected-warning{{'dllexport' attribute ignored}}
-inline void __declspec(dllimport) foo8(){} // expected-warning{{'dllimport' attribute ignored}}
-
-void __declspec(dllimport) foo9(){} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
-
-void __declspec(dllimport) __declspec(dllexport) foo10(); // expected-warning{{dllimport attribute ignored}}
-
-void __declspec(dllexport) foo11();
-void __declspec(dllimport) foo11(); // expected-warning{{dllimport attribute ignored}}
-
-typedef int __declspec(dllexport) type1; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-
-typedef int __declspec(dllimport) type2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-
-void __declspec(dllimport) foo12();
-void foo12(){} // expected-warning {{'foo12' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-
-void __attribute__((dllimport)) foo13(); // expected-warning{{dllimport attribute ignored}}
-void __attribute__((dllexport)) foo13();
-
-extern int foo14 __attribute__((dllexport));
-extern int foo14 __attribute__((dllimport));  // expected-warning{{dllimport attribute ignored}}
-
-__declspec(dllimport) int foo15 = 54; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
-
-extern __declspec(dllimport) int foo17;
-int foo17 = 54; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}

Added: cfe/trunk/test/Sema/dllimport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllimport.c?rev=201947&view=auto
==============================================================================
--- cfe/trunk/test/Sema/dllimport.c (added)
+++ cfe/trunk/test/Sema/dllimport.c Sat Feb 22 13:47:30 2014
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c99 %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c11 %s
+// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c11 %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c99 %s
+
+// Invalid usage.
+__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+enum __declspec(dllimport) Enum { EnumVal }; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+struct __declspec(dllimport) Record {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+__declspec(dllimport) extern int ExternGlobalDecl;
+
+// dllimport implies a declaration. FIXME: This should not warn.
+__declspec(dllimport) int GlobalDecl; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+// Not allowed on definitions.
+__declspec(dllimport) int GlobalInit1 = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+int __declspec(dllimport) GlobalInit2 = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+// Declare, then reject definition.
+__declspec(dllimport) extern int ExternGlobalDeclInit;
+int ExternGlobalDeclInit = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+// Redeclarations
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+
+// Import in local scope.
+void functionScope() {
+  __declspec(dllimport) extern int ExternLocalVarDecl;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration. Check different placements.
+__attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllimport)      void decl1B();
+
+void __attribute__((dllimport)) decl2A();
+void __declspec(dllimport)      decl2B();
+
+// Not allowed on function definitions.
+__declspec(dllimport) void def() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
+
+// Import inline function.
+__declspec(dllimport) inline void inlineFunc1() {} // expected-warning{{'dllimport' attribute ignored}}
+inline void __attribute__((dllimport)) inlineFunc2() {} // expected-warning{{'dllimport' attribute ignored}}
+
+// Redeclarations
+__declspec(dllimport) void redecl1();
+__declspec(dllimport) void redecl1();
+
+__declspec(dllimport) void redecl3();
+                      void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}

Added: cfe/trunk/test/SemaCXX/dllexport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllexport.cpp?rev=201947&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/dllexport.cpp (added)
+++ cfe/trunk/test/SemaCXX/dllexport.cpp Sat Feb 22 13:47:30 2014
@@ -0,0 +1,189 @@
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+
+
+// Invalid usage.
+__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+#if __has_feature(cxx_strong_enums)
+  enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+#endif
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Export declaration.
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// dllexport implies a definition.
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+__declspec(dllexport) int GlobalInit1 = 1;
+int __declspec(dllexport) GlobalInit2 = 1;
+
+// Declare, then export definition.
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Export in local scope.
+void functionScope() {
+  __declspec(dllexport) extern int ExternLocalVarDecl;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Export function declaration. Check different placements.
+__attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllexport)      void decl1B();
+
+void __attribute__((dllexport)) decl2A();
+void __declspec(dllexport)      decl2B();
+
+// Export function definition.
+__declspec(dllexport) void def() {}
+
+// extern "C"
+extern "C" __declspec(dllexport) void externC() {}
+
+// Export inline function.
+__declspec(dllexport) inline void inlineFunc1() {} // expected-warning{{'dllexport' attribute ignored}}
+inline void __attribute__((dllexport)) inlineFunc2() {} // expected-warning{{'dllexport' attribute ignored}}
+
+__declspec(dllexport) inline void inlineDecl(); // expected-warning{{'dllexport' attribute ignored}}
+                             void inlineDecl() {}
+
+__declspec(dllexport) void inlineDef();
+               inline void inlineDef() {}
+
+// Redeclarations
+__declspec(dllexport) void redecl1();
+__declspec(dllexport) void redecl1() {}
+
+__declspec(dllexport) void redecl2();
+                      void redecl2() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Export function template declaration. Check different placements.
+template<typename T> __declspec(dllexport) void funcTmplDecl1();
+template<typename T> void __declspec(dllexport) funcTmplDecl2();
+
+// Export function template definition.
+template<typename T> __declspec(dllexport) void funcTmplDef() {}
+
+// Redeclarations
+template<typename T> __declspec(dllexport) void funcTmplRedecl1();
+template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
+
+template<typename T> __declspec(dllexport) void funcTmplRedecl2();
+template<typename T>                       void funcTmplRedecl2() {}
+
+template<typename T> __declspec(dllexport) void funcTmplRedecl3();
+template<typename T>                       void funcTmplRedecl3() {}
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> __declspec(dllexport) void exportedFuncTmplDecl();
+template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
+
+// Export implicit instantiation of an exported function template.
+void useFunTmplDecl() { exportedFuncTmplDecl<ImplicitInst_Exported>(); }
+void useFunTmplDef() { exportedFuncTmpl<ImplicitInst_Exported>(); }
+
+// Export explicit instantiation declaration of an exported function template.
+extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
+       template void exportedFuncTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of an exported function template.
+template void exportedFuncTmpl<ExplicitInst_Exported>();
+
+// Export specialization of an exported function template.
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {} // expected-warning{{'dllexport' attribute ignored}}
+
+// Not exporting specialization of an exported function template without
+// explicit dllexport.
+template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported function template.
+extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of a non-exported function template.
+template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
+
+// Export specialization of a non-exported function template.
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {} // expected-warning{{'dllexport' attribute ignored}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over dllimport if both are specified.
+__attribute__((dllimport, dllexport))       extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport))       extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
+
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport)        int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport)        int PrecedenceGlobalRedecl2;
+
+void __attribute__((dllimport, dllexport))       precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __attribute__((dllexport, dllimport))       precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) precedenceRedecl1() {}
+
+void __declspec(dllexport) precedenceRedecl2();
+void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}

Added: cfe/trunk/test/SemaCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllimport.cpp?rev=201947&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/dllimport.cpp (added)
+++ cfe/trunk/test/SemaCXX/dllimport.cpp Sat Feb 22 13:47:30 2014
@@ -0,0 +1,127 @@
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
+
+
+// Invalid usage.
+__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+#if __has_feature(cxx_strong_enums)
+  enum class __declspec(dllimport) EnumClass {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+#endif
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+__declspec(dllimport) extern int ExternGlobalDecl;
+
+// dllimport implies a declaration. FIXME: This should not warn.
+__declspec(dllimport) int GlobalDecl; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+// Not allowed on definitions.
+__declspec(dllimport) int GlobalInit1 = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+int __declspec(dllimport) GlobalInit2 = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+// Declare, then reject definition.
+__declspec(dllimport) extern int ExternGlobalDeclInit;
+int ExternGlobalDeclInit = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+
+// Redeclarations
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+
+// Import in local scope.
+void functionScope() {
+  __declspec(dllimport) extern int ExternLocalVarDecl;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration. Check different placements.
+__attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllimport)      void decl1B();
+
+void __attribute__((dllimport)) decl2A();
+void __declspec(dllimport)      decl2B();
+
+// Not allowed on function definitions.
+__declspec(dllimport) void def() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
+
+// extern  "C"
+extern "C" __declspec(dllexport) void externC();
+
+// Import inline function.
+__declspec(dllimport) inline void inlineFunc1() {} // expected-warning{{'dllimport' attribute ignored}}
+inline void __attribute__((dllimport)) inlineFunc2() {} // expected-warning{{'dllimport' attribute ignored}}
+
+// Redeclarations
+__declspec(dllimport) void redecl1();
+__declspec(dllimport) void redecl1();
+
+__declspec(dllimport) void redecl3();
+                      void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Import function template declaration. Check different placements.
+template<typename T> __declspec(dllimport) void funcTmplDecl1();
+template<typename T> void __declspec(dllimport) funcTmplDecl2();
+
+// Redeclarations
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+
+template<typename T> __declspec(dllimport) void funcTmplRedecl2();
+template<typename T>                       void funcTmplRedecl2();
+
+template<typename T> __declspec(dllimport) void funcTmplRedecl3();
+template<typename T>                       void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> __declspec(dllimport) void importedFuncTmpl();
+
+// Import specialization of an imported function template. A definition must be
+// declared inline.
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
+template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {} // expected-warning{{'dllimport' attribute ignored}}
+
+// Not importing specialization of an imported function template without
+// explicit dllimport.
+template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
+
+
+// Import explicit instantiation declaration of a non-imported function template.
+extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
+
+// Import specialization of a non-imported function template. A definition must
+// be declared inline.
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
+template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {} // expected-warning{{'dllimport' attribute ignored}}





More information about the cfe-commits mailing list