diff options
Diffstat (limited to 'lib/CodeGen/MicrosoftCXXABI.cpp')
-rw-r--r-- | lib/CodeGen/MicrosoftCXXABI.cpp | 264 |
1 files changed, 135 insertions, 129 deletions
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index ffb3681c2585a..81ed05059546e 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -216,13 +216,20 @@ public: return DT != Dtor_Base; } + void setCXXDestructorDLLStorage(llvm::GlobalValue *GV, + const CXXDestructorDecl *Dtor, + CXXDtorType DT) const override; + + llvm::GlobalValue::LinkageTypes + getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor, + CXXDtorType DT) const override; + void EmitCXXDestructors(const CXXDestructorDecl *D) override; const CXXRecordDecl * getThisArgumentTypeForMethod(const CXXMethodDecl *MD) override { - MD = MD->getCanonicalDecl(); if (MD->isVirtual() && !isa<CXXDestructorDecl>(MD)) { - MicrosoftVTableContext::MethodVFTableLocation ML = + MethodVFTableLocation ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD); // The vbases might be ordered differently in the final overrider object // and the complete object, so the "this" argument may sometimes point to @@ -357,9 +364,6 @@ public: void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment) override { - // Never dllimport/dllexport thunks. - Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); - GVALinkage Linkage = getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.getDecl())); @@ -371,6 +375,8 @@ public: Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage); } + bool exportThunk() override { return false; } + llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA) override; @@ -516,10 +522,12 @@ public: if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name)) return GV; - return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty, - /*isConstant=*/true, - llvm::GlobalValue::ExternalLinkage, - /*Initializer=*/nullptr, Name); + auto *GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty, + /*isConstant=*/true, + llvm::GlobalValue::ExternalLinkage, + /*Initializer=*/nullptr, Name); + CGM.setDSOLocal(GV); + return GV; } llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) { @@ -558,7 +566,7 @@ private: GetNullMemberPointerFields(const MemberPointerType *MPT, llvm::SmallVectorImpl<llvm::Constant *> &fields); - /// \brief Shared code for virtual base adjustment. Returns the offset from + /// Shared code for virtual base adjustment. Returns the offset from /// the vbptr to the virtual base. Optionally returns the address of the /// vbptr itself. llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, @@ -582,14 +590,14 @@ private: performBaseAdjustment(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy); - /// \brief Performs a full virtual base adjustment. Used to dereference + /// Performs a full virtual base adjustment. Used to dereference /// pointers to members of virtual bases. llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const Expr *E, const CXXRecordDecl *RD, Address Base, llvm::Value *VirtualBaseAdjustmentOffset, llvm::Value *VBPtrOffset /* optional */); - /// \brief Emits a full member pointer with the fields common to data and + /// Emits a full member pointer with the fields common to data and /// function member pointers. llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField, bool IsMemberFunction, @@ -600,16 +608,15 @@ private: bool MemberPointerConstantIsNull(const MemberPointerType *MPT, llvm::Constant *MP); - /// \brief - Initialize all vbptrs of 'this' with RD as the complete type. + /// - Initialize all vbptrs of 'this' with RD as the complete type. void EmitVBPtrStores(CodeGenFunction &CGF, const CXXRecordDecl *RD); - /// \brief Caching wrapper around VBTableBuilder::enumerateVBTables(). + /// Caching wrapper around VBTableBuilder::enumerateVBTables(). const VBTableGlobals &enumerateVBTables(const CXXRecordDecl *RD); - /// \brief Generate a thunk for calling a virtual member function MD. - llvm::Function *EmitVirtualMemPtrThunk( - const CXXMethodDecl *MD, - const MicrosoftVTableContext::MethodVFTableLocation &ML); + /// Generate a thunk for calling a virtual member function MD. + llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD, + const MethodVFTableLocation &ML); public: llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override; @@ -753,15 +760,15 @@ private: typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy; typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy; typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy; - /// \brief All the vftables that have been referenced. + /// All the vftables that have been referenced. VFTablesMapTy VFTablesMap; VTablesMapTy VTablesMap; - /// \brief This set holds the record decls we've deferred vtable emission for. + /// This set holds the record decls we've deferred vtable emission for. llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables; - /// \brief All the vbtables which have been referenced. + /// All the vbtables which have been referenced. llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap; /// Info on the global variable used to guard initialization of static locals. @@ -820,45 +827,8 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const { return RAA_Default; case llvm::Triple::x86_64: - // If a class has a destructor, we'd really like to pass it indirectly - // because it allows us to elide copies. Unfortunately, MSVC makes that - // impossible for small types, which it will pass in a single register or - // stack slot. Most objects with dtors are large-ish, so handle that early. - // We can't call out all large objects as being indirect because there are - // multiple x64 calling conventions and the C++ ABI code shouldn't dictate - // how we pass large POD types. - // - // Note: This permits small classes with nontrivial destructors to be - // passed in registers, which is non-conforming. - if (RD->hasNonTrivialDestructor() && - getContext().getTypeSize(RD->getTypeForDecl()) > 64) - return RAA_Indirect; - - // If a class has at least one non-deleted, trivial copy constructor, it - // is passed according to the C ABI. Otherwise, it is passed indirectly. - // - // Note: This permits classes with non-trivial copy or move ctors to be - // passed in registers, so long as they *also* have a trivial copy ctor, - // which is non-conforming. - if (RD->needsImplicitCopyConstructor()) { - // If the copy ctor has not yet been declared, we can read its triviality - // off the AST. - if (!RD->defaultedCopyConstructorIsDeleted() && - RD->hasTrivialCopyConstructor()) - return RAA_Default; - } else { - // Otherwise, we need to find the copy constructor(s) and ask. - for (const CXXConstructorDecl *CD : RD->ctors()) { - if (CD->isCopyConstructor()) { - // We had at least one nondeleted trivial copy ctor. Return directly. - if (!CD->isDeleted() && CD->isTrivial()) - return RAA_Default; - } - } - } - - // We have no trivial, non-deleted copy constructor. - return RAA_Indirect; + case llvm::Triple::aarch64: + return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default; } llvm_unreachable("invalid enum"); @@ -890,20 +860,6 @@ void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) { CGF.EmitRuntimeCallOrInvoke(Fn, Args); } -namespace { -struct CatchRetScope final : EHScopeStack::Cleanup { - llvm::CatchPadInst *CPI; - - CatchRetScope(llvm::CatchPadInst *CPI) : CPI(CPI) {} - - void Emit(CodeGenFunction &CGF, Flags flags) override { - llvm::BasicBlock *BB = CGF.createBasicBlock("catchret.dest"); - CGF.Builder.CreateCatchRet(CPI, BB); - CGF.EmitBlock(BB); - } -}; -} - void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *S) { // In the MS ABI, the runtime handles the copy, and the catch handler is @@ -1105,10 +1061,22 @@ bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const { // the second parameter. FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false); FI.getReturnInfo().setSRetAfterThis(FI.isInstanceMethod()); + + // aarch64-windows requires that instance methods use X1 for the return + // address. So for aarch64-windows we do not mark the + // return as SRet. + FI.getReturnInfo().setSuppressSRet(CGM.getTarget().getTriple().getArch() == + llvm::Triple::aarch64); return true; } else if (!RD->isPOD()) { // If it's a free function, non-POD types are returned indirectly. FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false); + + // aarch64-windows requires that non-POD, non-instance returns use X0 for + // the return address. So for aarch64-windows we do not mark the return as + // SRet. + FI.getReturnInfo().setSuppressSRet(CGM.getTarget().getTriple().getArch() == + llvm::Triple::aarch64); return true; } @@ -1182,15 +1150,16 @@ void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers( unsigned AS = getThisAddress(CGF).getAddressSpace(); llvm::Value *Int8This = nullptr; // Initialize lazily. - for (VBOffsets::const_iterator I = VBaseMap.begin(), E = VBaseMap.end(); - I != E; ++I) { + for (const CXXBaseSpecifier &S : RD->vbases()) { + const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl(); + auto I = VBaseMap.find(VBase); + assert(I != VBaseMap.end()); if (!I->second.hasVtorDisp()) continue; llvm::Value *VBaseOffset = - GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, I->first); - uint64_t ConstantVBaseOffset = - Layout.getVBaseClassOffset(I->first).getQuantity(); + GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase); + uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity(); // vtorDisp_for_vbase = vbptr[vbase_idx] - offsetof(RD, vbase). llvm::Value *VtorDispValue = Builder.CreateSub( @@ -1233,7 +1202,7 @@ void MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { if (!hasDefaultCXXMethodCC(getContext(), D) || D->getNumParams() != 0) { llvm::Function *Fn = getAddrOfCXXCtorClosure(D, Ctor_DefaultClosure); Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage); - Fn->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + CGM.setGVProperties(Fn, D); } } @@ -1295,6 +1264,52 @@ MicrosoftCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T, return Added; } +void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV, + const CXXDestructorDecl *Dtor, + CXXDtorType DT) const { + // Deleting destructor variants are never imported or exported. Give them the + // default storage class. + if (DT == Dtor_Deleting) { + GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); + } else { + const NamedDecl *ND = Dtor; + CGM.setDLLImportDLLExport(GV, ND); + } +} + +llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage( + GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const { + // Internal things are always internal, regardless of attributes. After this, + // we know the thunk is externally visible. + if (Linkage == GVA_Internal) + return llvm::GlobalValue::InternalLinkage; + + switch (DT) { + case Dtor_Base: + // The base destructor most closely tracks the user-declared constructor, so + // we delegate back to the normal declarator case. + return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage, + /*isConstantVariable=*/false); + case Dtor_Complete: + // The complete destructor is like an inline function, but it may be + // imported and therefore must be exported as well. This requires changing + // the linkage if a DLL attribute is present. + if (Dtor->hasAttr<DLLExportAttr>()) + return llvm::GlobalValue::WeakODRLinkage; + if (Dtor->hasAttr<DLLImportAttr>()) + return llvm::GlobalValue::AvailableExternallyLinkage; + return llvm::GlobalValue::LinkOnceODRLinkage; + case Dtor_Deleting: + // Deleting destructors are like inline functions. They have vague linkage + // and are emitted everywhere they are used. They are internal if the class + // is internal. + return llvm::GlobalValue::LinkOnceODRLinkage; + case Dtor_Comdat: + llvm_unreachable("MS C++ ABI does not support comdat dtors"); + } + llvm_unreachable("invalid dtor type"); +} + void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { // The TU defining a dtor is only guaranteed to emit a base destructor. All // other destructor variants are delegating thunks. @@ -1303,10 +1318,8 @@ void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { CharUnits MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) { - GD = GD.getCanonicalDecl(); const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); - GlobalDecl LookupGD = GD; if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { // Complete destructors take a pointer to the complete object as a // parameter, thus don't need this adjustment. @@ -1315,11 +1328,11 @@ MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) { // There's no Dtor_Base in vftable but it shares the this adjustment with // the deleting one, so look it up instead. - LookupGD = GlobalDecl(DD, Dtor_Deleting); + GD = GlobalDecl(DD, Dtor_Deleting); } - MicrosoftVTableContext::MethodVFTableLocation ML = - CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); + MethodVFTableLocation ML = + CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD); CharUnits Adjustment = ML.VFPtrOffset; // Normal virtual instance methods need to adjust from the vfptr that first @@ -1353,7 +1366,6 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall( return CGF.Builder.CreateConstByteGEP(This, Adjustment); } - GD = GD.getCanonicalDecl(); const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); GlobalDecl LookupGD = GD; @@ -1367,7 +1379,7 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall( // with the base one, so look up the deleting one instead. LookupGD = GlobalDecl(DD, Dtor_Deleting); } - MicrosoftVTableContext::MethodVFTableLocation ML = + MethodVFTableLocation ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); CharUnits StaticOffset = ML.VFPtrOffset; @@ -1523,8 +1535,7 @@ CGCXXABI::AddedStructorArgs MicrosoftCXXABI::addImplicitConstructorArgs( } RValue RV = RValue::get(MostDerivedArg); if (FPT->isVariadic()) { - Args.insert(Args.begin() + 1, - CallArg(RV, getContext().IntTy, /*needscopy=*/false)); + Args.insert(Args.begin() + 1, CallArg(RV, getContext().IntTy)); return AddedStructorArgs::prefix(1); } Args.add(RV, getContext().IntTy); @@ -1535,6 +1546,12 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This) { + // Use the base destructor variant in place of the complete destructor variant + // if the class has no virtual bases. This effectively implements some of the + // -mconstructor-aliases optimization, but as part of the MS C++ ABI. + if (Type == Dtor_Complete && DD->getParent()->getNumVBases() == 0) + Type = Dtor_Base; + CGCallee Callee = CGCallee::forDirect( CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type)), DD); @@ -1817,7 +1834,6 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, Address This, llvm::Type *Ty, SourceLocation Loc) { - GD = GD.getCanonicalDecl(); CGBuilderTy &Builder = CGF.Builder; Ty = Ty->getPointerTo()->getPointerTo(); @@ -1828,8 +1844,7 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty, MethodDecl->getParent()); MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext(); - MicrosoftVTableContext::MethodVFTableLocation ML = - VFTContext.getMethodVFTableLocation(GD); + MethodVFTableLocation ML = VFTContext.getMethodVFTableLocation(GD); // Compute the identity of the most derived class whose virtual table is // located at the MethodVFTableLocation ML. @@ -1857,7 +1872,7 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, VFunc = Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign()); } - CGCallee Callee(MethodDecl, VFunc); + CGCallee Callee(MethodDecl->getCanonicalDecl(), VFunc); return Callee; } @@ -1872,9 +1887,8 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall( GlobalDecl GD(Dtor, Dtor_Deleting); const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration( Dtor, StructorType::Deleting); - llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); - CGCallee Callee = getVirtualFunctionPointer( - CGF, GD, This, Ty, CE ? CE->getLocStart() : SourceLocation()); + llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); + CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty); ASTContext &Context = getContext(); llvm::Value *ImplicitParam = llvm::ConstantInt::get( @@ -1915,23 +1929,24 @@ MicrosoftCXXABI::enumerateVBTables(const CXXRecordDecl *RD) { return VBGlobals; } -llvm::Function *MicrosoftCXXABI::EmitVirtualMemPtrThunk( - const CXXMethodDecl *MD, - const MicrosoftVTableContext::MethodVFTableLocation &ML) { +llvm::Function * +MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD, + const MethodVFTableLocation &ML) { assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) && "can't form pointers to ctors or virtual dtors"); // Calculate the mangled name. SmallString<256> ThunkName; llvm::raw_svector_ostream Out(ThunkName); - getMangleContext().mangleVirtualMemPtrThunk(MD, Out); + getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out); // If the thunk has been generated previously, just return it. if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName)) return cast<llvm::Function>(GV); // Create the llvm::Function. - const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSMemberPointerThunk(MD); + const CGFunctionInfo &FnInfo = + CGM.getTypes().arrangeUnprototypedMustTailThunk(MD); llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo); llvm::Function *ThunkFn = llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage, @@ -2716,9 +2731,8 @@ llvm::Constant * MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { assert(MD->isInstance() && "Member function must not be static!"); - MD = MD->getCanonicalDecl(); CharUnits NonVirtualBaseAdjustment = CharUnits::Zero(); - const CXXRecordDecl *RD = MD->getParent()->getMostRecentDecl(); + const CXXRecordDecl *RD = MD->getParent()->getMostRecentNonInjectedDecl(); CodeGenTypes &Types = CGM.getTypes(); unsigned VBTableIndex = 0; @@ -2738,8 +2752,7 @@ MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { FirstField = CGM.GetAddrOfFunction(MD, Ty); } else { auto &VTableContext = CGM.getMicrosoftVTableContext(); - MicrosoftVTableContext::MethodVFTableLocation ML = - VTableContext.getMethodVFTableLocation(MD); + MethodVFTableLocation ML = VTableContext.getMethodVFTableLocation(MD); FirstField = EmitVirtualMemPtrThunk(MD, ML); // Include the vfptr adjustment if the method is in a non-primary vftable. NonVirtualBaseAdjustment += ML.VFPtrOffset; @@ -3336,14 +3349,14 @@ CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) { // a reference to the TypeInfo for the type and a reference to the // CompleteHierarchyDescriptor for the type. // -// ClassHieararchyDescriptor: Contains information about a class hierarchy. +// ClassHierarchyDescriptor: Contains information about a class hierarchy. // Used during dynamic_cast to walk a class hierarchy. References a base // class array and the size of said array. // // BaseClassArray: Contains a list of classes in a hierarchy. BaseClassArray is // somewhat of a misnomer because the most derived class is also in the list // as well as multiple copies of virtual bases (if they occur multiple times -// in the hiearchy.) The BaseClassArray contains one BaseClassDescriptor for +// in the hierarchy.) The BaseClassArray contains one BaseClassDescriptor for // every path in the hierarchy, in pre-order depth first order. Note, we do // not declare a specific llvm type for BaseClassArray, it's merely an array // of BaseClassDescriptor pointers. @@ -3356,7 +3369,7 @@ CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) { // mangled into them so they can be aggressively deduplicated by the linker. static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) { - StringRef MangledName("\01??_7type_info@@6B@"); + StringRef MangledName("??_7type_info@@6B@"); if (auto VTable = CGM.getModule().getNamedGlobal(MangledName)) return VTable; return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy, @@ -3367,7 +3380,7 @@ static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) { namespace { -/// \brief A Helper struct that stores information about a class in a class +/// A Helper struct that stores information about a class in a class /// hierarchy. The information stored in these structs struct is used during /// the generation of ClassHierarchyDescriptors and BaseClassDescriptors. // During RTTI creation, MSRTTIClasses are stored in a contiguous array with @@ -3394,7 +3407,7 @@ struct MSRTTIClass { uint32_t Flags, NumBases, OffsetInVBase; }; -/// \brief Recursively initialize the base class array. +/// Recursively initialize the base class array. uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent, const CXXBaseSpecifier *Specifier) { Flags = HasHierarchyDescriptor; @@ -3441,7 +3454,7 @@ static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) { llvm_unreachable("Invalid linkage!"); } -/// \brief An ephemeral helper class for building MS RTTI types. It caches some +/// An ephemeral helper class for building MS RTTI types. It caches some /// calls to the module and information about the most derived class in a /// hierarchy. struct MSRTTIBuilder { @@ -3474,7 +3487,7 @@ struct MSRTTIBuilder { } // namespace -/// \brief Recursively serializes a class hierarchy in pre-order depth first +/// Recursively serializes a class hierarchy in pre-order depth first /// order. static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes, const CXXRecordDecl *RD) { @@ -3483,7 +3496,7 @@ static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes, serializeClassHierarchy(Classes, Base.getType()->getAsCXXRecordDecl()); } -/// \brief Find ambiguity among base classes. +/// Find ambiguity among base classes. static void detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) { llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases; @@ -3749,7 +3762,7 @@ MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType Type, Flags}; } -/// \brief Gets a TypeDescriptor. Returns a llvm::Constant * rather than a +/// Gets a TypeDescriptor. Returns a llvm::Constant * rather than a /// llvm::GlobalVariable * because different type descriptors have different /// types, and need to be abstracted. They are abstracting by casting the /// address to an Int8PtrTy. @@ -3791,7 +3804,7 @@ llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) { return llvm::ConstantExpr::getBitCast(Var, CGM.Int8PtrTy); } -/// \brief Gets or a creates a Microsoft CompleteObjectLocator. +/// Gets or a creates a Microsoft CompleteObjectLocator. llvm::GlobalVariable * MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD, const VPtrInfo &Info) { @@ -3808,19 +3821,12 @@ static void emitCXXConstructor(CodeGenModule &CGM, static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor, StructorType dtorType) { - // The complete destructor is equivalent to the base destructor for - // classes with no virtual bases, so try to emit it as an alias. - if (!dtor->getParent()->getNumVBases() && - (dtorType == StructorType::Complete || dtorType == StructorType::Base)) { - bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias( - GlobalDecl(dtor, Dtor_Complete), GlobalDecl(dtor, Dtor_Base)); - if (ProducedAlias) { - if (dtorType == StructorType::Complete) - return; - if (dtor->isVirtual()) - CGM.getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete)); - } - } + // Emit the base destructor if the base and complete (vbase) destructors are + // equivalent. This effectively implements -mconstructor-aliases as part of + // the ABI. + if (dtorType == StructorType::Complete && + dtor->getParent()->getNumVBases() == 0) + dtorType = StructorType::Base; // The base destructor is equivalent to the base destructor of its // base class if there is exactly one non-virtual base class with a @@ -3898,7 +3904,7 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD, SourceLocation(), &getContext().Idents.get("is_most_derived"), getContext().IntTy, ImplicitParamDecl::Other); - // Only add the parameter to the list if thie class has virtual bases. + // Only add the parameter to the list if the class has virtual bases. if (RD->getNumVBases() > 0) FunctionArgs.push_back(&IsMostDerived); |