diff options
author | Timur Iskhodzhanov <timurrrr@google.com> | 2013-01-21 13:02:41 +0000 |
---|---|---|
committer | Timur Iskhodzhanov <timurrrr@google.com> | 2013-01-21 13:02:41 +0000 |
commit | 649c7316aa29181df7270732722fe5d07ab3c7ad (patch) | |
tree | 24c9fd9364ad760821804f377567d0df8d199015 /lib/AST/VTableBuilder.cpp | |
parent | 445743dec72f675070d4789c348607cd8cbf6090 (diff) |
First step towards vftable generation with -cxx-abi microsoft PR13231
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173035 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/VTableBuilder.cpp')
-rw-r--r-- | lib/AST/VTableBuilder.cpp | 115 |
1 files changed, 86 insertions, 29 deletions
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 1ab2b990ea..00a186e9ee 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -1002,6 +1002,10 @@ public: dumpLayout(llvm::errs()); } + bool isMicrosoftABI() const { + return VTables.isMicrosoftABI(); + } + uint64_t getNumThunks() const { return Thunks.size(); } @@ -1296,9 +1300,18 @@ 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 only one destructor in MS mode. + // FIXME: The virtual destructors are handled differently in MS ABI, + // we should add such a support later. For now, put the complete + // destructor into the vftable just to make its layout right. + Components.push_back(VTableComponent::MakeCompleteDtor(DD)); + } } else { // Add the return adjustment if necessary. if (!ReturnAdjustment.isEmpty()) @@ -1613,14 +1626,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. @@ -2121,10 +2139,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_Complete))] + = MethodName; + } } else { IndicesMap[VTables.getMethodVTableIndex(MD)] = MethodName; } @@ -2155,12 +2179,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, @@ -2169,6 +2195,10 @@ VTableLayout::VTableLayout(uint64_t NumVTableComponents, VTableLayout::~VTableLayout() { } +VTableContext::VTableContext(ASTContext &Context) + : Context(Context), + IsMicrosoftABI(Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft) { } + VTableContext::~VTableContext() { llvm::DeleteContainerSeconds(VTableLayouts); } @@ -2240,12 +2270,17 @@ 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 { + MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = + getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Complete)); + } } else { MethodVTableIndices[MD] = getMethodVTableIndex(OverriddenMD); } @@ -2263,11 +2298,19 @@ 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 only the deleting dtor. + // FIXME: The virtual destructors are handled differently in MS ABI, + // we should add such a support later. For now, put the complete + // destructor into the vftable indices. + MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++; + } } else { // Add the entry. MethodVTableIndices[MD] = CurrentIndex++; @@ -2279,6 +2322,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++; @@ -2358,7 +2406,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) { @@ -2398,6 +2447,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, |