}
}
- // In MSVC mode, dllimported explicit instantiation definitions are treated as
- // instantiation declarations for most purposes.
- bool DLLImportExplicitInstantiationDef = false;
- if (TSK == TSK_ExplicitInstantiationDefinition &&
- Context.getTargetInfo().getCXXABI().isMicrosoft()) {
- // Check for dllimport class template instantiation definitions.
- bool DLLImport =
- ClassTemplate->getTemplatedDecl()->getAttr<DLLImportAttr>();
- for (AttributeList *A = Attr; A; A = A->getNext()) {
- if (A->getKind() == AttributeList::AT_DLLImport)
- DLLImport = true;
- if (A->getKind() == AttributeList::AT_DLLExport) {
- // dllexport trumps dllimport here.
- DLLImport = false;
- break;
- }
- }
- if (DLLImport) {
- TSK = TSK_ExplicitInstantiationDeclaration;
- DLLImportExplicitInstantiationDef = true;
- }
- }
-
// Translate the parser's template argument list in our AST format.
TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
Specialization->setLocation(TemplateNameLoc);
PrevDecl = nullptr;
}
-
- if (PrevDecl_TSK == TSK_ExplicitInstantiationDeclaration &&
- DLLImportExplicitInstantiationDef) {
- // The new specialization might add a dllimport attribute.
- HasNoEffect = false;
- }
}
if (!Specialization) {
Specialization->getDefinition());
if (Def) {
TemplateSpecializationKind Old_TSK = Def->getTemplateSpecializationKind();
+
// Fix a TSK_ExplicitInstantiationDeclaration followed by a
// TSK_ExplicitInstantiationDefinition
if (Old_TSK == TSK_ExplicitInstantiationDeclaration &&
- (TSK == TSK_ExplicitInstantiationDefinition ||
- DLLImportExplicitInstantiationDef)) {
+ TSK == TSK_ExplicitInstantiationDefinition) {
// FIXME: Need to notify the ASTMutationListener that we did this.
Def->setTemplateSpecializationKind(TSK);
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@pr26490@@QAEXXZ"
}
-// dllexport trumps dllexport on an explicit instantiation.
-template <typename T> struct ExplicitInstantiationTwoAttributes { void f() {} };
-template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
-// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ"
-
//===----------------------------------------------------------------------===//
// Classes with template base classes
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
// G32-DAG: define weak_odr x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
+template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} };
+extern template struct ExplicitInstantiationDeclTemplateBase2<int>;
+struct __declspec(dllexport) DerivedFromExplicitInstantiationDeclTemplateBase2 : public ExplicitInstantiationDeclTemplateBase2<int> {};
+template struct __declspec(dllimport) ExplicitInstantiationDeclTemplateBase2<int>;
+USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
+
// PR26076
struct LayerSelectionBound;
template <typename> struct Selection {};
namespace Vtordisp {
// Don't dllimport the vtordisp.
- // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@H@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
+ // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
class Base {
virtual void f() {}
C() {}
virtual void f() {}
};
- USECLASS(C<int>);
+ template class C<char>;
}
namespace ClassTemplateStaticDef {
template <typename T> struct A { static NonPOD x; };
template <typename T> NonPOD A<T>::x;
template struct __declspec(dllimport) A<int>;
- USEVARTYPE(NonPOD, A<int>::x);
- // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = external dllimport global %"struct.PR19933::NonPOD"
+ // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer
int f();
template <typename T> struct B { static int x; };
template <typename T> int B<T>::x = f();
template struct __declspec(dllimport) B<int>;
- USEVAR(B<int>::x);
- // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = external dllimport global i32
+ // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0
constexpr int g() { return 42; }
template <typename T> struct C { static int x; };
template <typename T> int C<T>::x = g();
template struct __declspec(dllimport) C<int>;
- USEVAR(C<int>::x);
- // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = external dllimport global i32
+ // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
template <int I> struct D { static int x, y; };
template <int I> int D<I>::x = I + 1;
template <int I> int D<I>::y = I + f();
template struct __declspec(dllimport) D<42>;
- USEVAR(D<42>::x);
- USEVAR(D<42>::y);
- // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32
- // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32
+ // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43
+ // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
}
namespace PR21355 {
USEMEMFUNC(PR23770BaseTemplate<int>, f);
// M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$PR23770BaseTemplate@H@@QAEXXZ"
-namespace PR27810 {
- template <class T>
- struct basic_ostream {
- struct sentry {
- sentry() { }
- void foo() { }
- };
- };
- template class __declspec(dllimport) basic_ostream<char>;
- // The explicit instantiation definition acts as an explicit instantiation
- // *declaration*, dllimport is not inherited by the inner class, and no
- // functions are emitted unless they are used.
-
- USEMEMFUNC(basic_ostream<char>::sentry, foo);
- // M32-DAG: {{declare|define available_externally}} x86_thiscallcc void @"\01?foo@sentry@?$basic_ostream@D@PR27810@@QAEXXZ"
- // M32-NOT: ??0sentry@?$basic_ostream@D@PR27810@@QAE@XZ
-}
-
-namespace PR27811 {
- template <class T> struct codecvt {
- virtual ~codecvt() { }
- };
- template class __declspec(dllimport) codecvt<char>;
-
- // dllimport means this explicit instantiation definition gets treated as a
- // declaration. Thus, the vtable should not be marked used, and in fact
- // nothing for this class should be emitted at all since it's not used.
- // M32-NOT: codecvt
-}
-
//===----------------------------------------------------------------------===//
// Classes with template base classes
//===----------------------------------------------------------------------===//