Author: rnk Date: Tue Dec 17 13:46:40 2013 New Revision: 197518 URL: http://llvm.org/viewvc/llvm-project?rev=197518&view=rev Log: [ms-cxxabi] The 'most derived' ctor parameter usually comes last
Unlike Itanium's VTTs, the 'most derived' boolean or bitfield is the last parameter for non-variadic constructors, rather than the second. For variadic constructors, the 'most derived' parameter comes after the 'this' parameter. This affects constructor calls and constructor decls in a variety of places. Reviewers: timurrrr Differential Revision: http://llvm-reviews.chandlerc.com/D2405 Modified: cfe/trunk/lib/CodeGen/CGCXXABI.cpp cfe/trunk/lib/CodeGen/CGCXXABI.h cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/lib/CodeGen/CGClass.cpp cfe/trunk/lib/CodeGen/CGVTables.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp Modified: cfe/trunk/lib/CodeGen/CGCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.cpp?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCXXABI.cpp Tue Dec 17 13:46:40 2013 @@ -116,7 +116,7 @@ bool CGCXXABI::isZeroInitializable(const return true; } -void CGCXXABI::BuildThisParam(CodeGenFunction &CGF, FunctionArgList ¶ms) { +void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList ¶ms) { const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); // FIXME: I'm not entirely sure I like using a fake decl just for code Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCXXABI.h (original) +++ cfe/trunk/lib/CodeGen/CGCXXABI.h Tue Dec 17 13:46:40 2013 @@ -67,11 +67,8 @@ protected: return CGF.CXXStructorImplicitParamValue; } - /// Build a parameter variable suitable for 'this'. - void BuildThisParam(CodeGenFunction &CGF, FunctionArgList &Params); - /// Perform prolog initialization of the parameter variable suitable - /// for 'this' emitted by BuildThisParam. + /// for 'this' emitted by buildThisParam. void EmitThisParam(CodeGenFunction &CGF); ASTContext &getContext() const { return CGM.getContext(); } @@ -270,16 +267,18 @@ public: return This; } - /// Build the ABI-specific portion of the parameter list for a - /// function. This generally involves a 'this' parameter and - /// possibly some extra data for constructors and destructors. + /// Build a parameter variable suitable for 'this'. + void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params); + + /// Insert any ABI-specific implicit parameters into the parameter list for a + /// function. This generally involves extra data for constructors and + /// destructors. /// /// ABIs may also choose to override the return type, which has been /// initialized with the type of 'this' if HasThisReturn(CGF.CurGD) is true or /// the formal return type of the function otherwise. - virtual void BuildInstanceFunctionParams(CodeGenFunction &CGF, - QualType &ResTy, - FunctionArgList &Params) = 0; + virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, + FunctionArgList &Params) = 0; /// Perform ABI-specific "this" parameter adjustment in a virtual function /// prologue. @@ -291,14 +290,14 @@ public: /// Emit the ABI-specific prolog for the function. virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0; - /// Emit the constructor call. - virtual void EmitConstructorCall(CodeGenFunction &CGF, - const CXXConstructorDecl *D, - CXXCtorType Type, - bool ForVirtualBase, bool Delegating, - llvm::Value *This, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd) = 0; + /// Add any ABI-specific implicit arguments needed to call a constructor. + /// + /// \return The number of args added to the call, which is typically zero or + /// one. + virtual unsigned + addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, + CXXCtorType Type, bool ForVirtualBase, + bool Delegating, CallArgList &Args) = 0; /// Emit the destructor call. virtual void EmitDestructorCall(CodeGenFunction &CGF, Modified: cfe/trunk/lib/CodeGen/CGCall.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Dec 17 13:46:40 2013 @@ -202,16 +202,17 @@ CodeGenTypes::arrangeCXXConstructorDecla CanQualType resultType = TheCXXABI.HasThisReturn(GD) ? argTypes.front() : Context.VoidTy; - TheCXXABI.BuildConstructorSignature(D, ctorKind, resultType, argTypes); - CanQual<FunctionProtoType> FTP = GetFormalType(D); - RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, argTypes.size()); - // Add the formal parameters. for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) argTypes.push_back(FTP->getArgType(i)); + TheCXXABI.BuildConstructorSignature(D, ctorKind, resultType, argTypes); + + RequiredArgs required = + (D->isVariadic() ? RequiredArgs(argTypes.size()) : RequiredArgs::All); + FunctionType::ExtInfo extInfo = FTP->getExtInfo(); return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo, required); } Modified: cfe/trunk/lib/CodeGen/CGClass.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGClass.cpp (original) +++ cfe/trunk/lib/CodeGen/CGClass.cpp Tue Dec 17 13:46:40 2013 @@ -1682,9 +1682,32 @@ CodeGenFunction::EmitCXXConstructorCall( return; } - // Non-trivial constructors are handled in an ABI-specific manner. - CGM.getCXXABI().EmitConstructorCall(*this, D, Type, ForVirtualBase, - Delegating, This, ArgBeg, ArgEnd); + // C++11 [class.mfct.non-static]p2: + // If a non-static member function of a class X is called for an object that + // is not of type X, or of a type derived from X, the behavior is undefined. + // FIXME: Provide a source location here. + EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, SourceLocation(), This, + getContext().getRecordType(D->getParent())); + + CallArgList Args; + + // Push the this ptr. + Args.add(RValue::get(This), D->getThisType(getContext())); + + // Add the rest of the user-supplied arguments. + const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>(); + EmitCallArgs(Args, FPT, ArgBeg, ArgEnd); + + // Insert any ABI-specific implicit constructor arguments. + unsigned ExtraArgs = CGM.getCXXABI().addImplicitConstructorArgs( + *this, D, Type, ForVirtualBase, Delegating, Args); + + // Emit the call. + llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); + RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, 1 + ExtraArgs); + const CGFunctionInfo &Info = + CGM.getTypes().arrangeCXXMethodCall(Args, FPT, Required); + EmitCall(Info, Callee, ReturnValueSlot(), Args, D); } void Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGVTables.cpp (original) +++ cfe/trunk/lib/CodeGen/CGVTables.cpp Tue Dec 17 13:46:40 2013 @@ -253,7 +253,7 @@ void CodeGenFunction::StartThunk(llvm::F FunctionArgList FunctionArgs; // Create the implicit 'this' parameter declaration. - CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResultType, FunctionArgs); + CGM.getCXXABI().buildThisParam(*this, FunctionArgs); // Add the rest of the parameters. for (FunctionDecl::param_const_iterator I = MD->param_begin(), @@ -261,6 +261,9 @@ void CodeGenFunction::StartThunk(llvm::F I != E; ++I) FunctionArgs.push_back(*I); + if (isa<CXXDestructorDecl>(MD)) + CGM.getCXXABI().addImplicitStructorParams(*this, ResultType, FunctionArgs); + // Start defining the function. StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs, SourceLocation()); Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Dec 17 13:46:40 2013 @@ -694,16 +694,19 @@ void CodeGenFunction::GenerateCode(Globa QualType ResTy = FD->getResultType(); CurGD = GD; - const CXXMethodDecl *MD; - if ((MD = dyn_cast<CXXMethodDecl>(FD)) && MD->isInstance()) { + const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD); + if (MD && MD->isInstance()) { if (CGM.getCXXABI().HasThisReturn(GD)) ResTy = MD->getThisType(getContext()); - CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResTy, Args); + CGM.getCXXABI().buildThisParam(*this, Args); } for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) Args.push_back(FD->getParamDecl(i)); + if (MD && (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD))) + CGM.getCXXABI().addImplicitStructorParams(*this, ResTy, Args); + SourceRange BodyRange; if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange(); CurEHLocation = BodyRange.getEnd(); Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Dec 17 13:46:40 2013 @@ -2492,6 +2492,7 @@ private: std::string &ConstraintStr, SourceLocation Loc); +public: /// EmitCallArgs - Emit call arguments for a function. template <typename T> void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, @@ -2565,6 +2566,7 @@ private: CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd, bool ForceColumnInfo); +private: const TargetCodeGenInfo &getTargetHooks() const { return CGM.getTargetCodeGenInfo(); } Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Dec 17 13:46:40 2013 @@ -136,18 +136,15 @@ public: void EmitCXXDestructors(const CXXDestructorDecl *D); - void BuildInstanceFunctionParams(CodeGenFunction &CGF, - QualType &ResTy, - FunctionArgList &Params); + void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, + FunctionArgList &Params); void EmitInstanceFunctionProlog(CodeGenFunction &CGF); - void EmitConstructorCall(CodeGenFunction &CGF, - const CXXConstructorDecl *D, CXXCtorType Type, - bool ForVirtualBase, bool Delegating, - llvm::Value *This, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd); + unsigned addImplicitConstructorArgs(CodeGenFunction &CGF, + const CXXConstructorDecl *D, + CXXCtorType Type, bool ForVirtualBase, + bool Delegating, CallArgList &Args); void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, @@ -801,18 +798,19 @@ ItaniumCXXABI::GetVirtualBaseClassOffset /// 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) { +void +ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, + CXXCtorType Type, CanQualType &ResTy, + SmallVectorImpl<CanQualType> &ArgTys) { ASTContext &Context = getContext(); - // 'this' parameter is already there, as well as 'this' return if - // HasThisReturn(GlobalDecl(Ctor, 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 == Ctor_Base && Ctor->getParent()->getNumVBases() != 0) - ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy)); + ArgTys.insert(ArgTys.begin() + 1, + Context.getPointerType(Context.VoidPtrTy)); } void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { @@ -863,14 +861,11 @@ void ItaniumCXXABI::EmitCXXDestructors(c CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting)); } -void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, - QualType &ResTy, - FunctionArgList &Params) { - /// Create the 'this' variable. - BuildThisParam(CGF, Params); - +void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF, + QualType &ResTy, + FunctionArgList &Params) { const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); - assert(MD->isInstance()); + assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)); // Check if we need a VTT parameter as well. if (NeedsVTTParameter(CGF.CurGD)) { @@ -881,7 +876,7 @@ void ItaniumCXXABI::BuildInstanceFunctio ImplicitParamDecl *VTTDecl = ImplicitParamDecl::Create(Context, 0, MD->getLocation(), &Context.Idents.get("vtt"), T); - Params.push_back(VTTDecl); + Params.insert(Params.begin() + 1, VTTDecl); getStructorImplicitParamDecl(CGF) = VTTDecl; } } @@ -908,21 +903,19 @@ void ItaniumCXXABI::EmitInstanceFunction CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); } -void ItaniumCXXABI::EmitConstructorCall(CodeGenFunction &CGF, - const CXXConstructorDecl *D, - CXXCtorType Type, - bool ForVirtualBase, bool Delegating, - llvm::Value *This, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd) { - llvm::Value *VTT = CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, - Delegating); +unsigned ItaniumCXXABI::addImplicitConstructorArgs( + CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, + bool ForVirtualBase, bool Delegating, CallArgList &Args) { + if (!NeedsVTTParameter(GlobalDecl(D, Type))) + return 0; + + // Insert the implicit 'vtt' argument as the second argument. + llvm::Value *VTT = + CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, Delegating); QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy); - llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type); - - // FIXME: Provide a source location here. - CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, - VTT, VTTTy, ArgBeg, ArgEnd); + Args.insert(Args.begin() + 1, + CallArg(RValue::get(VTT), VTTTy, /*needscopy=*/false)); + return 1; // Added one arg. } void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Dec 17 13:46:40 2013 @@ -140,21 +140,18 @@ public: GlobalDecl GD, llvm::Value *This); - void BuildInstanceFunctionParams(CodeGenFunction &CGF, - QualType &ResTy, - FunctionArgList &Params); + void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, + FunctionArgList &Params); llvm::Value *adjustThisParameterInVirtualFunctionPrologue( CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This); void EmitInstanceFunctionProlog(CodeGenFunction &CGF); - void EmitConstructorCall(CodeGenFunction &CGF, - const CXXConstructorDecl *D, CXXCtorType Type, - bool ForVirtualBase, bool Delegating, - llvm::Value *This, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd); + unsigned addImplicitConstructorArgs(CodeGenFunction &CGF, + const CXXConstructorDecl *D, + CXXCtorType Type, bool ForVirtualBase, + bool Delegating, CallArgList &Args); void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, @@ -450,16 +447,20 @@ bool MicrosoftCXXABI::HasThisReturn(Glob return isa<CXXConstructorDecl>(GD.getDecl()); } -void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, - CXXCtorType Type, - CanQualType &ResTy, - SmallVectorImpl<CanQualType> &ArgTys) { - // 'this' parameter and 'this' return are already in place +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()) { - // Constructors of classes with virtual bases take an implicit parameter. - ArgTys.push_back(CGM.getContext().IntTy); + if (FPT->isVariadic()) + ArgTys.insert(ArgTys.begin() + 1, CGM.getContext().IntTy); + else + ArgTys.push_back(CGM.getContext().IntTy); } } @@ -682,20 +683,25 @@ static bool IsDeletingDtor(GlobalDecl GD return false; } -void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, - QualType &ResTy, - FunctionArgList &Params) { - BuildThisParam(CGF, Params); - +void MicrosoftCXXABI::addImplicitStructorParams(CodeGenFunction &CGF, + QualType &ResTy, + FunctionArgList &Params) { ASTContext &Context = getContext(); const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); + assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)); if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { ImplicitParamDecl *IsMostDerived = ImplicitParamDecl::Create(Context, 0, CGF.CurGD.getDecl()->getLocation(), &Context.Idents.get("is_most_derived"), Context.IntTy); - Params.push_back(IsMostDerived); + // The 'most_derived' parameter goes second if the ctor is variadic and last + // if it's not. Dtors can't be variadic. + const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); + if (FPT->isVariadic()) + Params.insert(Params.begin() + 1, IsMostDerived); + else + Params.push_back(IsMostDerived); getStructorImplicitParamDecl(CGF) = IsMostDerived; } else if (IsDeletingDtor(CGF.CurGD)) { ImplicitParamDecl *ShouldDelete @@ -788,27 +794,29 @@ void MicrosoftCXXABI::EmitInstanceFuncti } } -void MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF, - const CXXConstructorDecl *D, - CXXCtorType Type, - bool ForVirtualBase, - bool Delegating, - llvm::Value *This, - CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd) { +unsigned MicrosoftCXXABI::addImplicitConstructorArgs( + CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, + bool ForVirtualBase, bool Delegating, CallArgList &Args) { assert(Type == Ctor_Complete || Type == Ctor_Base); - llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete); - llvm::Value *ImplicitParam = 0; - QualType ImplicitParamTy; - if (D->getParent()->getNumVBases()) { - ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete); - ImplicitParamTy = getContext().IntTy; + // Check if we need a 'most_derived' parameter. + if (!D->getParent()->getNumVBases()) + return 0; + + // Add the 'most_derived' argument second if we are variadic or last if not. + const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>(); + llvm::Value *MostDerivedArg = + llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete); + RValue RV = RValue::get(MostDerivedArg); + if (MostDerivedArg) { + if (FPT->isVariadic()) + Args.insert(Args.begin() + 1, + CallArg(RV, getContext().IntTy, /*needscopy=*/false)); + else + Args.add(RV, getContext().IntTy); } - // FIXME: Provide a source location here. - CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, - ImplicitParam, ImplicitParamTy, ArgBeg, ArgEnd); + return 1; // Added one arg. } void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp?rev=197518&r1=197517&r2=197518&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp (original) +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp Tue Dec 17 13:46:40 2013 @@ -300,6 +300,37 @@ void call_nv_deleting_dtor(D *d) { } +namespace test1 { +struct A { }; +struct B : virtual A { + B(int *a); + B(const char *a, ...); + __cdecl B(short *a); +}; +B::B(int *a) {} +B::B(const char *a, ...) {} +B::B(short *a) {} +// CHECK: define x86_thiscallcc %"struct.test1::B"* @"\01??0B@test1@@QAE@PAH@Z" +// CHECK: (%"struct.test1::B"* returned %this, i32* %a, i32 %is_most_derived) +// CHECK: define %"struct.test1::B"* @"\01??0B@test1@@QAA@PBDZZ" +// CHECK: (%"struct.test1::B"* returned %this, i32 %is_most_derived, i8* %a, ...) + +// FIXME: This should be x86_thiscallcc. MSVC ignores explicit CCs on structors. +// CHECK: define %"struct.test1::B"* @"\01??0B@test1@@QAA@PAF@Z" +// CHECK: (%"struct.test1::B"* returned %this, i16* %a, i32 %is_most_derived) + +void construct_b() { + int a; + B b1(&a); + B b2("%d %d", 1, 2); +} +// CHECK-LABEL: define void @"\01?construct_b@test1@@YAXXZ"() +// CHECK: call x86_thiscallcc %"struct.test1::B"* @"\01??0B@test1@@QAE@PAH@Z" +// CHECK: (%"struct.test1::B"* {{.*}}, i32* {{.*}}, i32 1) +// CHECK: call %"struct.test1::B"* (%"struct.test1::B"*, i32, i8*, ...)* @"\01??0B@test1@@QAA@PBDZZ" +// CHECK: (%"struct.test1::B"* {{.*}}, i32 1, i8* {{.*}}, i32 1, i32 2) +} + // Dtor thunks for classes in anonymous namespaces should be internal, not // linkonce_odr. namespace { _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
