diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 66 |
3 files changed, 52 insertions, 25 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 67849642118..3cb72bd1512 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -347,12 +347,16 @@ CodeGenTypes::arrangeMSMemberPointerThunk(const CXXMethodDecl *MD) { } const CGFunctionInfo & -CodeGenTypes::arrangeMSCopyCtorClosure(const CXXConstructorDecl *CD) { +CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD, + CXXCtorType CT) { + assert(CT == Ctor_CopyingClosure || CT == Ctor_DefaultClosure); + CanQual<FunctionProtoType> FTP = GetFormalType(CD); SmallVector<CanQualType, 2> ArgTys; const CXXRecordDecl *RD = CD->getParent(); ArgTys.push_back(GetThisType(Context, RD)); - ArgTys.push_back(*FTP->param_type_begin()); + if (CT == Ctor_CopyingClosure) + ArgTys.push_back(*FTP->param_type_begin()); if (RD->getNumVBases() > 0) ArgTys.push_back(Context.IntTy); CallingConv CC = Context.getDefaultCallingConvention( diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index f9cd3837fe9..26d37f3c240 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -264,7 +264,8 @@ public: const FunctionProtoType *type, RequiredArgs required); const CGFunctionInfo &arrangeMSMemberPointerThunk(const CXXMethodDecl *MD); - const CGFunctionInfo &arrangeMSCopyCtorClosure(const CXXConstructorDecl *CD); + const CGFunctionInfo &arrangeMSCtorClosure(const CXXConstructorDecl *CD, + CXXCtorType CT); const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionProtoType> Ty); const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionNoProtoType> Ty); diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 6b53359f28b..96fcb2f8dbe 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -635,7 +635,8 @@ public: return Fn; } - llvm::Function *getAddrOfCXXCopyCtorClosure(const CXXConstructorDecl *CD); + llvm::Function *getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD, + CXXCtorType CT); llvm::Constant *getCatchableType(QualType T, uint32_t NVOffset = 0, @@ -1060,9 +1061,29 @@ void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers( } } +static bool hasDefaultCXXMethodCC(ASTContext &Context, + const CXXMethodDecl *MD) { + CallingConv ExpectedCallingConv = Context.getDefaultCallingConvention( + /*IsVariadic=*/false, /*IsCXXMethod=*/true); + CallingConv ActualCallingConv = + MD->getType()->getAs<FunctionProtoType>()->getCallConv(); + return ExpectedCallingConv == ActualCallingConv; +} + void MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { // There's only one constructor type in this ABI. CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete)); + + // Exported default constructors either have a simple call-site where they use + // the typical calling convention and have a single 'this' pointer for an + // argument -or- they get a wrapper function which appropriately thunks to the + // real default constructor. This thunk is the default constructor closure. + if (D->hasAttr<DLLExportAttr>() && D->isDefaultConstructor()) + if (!hasDefaultCXXMethodCC(getContext(), D) || D->getNumParams() != 0) { + llvm::Function *Fn = getAddrOfCXXCtorClosure(D, Ctor_DefaultClosure); + Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage); + Fn->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + } } void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF, @@ -3223,11 +3244,14 @@ void MicrosoftCXXABI::emitCXXStructor(const CXXMethodDecl *MD, } llvm::Function * -MicrosoftCXXABI::getAddrOfCXXCopyCtorClosure(const CXXConstructorDecl *CD) { +MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD, + CXXCtorType CT) { + assert(CT == Ctor_CopyingClosure || CT == Ctor_DefaultClosure); + // Calculate the mangled name. SmallString<256> ThunkName; llvm::raw_svector_ostream Out(ThunkName); - getMangleContext().mangleCXXCtor(CD, Ctor_CopyingClosure, Out); + getMangleContext().mangleCXXCtor(CD, CT, Out); Out.flush(); // If the thunk has been generated previously, just return it. @@ -3235,12 +3259,13 @@ MicrosoftCXXABI::getAddrOfCXXCopyCtorClosure(const CXXConstructorDecl *CD) { return cast<llvm::Function>(GV); // Create the llvm::Function. - const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSCopyCtorClosure(CD); + const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSCtorClosure(CD, CT); llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo); const CXXRecordDecl *RD = CD->getParent(); QualType RecordTy = getContext().getRecordType(RD); llvm::Function *ThunkFn = llvm::Function::Create( ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.getModule()); + bool IsCopy = CT == Ctor_CopyingClosure; // Start codegen. CodeGenFunction CGF(CGM); @@ -3249,8 +3274,7 @@ MicrosoftCXXABI::getAddrOfCXXCopyCtorClosure(const CXXConstructorDecl *CD) { // Build FunctionArgs. FunctionArgList FunctionArgs; - // A copy constructor always starts with a 'this' pointer as its first - // argument. + // A constructor always starts with a 'this' pointer as its first argument. buildThisParam(CGF, FunctionArgs); // Following the 'this' pointer is a reference to the source object that we @@ -3259,11 +3283,12 @@ MicrosoftCXXABI::getAddrOfCXXCopyCtorClosure(const CXXConstructorDecl *CD) { getContext(), nullptr, SourceLocation(), &getContext().Idents.get("src"), getContext().getLValueReferenceType(RecordTy, /*SpelledAsLValue=*/true)); - FunctionArgs.push_back(&SrcParam); + if (IsCopy) + FunctionArgs.push_back(&SrcParam); - // Copy constructors for classes which utilize virtual bases have an - // additional parameter which indicates whether or not it is being delegated - // to by a more derived constructor. + // Constructors for classes which utilize virtual bases have an additional + // parameter which indicates whether or not it is being delegated to by a more + // derived constructor. ImplicitParamDecl IsMostDerived(getContext(), nullptr, SourceLocation(), &getContext().Idents.get("is_most_derived"), getContext().IntTy); @@ -3278,7 +3303,8 @@ MicrosoftCXXABI::getAddrOfCXXCopyCtorClosure(const CXXConstructorDecl *CD) { llvm::Value *This = getThisValue(CGF); llvm::Value *SrcVal = - CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&SrcParam), "src"); + IsCopy ? CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&SrcParam), "src") + : nullptr; CallArgList Args; @@ -3286,11 +3312,12 @@ MicrosoftCXXABI::getAddrOfCXXCopyCtorClosure(const CXXConstructorDecl *CD) { Args.add(RValue::get(This), CD->getThisType(getContext())); // Push the src ptr. - Args.add(RValue::get(SrcVal), SrcParam.getType()); + if (SrcVal) + Args.add(RValue::get(SrcVal), SrcParam.getType()); // Add the rest of the default arguments. std::vector<Stmt *> ArgVec; - for (unsigned I = 1, E = CD->getNumParams(); I != E; ++I) + for (unsigned I = IsCopy ? 1 : 0, E = CD->getNumParams(); I != E; ++I) ArgVec.push_back(getContext().getDefaultArgExprForConstructor(CD, I)); CodeGenFunction::RunCleanupsScope Cleanups(CGF); @@ -3298,7 +3325,7 @@ MicrosoftCXXABI::getAddrOfCXXCopyCtorClosure(const CXXConstructorDecl *CD) { const auto *FPT = CD->getType()->castAs<FunctionProtoType>(); ConstExprIterator ArgBegin(ArgVec.data()), ArgEnd(ArgVec.data() + ArgVec.size()); - CGF.EmitCallArgs(Args, FPT, ArgBegin, ArgEnd, CD, 1); + CGF.EmitCallArgs(Args, FPT, ArgBegin, ArgEnd, CD, IsCopy ? 1 : 0); // Insert any ABI-specific implicit constructor arguments. unsigned ExtraArgs = addImplicitConstructorArgs(CGF, CD, Ctor_Complete, @@ -3330,14 +3357,9 @@ llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType T, const CXXConstructorDecl *CD = RD ? CGM.getContext().getCopyConstructorForExceptionObject(RD) : nullptr; CXXCtorType CT = Ctor_Complete; - if (CD) { - CallingConv ExpectedCallingConv = getContext().getDefaultCallingConvention( - /*IsVariadic=*/false, /*IsCXXMethod=*/true); - CallingConv ActualCallingConv = - CD->getType()->getAs<FunctionProtoType>()->getCallConv(); - if (ExpectedCallingConv != ActualCallingConv || CD->getNumParams() != 1) + if (CD) + if (!hasDefaultCXXMethodCC(getContext(), CD) || CD->getNumParams() != 1) CT = Ctor_CopyingClosure; - } uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity(); SmallString<256> MangledName; @@ -3358,7 +3380,7 @@ llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType T, llvm::Constant *CopyCtor; if (CD) { if (CT == Ctor_CopyingClosure) - CopyCtor = getAddrOfCXXCopyCtorClosure(CD); + CopyCtor = getAddrOfCXXCtorClosure(CD, Ctor_CopyingClosure); else CopyCtor = CGM.getAddrOfCXXStructor(CD, StructorType::Complete); |