summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp5
-rw-r--r--clang/lib/AST/VTableBuilder.cpp14
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp5
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp15
4 files changed, 28 insertions, 11 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 0634319cbd1..930cf00d9e3 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -2599,7 +2599,10 @@ void MicrosoftMangleContextImpl::mangleCXXVFTable(
// NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
// is always '6' for vftables.
MicrosoftCXXNameMangler Mangler(*this, Out);
- Mangler.getStream() << "\01??_7";
+ if (Derived->hasAttr<DLLImportAttr>())
+ Mangler.getStream() << "\01??_S";
+ else
+ Mangler.getStream() << "\01??_7";
Mangler.mangleName(Derived);
Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
for (const CXXRecordDecl *RD : BasePath)
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index bae018652f9..e43acc4de78 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -2416,7 +2416,7 @@ private:
MethodVFTableLocationsTy MethodVFTableLocations;
/// \brief Does this class have an RTTI component?
- bool HasRTTIComponent;
+ bool HasRTTIComponent = false;
/// MethodInfo - Contains information about a method in a vtable.
/// (Used for computing 'this' pointer adjustment thunks.
@@ -2546,11 +2546,13 @@ public:
WhichVFPtr(*Which),
Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) {
// Only include the RTTI component if we know that we will provide a
- // definition of the vftable.
- HasRTTIComponent = Context.getLangOpts().RTTIData &&
- !MostDerivedClass->hasAttr<DLLImportAttr>() &&
- MostDerivedClass->getTemplateSpecializationKind() !=
- TSK_ExplicitInstantiationDeclaration;
+ // definition of the vftable. We always provide the definition of
+ // dllimported classes.
+ if (Context.getLangOpts().RTTIData)
+ if (MostDerivedClass->hasAttr<DLLImportAttr>() ||
+ MostDerivedClass->getTemplateSpecializationKind() !=
+ TSK_ExplicitInstantiationDeclaration)
+ HasRTTIComponent = true;
LayoutVFTable();
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 620e9223b2e..e96a8120207 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -838,6 +838,11 @@ CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.");
+ // We always synthesize vtables on the import side regardless of whether or
+ // not it is an explicit instantiation declaration.
+ if (CGM.getTarget().getCXXABI().isMicrosoft() && RD->hasAttr<DLLImportAttr>())
+ return false;
+
// If we have an explicit instantiation declaration (and not a
// definition), the vtable is defined elsewhere.
TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 2870a91dd5f..2567aa92f25 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1673,7 +1673,16 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
SmallString<256> VFTableName;
mangleVFTableName(getMangleContext(), RD, VFPtr, VFTableName);
- llvm::GlobalValue::LinkageTypes VFTableLinkage = CGM.getVTableLinkage(RD);
+ // Classes marked __declspec(dllimport) need vftables generated on the
+ // import-side in order to support features like constexpr. No other
+ // translation unit relies on the emission of the local vftable, translation
+ // units are expected to generate them as needed.
+ //
+ // Because of this unique behavior, we maintain this logic here instead of
+ // getVTableLinkage.
+ llvm::GlobalValue::LinkageTypes VFTableLinkage =
+ RD->hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
+ : CGM.getVTableLinkage(RD);
bool VFTableComesFromAnotherTU =
llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
@@ -1746,9 +1755,7 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
if (C)
VTable->setComdat(C);
- if (RD->hasAttr<DLLImportAttr>())
- VFTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
- else if (RD->hasAttr<DLLExportAttr>())
+ if (RD->hasAttr<DLLExportAttr>())
VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
VFTablesMap[ID] = VFTable;
OpenPOWER on IntegriCloud