summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-02-11 17:49:28 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-02-11 17:49:28 +0000
commit2d8b2008c85a88dfbd98949a315432e6d5fa77ac (patch)
treef0948df0f95c454fda71535e00c7365495f71812 /clang/lib
parent2ad1f851a12a5e8da59a2c6753a8ce2f133835ad (diff)
downloadbcm5719-llvm-2d8b2008c85a88dfbd98949a315432e6d5fa77ac.tar.gz
bcm5719-llvm-2d8b2008c85a88dfbd98949a315432e6d5fa77ac.zip
Revert "Revert r260388 "[MS ABI] Never reference dllimport'd vtables""
This reverts commit r260449. We would supress our emission of vftable definitions if we thought another translation unit would provide the definition because we saw an explicit instantiation declaration. This is not the case with dllimport, we want to synthesize a definition of the vftable regardless. This fixes PR26569. llvm-svn: 260548
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