diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp | 328 |
1 files changed, 167 insertions, 161 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp index 9570550..1a09830 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp @@ -11,16 +11,14 @@ // //===----------------------------------------------------------------------===// -#include "CodeGenFunction.h" #include "CGCXXABI.h" +#include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "ConstantBuilder.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/RecordLayout.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/CodeGenOptions.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Format.h" #include "llvm/Transforms/Utils/Cloning.h" #include <algorithm> @@ -32,7 +30,7 @@ using namespace CodeGen; CodeGenVTables::CodeGenVTables(CodeGenModule &CGM) : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {} -llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, +llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk) { const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); @@ -96,7 +94,7 @@ static RValue PerformReturnAdjustment(CodeGenFunction &CGF, AdjustNull = CGF.createBasicBlock("adjust.null"); AdjustNotNull = CGF.createBasicBlock("adjust.notnull"); AdjustEnd = CGF.createBasicBlock("adjust.end"); - + llvm::Value *IsNull = CGF.Builder.CreateIsNull(ReturnValue); CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull); CGF.EmitBlock(AdjustNotNull); @@ -113,14 +111,14 @@ static RValue PerformReturnAdjustment(CodeGenFunction &CGF, CGF.EmitBlock(AdjustNull); CGF.Builder.CreateBr(AdjustEnd); CGF.EmitBlock(AdjustEnd); - + llvm::PHINode *PHI = CGF.Builder.CreatePHI(ReturnValue->getType(), 2); PHI->addIncoming(ReturnValue, AdjustNotNull); - PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()), + PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()), AdjustNull); ReturnValue = PHI; } - + return RValue::get(ReturnValue); } @@ -232,8 +230,11 @@ void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD, CGM.getCXXABI().addImplicitStructorParams(*this, ResultType, FunctionArgs); // Start defining the function. + auto NL = ApplyDebugLocation::CreateEmpty(*this); StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs, - MD->getLocation(), MD->getLocation()); + MD->getLocation()); + // Create a scope with an artificial location for the body of this function. + auto AL = ApplyDebugLocation::CreateArtificial(*this); // Since we didn't pass a GlobalDecl to StartFunction, do this ourselves. CGM.getCXXABI().EmitInstanceFunctionProlog(*this); @@ -251,7 +252,7 @@ void CodeGenFunction::FinishThunk() { FinishFunction(); } -void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Value *Callee, +void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr, const ThunkInfo *Thunk) { assert(isa<CXXMethodDecl>(CurGD.getDecl()) && "Please use a new CGF for this thunk"); @@ -271,7 +272,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Value *Callee, CGM.ErrorUnsupported( MD, "non-trivial argument copy for return-adjusting thunk"); } - EmitMustTailThunk(MD, AdjustedThisPtr, Callee); + EmitMustTailThunk(MD, AdjustedThisPtr, CalleePtr); return; } @@ -285,7 +286,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Value *Callee, // Add the rest of the arguments. for (const ParmVarDecl *PD : MD->parameters()) - EmitDelegateCallArg(CallArgs, PD, PD->getLocStart()); + EmitDelegateCallArg(CallArgs, PD, SourceLocation()); const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); @@ -317,10 +318,11 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Value *Callee, CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect && !hasScalarEvaluationKind(CurFnInfo->getReturnType())) Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified()); - + // Now emit our call. llvm::Instruction *CallOrInvoke; - RValue RV = EmitCall(*CurFnInfo, Callee, Slot, CallArgs, MD, &CallOrInvoke); + CGCallee Callee = CGCallee::forDirect(CalleePtr, MD); + RValue RV = EmitCall(*CurFnInfo, Callee, Slot, CallArgs, &CallOrInvoke); // Consider return adjustment if we have ThunkInfo. if (Thunk && !Thunk->Return.isEmpty()) @@ -340,7 +342,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Value *Callee, void CodeGenFunction::EmitMustTailThunk(const CXXMethodDecl *MD, llvm::Value *AdjustedThisPtr, - llvm::Value *Callee) { + llvm::Value *CalleePtr) { // Emitting a musttail call thunk doesn't use any of the CGCall.cpp machinery // to translate AST arguments into LLVM IR arguments. For thunks, we know // that the caller prototype more or less matches the callee prototype with @@ -369,13 +371,14 @@ void CodeGenFunction::EmitMustTailThunk(const CXXMethodDecl *MD, // Emit the musttail call manually. Even if the prologue pushed cleanups, we // don't actually want to run them. - llvm::CallInst *Call = Builder.CreateCall(Callee, Args); + llvm::CallInst *Call = Builder.CreateCall(CalleePtr, Args); Call->setTailCallKind(llvm::CallInst::TCK_MustTail); // Apply the standard set of call attributes. unsigned CallingConv; CodeGen::AttributeListType AttributeList; - CGM.ConstructAttributeList(Callee->getName(), *CurFnInfo, MD, AttributeList, + CGM.ConstructAttributeList(CalleePtr->getName(), + *CurFnInfo, MD, AttributeList, CallingConv, /*AttrOnCallSite=*/true); llvm::AttributeSet Attrs = llvm::AttributeSet::get(getLLVMContext(), AttributeList); @@ -397,11 +400,13 @@ void CodeGenFunction::generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk) { StartThunk(Fn, GD, FnInfo); + // Create a scope with an artificial location for the body of this function. + auto AL = ApplyDebugLocation::CreateArtificial(*this); // Get our callee. llvm::Type *Ty = CGM.getTypes().GetFunctionType(CGM.getTypes().arrangeGlobalDeclaration(GD)); - llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); + llvm::Constant *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); // Make the call and return the result. EmitCallAndReturnForThunk(Callee, &Thunk); @@ -436,14 +441,14 @@ void CodeGenVTables::emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, // Remove the name from the old thunk function and get a new thunk. OldThunkFn->setName(StringRef()); Entry = cast<llvm::GlobalValue>(CGM.GetAddrOfThunk(GD, Thunk)); - + // If needed, replace the old thunk with a bitcast. if (!OldThunkFn->use_empty()) { llvm::Constant *NewPtrForOldDecl = llvm::ConstantExpr::getBitCast(Entry, OldThunkFn->getType()); OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl); } - + // Remove the old thunk. OldThunkFn->eraseFromParent(); } @@ -503,7 +508,7 @@ void CodeGenVTables::maybeEmitThunkForVTable(GlobalDecl GD, void CodeGenVTables::EmitThunks(GlobalDecl GD) { - const CXXMethodDecl *MD = + const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl(); // We don't need to generate thunks for the base destructor. @@ -520,146 +525,146 @@ void CodeGenVTables::EmitThunks(GlobalDecl GD) emitThunk(GD, Thunk, /*ForVTable=*/false); } -llvm::Constant *CodeGenVTables::CreateVTableInitializer( - const CXXRecordDecl *RD, const VTableComponent *Components, - unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks, - unsigned NumVTableThunks, llvm::Constant *RTTI) { - SmallVector<llvm::Constant *, 64> Inits; +void CodeGenVTables::addVTableComponent( + ConstantArrayBuilder &builder, const VTableLayout &layout, + unsigned idx, llvm::Constant *rtti, unsigned &nextVTableThunkIndex) { + auto &component = layout.vtable_components()[idx]; - llvm::Type *Int8PtrTy = CGM.Int8PtrTy; - - llvm::Type *PtrDiffTy = - CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType()); + auto addOffsetConstant = [&](CharUnits offset) { + builder.add(llvm::ConstantExpr::getIntToPtr( + llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()), + CGM.Int8PtrTy)); + }; - unsigned NextVTableThunkIndex = 0; + switch (component.getKind()) { + case VTableComponent::CK_VCallOffset: + return addOffsetConstant(component.getVCallOffset()); - llvm::Constant *PureVirtualFn = nullptr, *DeletedVirtualFn = nullptr; + case VTableComponent::CK_VBaseOffset: + return addOffsetConstant(component.getVBaseOffset()); - for (unsigned I = 0; I != NumComponents; ++I) { - VTableComponent Component = Components[I]; + case VTableComponent::CK_OffsetToTop: + return addOffsetConstant(component.getOffsetToTop()); - llvm::Constant *Init = nullptr; + case VTableComponent::CK_RTTI: + return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.Int8PtrTy)); - switch (Component.getKind()) { - case VTableComponent::CK_VCallOffset: - Init = llvm::ConstantInt::get(PtrDiffTy, - Component.getVCallOffset().getQuantity()); - Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); - break; - case VTableComponent::CK_VBaseOffset: - Init = llvm::ConstantInt::get(PtrDiffTy, - Component.getVBaseOffset().getQuantity()); - Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); + case VTableComponent::CK_FunctionPointer: + case VTableComponent::CK_CompleteDtorPointer: + case VTableComponent::CK_DeletingDtorPointer: { + GlobalDecl GD; + + // Get the right global decl. + switch (component.getKind()) { + default: + llvm_unreachable("Unexpected vtable component kind"); + case VTableComponent::CK_FunctionPointer: + GD = component.getFunctionDecl(); break; - case VTableComponent::CK_OffsetToTop: - Init = llvm::ConstantInt::get(PtrDiffTy, - Component.getOffsetToTop().getQuantity()); - Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy); + case VTableComponent::CK_CompleteDtorPointer: + GD = GlobalDecl(component.getDestructorDecl(), Dtor_Complete); break; - case VTableComponent::CK_RTTI: - Init = llvm::ConstantExpr::getBitCast(RTTI, Int8PtrTy); + case VTableComponent::CK_DeletingDtorPointer: + GD = GlobalDecl(component.getDestructorDecl(), Dtor_Deleting); break; - case VTableComponent::CK_FunctionPointer: - case VTableComponent::CK_CompleteDtorPointer: - case VTableComponent::CK_DeletingDtorPointer: { - GlobalDecl GD; - - // Get the right global decl. - switch (Component.getKind()) { - default: - llvm_unreachable("Unexpected vtable component kind"); - case VTableComponent::CK_FunctionPointer: - GD = Component.getFunctionDecl(); - break; - case VTableComponent::CK_CompleteDtorPointer: - GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete); - break; - case VTableComponent::CK_DeletingDtorPointer: - GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting); - break; - } - - if (CGM.getLangOpts().CUDA) { - // Emit NULL for methods we can't codegen on this - // side. Otherwise we'd end up with vtable with unresolved - // references. - const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); - // OK on device side: functions w/ __device__ attribute - // OK on host side: anything except __device__-only functions. - bool CanEmitMethod = CGM.getLangOpts().CUDAIsDevice - ? MD->hasAttr<CUDADeviceAttr>() - : (MD->hasAttr<CUDAHostAttr>() || - !MD->hasAttr<CUDADeviceAttr>()); - if (!CanEmitMethod) { - Init = llvm::ConstantExpr::getNullValue(Int8PtrTy); - break; - } - // Method is acceptable, continue processing as usual. - } + } - if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) { - // We have a pure virtual member function. - if (!PureVirtualFn) { - llvm::FunctionType *Ty = - llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); - StringRef PureCallName = CGM.getCXXABI().GetPureVirtualCallName(); - PureVirtualFn = CGM.CreateRuntimeFunction(Ty, PureCallName); - if (auto *F = dyn_cast<llvm::Function>(PureVirtualFn)) - F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); - PureVirtualFn = llvm::ConstantExpr::getBitCast(PureVirtualFn, - CGM.Int8PtrTy); - } - Init = PureVirtualFn; - } else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) { - if (!DeletedVirtualFn) { - llvm::FunctionType *Ty = - llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); - StringRef DeletedCallName = - CGM.getCXXABI().GetDeletedVirtualCallName(); - DeletedVirtualFn = CGM.CreateRuntimeFunction(Ty, DeletedCallName); - if (auto *F = dyn_cast<llvm::Function>(DeletedVirtualFn)) - F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); - DeletedVirtualFn = llvm::ConstantExpr::getBitCast(DeletedVirtualFn, - CGM.Int8PtrTy); - } - Init = DeletedVirtualFn; - } else { - // Check if we should use a thunk. - if (NextVTableThunkIndex < NumVTableThunks && - VTableThunks[NextVTableThunkIndex].first == I) { - const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second; - - maybeEmitThunkForVTable(GD, Thunk); - Init = CGM.GetAddrOfThunk(GD, Thunk); - - NextVTableThunkIndex++; - } else { - llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD); - - Init = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); - } - - Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy); - } - break; + if (CGM.getLangOpts().CUDA) { + // Emit NULL for methods we can't codegen on this + // side. Otherwise we'd end up with vtable with unresolved + // references. + const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); + // OK on device side: functions w/ __device__ attribute + // OK on host side: anything except __device__-only functions. + bool CanEmitMethod = + CGM.getLangOpts().CUDAIsDevice + ? MD->hasAttr<CUDADeviceAttr>() + : (MD->hasAttr<CUDAHostAttr>() || !MD->hasAttr<CUDADeviceAttr>()); + if (!CanEmitMethod) + return builder.addNullPointer(CGM.Int8PtrTy); + // Method is acceptable, continue processing as usual. } - case VTableComponent::CK_UnusedFunctionPointer: - Init = llvm::ConstantExpr::getNullValue(Int8PtrTy); - break; + auto getSpecialVirtualFn = [&](StringRef name) { + llvm::FunctionType *fnTy = + llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); + llvm::Constant *fn = CGM.CreateRuntimeFunction(fnTy, name); + if (auto f = dyn_cast<llvm::Function>(fn)) + f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + return llvm::ConstantExpr::getBitCast(fn, CGM.Int8PtrTy); }; - - Inits.push_back(Init); + + llvm::Constant *fnPtr; + + // Pure virtual member functions. + if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) { + if (!PureVirtualFn) + PureVirtualFn = + getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName()); + fnPtr = PureVirtualFn; + + // Deleted virtual member functions. + } else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) { + if (!DeletedVirtualFn) + DeletedVirtualFn = + getSpecialVirtualFn(CGM.getCXXABI().GetDeletedVirtualCallName()); + fnPtr = DeletedVirtualFn; + + // Thunks. + } else if (nextVTableThunkIndex < layout.vtable_thunks().size() && + layout.vtable_thunks()[nextVTableThunkIndex].first == idx) { + auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second; + + maybeEmitThunkForVTable(GD, thunkInfo); + nextVTableThunkIndex++; + fnPtr = CGM.GetAddrOfThunk(GD, thunkInfo); + + // Otherwise we can use the method definition directly. + } else { + llvm::Type *fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD); + fnPtr = CGM.GetAddrOfFunction(GD, fnTy, /*ForVTable=*/true); + } + + fnPtr = llvm::ConstantExpr::getBitCast(fnPtr, CGM.Int8PtrTy); + builder.add(fnPtr); + return; + } + + case VTableComponent::CK_UnusedFunctionPointer: + return builder.addNullPointer(CGM.Int8PtrTy); + } + + llvm_unreachable("Unexpected vtable component kind"); +} + +llvm::Type *CodeGenVTables::getVTableType(const VTableLayout &layout) { + SmallVector<llvm::Type *, 4> tys; + for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i) { + tys.push_back(llvm::ArrayType::get(CGM.Int8PtrTy, layout.getVTableSize(i))); + } + + return llvm::StructType::get(CGM.getLLVMContext(), tys); +} + +void CodeGenVTables::createVTableInitializer(ConstantStructBuilder &builder, + const VTableLayout &layout, + llvm::Constant *rtti) { + unsigned nextVTableThunkIndex = 0; + for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i) { + auto vtableElem = builder.beginArray(CGM.Int8PtrTy); + size_t thisIndex = layout.getVTableOffset(i); + size_t nextIndex = thisIndex + layout.getVTableSize(i); + for (unsigned i = thisIndex; i != nextIndex; ++i) { + addVTableComponent(vtableElem, layout, i, rtti, nextVTableThunkIndex); + } + vtableElem.finishAndAddTo(builder); } - - llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, NumComponents); - return llvm::ConstantArray::get(ArrayType, Inits); } llvm::GlobalVariable * -CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, - const BaseSubobject &Base, - bool BaseIsVirtual, +CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, + const BaseSubobject &Base, + bool BaseIsVirtual, llvm::GlobalVariable::LinkageTypes Linkage, VTableAddressPointsMapTy& AddressPoints) { if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) @@ -680,8 +685,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, Base.getBase(), Out); StringRef Name = OutName.str(); - llvm::ArrayType *ArrayType = - llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout->getNumVTableComponents()); + llvm::Type *VTType = getVTableType(*VTLayout); // Construction vtable symbols are not part of the Itanium ABI, so we cannot // guarantee that they actually will be available externally. Instead, when @@ -692,8 +696,8 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, Linkage = llvm::GlobalVariable::InternalLinkage; // Create the variable that will hold the construction vtable. - llvm::GlobalVariable *VTable = - CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, Linkage); + llvm::GlobalVariable *VTable = + CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage); CGM.setGlobalVisibility(VTable, RD); // V-tables are always unnamed_addr. @@ -703,12 +707,11 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, CGM.getContext().getTagDeclType(Base.getBase())); // Create and set the initializer. - llvm::Constant *Init = CreateVTableInitializer( - Base.getBase(), VTLayout->vtable_component_begin(), - VTLayout->getNumVTableComponents(), VTLayout->vtable_thunk_begin(), - VTLayout->getNumVTableThunks(), RTTI); - VTable->setInitializer(Init); - + ConstantInitBuilder builder(CGM); + auto components = builder.beginStruct(); + createVTableInitializer(components, *VTLayout, RTTI); + components.finishAndSetAsInitializer(VTable); + CGM.EmitVTableTypeMetadata(VTable, *VTLayout.get()); return VTable; @@ -723,7 +726,7 @@ static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, /// Compute the required linkage of the vtable for the given class. /// /// Note that we only call this at the end of the translation unit. -llvm::GlobalVariable::LinkageTypes +llvm::GlobalVariable::LinkageTypes CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { if (!RD->isExternallyVisible()) return llvm::GlobalVariable::InternalLinkage; @@ -737,7 +740,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { const FunctionDecl *def = nullptr; if (keyFunction->hasBody(def)) keyFunction = cast<CXXMethodDecl>(def); - + switch (keyFunction->getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ExplicitSpecialization: @@ -751,7 +754,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { return !Context.getLangOpts().AppleKext ? llvm::GlobalVariable::LinkOnceODRLinkage : llvm::Function::InternalLinkage; - + return llvm::GlobalVariable::ExternalLinkage; case TSK_ImplicitInstantiation: @@ -763,7 +766,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { return !Context.getLangOpts().AppleKext ? llvm::GlobalVariable::WeakODRLinkage : llvm::Function::InternalLinkage; - + case TSK_ExplicitInstantiationDeclaration: llvm_unreachable("Should not have been asked to emit this"); } @@ -819,7 +822,7 @@ void CodeGenModule::EmitVTable(CXXRecordDecl *theClass) { VTables.GenerateClassData(theClass); } -void +void CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) { if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) DI->completeClassData(RD); @@ -949,7 +952,10 @@ void CodeGenModule::EmitVTableTypeMetadata(llvm::GlobalVariable *VTable, std::vector<BSEntry> BitsetEntries; // Create a bit set entry for each address point. for (auto &&AP : VTLayout.getAddressPoints()) - BitsetEntries.push_back(std::make_pair(AP.first.getBase(), AP.second)); + BitsetEntries.push_back( + std::make_pair(AP.first.getBase(), + VTLayout.getVTableOffset(AP.second.VTableIndex) + + AP.second.AddressPointIndex)); // Sort the bit set entries for determinism. std::sort(BitsetEntries.begin(), BitsetEntries.end(), |