diff options
author | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
commit | c72c57c9e9b69944e3e009cd5e209634839581d3 (patch) | |
tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /lib/AST/VTableBuilder.cpp | |
parent | 5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff) | |
download | FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz |
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'lib/AST/VTableBuilder.cpp')
-rw-r--r-- | lib/AST/VTableBuilder.cpp | 126 |
1 files changed, 90 insertions, 36 deletions
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 33dad40..f80232f 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -17,6 +17,7 @@ #include "clang/AST/RecordLayout.h" #include "clang/Basic/TargetInfo.h" #include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cstdio> @@ -256,11 +257,9 @@ static BaseOffset ComputeBaseOffset(ASTContext &Context, const CXXRecordDecl *DerivedRD) { CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true, /*DetectVirtual=*/false); - - if (!const_cast<CXXRecordDecl *>(DerivedRD)-> - isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) { + + if (!DerivedRD->isDerivedFrom(BaseRD, Paths)) llvm_unreachable("Class must be derived from the passed in base class!"); - } return ComputeBaseOffset(Context, DerivedRD, Paths.front()); } @@ -1001,6 +1000,10 @@ public: dumpLayout(llvm::errs()); } + bool isMicrosoftABI() const { + return VTables.isMicrosoftABI(); + } + uint64_t getNumThunks() const { return Thunks.size(); } @@ -1157,6 +1160,8 @@ void VTableBuilder::ComputeThisAdjustments() { break; case VTableComponent::CK_DeletingDtorPointer: // We've already added the thunk when we saw the complete dtor pointer. + // FIXME: check how this works in the Microsoft ABI + // while working on the multiple inheritance patch. continue; } @@ -1197,10 +1202,8 @@ VTableBuilder::ComputeThisAdjustmentBaseOffset(BaseSubobject Base, CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/true); - if (!const_cast<CXXRecordDecl *>(DerivedRD)-> - isDerivedFrom(const_cast<CXXRecordDecl *>(BaseRD), Paths)) { + if (!DerivedRD->isDerivedFrom(BaseRD, Paths)) llvm_unreachable("Class must be derived from the passed in base class!"); - } // We have to go through all the paths, and see which one leads us to the // right base subobject. @@ -1295,9 +1298,15 @@ VTableBuilder::AddMethod(const CXXMethodDecl *MD, assert(ReturnAdjustment.isEmpty() && "Destructor can't have return adjustment!"); - // Add both the complete destructor and the deleting destructor. - Components.push_back(VTableComponent::MakeCompleteDtor(DD)); - Components.push_back(VTableComponent::MakeDeletingDtor(DD)); + // FIXME: Should probably add a layer of abstraction for vtable generation. + if (!isMicrosoftABI()) { + // Add both the complete destructor and the deleting destructor. + Components.push_back(VTableComponent::MakeCompleteDtor(DD)); + Components.push_back(VTableComponent::MakeDeletingDtor(DD)); + } else { + // Add the scalar deleting destructor. + Components.push_back(VTableComponent::MakeDeletingDtor(DD)); + } } else { // Add the return adjustment if necessary. if (!ReturnAdjustment.isEmpty()) @@ -1612,14 +1621,19 @@ VTableBuilder::LayoutPrimaryAndSecondaryVTables(BaseSubobject Base, if (Base.getBase() == MostDerivedClass) VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets(); - // Add the offset to top. - CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass; - Components.push_back( - VTableComponent::MakeOffsetToTop(OffsetToTop)); - - // Next, add the RTTI. - Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass)); - + // FIXME: Should probably add a layer of abstraction for vtable generation. + if (!isMicrosoftABI()) { + // Add the offset to top. + CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass; + Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop)); + + // Next, add the RTTI. + Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass)); + } else { + // FIXME: unclear what to do with RTTI in MS ABI as emitting it anywhere + // breaks the vftable layout. Just skip RTTI for now, can't mangle anyway. + } + uint64_t AddressPoint = Components.size(); // Now go through all virtual member functions and add them. @@ -1936,6 +1950,8 @@ void VTableBuilder::dumpLayout(raw_ostream& Out) { Out << DD->getQualifiedNameAsString(); if (IsComplete) Out << "() [complete]"; + else if (isMicrosoftABI()) + Out << "() [scalar deleting]"; else Out << "() [deleting]"; @@ -2120,10 +2136,16 @@ void VTableBuilder::dumpLayout(raw_ostream& Out) { MD); if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { - IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Complete))] = - MethodName + " [complete]"; - IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Deleting))] = - MethodName + " [deleting]"; + // FIXME: Should add a layer of abstraction for vtable generation. + if (!isMicrosoftABI()) { + IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Complete))] + = MethodName + " [complete]"; + IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Deleting))] + = MethodName + " [deleting]"; + } else { + IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Deleting))] + = MethodName + " [scalar deleting]"; + } } else { IndicesMap[VTables.getMethodVTableIndex(MD)] = MethodName; } @@ -2154,12 +2176,14 @@ VTableLayout::VTableLayout(uint64_t NumVTableComponents, const VTableComponent *VTableComponents, uint64_t NumVTableThunks, const VTableThunkTy *VTableThunks, - const AddressPointsMapTy &AddressPoints) + const AddressPointsMapTy &AddressPoints, + bool IsMicrosoftABI) : NumVTableComponents(NumVTableComponents), VTableComponents(new VTableComponent[NumVTableComponents]), NumVTableThunks(NumVTableThunks), VTableThunks(new VTableThunkTy[NumVTableThunks]), - AddressPoints(AddressPoints) { + AddressPoints(AddressPoints), + IsMicrosoftABI(IsMicrosoftABI) { std::copy(VTableComponents, VTableComponents+NumVTableComponents, this->VTableComponents.get()); std::copy(VTableThunks, VTableThunks+NumVTableThunks, @@ -2168,6 +2192,11 @@ VTableLayout::VTableLayout(uint64_t NumVTableComponents, VTableLayout::~VTableLayout() { } +VTableContext::VTableContext(ASTContext &Context) + : Context(Context), + IsMicrosoftABI(Context.getTargetInfo().getCXXABI().isMicrosoft()) { +} + VTableContext::~VTableContext() { llvm::DeleteContainerSeconds(VTableLayouts); } @@ -2239,12 +2268,18 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) { if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { const CXXDestructorDecl *OverriddenDD = cast<CXXDestructorDecl>(OverriddenMD); - - // Add both the complete and deleting entries. - MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = - getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Complete)); - MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = - getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting)); + + if (!isMicrosoftABI()) { + // Add both the complete and deleting entries. + MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = + getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Complete)); + MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = + getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting)); + } else { + // Add the scalar deleting destructor. + MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = + getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting)); + } } else { MethodVTableIndices[MD] = getMethodVTableIndex(OverriddenMD); } @@ -2262,11 +2297,16 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) { continue; } - // Add the complete dtor. - MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++; - - // Add the deleting dtor. - MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++; + if (!isMicrosoftABI()) { + // Add the complete dtor. + MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++; + + // Add the deleting dtor. + MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++; + } else { + // Add the scalar deleting dtor. + MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++; + } } else { // Add the entry. MethodVTableIndices[MD] = CurrentIndex++; @@ -2278,6 +2318,11 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) { // If a class has an implicitly-defined virtual destructor, // its entries come after the declared virtual function pointers. + if (isMicrosoftABI()) { + ErrorUnsupported("implicit virtual destructor in the Microsoft ABI", + ImplicitVirtualDtor->getLocation()); + } + // Add the complete dtor. MethodVTableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] = CurrentIndex++; @@ -2357,7 +2402,8 @@ static VTableLayout *CreateVTableLayout(const VTableBuilder &Builder) { Builder.vtable_component_begin(), VTableThunks.size(), VTableThunks.data(), - Builder.getAddressPoints()); + Builder.getAddressPoints(), + Builder.isMicrosoftABI()); } void VTableContext::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) { @@ -2397,6 +2443,14 @@ void VTableContext::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) { } } +void VTableContext::ErrorUnsupported(StringRef Feature, + SourceLocation Location) { + clang::DiagnosticsEngine &Diags = Context.getDiagnostics(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "v-table layout for %0 is not supported yet"); + Diags.Report(Context.getFullLoc(Location), DiagID) << Feature; +} + VTableLayout *VTableContext::createConstructionVTableLayout( const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset, |