diff options
author | Justin Bogner <mail@justinbogner.com> | 2015-08-18 05:40:20 +0000 |
---|---|---|
committer | Justin Bogner <mail@justinbogner.com> | 2015-08-18 05:40:20 +0000 |
commit | 3c32c83daa5e7ceda3f5cb7cd3bf4059c197a202 (patch) | |
tree | 98bf51e1b3a2870332dc6c05d56ac88b32a8da5a /clang/lib | |
parent | 0081f9185353814969acf8e3af7677eff29f3f63 (diff) | |
download | bcm5719-llvm-3c32c83daa5e7ceda3f5cb7cd3bf4059c197a202.tar.gz bcm5719-llvm-3c32c83daa5e7ceda3f5cb7cd3bf4059c197a202.zip |
Revert "Generating assumption loads of vptr after ctor call (fixed)"
Bootstrap bots were failing:
http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_build/6382/
http://bb.pgr.jp/builders/clang-3stage-i686-linux/builds/2969
This reverts r245264.
llvm-svn: 245267
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.h | 24 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 119 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 41 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 90 | ||||
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 51 |
6 files changed, 110 insertions, 218 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index 158d29ab510..5ef409ecdee 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -346,25 +346,13 @@ public: virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD) = 0; - /// Checks if ABI requires extra virtual offset for vtable field. - virtual bool - isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, - CodeGenFunction::VPtr Vptr) = 0; - - /// Checks if ABI requires to initilize vptrs for given dynamic class. - virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) = 0; - - /// Get the address point of the vtable for the given base subobject. - virtual llvm::Constant * - getVTableAddressPoint(BaseSubobject Base, - const CXXRecordDecl *VTableClass) = 0; - /// Get the address point of the vtable for the given base subobject while - /// building a constructor or a destructor. - virtual llvm::Value * - getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, - BaseSubobject Base, - const CXXRecordDecl *NearestVBase) = 0; + /// building a constructor or a destructor. On return, NeedsVirtualOffset + /// tells if a virtual base adjustment is needed in order to get the offset + /// of the base subobject. + virtual llvm::Value *getVTableAddressPointInStructor( + CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, + const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) = 0; /// Get the address point of the vtable for the given base subobject while /// building a constexpr. diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 2511e26e770..f7107b61060 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1412,8 +1412,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) { const FunctionProtoType *FPT = Fn->getType()->getAs<FunctionProtoType>(); - if (FPT && !isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) && - FPT->isNothrow(getContext())) + if (FPT && FPT->isNothrow(getContext())) FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); // Don't use [[noreturn]] or _Noreturn for a call to a virtual function. // These attributes are not inherited by overloads. diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 0ee74c01dcc..fea72f6818e 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1806,14 +1806,12 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, bool ForVirtualBase, bool Delegating, llvm::Value *This, const CXXConstructExpr *E) { - const CXXRecordDecl *ClassDecl = D->getParent(); - // C++11 [class.mfct.non-static]p2: // If a non-static member function of a class X is called for an object that // is not of type X, or of a type derived from X, the behavior is undefined. // FIXME: Provide a source location here. EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, SourceLocation(), This, - getContext().getRecordType(ClassDecl)); + getContext().getRecordType(D->getParent())); if (D->isTrivial() && D->isDefaultConstructor()) { assert(E->getNumArgs() == 0 && "trivial default ctor with args"); @@ -1829,7 +1827,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, const Expr *Arg = E->getArg(0); QualType SrcTy = Arg->getType(); llvm::Value *Src = EmitLValue(Arg).getAddress(); - QualType DestTy = getContext().getTypeDeclType(ClassDecl); + QualType DestTy = getContext().getTypeDeclType(D->getParent()); EmitAggregateCopyCtor(This, Src, DestTy, SrcTy); return; } @@ -1852,41 +1850,6 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs); EmitCall(Info, Callee, ReturnValueSlot(), Args, D); - - // Generate vtable assumptions if we're constructing a complete object - // with a vtable. We don't do this for base subobjects for two reasons: - // first, it's incorrect for classes with virtual bases, and second, we're - // about to overwrite the vptrs anyway. - if (CGM.getCodeGenOpts().OptimizationLevel > 0 && - ClassDecl->isDynamicClass() && Type != Ctor_Base) - EmitVTableAssumptionLoads(ClassDecl, This); -} - -void CodeGenFunction::EmitVTableAssumptionLoad(const VPtr &Vptr, - llvm::Value *This) { - llvm::Value *VTableGlobal = - CGM.getCXXABI().getVTableAddressPoint(Vptr.Base, Vptr.VTableClass); - if (!VTableGlobal) - return; - - // We can just use the base offset in the complete class. - CharUnits NonVirtualOffset = Vptr.Base.getBaseOffset(); - - if (!NonVirtualOffset.isZero()) - This = - ApplyNonVirtualAndVirtualOffset(*this, This, NonVirtualOffset, nullptr); - - llvm::Value *VPtrValue = GetVTablePtr(This, VTableGlobal->getType()); - llvm::Value *Cmp = - Builder.CreateICmpEQ(VPtrValue, VTableGlobal, "cmp.vtables"); - Builder.CreateAssumption(Cmp); -} - -void CodeGenFunction::EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, - llvm::Value *This) { - if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl)) - for (const VPtr &Vptr : getVTablePointers(ClassDecl)) - EmitVTableAssumptionLoad(Vptr, This); } void @@ -2054,12 +2017,24 @@ void CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) { PushDestructorCleanup(D, Addr); } -void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { +void +CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, + const CXXRecordDecl *NearestVBase, + CharUnits OffsetFromNearestVBase, + const CXXRecordDecl *VTableClass) { + const CXXRecordDecl *RD = Base.getBase(); + + // Don't initialize the vtable pointer if the class is marked with the + // 'novtable' attribute. + if ((RD == VTableClass || RD == NearestVBase) && + VTableClass->hasAttr<MSNoVTableAttr>()) + return; + // Compute the address point. + bool NeedsVirtualOffset; llvm::Value *VTableAddressPoint = CGM.getCXXABI().getVTableAddressPointInStructor( - *this, Vptr.VTableClass, Vptr.Base, Vptr.NearestVBase); - + *this, VTableClass, Base, NearestVBase, NeedsVirtualOffset); if (!VTableAddressPoint) return; @@ -2067,15 +2042,17 @@ void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { llvm::Value *VirtualOffset = nullptr; CharUnits NonVirtualOffset = CharUnits::Zero(); - if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*this, Vptr)) { + if (NeedsVirtualOffset) { // We need to use the virtual base offset offset because the virtual base // might have a different offset in the most derived class. - VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset( - *this, LoadCXXThis(), Vptr.VTableClass, Vptr.NearestVBase); - NonVirtualOffset = Vptr.OffsetFromNearestVBase; + VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this, + LoadCXXThis(), + VTableClass, + NearestVBase); + NonVirtualOffset = OffsetFromNearestVBase; } else { // We can just use the base offset in the complete class. - NonVirtualOffset = Vptr.Base.getBaseOffset(); + NonVirtualOffset = Base.getBaseOffset(); } // Apply the offsets. @@ -2094,36 +2071,23 @@ void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { ->getPointerTo(); VTableField = Builder.CreateBitCast(VTableField, VTablePtrTy->getPointerTo()); VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy); - llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr()); } -CodeGenFunction::VPtrsVector -CodeGenFunction::getVTablePointers(const CXXRecordDecl *VTableClass) { - CodeGenFunction::VPtrsVector VPtrsResult; - VisitedVirtualBasesSetTy VBases; - getVTablePointers(BaseSubobject(VTableClass, CharUnits::Zero()), - /*NearestVBase=*/nullptr, - /*OffsetFromNearestVBase=*/CharUnits::Zero(), - /*BaseIsNonVirtualPrimaryBase=*/false, VTableClass, VBases, - VPtrsResult); - return VPtrsResult; -} - -void CodeGenFunction::getVTablePointers(BaseSubobject Base, - const CXXRecordDecl *NearestVBase, - CharUnits OffsetFromNearestVBase, - bool BaseIsNonVirtualPrimaryBase, - const CXXRecordDecl *VTableClass, - VisitedVirtualBasesSetTy &VBases, - VPtrsVector &Vptrs) { +void +CodeGenFunction::InitializeVTablePointers(BaseSubobject Base, + const CXXRecordDecl *NearestVBase, + CharUnits OffsetFromNearestVBase, + bool BaseIsNonVirtualPrimaryBase, + const CXXRecordDecl *VTableClass, + VisitedVirtualBasesSetTy& VBases) { // If this base is a non-virtual primary base the address point has already // been set. if (!BaseIsNonVirtualPrimaryBase) { // Initialize the vtable pointer for this base. - VPtr Vptr = {Base, NearestVBase, OffsetFromNearestVBase, VTableClass}; - Vptrs.push_back(Vptr); + InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase, + VTableClass); } const CXXRecordDecl *RD = Base.getBase(); @@ -2161,10 +2125,11 @@ void CodeGenFunction::getVTablePointers(BaseSubobject Base, BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; } - getVTablePointers( - BaseSubobject(BaseDecl, BaseOffset), - I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase, - BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs); + InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), + I.isVirtual() ? BaseDecl : NearestVBase, + BaseOffsetFromNearestVBase, + BaseDeclIsNonVirtualPrimaryBase, + VTableClass, VBases); } } @@ -2174,9 +2139,11 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { return; // Initialize the vtable pointers for this class and all of its bases. - if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD)) - for (const VPtr &Vptr : getVTablePointers(RD)) - InitializeVTablePointer(Vptr); + VisitedVirtualBasesSetTy VBases; + InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()), + /*NearestVBase=*/nullptr, + /*OffsetFromNearestVBase=*/CharUnits::Zero(), + /*BaseIsNonVirtualPrimaryBase=*/false, RD, VBases); if (RD->getNumVBases()) CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 26ce8e72afa..95a512c48e2 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1309,27 +1309,21 @@ public: void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init, ArrayRef<VarDecl *> ArrayIndexes); - /// Struct with all informations about dynamic [sub]class needed to set vptr. - struct VPtr { - BaseSubobject Base; - const CXXRecordDecl *NearestVBase; - CharUnits OffsetFromNearestVBase; - const CXXRecordDecl *VTableClass; - }; - - /// Initialize the vtable pointer of the given subobject. - void InitializeVTablePointer(const VPtr &vptr); - - typedef llvm::SmallVector<VPtr, 4> VPtrsVector; + /// InitializeVTablePointer - Initialize the vtable pointer of the given + /// subobject. + /// + void InitializeVTablePointer(BaseSubobject Base, + const CXXRecordDecl *NearestVBase, + CharUnits OffsetFromNearestVBase, + const CXXRecordDecl *VTableClass); typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; - VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass); - - void getVTablePointers(BaseSubobject Base, const CXXRecordDecl *NearestVBase, - CharUnits OffsetFromNearestVBase, - bool BaseIsNonVirtualPrimaryBase, - const CXXRecordDecl *VTableClass, - VisitedVirtualBasesSetTy &VBases, VPtrsVector &vptrs); + void InitializeVTablePointers(BaseSubobject Base, + const CXXRecordDecl *NearestVBase, + CharUnits OffsetFromNearestVBase, + bool BaseIsNonVirtualPrimaryBase, + const CXXRecordDecl *VTableClass, + VisitedVirtualBasesSetTy& VBases); void InitializeVTablePointers(const CXXRecordDecl *ClassDecl); @@ -1758,19 +1752,10 @@ public: // they are substantially the same. void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, const FunctionArgList &Args); - void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, llvm::Value *This, const CXXConstructExpr *E); - /// Emit assumption load for all bases. Requires to be be called only on - /// most-derived class and not under construction of the object. - void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, - llvm::Value *This); - - /// Emit assumption that vptr load == global vtable. - void EmitVTableAssumptionLoad(const VPtr &vptr, llvm::Value *This); - void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, llvm::Value *This, llvm::Value *Src, const CXXConstructExpr *E); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index cf718cfd530..3948b2447eb 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -190,24 +190,10 @@ public: void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD) override; - bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, - CodeGenFunction::VPtr Vptr) override; - - bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) override { - return true; - } - - llvm::Constant * - getVTableAddressPoint(BaseSubobject Base, - const CXXRecordDecl *VTableClass) override; - llvm::Value *getVTableAddressPointInStructor( CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, - BaseSubobject Base, const CXXRecordDecl *NearestVBase) override; - - llvm::Value *getVTableAddressPointInStructorWithVTT( - CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, - BaseSubobject Base, const CXXRecordDecl *NearestVBase); + BaseSubobject Base, const CXXRecordDecl *NearestVBase, + bool &NeedsVirtualOffset) override; llvm::Constant * getVTableAddressPointForConstExpr(BaseSubobject Base, @@ -1390,29 +1376,41 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, CGM.EmitVTableBitSetEntries(VTable, VTLayout); } -bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField( - CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) { - if (Vptr.NearestVBase == nullptr) - return false; - return NeedsVTTParameter(CGF.CurGD); -} - llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor( CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, - const CXXRecordDecl *NearestVBase) { - - if ((Base.getBase()->getNumVBases() || NearestVBase != nullptr) && - NeedsVTTParameter(CGF.CurGD)) { - return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base, - NearestVBase); + const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) { + bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CGF.CurGD); + NeedsVirtualOffset = (NeedsVTTParam && NearestVBase); + + llvm::Value *VTableAddressPoint; + if (NeedsVTTParam && (Base.getBase()->getNumVBases() || NearestVBase)) { + // Get the secondary vpointer index. + uint64_t VirtualPointerIndex = + CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); + + /// Load the VTT. + llvm::Value *VTT = CGF.LoadCXXVTT(); + if (VirtualPointerIndex) + VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); + + // And load the address point from the VTT. + VTableAddressPoint = CGF.Builder.CreateLoad(VTT); + } else { + llvm::Constant *VTable = + CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits()); + uint64_t AddressPoint = CGM.getItaniumVTableContext() + .getVTableLayout(VTableClass) + .getAddressPoint(Base); + VTableAddressPoint = + CGF.Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); } - return getVTableAddressPoint(Base, VTableClass); + + return VTableAddressPoint; } -llvm::Constant * -ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base, - const CXXRecordDecl *VTableClass) { - llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits()); +llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr( + BaseSubobject Base, const CXXRecordDecl *VTableClass) { + auto *VTable = getAddrOfVTable(VTableClass, CharUnits()); // Find the appropriate vtable within the vtable group. uint64_t AddressPoint = CGM.getItaniumVTableContext() @@ -1427,30 +1425,6 @@ ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base, VTable, Indices); } -llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT( - CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, - const CXXRecordDecl *NearestVBase) { - assert((Base.getBase()->getNumVBases() || NearestVBase != nullptr) && - NeedsVTTParameter(CGF.CurGD) && "This class doesn't have VTT"); - - // Get the secondary vpointer index. - uint64_t VirtualPointerIndex = - CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); - - /// Load the VTT. - llvm::Value *VTT = CGF.LoadCXXVTT(); - if (VirtualPointerIndex) - VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); - - // And load the address point from the VTT. - return CGF.Builder.CreateLoad(VTT); -} - -llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr( - BaseSubobject Base, const CXXRecordDecl *VTableClass) { - return getVTableAddressPoint(Base, VTableClass); -} - llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset) { assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets"); diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index ce630d8dea1..c1a00d60689 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -215,22 +215,10 @@ public: void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD) override; - bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, - CodeGenFunction::VPtr Vptr) override; - - /// Don't initialize vptrs if dynamic class - /// is marked with with the 'novtable' attribute. - bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) override { - return !VTableClass->hasAttr<MSNoVTableAttr>(); - } - - llvm::Constant * - getVTableAddressPoint(BaseSubobject Base, - const CXXRecordDecl *VTableClass) override; - llvm::Value *getVTableAddressPointInStructor( CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, - BaseSubobject Base, const CXXRecordDecl *NearestVBase) override; + BaseSubobject Base, const CXXRecordDecl *NearestVBase, + bool &NeedsVirtualOffset) override; llvm::Constant * getVTableAddressPointForConstExpr(BaseSubobject Base, @@ -1580,15 +1568,14 @@ void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, } } -bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField( - CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) { - return Vptr.NearestVBase != nullptr; -} - llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor( CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, - const CXXRecordDecl *NearestVBase) { - llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass); + const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) { + NeedsVirtualOffset = (NearestVBase != nullptr); + + (void)getAddrOfVTable(VTableClass, Base.getBaseOffset()); + VFTableIdTy ID(VTableClass, Base.getBaseOffset()); + llvm::GlobalValue *VTableAddressPoint = VFTablesMap[ID]; if (!VTableAddressPoint) { assert(Base.getBase()->getNumVBases() && !getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr()); @@ -1603,17 +1590,11 @@ static void mangleVFTableName(MicrosoftMangleContext &MangleContext, MangleContext.mangleCXXVFTable(RD, VFPtr->MangledPath, Out); } -llvm::Constant * -MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base, - const CXXRecordDecl *VTableClass) { - (void)getAddrOfVTable(VTableClass, Base.getBaseOffset()); - VFTableIdTy ID(VTableClass, Base.getBaseOffset()); - return VFTablesMap[ID]; -} - llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr( BaseSubobject Base, const CXXRecordDecl *VTableClass) { - llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass); + (void)getAddrOfVTable(VTableClass, Base.getBaseOffset()); + VFTableIdTy ID(VTableClass, Base.getBaseOffset()); + llvm::GlobalValue *VFTable = VFTablesMap[ID]; assert(VFTable && "Couldn't find a vftable for the given base?"); return VFTable; } @@ -1623,7 +1604,6 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, // getAddrOfVTable may return 0 if asked to get an address of a vtable which // shouldn't be used in the given record type. We want to cache this result in // VFTablesMap, thus a simple zero check is not sufficient. - VFTableIdTy ID(RD, VPtrOffset); VTablesMapTy::iterator I; bool Inserted; @@ -1677,11 +1657,10 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, if (llvm::GlobalValue *VFTable = CGM.getModule().getNamedGlobal(VFTableName)) { VFTablesMap[ID] = VFTable; - VTable = VTableAliasIsRequred - ? cast<llvm::GlobalVariable>( - cast<llvm::GlobalAlias>(VFTable)->getBaseObject()) - : cast<llvm::GlobalVariable>(VFTable); - return VTable; + return VTableAliasIsRequred + ? cast<llvm::GlobalVariable>( + cast<llvm::GlobalAlias>(VFTable)->getBaseObject()) + : cast<llvm::GlobalVariable>(VFTable); } uint64_t NumVTableSlots = |