diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2016-02-10 17:40:47 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2016-02-10 17:40:47 +0000 |
| commit | 1b2d0b4637a9b808aee88ba7a8b99fe446ed4c07 (patch) | |
| tree | a9c04af507b8c2c9c1934a3a30be2c61c43b16be /clang/lib | |
| parent | 932b4cbf5d4b629c2796aeb9460b988a555a85e0 (diff) | |
| download | bcm5719-llvm-1b2d0b4637a9b808aee88ba7a8b99fe446ed4c07.tar.gz bcm5719-llvm-1b2d0b4637a9b808aee88ba7a8b99fe446ed4c07.zip | |
[MS ABI] Never reference dllimport'd vtables
Referencing a dllimported vtable is impossible in a constexpr
constructor. It would be friendlier to C++ programmers if we
synthesized a copy of the vftable which referenced imported virtual
functions. This would let us initialize the object in a way which
preserves both the intent to import functionality from another DLL while
also making constexpr work.
Differential Revision: http://reviews.llvm.org/D17061
llvm-svn: 260388
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/AST/VTableBuilder.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 15 |
3 files changed, 15 insertions, 6 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..b728b279182 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -2548,7 +2548,6 @@ public: // 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; diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 0664381b44f..f47b120a90c 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; |

