[MSVC][dllexport/dllimport] Propagate a dllexport/dllimport attribute to template baseclass

For the Playstation platform, mimick MSVC in propagating dllexport/dllimport attributes
to an instantiated template base class.

Reviewed By: hans

Differential Revision: https://reviews.llvm.org/D145970
This commit is contained in:
Wolfgang Pieb 2023-03-15 10:04:26 -07:00
parent e94b59ee75
commit 634430d585
5 changed files with 48 additions and 16 deletions

View File

@ -2608,7 +2608,8 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
}
// For the MS ABI, propagate DLL attributes to base class templates.
if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
Context.getTargetInfo().getTriple().isPS()) {
if (Attr *ClassAttr = getDLLAttr(Class)) {
if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
BaseType->getAsCXXRecordDecl())) {

View File

@ -6,6 +6,8 @@
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck -allow-deprecated-dag-overlap --check-prefix=GNU --check-prefix=G32 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck -allow-deprecated-dag-overlap --check-prefix=GNU %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-scei-ps4 -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck -allow-deprecated-dag-overlap --check-prefix=PS %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-sie-ps5 -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck -allow-deprecated-dag-overlap --check-prefix=PS %s
// Helper structs to make templates more expressive.
struct ImplicitInst_Exported {};
@ -980,18 +982,21 @@ struct __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
USEMEMFUNC(DerivedFromTemplate, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ClassTemplate@H@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN13ClassTemplateIiE4funcEv
// ExportedTemplate is explicitly exported.
struct __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
USEMEMFUNC(DerivedFromExportedTemplate, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExportedClassTemplate@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN21ExportedClassTemplateIiE4funcEv
// ImportedClassTemplate is explicitly imported.
struct __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
USEMEMFUNC(DerivedFromImportedTemplate, func)
// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$ImportedClassTemplate@H@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN21ImportedClassTemplateIiE4funcEv
// Base class already implicitly instantiated without dll attribute.
struct DerivedFromTemplateD : public ClassTemplate<double> {};
@ -999,6 +1004,7 @@ struct __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double
USEMEMFUNC(DerivedFromTemplateD2, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ClassTemplate@N@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN13ClassTemplateIdE4funcEv
// MS: Base class already instantiated with different dll attribute.
struct __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
@ -1006,42 +1012,49 @@ struct __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool>
USEMEMFUNC(DerivedFromTemplateB2, func)
// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$ClassTemplate@_N@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
// PS-DAG: declare dllimport void @_ZN13ClassTemplateIbE4funcEv
// Base class already specialized without dll attribute.
struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
USEMEMFUNC(DerivedFromExplicitlySpecializedTemplate, func)
// M32-DAG: define dso_local x86_thiscallcc void @"?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
// G32-DAG: define dso_local x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
// PS-DAG: define dso_local void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
// Base class alredy specialized with export attribute.
struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
USEMEMFUNC(DerivedFromExplicitlyExportSpecializedTemplate, func)
// M32-DAG: define dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
// PS-DAG: define dso_local dllexport void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
// Base class already specialized with import attribute.
struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
USEMEMFUNC(DerivedFromExplicitlyImportSpecializedTemplate, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
// Base class already instantiated without dll attribute.
struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
USEMEMFUNC(DerivedFromExplicitlyInstantiatedTemplate, func)
// M32-DAG: define weak_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
// PS-DAG: define weak_odr void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
// Base class already instantiated with export attribute.
struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
USEMEMFUNC(DerivedFromExplicitlyExportInstantiatedTemplate, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
// Base class already instantiated with import attribute.
struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
USEMEMFUNC(DerivedFromExplicitlyImportInstantiatedTemplate, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
// MS: A dll attribute propagates through multiple levels of instantiation.
template <typename T> struct TopClass { void func() {} };
@ -1050,6 +1063,7 @@ struct __declspec(dllexport) BottomClass : public MiddleClass<int> { };
USEMEMFUNC(BottomClass, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$TopClass@H@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN8TopClassIiE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN8TopClassIiE4funcEv
template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
extern template struct ExplicitInstantiationDeclTemplateBase<int>;
@ -1057,6 +1071,7 @@ struct __declspec(dllexport) DerivedFromExplicitInstantiationDeclTemplateBase :
template struct ExplicitInstantiationDeclTemplateBase<int>;
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
// PR26076
struct LayerSelectionBound;

View File

@ -5,6 +5,8 @@
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -w | FileCheck --check-prefix=GO1 %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-scei-ps4 -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=PS %s
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-sie-ps5 -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=PS %s
// CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s
@ -917,18 +919,21 @@ struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
USEMEMFUNC(ClassTemplate<int>, func)
// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$ClassTemplate@H@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN13ClassTemplateIiE4funcEv
// ImportedTemplate is explicitly imported.
struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
USEMEMFUNC(ImportedClassTemplate<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ImportedClassTemplate@H@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN21ImportedClassTemplateIiE4funcEv
// ExportedTemplate is explicitly exported.
struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
USEMEMFUNC(ExportedClassTemplate<int>, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExportedClassTemplate@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN21ExportedClassTemplateIiE4funcEv
// Base class already implicitly instantiated without attribute.
struct DerivedFromTemplateD : public ClassTemplate<double> {};
@ -936,6 +941,7 @@ struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double
USEMEMFUNC(ClassTemplate<double>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ClassTemplate@N@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
// PS-DAG: declare dllimport void @_ZN13ClassTemplateIdE4funcEv
// MS: Base class already instantiated with dfferent attribute.
struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
@ -943,42 +949,49 @@ struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool>
USEMEMFUNC(ClassTemplate<bool>, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ClassTemplate@_N@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN13ClassTemplateIbE4funcEv
// Base class already specialized without dll attribute.
struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
// M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
// PS-DAG: define linkonce_odr void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
// Base class alredy specialized with export attribute.
struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
// M32-DAG: define dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
// PS-DAG: define dso_local dllexport void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
// Base class already specialized with import attribute.
struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
// Base class already instantiated without dll attribute.
struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
// M32-DAG: define weak_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
// PS-DAG: define weak_odr void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
// Base class already instantiated with export attribute.
struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
// PS-DAG: define weak_odr dllexport void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
// Base class already instantiated with import attribute.
struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
// G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
// PS-DAG: declare dllimport void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
// MS: A dll attribute propagates through multiple levels of instantiation.
template <typename T> struct TopClass { void func() {} };
@ -987,6 +1000,7 @@ struct __declspec(dllimport) BottomClass : public MiddleClass<int> { };
USEMEMFUNC(TopClass<int>, func)
// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$TopClass@H@@QAEXXZ"
// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN8TopClassIiE4funcEv
// PS-DAG: declare dllimport void @_ZN8TopClassIiE4funcEv
template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
extern template struct ExplicitInstantiationDeclTemplateBase<int>;
@ -995,6 +1009,7 @@ template struct ExplicitInstantiationDeclTemplateBase<int>;
USEMEMFUNC(ExplicitInstantiationDeclTemplateBase<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
// PS-DAG: declare dllimport void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} };
extern template struct ExplicitInstantiationDeclTemplateBase2<int>;
@ -1003,6 +1018,7 @@ template struct __declspec(dllexport) ExplicitInstantiationDeclTemplateBase2<int
USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func)
// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"
// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
// PS-DAG: declare dllimport void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
namespace pr39496 {
// Make sure dll attribute are inherited by static locals also in template

View File

@ -4,8 +4,8 @@
// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s
// RUN: %clang_cc1 -triple i686-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI %s
// RUN: %clang_cc1 -triple x86_64-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DWI %s
// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI %s
// RUN: %clang_cc1 -triple x86_64-sie-ps5 -fsyntax-only -fdeclspec -verify -std=c++1y -Wunsupported-dll-base-class-template -DWI %s
// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI -DPS %s
// RUN: %clang_cc1 -triple x86_64-sie-ps5 -fsyntax-only -fdeclspec -verify -std=c++1y -Wunsupported-dll-base-class-template -DWI -DPS %s
// Helper structs to make templates more expressive.
struct ImplicitInst_Exported {};
@ -390,13 +390,13 @@ template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedExporte
template struct ExplicitlyInstantiatedExportedTemplate<IncompleteType3>; // expected-note{{in instantiation of member function 'ExplicitlyInstantiatedExportedTemplate<IncompleteType3>::f' requested here}}
// In MS mode, instantiate members of class templates that are base classes of exported classes.
#ifdef MS
#if defined(MS) || defined(PS)
// expected-note@+3{{forward declaration of 'IncompleteType4'}}
// expected-note@+3{{in instantiation of member function 'BaseClassTemplateOfExportedClass<IncompleteType4>::f' requested here}}
#endif
struct IncompleteType4;
template <typename T> struct BaseClassTemplateOfExportedClass {
#ifdef MS
#if defined(MS) || defined(PS)
// expected-error@+2{{invalid application of 'sizeof' to an incomplete type 'IncompleteType4'}}
#endif
int f() { return sizeof(T); };
@ -439,7 +439,7 @@ template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
#ifdef MS
#if defined(MS) || defined(PS)
// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
#endif
template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
@ -449,7 +449,7 @@ template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {
template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
#ifdef MS
#if defined(MS) || defined(PS)
// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
#endif
template struct ExplicitlyInstantiatedTemplate<int>;
@ -488,7 +488,7 @@ class __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {}
// The second derived class doesn't change anything, the attribute that was propagated first wins.
class __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
#ifdef MS
#if defined(MS) || defined(PS)
// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
// expected-note@+2{{attribute is here}}
#endif
@ -500,7 +500,7 @@ struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : pu
// Base class already specialized with import attribute.
struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
#ifdef MS
#if defined(MS) || defined(PS)
// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
// expected-note@+2{{attribute is here}}
#endif

View File

@ -5,9 +5,9 @@
// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++17 -Wunsupported-dll-base-class-template -DGNU %s
// RUN: %clang_cc1 -triple i686-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI %s
// RUN: %clang_cc1 -triple x86_64-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++17 -Wunsupported-dll-base-class-template -DWI %s
// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI %s
// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++17 -Wunsupported-dll-base-class-template -DWI %s
// RUN: %clang_cc1 -triple x86_64-sie-ps5 -fsyntax-only -fdeclspec -verify -std=c++17 -Wunsupported-dll-base-class-template -DWI %s
// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI -DPS %s
// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++17 -Wunsupported-dll-base-class-template -DWI -DPS %s
// RUN: %clang_cc1 -triple x86_64-sie-ps5 -fsyntax-only -fdeclspec -verify -std=c++17 -Wunsupported-dll-base-class-template -DWI -DPS %s
// Helper structs to make templates more expressive.
struct ImplicitInst_Imported {};
@ -1557,7 +1557,7 @@ class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {}
class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
#ifdef MS
#if defined(MS) || defined(PS)
// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
#endif
template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
@ -1567,7 +1567,7 @@ template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {
template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
#ifdef MS
#if defined(MS) || defined(PS)
// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
#endif
template struct ExplicitlyInstantiatedTemplate<int>;
@ -1576,7 +1576,7 @@ template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
#ifdef MS
#if defined(MS) || defined(PS)
// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
// expected-note@+2{{attribute is here}}
#endif
@ -1588,7 +1588,7 @@ struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : pu
// Base class already specialized with import attribute.
struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
#ifdef MS
#if defined(MS) || defined(PS)
// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
// expected-note@+2{{attribute is here}}
#endif