From 99f12ef44fca4b3036b95c990ceec70a1264a064 Mon Sep 17 00:00:00 2001 From: Nico Rieck Date: Sun, 25 May 2014 10:34:36 +0000 Subject: [PATCH] Sema: Add dll attribute tests for variable templates llvm-svn: 209597 --- clang/test/SemaCXX/dllexport.cpp | 77 ++++++++++++++++++++++++++++++++++++++ clang/test/SemaCXX/dllimport.cpp | 80 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) diff --git a/clang/test/SemaCXX/dllexport.cpp b/clang/test/SemaCXX/dllexport.cpp index 4d3538e..c9b8bc8 100644 --- a/clang/test/SemaCXX/dllexport.cpp +++ b/clang/test/SemaCXX/dllexport.cpp @@ -75,6 +75,83 @@ void functionScope() { //===----------------------------------------------------------------------===// +// Variable templates +//===----------------------------------------------------------------------===// +#if __has_feature(cxx_variable_templates) + +// Export declaration. +template __declspec(dllexport) extern int ExternVarTmplDecl; + +// dllexport implies a definition. +template __declspec(dllexport) int VarTmplDef; + +// Export definition. +template __declspec(dllexport) int VarTmplInit1 = 1; +template int __declspec(dllexport) VarTmplInit2 = 1; + +// Declare, then export definition. +template __declspec(dllexport) extern int VarTmplDeclInit; +template int VarTmplDeclInit = 1; + +// Redeclarations +template __declspec(dllexport) extern int VarTmplRedecl1; +template __declspec(dllexport) int VarTmplRedecl1 = 1; + +template __declspec(dllexport) extern int VarTmplRedecl2; +template int VarTmplRedecl2 = 1; + +template extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} +template __declspec(dllexport) extern int VarTmplRedecl3; // expected-error{{redeclaration of 'VarTmplRedecl3' cannot add 'dllexport' attribute}} + +// External linkage is required. +template __declspec(dllexport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllexport'}} +template __declspec(dllexport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllexport'}} +namespace { template __declspec(dllexport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}} +namespace ns { template __declspec(dllexport) int ExternalVarTmpl = 1; } + +template __declspec(dllexport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllexport'}} +template __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External(); +template External ExternalAutoTypeVarTmpl; + + +template int VarTmpl = 1; +template __declspec(dllexport) int ExportedVarTmpl = 1; + +// Export implicit instantiation of an exported variable template. +int useVarTmpl() { return ExportedVarTmpl; } + +// Export explicit instantiation declaration of an exported variable template. +extern template int ExportedVarTmpl; + template int ExportedVarTmpl; + +// Export explicit instantiation definition of an exported variable template. +template __declspec(dllexport) int ExportedVarTmpl; + +// Export specialization of an exported variable template. +template<> __declspec(dllexport) int ExportedVarTmpl; +template<> __declspec(dllexport) int ExportedVarTmpl = 1; + +// Not exporting specialization of an exported variable template without +// explicit dllexport. +template<> int ExportedVarTmpl; + + +// Export explicit instantiation declaration of a non-exported variable template. +extern template __declspec(dllexport) int VarTmpl; + template __declspec(dllexport) int VarTmpl; + +// Export explicit instantiation definition of a non-exported variable template. +template __declspec(dllexport) int VarTmpl; + +// Export specialization of a non-exported variable template. +template<> __declspec(dllexport) int VarTmpl; +template<> __declspec(dllexport) int VarTmpl = 1; + +#endif // __has_feature(cxx_variable_templates) + + + +//===----------------------------------------------------------------------===// // Functions //===----------------------------------------------------------------------===// diff --git a/clang/test/SemaCXX/dllimport.cpp b/clang/test/SemaCXX/dllimport.cpp index 2e7bd14..954b543 100644 --- a/clang/test/SemaCXX/dllimport.cpp +++ b/clang/test/SemaCXX/dllimport.cpp @@ -105,6 +105,86 @@ void functionScope() { //===----------------------------------------------------------------------===// +// Variable templates +//===----------------------------------------------------------------------===// +#if __has_feature(cxx_variable_templates) + +// Import declaration. +template __declspec(dllimport) extern int ExternVarTmplDecl; + +// dllimport implies a declaration. +template __declspec(dllimport) int VarTmplDecl; + +// Not allowed on definitions. +template __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}} +template __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}} +template int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}} + +// Declare, then reject definition. +template __declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +template int ExternVarTmplDeclInit = 1; // expected-warning{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} + +template __declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +template int VarTmplDeclInit = 1; // expected-warning{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} + +// Redeclarations +template __declspec(dllimport) extern int VarTmplRedecl1; +template __declspec(dllimport) extern int VarTmplRedecl1; + +template __declspec(dllimport) int VarTmplRedecl2; +template __declspec(dllimport) int VarTmplRedecl2; + +template __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} +template extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} + +template extern int VarTmplRedecl4; // expected-note{{previous declaration is here}} +template __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}} + +// External linkage is required. +template __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}} +template __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}} +namespace { template __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}} +namespace ns { template __declspec(dllimport) int ExternalVarTmpl; } + +template __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}} + + +template int VarTmpl; +template __declspec(dllimport) int ImportedVarTmpl; + +// Import implicit instantiation of an imported variable template. +int useVarTmpl() { return ImportedVarTmpl; } + +// Import explicit instantiation declaration of an imported variable template. +extern template int ImportedVarTmpl; + +// 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; +template<> __declspec(dllimport) int ImportedVarTmpl = 1; // expected-error{{definition of dllimport data}} + +// Not importing specialization of an imported variable template without +// explicit dllimport. +template<> int ImportedVarTmpl; + + +// Import explicit instantiation declaration of a non-imported variable template. +extern template __declspec(dllimport) int VarTmpl; + +// Import explicit instantiation definition of a non-imported variable template. +template __declspec(dllimport) int VarTmpl; + +// Import specialization of a non-imported variable template. +template<> __declspec(dllimport) int VarTmpl; +template<> __declspec(dllimport) int VarTmpl = 1; // expected-error{{definition of dllimport data}} + +#endif // __has_feature(cxx_variable_templates) + + + +//===----------------------------------------------------------------------===// // Functions //===----------------------------------------------------------------------===// -- 2.7.4