forked from OSchip/llvm-project
Sema: Check dll attributes on static data members
Redeclarations cannot add a dll attribute and static data members cannot be defined. llvm-svn: 209825
This commit is contained in:
parent
a670c20894
commit
078d2f89cd
|
@ -2102,6 +2102,8 @@ def err_attribute_dllimport_function_definition : Error<
|
|||
"dllimport cannot be applied to non-inline function definition">;
|
||||
def err_attribute_dllimport_data_definition : Error<
|
||||
"definition of dllimport data">;
|
||||
def err_attribute_dllimport_static_field_definition : Error<
|
||||
"definition of dllimport static field not allowed">;
|
||||
def err_attribute_weakref_not_static : Error<
|
||||
"weakref declaration must have internal linkage">;
|
||||
def err_attribute_weakref_not_global_context : Error<
|
||||
|
@ -2443,6 +2445,7 @@ def warn_attribute_protected_visibility :
|
|||
InGroup<DiagGroup<"unsupported-visibility">>;
|
||||
def err_mismatched_visibility: Error<"visibility does not match previous declaration">;
|
||||
def note_previous_attribute : Note<"previous attribute is here">;
|
||||
def note_attribute : Note<"attribute is here">;
|
||||
def err_mismatched_ms_inheritance : Error<
|
||||
"inheritance model does not match %select{definition|previous declaration}0">;
|
||||
def warn_ignored_ms_inheritance : Warning<
|
||||
|
|
|
@ -4907,10 +4907,15 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
|
|||
// A redeclaration is not allowed to drop a dllimport attribute, the only
|
||||
// exception being inline function definitions.
|
||||
// NB: MSVC converts such a declaration to dllexport.
|
||||
bool IsInline =
|
||||
isa<FunctionDecl>(NewDecl) && cast<FunctionDecl>(NewDecl)->isInlined();
|
||||
bool IsInline = false, IsStaticDataMember = false;
|
||||
if (const auto *VD = dyn_cast<VarDecl>(NewDecl))
|
||||
// Ignore static data because out-of-line definitions are diagnosed
|
||||
// separately.
|
||||
IsStaticDataMember = VD->isStaticDataMember();
|
||||
else if (const auto *FD = dyn_cast<FunctionDecl>(NewDecl))
|
||||
IsInline = FD->isInlined();
|
||||
|
||||
if (OldImportAttr && !HasNewAttr && !IsInline) {
|
||||
if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember) {
|
||||
S.Diag(NewDecl->getLocation(),
|
||||
diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
|
||||
<< NewDecl << OldImportAttr;
|
||||
|
@ -9052,6 +9057,17 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
|
|||
|
||||
checkAttributesAfterMerging(*this, *VD);
|
||||
|
||||
// Imported static data members cannot be defined out-of-line.
|
||||
if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) {
|
||||
if (VD->isStaticDataMember() && VD->isOutOfLine() &&
|
||||
VD->isThisDeclarationADefinition()) {
|
||||
Diag(VD->getLocation(),
|
||||
diag::err_attribute_dllimport_static_field_definition);
|
||||
Diag(IA->getLocation(), diag::note_attribute);
|
||||
VD->setInvalidDecl();
|
||||
}
|
||||
}
|
||||
|
||||
if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {
|
||||
if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {
|
||||
Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr;
|
||||
|
|
|
@ -379,6 +379,17 @@ protected:
|
|||
__declspec(dllexport) void protectedDef();
|
||||
private:
|
||||
__declspec(dllexport) void privateDef();
|
||||
public:
|
||||
|
||||
__declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
|
||||
__declspec(dllexport) static int StaticField;
|
||||
__declspec(dllexport) static int StaticFieldDef;
|
||||
__declspec(dllexport) static const int StaticConstField;
|
||||
__declspec(dllexport) static const int StaticConstFieldDef;
|
||||
__declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
|
||||
__declspec(dllexport) static const int StaticConstFieldBraceInit{1};
|
||||
__declspec(dllexport) constexpr static int ConstexprField = 1;
|
||||
__declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
|
||||
};
|
||||
|
||||
void ExportMembers::Nested::normalDef() {}
|
||||
|
@ -394,6 +405,10 @@ inline void ExportMembers::staticInlineDef() {}
|
|||
void ExportMembers::protectedDef() {}
|
||||
void ExportMembers::privateDef() {}
|
||||
|
||||
int ExportMembers::StaticFieldDef;
|
||||
const int ExportMembers::StaticConstFieldDef = 1;
|
||||
constexpr int ExportMembers::ConstexprFieldDef;
|
||||
|
||||
|
||||
// Export on member definitions.
|
||||
struct ExportMemberDefs {
|
||||
|
@ -406,6 +421,10 @@ struct ExportMemberDefs {
|
|||
__declspec(dllexport) static void staticDef();
|
||||
__declspec(dllexport) static void staticInlineDef();
|
||||
__declspec(dllexport) static inline void staticInlineDecl();
|
||||
|
||||
__declspec(dllexport) static int StaticField;
|
||||
__declspec(dllexport) static const int StaticConstField;
|
||||
__declspec(dllexport) constexpr static int ConstexprField = 1;
|
||||
};
|
||||
|
||||
__declspec(dllexport) void ExportMemberDefs::normalDef() {}
|
||||
|
@ -418,6 +437,10 @@ __declspec(dllexport) void ExportMemberDefs::staticDef() {}
|
|||
__declspec(dllexport) inline void ExportMemberDefs::staticInlineDef() {}
|
||||
__declspec(dllexport) void ExportMemberDefs::staticInlineDecl() {}
|
||||
|
||||
__declspec(dllexport) int ExportMemberDefs::StaticField;
|
||||
__declspec(dllexport) const int ExportMemberDefs::StaticConstField = 1;
|
||||
__declspec(dllexport) constexpr int ExportMemberDefs::ConstexprField;
|
||||
|
||||
|
||||
// Export special member functions.
|
||||
struct ExportSpecials {
|
||||
|
@ -497,6 +520,10 @@ struct MemberRedecl {
|
|||
static void staticDef(); // expected-note{{previous declaration is here}}
|
||||
static void staticInlineDef(); // expected-note{{previous declaration is here}}
|
||||
static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
|
||||
|
||||
static int StaticField; // expected-note{{previous declaration is here}}
|
||||
static const int StaticConstField; // expected-note{{previous declaration is here}}
|
||||
constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
|
||||
};
|
||||
|
||||
__declspec(dllexport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}}
|
||||
|
@ -509,6 +536,10 @@ __declspec(dllexport) void MemberRedecl::staticDef() {} // expect
|
|||
__declspec(dllexport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
|
||||
__declspec(dllexport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
|
||||
|
||||
__declspec(dllexport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}}
|
||||
__declspec(dllexport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}}
|
||||
__declspec(dllexport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -526,6 +557,17 @@ struct ExportMemberTmpl {
|
|||
template<typename T> __declspec(dllexport) static void staticInclass() {}
|
||||
template<typename T> __declspec(dllexport) static void staticInlineDef();
|
||||
template<typename T> __declspec(dllexport) static inline void staticInlineDecl();
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> __declspec(dllexport) static int StaticField;
|
||||
template<typename T> __declspec(dllexport) static int StaticFieldDef;
|
||||
template<typename T> __declspec(dllexport) static const int StaticConstField;
|
||||
template<typename T> __declspec(dllexport) static const int StaticConstFieldDef;
|
||||
template<typename T> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
|
||||
template<typename T> __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
|
||||
template<typename T> __declspec(dllexport) constexpr static int ConstexprField = 1;
|
||||
template<typename T> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
};
|
||||
|
||||
template<typename T> void ExportMemberTmpl::normalDef() {}
|
||||
|
@ -535,6 +577,11 @@ template<typename T> void ExportMemberTmpl::staticDef() {}
|
|||
template<typename T> inline void ExportMemberTmpl::staticInlineDef() {}
|
||||
template<typename T> void ExportMemberTmpl::staticInlineDecl() {}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> int ExportMemberTmpl::StaticFieldDef;
|
||||
template<typename T> const int ExportMemberTmpl::StaticConstFieldDef = 1;
|
||||
template<typename T> constexpr int ExportMemberTmpl::ConstexprFieldDef;
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
||||
|
||||
// Redeclarations cannot add dllexport.
|
||||
|
@ -545,6 +592,12 @@ struct MemTmplRedecl {
|
|||
template<typename T> static void staticDef(); // expected-note{{previous declaration is here}}
|
||||
template<typename T> static void staticInlineDef(); // expected-note{{previous declaration is here}}
|
||||
template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> static int StaticField; // expected-note{{previous declaration is here}}
|
||||
template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}}
|
||||
template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
};
|
||||
|
||||
template<typename T> __declspec(dllexport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllexport' attribute}}
|
||||
|
@ -554,6 +607,12 @@ template<typename T> __declspec(dllexport) void MemTmplRedecl::staticDef(
|
|||
template<typename T> __declspec(dllexport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
|
||||
template<typename T> __declspec(dllexport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> __declspec(dllexport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}}
|
||||
template<typename T> __declspec(dllexport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}}
|
||||
template<typename T> __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
||||
|
||||
|
||||
struct MemFunTmpl {
|
||||
|
@ -621,6 +680,52 @@ template<> __declspec(dllexport) inline void MemFunTmpl::staticDef<ExplicitSpec_
|
|||
|
||||
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
struct MemVarTmpl {
|
||||
template<typename T> static const int StaticVar = 1;
|
||||
template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1;
|
||||
};
|
||||
template<typename T> const int MemVarTmpl::StaticVar;
|
||||
template<typename T> const int MemVarTmpl::ExportedStaticVar;
|
||||
|
||||
// Export implicit instantiation of an exported member variable template.
|
||||
int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
|
||||
|
||||
// Export explicit instantiation declaration of an exported member variable
|
||||
// template.
|
||||
extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
|
||||
template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
|
||||
|
||||
// Export explicit instantiation definition of an exported member variable
|
||||
// template.
|
||||
template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
|
||||
|
||||
// Export specialization of an exported member variable template.
|
||||
template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Exported>;
|
||||
template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1;
|
||||
|
||||
// Not exporting specialization of an exported member variable template without
|
||||
// explicit dllexport.
|
||||
template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported>;
|
||||
|
||||
|
||||
// Export explicit instantiation declaration of a non-exported member variable
|
||||
// template.
|
||||
extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
|
||||
template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
|
||||
|
||||
// Export explicit instantiation definition of a non-exported member variable
|
||||
// template.
|
||||
template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
|
||||
|
||||
// Export specialization of a non-exported member variable template.
|
||||
template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Exported>;
|
||||
template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1;
|
||||
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Class template members
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -648,6 +753,17 @@ protected:
|
|||
__declspec(dllexport) void protectedDef();
|
||||
private:
|
||||
__declspec(dllexport) void privateDef();
|
||||
public:
|
||||
|
||||
__declspec(dllexport) int Field; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
|
||||
__declspec(dllexport) static int StaticField;
|
||||
__declspec(dllexport) static int StaticFieldDef;
|
||||
__declspec(dllexport) static const int StaticConstField;
|
||||
__declspec(dllexport) static const int StaticConstFieldDef;
|
||||
__declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
|
||||
__declspec(dllexport) static const int StaticConstFieldBraceInit{1};
|
||||
__declspec(dllexport) constexpr static int ConstexprField = 1;
|
||||
__declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
|
||||
};
|
||||
|
||||
template<typename T> void ExportClassTmplMembers<T>::normalDef() {}
|
||||
|
@ -662,6 +778,10 @@ template<typename T> void ExportClassTmplMembers<T>::staticInlineDecl() {
|
|||
template<typename T> void ExportClassTmplMembers<T>::protectedDef() {}
|
||||
template<typename T> void ExportClassTmplMembers<T>::privateDef() {}
|
||||
|
||||
template<typename T> int ExportClassTmplMembers<T>::StaticFieldDef;
|
||||
template<typename T> const int ExportClassTmplMembers<T>::StaticConstFieldDef = 1;
|
||||
template<typename T> constexpr int ExportClassTmplMembers<T>::ConstexprFieldDef;
|
||||
|
||||
template struct ExportClassTmplMembers<ImplicitInst_Exported>;
|
||||
|
||||
|
||||
|
@ -677,6 +797,10 @@ struct CTMR /*ClassTmplMemberRedecl*/ {
|
|||
static void staticDef(); // expected-note{{previous declaration is here}}
|
||||
static void staticInlineDef(); // expected-note{{previous declaration is here}}
|
||||
static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
|
||||
|
||||
static int StaticField; // expected-note{{previous declaration is here}}
|
||||
static const int StaticConstField; // expected-note{{previous declaration is here}}
|
||||
constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
|
||||
};
|
||||
|
||||
template<typename T> __declspec(dllexport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}}
|
||||
|
@ -689,6 +813,10 @@ template<typename T> __declspec(dllexport) void CTMR<T>::staticDef() {}
|
|||
template<typename T> __declspec(dllexport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllexport' attribute}}
|
||||
template<typename T> __declspec(dllexport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllexport' attribute}}
|
||||
|
||||
template<typename T> __declspec(dllexport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}}
|
||||
template<typename T> __declspec(dllexport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}}
|
||||
template<typename T> __declspec(dllexport) constexpr int CTMR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -707,6 +835,17 @@ struct ExportClsTmplMemTmpl {
|
|||
template<typename U> __declspec(dllexport) static void staticInclass() {}
|
||||
template<typename U> __declspec(dllexport) static void staticInlineDef();
|
||||
template<typename U> __declspec(dllexport) static inline void staticInlineDecl();
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename U> __declspec(dllexport) static int StaticField;
|
||||
template<typename U> __declspec(dllexport) static int StaticFieldDef;
|
||||
template<typename U> __declspec(dllexport) static const int StaticConstField;
|
||||
template<typename U> __declspec(dllexport) static const int StaticConstFieldDef;
|
||||
template<typename U> __declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
|
||||
template<typename U> __declspec(dllexport) static const int StaticConstFieldBraceInit{1};
|
||||
template<typename U> __declspec(dllexport) constexpr static int ConstexprField = 1;
|
||||
template<typename U> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
};
|
||||
|
||||
template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::normalDef() {}
|
||||
|
@ -716,6 +855,12 @@ template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::s
|
|||
template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::staticInlineDef() {}
|
||||
template<typename T> template<typename U> void ExportClsTmplMemTmpl<T>::staticInlineDecl() {}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> template<typename U> int ExportClsTmplMemTmpl<T>::StaticFieldDef;
|
||||
template<typename T> template<typename U> const int ExportClsTmplMemTmpl<T>::StaticConstFieldDef = 1;
|
||||
template<typename T> template<typename U> constexpr int ExportClsTmplMemTmpl<T>::ConstexprFieldDef;
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
||||
|
||||
// Redeclarations cannot add dllexport.
|
||||
template<typename T>
|
||||
|
@ -726,6 +871,12 @@ struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
|
|||
template<typename U> static void staticDef(); // expected-note{{previous declaration is here}}
|
||||
template<typename U> static void staticInlineDef(); // expected-note{{previous declaration is here}}
|
||||
template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename U> static int StaticField; // expected-note{{previous declaration is here}}
|
||||
template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}}
|
||||
template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
};
|
||||
|
||||
template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllexport' attribute}}
|
||||
|
@ -734,3 +885,9 @@ template<typename T> template<typename U> __declspec(dllexport) void CTMT
|
|||
template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllexport' attribute}}
|
||||
template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllexport' attribute}}
|
||||
template<typename T> template<typename U> __declspec(dllexport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllexport' attribute}}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> template<typename U> __declspec(dllexport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}}
|
||||
template<typename T> template<typename U> __declspec(dllexport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}}
|
||||
template<typename T> template<typename U> __declspec(dllexport) constexpr int CTMTR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
|
|
@ -387,6 +387,17 @@ protected:
|
|||
__declspec(dllimport) void protectedDecl();
|
||||
private:
|
||||
__declspec(dllimport) void privateDecl();
|
||||
public:
|
||||
|
||||
__declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
|
||||
__declspec(dllimport) static int StaticField;
|
||||
__declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
|
||||
__declspec(dllimport) static const int StaticConstField;
|
||||
__declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}
|
||||
__declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
|
||||
__declspec(dllimport) static const int StaticConstFieldBraceInit{1};
|
||||
__declspec(dllimport) constexpr static int ConstexprField = 1;
|
||||
__declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
|
||||
};
|
||||
|
||||
void ImportMembers::Nested::normalDef() {} // expected-warning{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
|
||||
|
@ -400,6 +411,10 @@ inline void ImportMembers::virtualInlineDef() {}
|
|||
inline void ImportMembers::staticInlineDef() {}
|
||||
void ImportMembers::staticInlineDecl() {}
|
||||
|
||||
int ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
|
||||
const int ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
|
||||
constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
|
||||
|
||||
|
||||
// Import on member definitions.
|
||||
struct ImportMemberDefs {
|
||||
|
@ -412,6 +427,10 @@ struct ImportMemberDefs {
|
|||
__declspec(dllimport) static void staticDef();
|
||||
__declspec(dllimport) static void staticInlineDef();
|
||||
__declspec(dllimport) static inline void staticInlineDecl();
|
||||
|
||||
__declspec(dllimport) static int StaticField;
|
||||
__declspec(dllimport) static const int StaticConstField;
|
||||
__declspec(dllimport) constexpr static int ConstexprField = 1;
|
||||
};
|
||||
|
||||
__declspec(dllimport) void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
|
||||
|
@ -424,6 +443,10 @@ __declspec(dllimport) void ImportMemberDefs::staticDef() {} // expected-e
|
|||
__declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {}
|
||||
__declspec(dllimport) void ImportMemberDefs::staticInlineDecl() {}
|
||||
|
||||
__declspec(dllimport) int ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
|
||||
__declspec(dllimport) const int ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
|
||||
__declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
|
||||
|
||||
|
||||
// Import special member functions.
|
||||
struct ImportSpecials {
|
||||
|
@ -493,6 +516,10 @@ struct MemberRedecl {
|
|||
static void staticDef(); // expected-note{{previous declaration is here}}
|
||||
static void staticInlineDef(); // expected-note{{previous declaration is here}}
|
||||
static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
|
||||
|
||||
static int StaticField; // expected-note{{previous declaration is here}}
|
||||
static const int StaticConstField; // expected-note{{previous declaration is here}}
|
||||
constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
|
||||
};
|
||||
|
||||
__declspec(dllimport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}}
|
||||
|
@ -508,6 +535,16 @@ __declspec(dllimport) void MemberRedecl::staticDef() {} // expect
|
|||
__declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
|
||||
__declspec(dllimport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
|
||||
|
||||
__declspec(dllimport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}}
|
||||
// expected-error@-1{{definition of dllimport static field not allowed}}
|
||||
// expected-note@-2{{attribute is here}}
|
||||
__declspec(dllimport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}}
|
||||
// expected-error@-1{{definition of dllimport static field not allowed}}
|
||||
// expected-note@-2{{attribute is here}}
|
||||
__declspec(dllimport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}}
|
||||
// expected-error@-1{{definition of dllimport static field not allowed}}
|
||||
// expected-note@-2{{attribute is here}}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -525,6 +562,17 @@ struct ImportMemberTmpl {
|
|||
template<typename T> __declspec(dllimport) static void staticInclass() {}
|
||||
template<typename T> __declspec(dllimport) static void staticInlineDef();
|
||||
template<typename T> __declspec(dllimport) static inline void staticInlineDecl();
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> __declspec(dllimport) static int StaticField;
|
||||
template<typename T> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
|
||||
template<typename T> __declspec(dllimport) static const int StaticConstField;
|
||||
template<typename T> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}
|
||||
template<typename T> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
|
||||
template<typename T> __declspec(dllimport) static const int StaticConstFieldBraceInit{1};
|
||||
template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1;
|
||||
template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
};
|
||||
|
||||
template<typename T> void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
|
||||
|
@ -534,6 +582,12 @@ template<typename T> void ImportMemberTmpl::staticDef() {} // expected-wa
|
|||
template<typename T> inline void ImportMemberTmpl::staticInlineDef() {}
|
||||
template<typename T> void ImportMemberTmpl::staticInlineDecl() {}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> int ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
|
||||
template<typename T> const int ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
|
||||
template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
||||
|
||||
// Redeclarations cannot add dllimport.
|
||||
struct MemTmplRedecl {
|
||||
|
@ -543,6 +597,12 @@ struct MemTmplRedecl {
|
|||
template<typename T> static void staticDef(); // expected-note{{previous declaration is here}}
|
||||
template<typename T> static void staticInlineDef(); // expected-note{{previous declaration is here}}
|
||||
template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> static int StaticField; // expected-note{{previous declaration is here}}
|
||||
template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}}
|
||||
template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
};
|
||||
|
||||
template<typename T> __declspec(dllimport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}}
|
||||
|
@ -554,6 +614,18 @@ template<typename T> __declspec(dllimport) void MemTmplRedecl::staticDef(
|
|||
template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
|
||||
template<typename T> __declspec(dllimport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename T> __declspec(dllimport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}}
|
||||
// expected-error@-1{{definition of dllimport static field not allowed}}
|
||||
// expected-note@-2{{attribute is here}}
|
||||
template<typename T> __declspec(dllimport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}}
|
||||
// expected-error@-1{{definition of dllimport static field not allowed}}
|
||||
// expected-note@-2{{attribute is here}}
|
||||
template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllimport' attribute}}
|
||||
// expected-error@-1{{definition of dllimport static field not allowed}}
|
||||
// expected-note@-2{{attribute is here}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
||||
|
||||
|
||||
struct MemFunTmpl {
|
||||
|
@ -628,6 +700,52 @@ template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_
|
|||
|
||||
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
struct MemVarTmpl {
|
||||
template<typename T> static const int StaticVar = 1;
|
||||
template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
|
||||
};
|
||||
|
||||
// Import implicit instantiation of an imported member variable template.
|
||||
int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; }
|
||||
|
||||
// Import explicit instantiation declaration of an imported member variable
|
||||
// template.
|
||||
extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
|
||||
|
||||
// An explicit instantiation definition of an imported member variable template
|
||||
// cannot be imported because the template must be defined which is illegal. The
|
||||
// in-class initializer does not count.
|
||||
|
||||
// Import specialization of an imported member variable template.
|
||||
template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
|
||||
template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 1;
|
||||
// expected-error@-1{{definition of dllimport static field not allowed}}
|
||||
// expected-note@-2{{attribute is here}}
|
||||
|
||||
// Not importing specialization of a member variable template without explicit
|
||||
// dllimport.
|
||||
template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
|
||||
|
||||
|
||||
// Import explicit instantiation declaration of a non-imported member variable
|
||||
// template.
|
||||
extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
|
||||
|
||||
// An explicit instantiation definition of a non-imported member variable template
|
||||
// cannot be imported because the template must be defined which is illegal. The
|
||||
// in-class initializer does not count.
|
||||
|
||||
// Import specialization of a non-imported member variable template.
|
||||
template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
|
||||
template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 1;
|
||||
// expected-error@-1{{definition of dllimport static field not allowed}}
|
||||
// expected-note@-2{{attribute is here}}
|
||||
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Class template members
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -655,6 +773,17 @@ protected:
|
|||
__declspec(dllimport) void protectedDecl();
|
||||
private:
|
||||
__declspec(dllimport) void privateDecl();
|
||||
public:
|
||||
|
||||
__declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
|
||||
__declspec(dllimport) static int StaticField;
|
||||
__declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
|
||||
__declspec(dllimport) static const int StaticConstField;
|
||||
__declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}
|
||||
__declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
|
||||
__declspec(dllimport) static const int StaticConstFieldBraceInit{1};
|
||||
__declspec(dllimport) constexpr static int ConstexprField = 1;
|
||||
__declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
|
||||
};
|
||||
|
||||
// NB: MSVC is inconsistent here and disallows *InlineDef on class templates,
|
||||
|
@ -669,6 +798,10 @@ template<typename T> void ImportClassTmplMembers<T>::staticDef() {} // ex
|
|||
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}}
|
||||
|
||||
|
||||
// Redeclarations cannot add dllimport.
|
||||
template<typename T>
|
||||
|
@ -682,6 +815,10 @@ struct CTMR /*ClassTmplMemberRedecl*/ {
|
|||
static void staticDef(); // expected-note{{previous declaration is here}}
|
||||
static void staticInlineDef(); // expected-note{{previous declaration is here}}
|
||||
static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
|
||||
|
||||
static int StaticField; // expected-note{{previous declaration is here}}
|
||||
static const int StaticConstField; // expected-note{{previous declaration is here}}
|
||||
constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
|
||||
};
|
||||
|
||||
template<typename T> __declspec(dllimport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}
|
||||
|
@ -697,6 +834,16 @@ template<typename T> __declspec(dllimport) void CTMR<T>::staticDef() {}
|
|||
template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}
|
||||
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-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-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-note@-2{{attribute is here}}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -715,6 +862,17 @@ struct ImportClsTmplMemTmpl {
|
|||
template<typename U> __declspec(dllimport) static void staticInclass() {}
|
||||
template<typename U> __declspec(dllimport) static void staticInlineDef();
|
||||
template<typename U> __declspec(dllimport) static inline void staticInlineDecl();
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename U> __declspec(dllimport) static int StaticField;
|
||||
template<typename U> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}
|
||||
template<typename U> __declspec(dllimport) static const int StaticConstField;
|
||||
template<typename U> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}
|
||||
template<typename U> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;
|
||||
template<typename U> __declspec(dllimport) static const int StaticConstFieldBraceInit{1};
|
||||
template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1;
|
||||
template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
};
|
||||
|
||||
template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
|
||||
|
@ -724,6 +882,12 @@ template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::s
|
|||
template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {}
|
||||
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}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
||||
|
||||
// Redeclarations cannot add dllimport.
|
||||
template<typename T>
|
||||
|
@ -734,6 +898,12 @@ struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
|
|||
template<typename U> static void staticDef(); // expected-note{{previous declaration is here}}
|
||||
template<typename U> static void staticInlineDef(); // expected-note{{previous declaration is here}}
|
||||
template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}
|
||||
|
||||
#if __has_feature(cxx_variable_templates)
|
||||
template<typename U> static int StaticField; // expected-note{{previous declaration is here}}
|
||||
template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}}
|
||||
template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
};
|
||||
|
||||
template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}}
|
||||
|
@ -744,3 +914,15 @@ template<typename T> template<typename U> __declspec(dllimport) void CTMT
|
|||
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
|
||||
template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}
|
||||
template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}}
|
||||
|
||||
#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-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-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-note@-2{{attribute is here}}
|
||||
#endif // __has_feature(cxx_variable_templates)
|
||||
|
|
Loading…
Reference in New Issue