It looks like there are code paths that are duplicated for constructors and destructors just because we have both CXXCtorType and CXXDtorsTypes.
This patch introduces a CDtorType enum that lets us reduce the duplication a bit. Cheers, Rafael
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 545c5ef..a8ea055 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -213,7 +213,7 @@ void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor, } const CGFunctionInfo &fnInfo = - getTypes().arrangeCXXConstructorDeclaration(ctor, ctorType); + getTypes().arrangeCXXCDtorDeclaration(ctor, getFromCtorType(ctorType)); auto *fn = cast<llvm::Function>( GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo, true)); @@ -226,25 +226,39 @@ void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor, } llvm::GlobalValue * -CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor, - CXXCtorType ctorType, - const CGFunctionInfo *fnInfo, - bool DontDefer) { - GlobalDecl GD(ctor, ctorType); - - StringRef name = getMangledName(GD); - if (llvm::GlobalValue *existing = GetGlobalValue(name)) - return existing; +CodeGenModule::getAddrOfCXXCDtor(const CXXMethodDecl *MD, CDtorType Type, + const CGFunctionInfo *FnInfo, + llvm::FunctionType *FnType, bool DontDefer) { + GlobalDecl GD; + if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) { + GD = GlobalDecl(CD, toCXXCtorType(Type)); + } else { + auto *DD = dyn_cast<CXXDestructorDecl>(MD); + GD = GlobalDecl(DD, toCXXDtorType(Type)); + } - if (!fnInfo) - fnInfo = &getTypes().arrangeCXXConstructorDeclaration(ctor, ctorType); + StringRef Name = getMangledName(GD); + if (llvm::GlobalValue *Existing = GetGlobalValue(Name)) + return Existing; - llvm::FunctionType *fnType = getTypes().GetFunctionType(*fnInfo); - return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD, + if (!FnType) { + if (!FnInfo) + FnInfo = &getTypes().arrangeCXXCDtorDeclaration(MD, Type); + FnType = getTypes().GetFunctionType(*FnInfo); + } + + return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FnType, GD, /*ForVTable=*/false, DontDefer)); } +llvm::GlobalValue *CodeGenModule::GetAddrOfCXXConstructor( + const CXXConstructorDecl *ctor, CXXCtorType ctorType, + const CGFunctionInfo *fnInfo, bool DontDefer) { + return getAddrOfCXXCDtor(ctor, getFromCtorType(ctorType), fnInfo, nullptr, + DontDefer); +} + void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor, CXXDtorType dtorType) { // The complete destructor is equivalent to the base destructor for @@ -270,7 +284,7 @@ void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor, return; const CGFunctionInfo &fnInfo = - getTypes().arrangeCXXDestructor(dtor, dtorType); + getTypes().arrangeCXXCDtorDeclaration(dtor, getFromDtorType(dtorType)); auto *fn = cast<llvm::Function>( GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo, nullptr, true)); @@ -288,19 +302,8 @@ CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor, const CGFunctionInfo *fnInfo, llvm::FunctionType *fnType, bool DontDefer) { - GlobalDecl GD(dtor, dtorType); - - StringRef name = getMangledName(GD); - if (llvm::GlobalValue *existing = GetGlobalValue(name)) - return existing; - - if (!fnType) { - if (!fnInfo) fnInfo = &getTypes().arrangeCXXDestructor(dtor, dtorType); - fnType = getTypes().GetFunctionType(*fnInfo); - } - return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD, - /*ForVTable=*/false, - DontDefer)); + return getAddrOfCXXCDtor(dtor, getFromDtorType(dtorType), fnInfo, fnType, + DontDefer); } static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF, @@ -361,7 +364,7 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall( if (MD->isVirtual() && Type != Dtor_Base) { // Compute the function type we're calling. const CGFunctionInfo &FInfo = - CGM.getTypes().arrangeCXXDestructor(DD, Dtor_Complete); + CGM.getTypes().arrangeCXXCDtorDeclaration(DD, CDtorType::Complete); llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo); return ::BuildAppleKextVirtualCall(*this, GlobalDecl(DD, Type), Ty, RD); } diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h index 39813fd..3c34b4c 100644 --- a/lib/CodeGen/CGCXXABI.h +++ b/lib/CodeGen/CGCXXABI.h @@ -241,20 +241,6 @@ public: const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl) = 0; - /// Build the signature of the given constructor variant by adding - /// any required parameters. For convenience, ArgTys has been initialized - /// with the type of 'this' and ResTy has been initialized with the type of - /// 'this' if HasThisReturn(GlobalDecl(Ctor, T)) is true or 'void' otherwise - /// (although both may be changed by the ABI). - /// - /// If there are ever any ABIs where the implicit parameters are - /// intermixed with the formal parameters, we can address those - /// then. - virtual void BuildConstructorSignature(const CXXConstructorDecl *Ctor, - CXXCtorType T, - CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) = 0; - virtual llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD); @@ -267,15 +253,11 @@ public: /// Emit constructor variants required by this ABI. virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0; - /// Build the signature of the given destructor variant by adding - /// any required parameters. For convenience, ArgTys has been initialized - /// with the type of 'this' and ResTy has been initialized with the type of - /// 'this' if HasThisReturn(GlobalDecl(Dtor, T)) is true or 'void' otherwise - /// (although both may be changed by the ABI). - virtual void BuildDestructorSignature(const CXXDestructorDecl *Dtor, - CXXDtorType T, - CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) = 0; + /// Build the signature of the given constructor or destructor variant by + /// adding any required parameters. For convenience, ArgTys has been + /// initialized with the type of 'this'. + virtual void buildCDtorSignature(const CXXMethodDecl *MD, CDtorType T, + SmallVectorImpl<CanQualType> &ArgTys) = 0; /// Returns true if the given destructor type should be emitted as a linkonce /// delegating thunk, regardless of whether the dtor is defined in this TU or diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index ce16d3b..658479d 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -181,30 +181,35 @@ CodeGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *MD) { return arrangeFreeFunctionType(prototype); } -/// Arrange the argument and result information for a declaration -/// or definition to the given constructor variant. const CGFunctionInfo & -CodeGenTypes::arrangeCXXConstructorDeclaration(const CXXConstructorDecl *D, - CXXCtorType ctorKind) { +CodeGenTypes::arrangeCXXCDtorDeclaration(const CXXMethodDecl *MD, + CDtorType Type) { + SmallVector<CanQualType, 16> argTypes; - argTypes.push_back(GetThisType(Context, D->getParent())); + argTypes.push_back(GetThisType(Context, MD->getParent())); - GlobalDecl GD(D, ctorKind); - CanQualType resultType = - TheCXXABI.HasThisReturn(GD) ? argTypes.front() : Context.VoidTy; + GlobalDecl GD; + if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) { + GD = GlobalDecl(CD, toCXXCtorType(Type)); + } else { + auto *DD = dyn_cast<CXXDestructorDecl>(MD); + GD = GlobalDecl(DD, toCXXDtorType(Type)); + } - CanQual<FunctionProtoType> FTP = GetFormalType(D); + CanQual<FunctionProtoType> FTP = GetFormalType(MD); // Add the formal parameters. for (unsigned i = 0, e = FTP->getNumParams(); i != e; ++i) argTypes.push_back(FTP->getParamType(i)); - TheCXXABI.BuildConstructorSignature(D, ctorKind, resultType, argTypes); + TheCXXABI.buildCDtorSignature(MD, Type, argTypes); RequiredArgs required = - (D->isVariadic() ? RequiredArgs(argTypes.size()) : RequiredArgs::All); + (MD->isVariadic() ? RequiredArgs(argTypes.size()) : RequiredArgs::All); FunctionType::ExtInfo extInfo = FTP->getExtInfo(); + CanQualType resultType = + TheCXXABI.HasThisReturn(GD) ? argTypes.front() : Context.VoidTy; return arrangeLLVMFunctionInfo(resultType, true, argTypes, extInfo, required); } @@ -229,30 +234,6 @@ CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args, return arrangeLLVMFunctionInfo(ResultType, true, ArgTypes, Info, Required); } -/// Arrange the argument and result information for a declaration, -/// definition, or call to the given destructor variant. It so -/// happens that all three cases produce the same information. -const CGFunctionInfo & -CodeGenTypes::arrangeCXXDestructor(const CXXDestructorDecl *D, - CXXDtorType dtorKind) { - SmallVector<CanQualType, 2> argTypes; - argTypes.push_back(GetThisType(Context, D->getParent())); - - GlobalDecl GD(D, dtorKind); - CanQualType resultType = - TheCXXABI.HasThisReturn(GD) ? argTypes.front() : Context.VoidTy; - - TheCXXABI.BuildDestructorSignature(D, dtorKind, resultType, argTypes); - - CanQual<FunctionProtoType> FTP = GetFormalType(D); - assert(FTP->getNumParams() == 0 && "dtor with formal parameters"); - assert(FTP->isVariadic() == 0 && "dtor with formal parameters"); - - FunctionType::ExtInfo extInfo = FTP->getExtInfo(); - return arrangeLLVMFunctionInfo(resultType, true, argTypes, extInfo, - RequiredArgs::All); -} - /// Arrange the argument and result information for the declaration or /// definition of the given function. const CGFunctionInfo & @@ -324,10 +305,10 @@ CodeGenTypes::arrangeGlobalDeclaration(GlobalDecl GD) { const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) - return arrangeCXXConstructorDeclaration(CD, GD.getCtorType()); + return arrangeCXXCDtorDeclaration(CD, getFromCtorType(GD.getCtorType())); if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) - return arrangeCXXDestructor(DD, GD.getDtorType()); + return arrangeCXXCDtorDeclaration(DD, getFromDtorType(GD.getDtorType())); return arrangeFunctionDeclaration(FD); } @@ -1029,7 +1010,7 @@ llvm::Type *CodeGenTypes::GetFunctionTypeForVTable(GlobalDecl GD) { const CGFunctionInfo *Info; if (isa<CXXDestructorDecl>(MD)) - Info = &arrangeCXXDestructor(cast<CXXDestructorDecl>(MD), GD.getDtorType()); + Info = &arrangeCXXCDtorDeclaration(MD, getFromDtorType(GD.getDtorType())); else Info = &arrangeCXXMethodDeclaration(MD); return GetFunctionType(*Info); diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 5a033de..b3e9238 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -1758,7 +1758,8 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, } llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(Ctor, CtorType); - EmitCall(CGM.getTypes().arrangeCXXConstructorDeclaration(Ctor, CtorType), + EmitCall(CGM.getTypes() + .arrangeCXXCDtorDeclaration(Ctor, getFromCtorType(CtorType)), Callee, ReturnValueSlot(), DelegateArgs, Ctor); } diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index db876b1..d0ee858 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -170,11 +170,11 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, const CXXMethodDecl *CalleeDecl = DevirtualizedMethod ? DevirtualizedMethod : MD; const CGFunctionInfo *FInfo = nullptr; if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl)) - FInfo = &CGM.getTypes().arrangeCXXDestructor(Dtor, - Dtor_Complete); + FInfo = + &CGM.getTypes().arrangeCXXCDtorDeclaration(Dtor, CDtorType::Complete); else if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(CalleeDecl)) - FInfo = &CGM.getTypes().arrangeCXXConstructorDeclaration(Ctor, - Ctor_Complete); + FInfo = + &CGM.getTypes().arrangeCXXCDtorDeclaration(Ctor, CDtorType::Complete); else FInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 985e536..3336f7e 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -803,6 +803,12 @@ public: QualType getObjCFastEnumerationStateType(); /// Return the address of the constructor of the given type. + + llvm::GlobalValue *getAddrOfCXXCDtor(const CXXMethodDecl *MD, CDtorType Type, + const CGFunctionInfo *FnInfo = nullptr, + llvm::FunctionType *FnType = nullptr, + bool DontDefer = false); + llvm::GlobalValue * GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor, CXXCtorType ctorType, const CGFunctionInfo *fnInfo = nullptr, diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index 91727e3..23d6ec6 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -56,6 +56,57 @@ namespace CodeGen { class CodeGenModule; class RequiredArgs; + +enum class CDtorType { + Complete, // constructor or destructor + Base, // constructor or destructor + Deleting // destructor only +}; + +inline CXXCtorType toCXXCtorType(CDtorType T) { + switch (T) { + case CDtorType::Complete: + return Ctor_Complete; + case CDtorType::Base: + return Ctor_Base; + case CDtorType::Deleting: + llvm_unreachable("foo"); + } +} + +inline CDtorType getFromCtorType(CXXCtorType T) { + switch (T) { + case Ctor_Complete: + return CDtorType::Complete; + case Ctor_Base: + return CDtorType::Base; + case Ctor_CompleteAllocating: + llvm_unreachable("foo"); + } +} + +inline CXXDtorType toCXXDtorType(CDtorType T) { + switch (T) { + case CDtorType::Complete: + return Dtor_Complete; + case CDtorType::Base: + return Dtor_Base; + case CDtorType::Deleting: + return Dtor_Deleting; + } +} + +inline CDtorType getFromDtorType(CXXDtorType T) { + switch (T) { + case Dtor_Deleting: + return CDtorType::Deleting; + case Dtor_Complete: + return CDtorType::Complete; + case Dtor_Base: + return CDtorType::Base; + } +} + /// CodeGenTypes - This class organizes the cross-module state that is used /// while lowering AST types to LLVM types. class CodeGenTypes { @@ -185,16 +236,12 @@ public: QualType receiverType); const CGFunctionInfo &arrangeCXXMethodDeclaration(const CXXMethodDecl *MD); - const CGFunctionInfo &arrangeCXXConstructorDeclaration( - const CXXConstructorDecl *D, - CXXCtorType Type); + const CGFunctionInfo &arrangeCXXCDtorDeclaration(const CXXMethodDecl *MD, + CDtorType Type); const CGFunctionInfo &arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraArgs); - const CGFunctionInfo &arrangeCXXDestructor(const CXXDestructorDecl *D, - CXXDtorType Type); - const CGFunctionInfo &arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty); const CGFunctionInfo &arrangeFreeFunctionCall(QualType ResTy, diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index f861af3..34f888c 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -138,15 +138,10 @@ public: const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl) override; - void BuildConstructorSignature(const CXXConstructorDecl *Ctor, - CXXCtorType T, CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) override; - void EmitCXXConstructors(const CXXConstructorDecl *D) override; - void BuildDestructorSignature(const CXXDestructorDecl *Dtor, - CXXDtorType T, CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) override; + void buildCDtorSignature(const CXXMethodDecl *MD, CDtorType T, + SmallVectorImpl<CanQualType> &ArgTys) override; bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, CXXDtorType DT) const override { @@ -1066,23 +1061,6 @@ ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, return VBaseOffset; } -/// The generic ABI passes 'this', plus a VTT if it's initializing a -/// base subobject. -void -ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, - CXXCtorType Type, CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) { - ASTContext &Context = getContext(); - - // All parameters are already in place except VTT, which goes after 'this'. - // These are Clang types, so we don't need to worry about sret yet. - - // Check if we need to add a VTT parameter (which has type void **). - if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0) - ArgTys.insert(ArgTys.begin() + 1, - Context.getPointerType(Context.VoidPtrTy)); -} - void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { // Just make sure we're in sync with TargetCXXABI. assert(CGM.getTarget().getCXXABI().hasConstructorVariants()); @@ -1099,20 +1077,17 @@ void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { } } -/// The generic ABI passes 'this', plus a VTT if it's destroying a -/// base subobject. -void ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor, - CXXDtorType Type, - CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) { +void ItaniumCXXABI::buildCDtorSignature(const CXXMethodDecl *MD, CDtorType T, + SmallVectorImpl<CanQualType> &ArgTys) { ASTContext &Context = getContext(); - // 'this' parameter is already there, as well as 'this' return if - // HasThisReturn(GlobalDecl(Dtor, Type)) is true + // All parameters are already in place except VTT, which goes after 'this'. + // These are Clang types, so we don't need to worry about sret yet. // Check if we need to add a VTT parameter (which has type void **). - if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0) - ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy)); + if (T == CDtorType::Base && MD->getParent()->getNumVBases() != 0) + ArgTys.insert(ArgTys.begin() + 1, + Context.getPointerType(Context.VoidPtrTy)); } void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { @@ -1346,8 +1321,8 @@ void ItaniumCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, assert(CE == nullptr || CE->arg_begin() == CE->arg_end()); assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); - const CGFunctionInfo *FInfo - = &CGM.getTypes().arrangeCXXDestructor(Dtor, DtorType); + const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXCDtorDeclaration( + Dtor, getFromDtorType(DtorType)); llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); llvm::Value *Callee = getVirtualFunctionPointer(CGF, GlobalDecl(Dtor, DtorType), This, Ty); diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 134f0b7..35e41f1 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -89,10 +89,6 @@ public: const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl) override; - void BuildConstructorSignature(const CXXConstructorDecl *Ctor, - CXXCtorType Type, CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) override; - llvm::BasicBlock * EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD) override; @@ -134,10 +130,8 @@ public: // lacks a definition for the destructor, non-base destructors must always // delegate to or alias the base destructor. - void BuildDestructorSignature(const CXXDestructorDecl *Dtor, - CXXDtorType Type, - CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) override; + void buildCDtorSignature(const CXXMethodDecl *MD, CDtorType T, + SmallVectorImpl<CanQualType> &ArgTys) override; /// Non-base dtors should be emitted as delegating thunks in this ABI. bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, @@ -785,23 +779,6 @@ bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const { return false; } -void MicrosoftCXXABI::BuildConstructorSignature( - const CXXConstructorDecl *Ctor, CXXCtorType Type, CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) { - - // All parameters are already in place except is_most_derived, which goes - // after 'this' if it's variadic and last if it's not. - - const CXXRecordDecl *Class = Ctor->getParent(); - const FunctionProtoType *FPT = Ctor->getType()->castAs<FunctionProtoType>(); - if (Class->getNumVBases()) { - if (FPT->isVariadic()) - ArgTys.insert(ArgTys.begin() + 1, CGM.getContext().IntTy); - else - ArgTys.push_back(CGM.getContext().IntTy); - } -} - llvm::BasicBlock * MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD) { @@ -910,18 +887,29 @@ void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF, } } -void MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor, - CXXDtorType Type, - CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) { - // 'this' is already in place - +void +MicrosoftCXXABI::buildCDtorSignature(const CXXMethodDecl *MD, CDtorType T, + SmallVectorImpl<CanQualType> &ArgTys) { // TODO: 'for base' flag - - if (Type == Dtor_Deleting) { + if (T == CDtorType::Deleting) { // The scalar deleting destructor takes an implicit int parameter. ArgTys.push_back(CGM.getContext().IntTy); } + auto *CD = dyn_cast<CXXConstructorDecl>(MD); + if (!CD) + return; + + // All parameters are already in place except is_most_derived, which goes + // after 'this' if it's variadic and last if it's not. + + const CXXRecordDecl *Class = CD->getParent(); + const FunctionProtoType *FPT = CD->getType()->castAs<FunctionProtoType>(); + if (Class->getNumVBases()) { + if (FPT->isVariadic()) + ArgTys.insert(ArgTys.begin() + 1, CGM.getContext().IntTy); + else + ArgTys.push_back(CGM.getContext().IntTy); + } } void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { @@ -1388,7 +1376,7 @@ void MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, // by passing an implicit int parameter. GlobalDecl GD(Dtor, Dtor_Deleting); const CGFunctionInfo *FInfo = - &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting); + &CGM.getTypes().arrangeCXXCDtorDeclaration(Dtor, CDtorType::Deleting); llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); llvm::Value *Callee = getVirtualFunctionPointer(CGF, GD, This, Ty);
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits