<div dir="ltr">Confirm, the assertions are different from the last one.</div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 17, 2015 at 11:45 PM, Justin Bogner via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> writes:<br>
> Are you sure it was this change and not r245265?<br>
<br>
</span>Pretty sure - I ran the crash repro script with tot and it repro'd, then<br>
with r245264 reverted and it didn't. That's when I pushed the revert.<br>
<div class="HOEnZb"><div class="h5"><br>
> On Aug 17, 2015 10:41 PM, "Justin Bogner via cfe-commits" <<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
><br>
> Author: bogner<br>
> Date: Tue Aug 18 00:40:20 2015<br>
> New Revision: 245267<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=245267&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=245267&view=rev</a><br>
> Log:<br>
> Revert "Generating assumption loads of vptr after ctor call (fixed)"<br>
><br>
> Bootstrap bots were failing:<br>
><br>
> <a href="http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_build/6382/" rel="noreferrer" target="_blank">http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_build/6382/</a><br>
> <a href="http://bb.pgr.jp/builders/clang-3stage-i686-linux/builds/2969" rel="noreferrer" target="_blank">http://bb.pgr.jp/builders/clang-3stage-i686-linux/builds/2969</a><br>
><br>
> This reverts r245264.<br>
><br>
> Removed:<br>
> cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp<br>
> Modified:<br>
> cfe/trunk/lib/CodeGen/CGCXXABI.h<br>
> cfe/trunk/lib/CodeGen/CGCall.cpp<br>
> cfe/trunk/lib/CodeGen/CGClass.cpp<br>
> cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
> cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp<br>
> cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp<br>
> cfe/trunk/test/CodeGen/available-externally-hidden.cpp<br>
> cfe/trunk/test/CodeGenCXX/ctor-globalopt.cpp<br>
> cfe/trunk/test/CodeGenCXX/template-instantiation.cpp<br>
> cfe/trunk/test/CodeGenCXX/thunks.cpp<br>
> cfe/trunk/test/CodeGenCXX/virtual-base-ctor.cpp<br>
> cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h</a>?<br>
> rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGCXXABI.h Tue Aug 18 00:40:20 2015<br>
> @@ -346,25 +346,13 @@ public:<br>
> virtual void emitVTableDefinitions(CodeGenVTables &CGVT,<br>
> const CXXRecordDecl *RD) = 0;<br>
><br>
> - /// Checks if ABI requires extra virtual offset for vtable field.<br>
> - virtual bool<br>
> - isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,<br>
> - CodeGenFunction::VPtr Vptr) = 0;<br>
> -<br>
> - /// Checks if ABI requires to initilize vptrs for given dynamic class.<br>
> - virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl<br>
> *VTableClass) = 0;<br>
> -<br>
> - /// Get the address point of the vtable for the given base subobject.<br>
> - virtual llvm::Constant *<br>
> - getVTableAddressPoint(BaseSubobject Base,<br>
> - const CXXRecordDecl *VTableClass) = 0;<br>
> -<br>
> /// Get the address point of the vtable for the given base subobject<br>
> while<br>
> - /// building a constructor or a destructor.<br>
> - virtual llvm::Value *<br>
> - getVTableAddressPointInStructor(CodeGenFunction &CGF, const<br>
> CXXRecordDecl *RD,<br>
> - BaseSubobject Base,<br>
> - const CXXRecordDecl *NearestVBase) = 0;<br>
> + /// building a constructor or a destructor. On return,<br>
> NeedsVirtualOffset<br>
> + /// tells if a virtual base adjustment is needed in order to get the<br>
> offset<br>
> + /// of the base subobject.<br>
> + virtual llvm::Value *getVTableAddressPointInStructor(<br>
> + CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base,<br>
> + const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) = 0;<br>
><br>
> /// Get the address point of the vtable for the given base subobject<br>
> while<br>
> /// building a constexpr.<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CGCall.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp</a>?<br>
> rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/lib/CodeGen/CGCall.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Aug 18 00:40:20 2015<br>
> @@ -1412,8 +1412,7 @@ void CodeGenModule::ConstructAttributeLi<br>
><br>
> if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {<br>
> const FunctionProtoType *FPT = Fn->getType()->getAs<br>
> <FunctionProtoType>();<br>
> - if (FPT && !isUnresolvedExceptionSpec(FPT->getExceptionSpecType())<br>
> &&<br>
> - FPT->isNothrow(getContext()))<br>
> + if (FPT && FPT->isNothrow(getContext()))<br>
> FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);<br>
> // Don't use [[noreturn]] or _Noreturn for a call to a virtual<br>
> function.<br>
> // These attributes are not inherited by overloads.<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CGClass.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/</a><br>
> CGClass.cpp?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/lib/CodeGen/CGClass.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGClass.cpp Tue Aug 18 00:40:20 2015<br>
> @@ -1806,14 +1806,12 @@ void CodeGenFunction::EmitCXXConstructor<br>
> bool ForVirtualBase,<br>
> bool Delegating, llvm::Value<br>
> *This,<br>
> const CXXConstructExpr *E) {<br>
> - const CXXRecordDecl *ClassDecl = D->getParent();<br>
> -<br>
> // C++11 [class.mfct.non-static]p2:<br>
> // If a non-static member function of a class X is called for an<br>
> object that<br>
> // is not of type X, or of a type derived from X, the behavior is<br>
> undefined.<br>
> // FIXME: Provide a source location here.<br>
> EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, SourceLocation(),<br>
> This,<br>
> - getContext().getRecordType(ClassDecl));<br>
> + getContext().getRecordType(D->getParent()));<br>
><br>
> if (D->isTrivial() && D->isDefaultConstructor()) {<br>
> assert(E->getNumArgs() == 0 && "trivial default ctor with args");<br>
> @@ -1829,7 +1827,7 @@ void CodeGenFunction::EmitCXXConstructor<br>
> const Expr *Arg = E->getArg(0);<br>
> QualType SrcTy = Arg->getType();<br>
> llvm::Value *Src = EmitLValue(Arg).getAddress();<br>
> - QualType DestTy = getContext().getTypeDeclType(ClassDecl);<br>
> + QualType DestTy = getContext().getTypeDeclType(D->getParent());<br>
> EmitAggregateCopyCtor(This, Src, DestTy, SrcTy);<br>
> return;<br>
> }<br>
> @@ -1852,41 +1850,6 @@ void CodeGenFunction::EmitCXXConstructor<br>
> const CGFunctionInfo &Info =<br>
> CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs);<br>
> EmitCall(Info, Callee, ReturnValueSlot(), Args, D);<br>
> -<br>
> - // Generate vtable assumptions if we're constructing a complete object<br>
> - // with a vtable. We don't do this for base subobjects for two<br>
> reasons:<br>
> - // first, it's incorrect for classes with virtual bases, and second,<br>
> we're<br>
> - // about to overwrite the vptrs anyway.<br>
> - if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&<br>
> - ClassDecl->isDynamicClass() && Type != Ctor_Base)<br>
> - EmitVTableAssumptionLoads(ClassDecl, This);<br>
> -}<br>
> -<br>
> -void CodeGenFunction::EmitVTableAssumptionLoad(const VPtr &Vptr,<br>
> - llvm::Value *This) {<br>
> - llvm::Value *VTableGlobal =<br>
> - CGM.getCXXABI().getVTableAddressPoint(Vptr.Base, Vptr.VTableClass);<br>
> - if (!VTableGlobal)<br>
> - return;<br>
> -<br>
> - // We can just use the base offset in the complete class.<br>
> - CharUnits NonVirtualOffset = Vptr.Base.getBaseOffset();<br>
> -<br>
> - if (!NonVirtualOffset.isZero())<br>
> - This =<br>
> - ApplyNonVirtualAndVirtualOffset(*this, This, NonVirtualOffset,<br>
> nullptr);<br>
> -<br>
> - llvm::Value *VPtrValue = GetVTablePtr(This, VTableGlobal->getType());<br>
> - llvm::Value *Cmp =<br>
> - Builder.CreateICmpEQ(VPtrValue, VTableGlobal, "cmp.vtables");<br>
> - Builder.CreateAssumption(Cmp);<br>
> -}<br>
> -<br>
> -void CodeGenFunction::EmitVTableAssumptionLoads(const CXXRecordDecl<br>
> *ClassDecl,<br>
> - llvm::Value *This) {<br>
> - if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))<br>
> - for (const VPtr &Vptr : getVTablePointers(ClassDecl))<br>
> - EmitVTableAssumptionLoad(Vptr, This);<br>
> }<br>
><br>
> void<br>
> @@ -2054,12 +2017,24 @@ void CodeGenFunction::PushDestructorClea<br>
> PushDestructorCleanup(D, Addr);<br>
> }<br>
><br>
> -void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {<br>
> +void<br>
> +CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,<br>
> + const CXXRecordDecl<br>
> *NearestVBase,<br>
> + CharUnits<br>
> OffsetFromNearestVBase,<br>
> + const CXXRecordDecl<br>
> *VTableClass) {<br>
> + const CXXRecordDecl *RD = Base.getBase();<br>
> +<br>
> + // Don't initialize the vtable pointer if the class is marked with the<br>
> + // 'novtable' attribute.<br>
> + if ((RD == VTableClass || RD == NearestVBase) &&<br>
> + VTableClass->hasAttr<MSNoVTableAttr>())<br>
> + return;<br>
> +<br>
> // Compute the address point.<br>
> + bool NeedsVirtualOffset;<br>
> llvm::Value *VTableAddressPoint =<br>
> CGM.getCXXABI().getVTableAddressPointInStructor(<br>
> - *this, Vptr.VTableClass, Vptr.Base, Vptr.NearestVBase);<br>
> -<br>
> + *this, VTableClass, Base, NearestVBase, NeedsVirtualOffset);<br>
> if (!VTableAddressPoint)<br>
> return;<br>
><br>
> @@ -2067,15 +2042,17 @@ void CodeGenFunction::InitializeVTablePo<br>
> llvm::Value *VirtualOffset = nullptr;<br>
> CharUnits NonVirtualOffset = CharUnits::Zero();<br>
><br>
> - if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*this, Vptr)) {<br>
> + if (NeedsVirtualOffset) {<br>
> // We need to use the virtual base offset offset because the virtual<br>
> base<br>
> // might have a different offset in the most derived class.<br>
> - VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(<br>
> - *this, LoadCXXThis(), Vptr.VTableClass, Vptr.NearestVBase);<br>
> - NonVirtualOffset = Vptr.OffsetFromNearestVBase;<br>
> + VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this,<br>
> + LoadCXXThis<br>
> (),<br>
> + <br>
> VTableClass,<br>
> + <br>
> NearestVBase);<br>
> + NonVirtualOffset = OffsetFromNearestVBase;<br>
> } else {<br>
> // We can just use the base offset in the complete class.<br>
> - NonVirtualOffset = Vptr.Base.getBaseOffset();<br>
> + NonVirtualOffset = Base.getBaseOffset();<br>
> }<br>
><br>
> // Apply the offsets.<br>
> @@ -2094,36 +2071,23 @@ void CodeGenFunction::InitializeVTablePo<br>
> ->getPointerTo();<br>
> VTableField = Builder.CreateBitCast(VTableField, VTablePtrTy-><br>
> getPointerTo());<br>
> VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint,<br>
> VTablePtrTy);<br>
> -<br>
> llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint,<br>
> VTableField);<br>
> CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr());<br>
> }<br>
><br>
> -CodeGenFunction::VPtrsVector<br>
> -CodeGenFunction::getVTablePointers(const CXXRecordDecl *VTableClass) {<br>
> - CodeGenFunction::VPtrsVector VPtrsResult;<br>
> - VisitedVirtualBasesSetTy VBases;<br>
> - getVTablePointers(BaseSubobject(VTableClass, CharUnits::Zero()),<br>
> - /*NearestVBase=*/nullptr,<br>
> - /*OffsetFromNearestVBase=*/CharUnits::Zero(),<br>
> - /*BaseIsNonVirtualPrimaryBase=*/false, VTableClass,<br>
> VBases,<br>
> - VPtrsResult);<br>
> - return VPtrsResult;<br>
> -}<br>
> -<br>
> -void CodeGenFunction::getVTablePointers(BaseSubobject Base,<br>
> - const CXXRecordDecl<br>
> *NearestVBase,<br>
> - CharUnits OffsetFromNearestVBase,<br>
> - bool BaseIsNonVirtualPrimaryBase,<br>
> - const CXXRecordDecl *VTableClass,<br>
> - VisitedVirtualBasesSetTy &VBases,<br>
> - VPtrsVector &Vptrs) {<br>
> +void<br>
> +CodeGenFunction::InitializeVTablePointers(BaseSubobject Base,<br>
> + const CXXRecordDecl<br>
> *NearestVBase,<br>
> + CharUnits<br>
> OffsetFromNearestVBase,<br>
> + bool<br>
> BaseIsNonVirtualPrimaryBase,<br>
> + const CXXRecordDecl<br>
> *VTableClass,<br>
> + VisitedVirtualBasesSetTy&<br>
> VBases) {<br>
> // If this base is a non-virtual primary base the address point has<br>
> already<br>
> // been set.<br>
> if (!BaseIsNonVirtualPrimaryBase) {<br>
> // Initialize the vtable pointer for this base.<br>
> - VPtr Vptr = {Base, NearestVBase, OffsetFromNearestVBase,<br>
> VTableClass};<br>
> - Vptrs.push_back(Vptr);<br>
> + InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase,<br>
> + VTableClass);<br>
> }<br>
><br>
> const CXXRecordDecl *RD = Base.getBase();<br>
> @@ -2161,10 +2125,11 @@ void CodeGenFunction::getVTablePointers(<br>
> BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() ==<br>
> BaseDecl;<br>
> }<br>
><br>
> - getVTablePointers(<br>
> - BaseSubobject(BaseDecl, BaseOffset),<br>
> - I.isVirtual() ? BaseDecl : NearestVBase,<br>
> BaseOffsetFromNearestVBase,<br>
> - BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);<br>
> + InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset),<br>
> + I.isVirtual() ? BaseDecl : NearestVBase,<br>
> + BaseOffsetFromNearestVBase,<br>
> + BaseDeclIsNonVirtualPrimaryBase,<br>
> + VTableClass, VBases);<br>
> }<br>
> }<br>
><br>
> @@ -2174,9 +2139,11 @@ void CodeGenFunction::InitializeVTablePo<br>
> return;<br>
><br>
> // Initialize the vtable pointers for this class and all of its bases.<br>
> - if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD))<br>
> - for (const VPtr &Vptr : getVTablePointers(RD))<br>
> - InitializeVTablePointer(Vptr);<br>
> + VisitedVirtualBasesSetTy VBases;<br>
> + InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()),<br>
> + /*NearestVBase=*/nullptr,<br>
> + /*OffsetFromNearestVBase=*/CharUnits::Zero(),<br>
> + /*BaseIsNonVirtualPrimaryBase=*/false, RD,<br>
> VBases);<br>
><br>
> if (RD->getNumVBases())<br>
> CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD);<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/</a><br>
> CodeGenFunction.h?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br>
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Aug 18 00:40:20 2015<br>
> @@ -1309,27 +1309,21 @@ public:<br>
> void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init,<br>
> ArrayRef<VarDecl *> ArrayIndexes);<br>
><br>
> - /// Struct with all informations about dynamic [sub]class needed to set<br>
> vptr.<br>
> - struct VPtr {<br>
> - BaseSubobject Base;<br>
> - const CXXRecordDecl *NearestVBase;<br>
> - CharUnits OffsetFromNearestVBase;<br>
> - const CXXRecordDecl *VTableClass;<br>
> - };<br>
> -<br>
> - /// Initialize the vtable pointer of the given subobject.<br>
> - void InitializeVTablePointer(const VPtr &vptr);<br>
> -<br>
> - typedef llvm::SmallVector<VPtr, 4> VPtrsVector;<br>
> + /// InitializeVTablePointer - Initialize the vtable pointer of the<br>
> given<br>
> + /// subobject.<br>
> + ///<br>
> + void InitializeVTablePointer(BaseSubobject Base,<br>
> + const CXXRecordDecl *NearestVBase,<br>
> + CharUnits OffsetFromNearestVBase,<br>
> + const CXXRecordDecl *VTableClass);<br>
><br>
> typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4><br>
> VisitedVirtualBasesSetTy;<br>
> - VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass);<br>
> -<br>
> - void getVTablePointers(BaseSubobject Base, const CXXRecordDecl<br>
> *NearestVBase,<br>
> - CharUnits OffsetFromNearestVBase,<br>
> - bool BaseIsNonVirtualPrimaryBase,<br>
> - const CXXRecordDecl *VTableClass,<br>
> - VisitedVirtualBasesSetTy &VBases, VPtrsVector &<br>
> vptrs);<br>
> + void InitializeVTablePointers(BaseSubobject Base,<br>
> + const CXXRecordDecl *NearestVBase,<br>
> + CharUnits OffsetFromNearestVBase,<br>
> + bool BaseIsNonVirtualPrimaryBase,<br>
> + const CXXRecordDecl *VTableClass,<br>
> + VisitedVirtualBasesSetTy& VBases);<br>
><br>
> void InitializeVTablePointers(const CXXRecordDecl *ClassDecl);<br>
><br>
> @@ -1758,19 +1752,10 @@ public:<br>
> // they are substantially the same.<br>
> void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,<br>
> const FunctionArgList &Args);<br>
> -<br>
> void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType<br>
> Type,<br>
> bool ForVirtualBase, bool Delegating,<br>
> llvm::Value *This, const CXXConstructExpr<br>
> *E);<br>
><br>
> - /// Emit assumption load for all bases. Requires to be be called only<br>
> on<br>
> - /// most-derived class and not under construction of the object.<br>
> - void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl,<br>
> - llvm::Value *This);<br>
> -<br>
> - /// Emit assumption that vptr load == global vtable.<br>
> - void EmitVTableAssumptionLoad(const VPtr &vptr, llvm::Value *This);<br>
> -<br>
> void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,<br>
> llvm::Value *This, llvm::Value *Src,<br>
> const CXXConstructExpr *E);<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/</a><br>
> ItaniumCXXABI.cpp?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Aug 18 00:40:20 2015<br>
> @@ -190,24 +190,10 @@ public:<br>
> void emitVTableDefinitions(CodeGenVTables &CGVT,<br>
> const CXXRecordDecl *RD) override;<br>
><br>
> - bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,<br>
> - CodeGenFunction::VPtr Vptr)<br>
> override;<br>
> -<br>
> - bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)<br>
> override {<br>
> - return true;<br>
> - }<br>
> -<br>
> - llvm::Constant *<br>
> - getVTableAddressPoint(BaseSubobject Base,<br>
> - const CXXRecordDecl *VTableClass) override;<br>
> -<br>
> llvm::Value *getVTableAddressPointInStructor(<br>
> CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,<br>
> - BaseSubobject Base, const CXXRecordDecl *NearestVBase) override;<br>
> -<br>
> - llvm::Value *getVTableAddressPointInStructorWithVTT(<br>
> - CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,<br>
> - BaseSubobject Base, const CXXRecordDecl *NearestVBase);<br>
> + BaseSubobject Base, const CXXRecordDecl *NearestVBase,<br>
> + bool &NeedsVirtualOffset) override;<br>
><br>
> llvm::Constant *<br>
> getVTableAddressPointForConstExpr(BaseSubobject Base,<br>
> @@ -1390,29 +1376,41 @@ void ItaniumCXXABI::emitVTableDefinition<br>
> CGM.EmitVTableBitSetEntries(VTable, VTLayout);<br>
> }<br>
><br>
> -bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(<br>
> - CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {<br>
> - if (Vptr.NearestVBase == nullptr)<br>
> - return false;<br>
> - return NeedsVTTParameter(CGF.CurGD);<br>
> -}<br>
> -<br>
> llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(<br>
> CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject<br>
> Base,<br>
> - const CXXRecordDecl *NearestVBase) {<br>
> + const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {<br>
> + bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CGF.CurGD);<br>
> + NeedsVirtualOffset = (NeedsVTTParam && NearestVBase);<br>
> +<br>
> + llvm::Value *VTableAddressPoint;<br>
> + if (NeedsVTTParam && (Base.getBase()->getNumVBases() || NearestVBase))<br>
> {<br>
> + // Get the secondary vpointer index.<br>
> + uint64_t VirtualPointerIndex =<br>
> + CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass,<br>
> Base);<br>
> +<br>
> + /// Load the VTT.<br>
> + llvm::Value *VTT = CGF.LoadCXXVTT();<br>
> + if (VirtualPointerIndex)<br>
> + VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT,<br>
> VirtualPointerIndex);<br>
><br>
> - if ((Base.getBase()->getNumVBases() || NearestVBase != nullptr) &&<br>
> - NeedsVTTParameter(CGF.CurGD)) {<br>
> - return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,<br>
> - NearestVBase);<br>
> + // And load the address point from the VTT.<br>
> + VTableAddressPoint = CGF.Builder.CreateLoad(VTT);<br>
> + } else {<br>
> + llvm::Constant *VTable =<br>
> + CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits());<br>
> + uint64_t AddressPoint = CGM.getItaniumVTableContext()<br>
> + .getVTableLayout(VTableClass)<br>
> + .getAddressPoint(Base);<br>
> + VTableAddressPoint =<br>
> + CGF.Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);<br>
> }<br>
> - return getVTableAddressPoint(Base, VTableClass);<br>
> +<br>
> + return VTableAddressPoint;<br>
> }<br>
><br>
> -llvm::Constant *<br>
> -ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,<br>
> - const CXXRecordDecl *VTableClass) {<br>
> - llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());<br>
> +llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(<br>
> + BaseSubobject Base, const CXXRecordDecl *VTableClass) {<br>
> + auto *VTable = getAddrOfVTable(VTableClass, CharUnits());<br>
><br>
> // Find the appropriate vtable within the vtable group.<br>
> uint64_t AddressPoint = CGM.getItaniumVTableContext()<br>
> @@ -1427,30 +1425,6 @@ ItaniumCXXABI::getVTableAddressPoint(Bas<br>
> VTable, Indices);<br>
> }<br>
><br>
> -llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(<br>
> - CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject<br>
> Base,<br>
> - const CXXRecordDecl *NearestVBase) {<br>
> - assert((Base.getBase()->getNumVBases() || NearestVBase != nullptr) &&<br>
> - NeedsVTTParameter(CGF.CurGD) && "This class doesn't have VTT");<br>
> -<br>
> - // Get the secondary vpointer index.<br>
> - uint64_t VirtualPointerIndex =<br>
> - CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass,<br>
> Base);<br>
> -<br>
> - /// Load the VTT.<br>
> - llvm::Value *VTT = CGF.LoadCXXVTT();<br>
> - if (VirtualPointerIndex)<br>
> - VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT,<br>
> VirtualPointerIndex);<br>
> -<br>
> - // And load the address point from the VTT.<br>
> - return CGF.Builder.CreateLoad(VTT);<br>
> -}<br>
> -<br>
> -llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(<br>
> - BaseSubobject Base, const CXXRecordDecl *VTableClass) {<br>
> - return getVTableAddressPoint(Base, VTableClass);<br>
> -}<br>
> -<br>
> llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl<br>
> *RD,<br>
> CharUnits<br>
> VPtrOffset) {<br>
> assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr<br>
> offsets");<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/</a><br>
> MicrosoftCXXABI.cpp?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Aug 18 00:40:20 2015<br>
> @@ -215,22 +215,10 @@ public:<br>
> void emitVTableDefinitions(CodeGenVTables &CGVT,<br>
> const CXXRecordDecl *RD) override;<br>
><br>
> - bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,<br>
> - CodeGenFunction::VPtr Vptr)<br>
> override;<br>
> -<br>
> - /// Don't initialize vptrs if dynamic class<br>
> - /// is marked with with the 'novtable' attribute.<br>
> - bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)<br>
> override {<br>
> - return !VTableClass->hasAttr<MSNoVTableAttr>();<br>
> - }<br>
> -<br>
> - llvm::Constant *<br>
> - getVTableAddressPoint(BaseSubobject Base,<br>
> - const CXXRecordDecl *VTableClass) override;<br>
> -<br>
> llvm::Value *getVTableAddressPointInStructor(<br>
> CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,<br>
> - BaseSubobject Base, const CXXRecordDecl *NearestVBase) override;<br>
> + BaseSubobject Base, const CXXRecordDecl *NearestVBase,<br>
> + bool &NeedsVirtualOffset) override;<br>
><br>
> llvm::Constant *<br>
> getVTableAddressPointForConstExpr(BaseSubobject Base,<br>
> @@ -1580,15 +1568,14 @@ void MicrosoftCXXABI::emitVTableDefiniti<br>
> }<br>
> }<br>
><br>
> -bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(<br>
> - CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {<br>
> - return Vptr.NearestVBase != nullptr;<br>
> -}<br>
> -<br>
> llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(<br>
> CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject<br>
> Base,<br>
> - const CXXRecordDecl *NearestVBase) {<br>
> - llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base,<br>
> VTableClass);<br>
> + const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {<br>
> + NeedsVirtualOffset = (NearestVBase != nullptr);<br>
> +<br>
> + (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());<br>
> + VFTableIdTy ID(VTableClass, Base.getBaseOffset());<br>
> + llvm::GlobalValue *VTableAddressPoint = VFTablesMap[ID];<br>
> if (!VTableAddressPoint) {<br>
> assert(Base.getBase()->getNumVBases() &&<br>
> !getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr<br>
> ());<br>
> @@ -1603,17 +1590,11 @@ static void mangleVFTableName(MicrosoftM<br>
> MangleContext.mangleCXXVFTable(RD, VFPtr->MangledPath, Out);<br>
> }<br>
><br>
> -llvm::Constant *<br>
> -MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base,<br>
> - const CXXRecordDecl *VTableClass)<br>
> {<br>
> - (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());<br>
> - VFTableIdTy ID(VTableClass, Base.getBaseOffset());<br>
> - return VFTablesMap[ID];<br>
> -}<br>
> -<br>
> llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(<br>
> BaseSubobject Base, const CXXRecordDecl *VTableClass) {<br>
> - llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass);<br>
> + (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());<br>
> + VFTableIdTy ID(VTableClass, Base.getBaseOffset());<br>
> + llvm::GlobalValue *VFTable = VFTablesMap[ID];<br>
> assert(VFTable && "Couldn't find a vftable for the given base?");<br>
> return VFTable;<br>
> }<br>
> @@ -1623,7 +1604,6 @@ llvm::GlobalVariable *MicrosoftCXXABI::g<br>
> // getAddrOfVTable may return 0 if asked to get an address of a vtable<br>
> which<br>
> // shouldn't be used in the given record type. We want to cache this<br>
> result in<br>
> // VFTablesMap, thus a simple zero check is not sufficient.<br>
> -<br>
> VFTableIdTy ID(RD, VPtrOffset);<br>
> VTablesMapTy::iterator I;<br>
> bool Inserted;<br>
> @@ -1677,11 +1657,10 @@ llvm::GlobalVariable *MicrosoftCXXABI::g<br>
> if (llvm::GlobalValue *VFTable =<br>
> CGM.getModule().getNamedGlobal(VFTableName)) {<br>
> VFTablesMap[ID] = VFTable;<br>
> - VTable = VTableAliasIsRequred<br>
> - ? cast<llvm::GlobalVariable>(<br>
> - cast<llvm::GlobalAlias>(VFTable)->getBaseObject())<br>
> - : cast<llvm::GlobalVariable>(VFTable);<br>
> - return VTable;<br>
> + return VTableAliasIsRequred<br>
> + ? cast<llvm::GlobalVariable>(<br>
> + cast<llvm::GlobalAlias>(VFTable)->getBaseObject())<br>
> + : cast<llvm::GlobalVariable>(VFTable);<br>
> }<br>
><br>
> uint64_t NumVTableSlots =<br>
><br>
> Modified: cfe/trunk/test/CodeGen/available-externally-hidden.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/</a><br>
> available-externally-hidden.cpp?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CodeGen/available-externally-hidden.cpp (original)<br>
> +++ cfe/trunk/test/CodeGen/available-externally-hidden.cpp Tue Aug 18<br>
> 00:40:20 2015<br>
> @@ -27,6 +27,6 @@ class TestSyncMessageFilter : public Syn<br>
> };<br>
><br>
> int main() {<br>
> - TestSyncMessageFilter *f = new TestSyncMessageFilter;<br>
> +TestSyncMessageFilter* f = new TestSyncMessageFilter;<br>
> f->Send(new Message);<br>
> }<br>
><br>
> Modified: cfe/trunk/test/CodeGenCXX/ctor-globalopt.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/</a><br>
> ctor-globalopt.cpp?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CodeGenCXX/ctor-globalopt.cpp (original)<br>
> +++ cfe/trunk/test/CodeGenCXX/ctor-globalopt.cpp Tue Aug 18 00:40:20 2015<br>
> @@ -1,7 +1,7 @@<br>
> // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s |<br>
> FileCheck %s<br>
> -// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s -O2 |<br>
> opt - -S -globalopt -o - | FileCheck %s --check-prefix=O1<br>
> +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s -O1 |<br>
> FileCheck %s --check-prefix=O1<br>
> // RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s | FileCheck<br>
> %s<br>
> -// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s -O2 | opt -<br>
> -S -globalopt -o - | FileCheck %s --check-prefix=O1<br>
> +// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s -O1 |<br>
> FileCheck %s --check-prefix=O1<br>
><br>
> // Check that GlobalOpt can eliminate static constructors for simple<br>
> implicit<br>
> // constructors. This is a targetted integration test to make sure that<br>
> LLVM's<br>
><br>
> Modified: cfe/trunk/test/CodeGenCXX/template-instantiation.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/</a><br>
> template-instantiation.cpp?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CodeGenCXX/template-instantiation.cpp (original)<br>
> +++ cfe/trunk/test/CodeGenCXX/template-instantiation.cpp Tue Aug 18<br>
> 00:40:20 2015<br>
> @@ -1,7 +1,5 @@<br>
> // RUN: %clang_cc1 %s -O1 -disable-llvm-optzns -triple=<br>
> x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s<br>
><br>
> -// CHECK: @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr<br>
> unnamed_addr constant<br>
> -<br>
> // CHECK: @_ZN7PR100011xE = global<br>
> // CHECK-NOT: @_ZN7PR100014kBarE = external global i32<br>
> //<br>
> @@ -14,6 +12,7 @@<br>
> // CHECK: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32]<br>
> // CHECK-NOT: @_ZN7PR100011SIiE3arr2E = linkonce_odr global [3 x i32]A<br>
><br>
> +// CHECK: @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr<br>
> unnamed_addr constant<br>
><br>
> // CHECK-NOT: _ZTVN5test31SIiEE<br>
> // CHECK-NOT: _ZTSN5test31SIiEE<br>
><br>
> Modified: cfe/trunk/test/CodeGenCXX/thunks.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/</a><br>
> thunks.cpp?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CodeGenCXX/thunks.cpp (original)<br>
> +++ cfe/trunk/test/CodeGenCXX/thunks.cpp Tue Aug 18 00:40:20 2015<br>
> @@ -1,9 +1,5 @@<br>
> -// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables<br>
> -emit-llvm -o %t<br>
> -// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables<br>
> -emit-llvm -o %t.opt -O1 -disable-llvm-optzns<br>
> -// RUN: FileCheck %s < %t<br>
> -// RUN: FileCheck %s < %t.opt<br>
> -// RUN: FileCheck --check-prefix=CHECK-NONOPT %s < %t<br>
> -// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt<br>
> +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables<br>
> -emit-llvm -o - | FileCheck %s<br>
> +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables<br>
> -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s<br>
><br>
> namespace Test1 {<br>
><br>
> @@ -384,25 +380,13 @@ D::~D() {}<br>
><br>
> /**** The following has to go at the end of the file ****/<br>
><br>
> -// checking without opt<br>
> -// CHECK-NONOPT-LABEL: define internal void<br>
> @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(<br>
> -// CHECK-NONOPT-NOT: comdat<br>
> -<br>
> // This is from Test5:<br>
> -// CHECK-NONOPT-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv<br>
> -<br>
> -// This is from Test10:<br>
> -// CHECK-NONOPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv<br>
> -// CHECK-NONOPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv<br>
> -<br>
> -// Checking with opt<br>
> -// CHECK-OPT-LABEL: define internal void<br>
> @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous<br>
> namespace)::C"* %this) unnamed_addr #0 align 2<br>
> +// CHECK-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv<br>
> (<br>
> +// CHECK-NOT: comdat<br>
> +// CHECK-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv<br>
><br>
> // This is from Test10:<br>
> -// CHECK-OPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv<br>
> -// CHECK-OPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv<br>
> -<br>
> -// This is from Test5:<br>
> -// CHECK-OPT-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv<br>
> +// CHECK-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv<br>
> +// CHECK-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv<br>
><br>
> // CHECK: attributes [[NUW]] = { nounwind uwtable{{.*}} }<br>
><br>
> Modified: cfe/trunk/test/CodeGenCXX/virtual-base-ctor.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/</a><br>
> virtual-base-ctor.cpp?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CodeGenCXX/virtual-base-ctor.cpp (original)<br>
> +++ cfe/trunk/test/CodeGenCXX/virtual-base-ctor.cpp Tue Aug 18 00:40:20<br>
> 2015<br>
> @@ -1,4 +1,4 @@<br>
> -// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - -O2 |<br>
> opt - -S -globalopt -o - | FileCheck %s<br>
> +// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - -O2 |<br>
> FileCheck %s<br>
><br>
> struct B;<br>
> extern B x;<br>
><br>
> Removed: cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/</a><br>
> vtable-assume-load.cpp?rev=245266&view=auto<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp (original)<br>
> +++ cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp (removed)<br>
> @@ -1,172 +0,0 @@<br>
> -// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll<br>
> -O1 -disable-llvm-optzns -fms-extensions<br>
> -// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1<br>
> -disable-llvm-optzns -fms-extensions<br>
> -<br>
> -// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s<br>
> -// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s<br>
> -// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s<br>
> -// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s<br>
> -// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s<br>
> -<br>
> -namespace test1 {<br>
> -<br>
> -struct A {<br>
> - A();<br>
> - virtual void foo();<br>
> -};<br>
> -<br>
> -struct B : A {<br>
> - virtual void foo();<br>
> -};<br>
> -<br>
> -void g(A *a) { a->foo(); }<br>
> -<br>
> -// CHECK1-LABEL: define void @_ZN5test14fooAEv()<br>
> -// CHECK1: call void @_ZN5test11AC1Ev(%"struct.test1::A"*<br>
> -// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}<br>
> -// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds<br>
> ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)<br>
> -// CHECK1: call void @llvm.assume(i1 %[[CMP]])<br>
> -// CHECK1-LABEL: }<br>
> -<br>
> -void fooA() {<br>
> - A a;<br>
> - g(&a);<br>
> -}<br>
> -<br>
> -// CHECK1-LABEL: define void @_ZN5test14fooBEv()<br>
> -// CHECK1: call void @_ZN5test11BC1Ev(%"struct.test1::B"* %{{.*}})<br>
> -// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}<br>
> -// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds<br>
> ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)<br>
> -// CHECK1: call void @llvm.assume(i1 %[[CMP]])<br>
> -// CHECK1-LABEL: }<br>
> -<br>
> -void fooB() {<br>
> - B b;<br>
> - g(&b);<br>
> -}<br>
> -// there should not be any assumes in the ctor that calls base ctor<br>
> -// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev<br>
> (%"struct.test1::B"*<br>
> -// CHECK1-NOT: @llvm.assume(<br>
> -// CHECK1-LABEL: }<br>
> -}<br>
> -namespace test2 {<br>
> -struct A {<br>
> - A();<br>
> - virtual void foo();<br>
> -};<br>
> -<br>
> -struct B {<br>
> - B();<br>
> - virtual void bar();<br>
> -};<br>
> -<br>
> -struct C : A, B {<br>
> - C();<br>
> - virtual void foo();<br>
> -};<br>
> -void g(A *a) { a->foo(); }<br>
> -void h(B *b) { b->bar(); }<br>
> -<br>
> -// CHECK2-LABEL: define void @_ZN5test24testEv()<br>
> -// CHECK2: call void @_ZN5test21CC1Ev(%"struct.test2::C"*<br>
> -// CHECK2: %[[VTABLE:.*]] = load i8**, i8*** {{.*}}<br>
> -// CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds<br>
> ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 2)<br>
> -// CHECK2: call void @llvm.assume(i1 %[[CMP]])<br>
> -<br>
> -// CHECK2: %[[V2:.*]] = bitcast %"struct.test2::C"* %{{.*}} to i8*<br>
> -// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64<br>
> 8<br>
> -// CHECK2: %[[V3:.*]] = bitcast i8* %[[ADD_PTR]] to i8***<br>
> -// CHECK2: %[[VTABLE2:.*]] = load i8**, i8*** %[[V3]]<br>
> -// CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr<br>
> inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 5)<br>
> -// CHECK2: call void @llvm.assume(i1 %[[CMP2]])<br>
> -<br>
> -// CHECK2: call void @_ZN5test21gEPNS_1AE(<br>
> -// CHECK2-LABEL: }<br>
> -<br>
> -void test() {<br>
> - C c;<br>
> - g(&c);<br>
> - h(&c);<br>
> -}<br>
> -}<br>
> -<br>
> -namespace test3 {<br>
> -struct A {<br>
> - A();<br>
> -};<br>
> -<br>
> -struct B : A {<br>
> - B();<br>
> - virtual void foo();<br>
> -};<br>
> -<br>
> -struct C : virtual A, B {<br>
> - C();<br>
> - virtual void foo();<br>
> -};<br>
> -void g(B *a) { a->foo(); }<br>
> -<br>
> -// CHECK3-LABEL: define void @_ZN5test34testEv()<br>
> -// CHECK3: call void @_ZN5test31CC1Ev(%"struct.test3::C"*<br>
> -// CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr inbounds ([4<br>
> x i8*], [4 x i8*]* @_ZTVN5test31CE, i64 0, i64 3)<br>
> -// CHECK3: call void @llvm.assume(i1 %[[CMP]])<br>
> -// CHECK3-LABLEL: }<br>
> -void test() {<br>
> - C c;<br>
> - g(&c);<br>
> -}<br>
> -} // test3<br>
> -<br>
> -namespace test4 {<br>
> -struct A {<br>
> - A();<br>
> - virtual void foo();<br>
> -};<br>
> -<br>
> -struct B : virtual A {<br>
> - B();<br>
> - virtual void foo();<br>
> -};<br>
> -struct C : B {<br>
> - C();<br>
> - virtual void foo();<br>
> -};<br>
> -<br>
> -void g(C *c) { c->foo(); }<br>
> -<br>
> -// CHECK4-LABEL: define void @_ZN5test44testEv()<br>
> -// CHECK4: call void @_ZN5test41CC1Ev(%"struct.test4::C"*<br>
> -// CHECK4: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}<br>
> -// CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds<br>
> ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4)<br>
> -// CHECK4: call void @llvm.assume(i1 %[[CMP]]<br>
> -<br>
> -// CHECK4: %[[VTABLE2:.*]] = load i8**, i8*** %{{.*}}<br>
> -// CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr<br>
> inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4)<br>
> -// CHECK4: call void @llvm.assume(i1 %[[CMP2]])<br>
> -// CHECK4-LABEL: }<br>
> -<br>
> -void test() {<br>
> - C c;<br>
> - g(&c);<br>
> -}<br>
> -} // test4<br>
> -<br>
> -namespace test5 {<br>
> -<br>
> -struct __declspec(novtable) S {<br>
> - virtual void foo();<br>
> -};<br>
> -<br>
> -void g(S &s) { s.foo(); }<br>
> -<br>
> -// if struct has novtable specifier, then we can't generate assumes<br>
> -// CHECK-MS-LABEL: define void @"\01?test@test5@@YAXXZ"()<br>
> -// CHECK-MS: call x86_thiscallcc %"struct.test5::S"* @"\01??<br>
> 0S@test5@@QAE@XZ"(<br>
> -// CHECK-MS-NOT: @llvm.assume<br>
> -// CHECK-MS-LABEL: }<br>
> -<br>
> -void test() {<br>
> - S s;<br>
> - g(s);<br>
> -}<br>
> -<br>
> -} // test5<br>
><br>
> Modified: cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/</a><br>
> vtable-available-externally.cpp?rev=245267&r1=245266&r2=245267&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp (original)<br>
> +++ cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp Tue Aug 18<br>
> 00:40:20 2015<br>
> @@ -182,8 +182,8 @@ void f() {<br>
> namespace Test9 {<br>
> // all virtual functions are outline, so we can assume that it will<br>
> // be generated in translation unit where foo is defined<br>
> -// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr<br>
> constant<br>
> -// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr<br>
> constant<br>
> +// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr<br>
> constant<br>
> +// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr<br>
> constant<br>
> struct A {<br>
> virtual void foo();<br>
> virtual void bar();<br>
> @@ -206,7 +206,7 @@ void g() {<br>
> namespace Test10 {<br>
><br>
> // because A's key function is defined here, vtable is generated in this<br>
> TU<br>
> -// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant<br>
> +// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant<br>
> struct A {<br>
> virtual void foo();<br>
> virtual void bar();<br>
> @@ -214,14 +214,14 @@ struct A {<br>
> void A::foo() {}<br>
><br>
> // Because key function is inline we will generate vtable as linkonce_odr<br>
> -// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr<br>
> constant<br>
> +// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant<br>
> struct D : A {<br>
> void bar();<br>
> };<br>
> inline void D::bar() {}<br>
><br>
> // because B has outline key function then we can refer to<br>
> -// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr<br>
> constant<br>
> +// CHECK-TEST10: @_ZTVN6Test101BE = available_externally unnamed_addr<br>
> constant<br>
> struct B : A {<br>
> void foo();<br>
> void bar();<br>
> @@ -230,7 +230,7 @@ struct B : A {<br>
> // C's key function (car) is outline, but C has inline virtual function<br>
> so we<br>
> // can't guarantee that we will be able to refer to bar from name<br>
> // so (at the moment) we can't emit vtable available_externally<br>
> -// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant<br>
> +// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant<br>
> struct C : A {<br>
> void bar() {} // defined in body - not key function<br>
> virtual inline void gar(); // inline in body - not key function<br>
> @@ -238,7 +238,7 @@ struct C : A {<br>
> };<br>
><br>
> // no key function, vtable will be generated everywhere it will be used<br>
> -// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr<br>
> constant<br>
> +// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant<br>
> struct E : A {};<br>
><br>
> void g(A& a) {<br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div>