Sema: Add dll attribute tests for variable templates
authorNico Rieck <nico.rieck@gmail.com>
Sun, 25 May 2014 10:34:36 +0000 (10:34 +0000)
committerNico Rieck <nico.rieck@gmail.com>
Sun, 25 May 2014 10:34:36 +0000 (10:34 +0000)
llvm-svn: 209597

clang/test/SemaCXX/dllexport.cpp
clang/test/SemaCXX/dllimport.cpp

index 4d3538e..c9b8bc8 100644 (file)
@@ -75,6 +75,83 @@ void functionScope() {
 
 
 //===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+#if __has_feature(cxx_variable_templates)
+
+// Export declaration.
+template<typename T> __declspec(dllexport) extern int ExternVarTmplDecl;
+
+// dllexport implies a definition.
+template<typename T> __declspec(dllexport) int VarTmplDef;
+
+// Export definition.
+template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
+template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
+
+// Declare, then export definition.
+template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
+template<typename T>                              int VarTmplDeclInit = 1;
+
+// Redeclarations
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllexport)        int VarTmplRedecl1 = 1;
+
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
+template<typename T>                              int VarTmplRedecl2 = 1;
+
+template<typename T>                       extern int VarTmplRedecl3; // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl3; // expected-error{{redeclaration of 'VarTmplRedecl3' cannot add 'dllexport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllexport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllexport'}}
+template<typename T> __declspec(dllexport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllexport'}}
+namespace    { template<typename T> __declspec(dllexport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}}
+namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
+
+template<typename T> __declspec(dllexport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllexport'}}
+template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
+template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
+
+
+template<typename T> int VarTmpl = 1;
+template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
+
+// Export implicit instantiation of an exported variable template.
+int useVarTmpl() { return ExportedVarTmpl<ImplicitInst_Exported>; }
+
+// Export explicit instantiation declaration of an exported variable template.
+extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
+       template int ExportedVarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported variable template.
+template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of an exported variable template.
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported variable template without
+// explicit dllexport.
+template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
+
+
+// Export explicit instantiation declaration of a non-exported variable template.
+extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+       template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported variable template.
+template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported variable template.
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
 // Functions
 //===----------------------------------------------------------------------===//
 
index 2e7bd14..954b543 100644 (file)
@@ -105,6 +105,86 @@ void functionScope() {
 
 
 //===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+#if __has_feature(cxx_variable_templates)
+
+// Import declaration.
+template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
+
+// dllimport implies a declaration.
+template<typename T> __declspec(dllimport) int VarTmplDecl;
+
+// Not allowed on definitions.
+template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}}
+template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}}
+template<typename T> int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}}
+
+// Declare, then reject definition.
+template<typename T> __declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                              int ExternVarTmplDeclInit = 1; // expected-warning{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> __declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                       int VarTmplDeclInit = 1; // expected-warning{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Redeclarations
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                       extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T>                       extern int VarTmplRedecl4; // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}
+template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}
+namespace    { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}
+namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
+
+template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}}
+
+
+template<typename T> int VarTmpl;
+template<typename T> __declspec(dllimport) int ImportedVarTmpl;
+
+// Import implicit instantiation of an imported variable template.
+int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; }
+
+// Import explicit instantiation declaration of an imported variable template.
+extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
+
+// An explicit instantiation definition of an imported variable template cannot
+// be imported because the template must be defined which is illegal.
+
+// Import specialization of an imported variable template.
+template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
+
+// Not importing specialization of an imported variable template without
+// explicit dllimport.
+template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
+
+
+// Import explicit instantiation declaration of a non-imported variable template.
+extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
+
+// Import explicit instantiation definition of a non-imported variable template.
+template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
+
+// Import specialization of a non-imported variable template.
+template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
 // Functions
 //===----------------------------------------------------------------------===//