diff options
author | John McCall <rjmccall@apple.com> | 2012-07-07 06:41:13 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2012-07-07 06:41:13 +0000 |
commit | 0f3d0970dcdf6cf17550b86838dff12813968dbc (patch) | |
tree | 911b6054fa35afefb9c3db10172fca6e87d6a475 /lib/CodeGen/CGCall.cpp | |
parent | a437b84765d6b98d57f2789435ad641f1dd61474 (diff) |
Distinguish more carefully between free functions and C++ instance methods
in the ABI arrangement, and leave a hook behind so that we can easily
tweak CCs on platforms that use different CCs by default for C++
instance methods.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159894 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 146 |
1 files changed, 96 insertions, 50 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index cb4ccb22eb..0ecd97693f 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -67,39 +67,64 @@ static CanQualType GetReturnType(QualType RetTy) { return RetTy->getCanonicalTypeUnqualified().getUnqualifiedType(); } -/// Arrange the argument and result information for a value of the -/// given unprototyped function type. +/// Arrange the argument and result information for a value of the given +/// unprototyped freestanding function type. const CGFunctionInfo & -CodeGenTypes::arrangeFunctionType(CanQual<FunctionNoProtoType> FTNP) { +CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) { // When translating an unprototyped function type, always use a // variadic type. - return arrangeFunctionType(FTNP->getResultType().getUnqualifiedType(), - ArrayRef<CanQualType>(), - FTNP->getExtInfo(), - RequiredArgs(0)); + return arrangeLLVMFunctionInfo(FTNP->getResultType().getUnqualifiedType(), + ArrayRef<CanQualType>(), + FTNP->getExtInfo(), + RequiredArgs(0)); } -/// Arrange the argument and result information for a value of the -/// given function type, on top of any implicit parameters already -/// stored. -static const CGFunctionInfo &arrangeFunctionType(CodeGenTypes &CGT, - SmallVectorImpl<CanQualType> &argTypes, - CanQual<FunctionProtoType> FTP) { - RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, argTypes.size()); +/// Arrange the LLVM function layout for a value of the given function +/// type, on top of any implicit parameters already stored. Use the +/// given ExtInfo instead of the ExtInfo from the function type. +static const CGFunctionInfo &arrangeLLVMFunctionInfo(CodeGenTypes &CGT, + SmallVectorImpl<CanQualType> &prefix, + CanQual<FunctionProtoType> FTP, + FunctionType::ExtInfo extInfo) { + RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, prefix.size()); // FIXME: Kill copy. for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) - argTypes.push_back(FTP->getArgType(i)); + prefix.push_back(FTP->getArgType(i)); CanQualType resultType = FTP->getResultType().getUnqualifiedType(); - return CGT.arrangeFunctionType(resultType, argTypes, - FTP->getExtInfo(), required); + return CGT.arrangeLLVMFunctionInfo(resultType, prefix, extInfo, required); +} + +/// Arrange the argument and result information for a free function (i.e. +/// not a C++ or ObjC instance method) of the given type. +static const CGFunctionInfo &arrangeFreeFunctionType(CodeGenTypes &CGT, + SmallVectorImpl<CanQualType> &prefix, + CanQual<FunctionProtoType> FTP) { + return arrangeLLVMFunctionInfo(CGT, prefix, FTP, FTP->getExtInfo()); +} + +/// Given the formal ext-info of a C++ instance method, adjust it +/// according to the C++ ABI in effect. +static void adjustCXXMethodInfo(CodeGenTypes &CGT, + FunctionType::ExtInfo &extInfo) { + // FIXME: thiscall on Microsoft +} + +/// Arrange the argument and result information for a free function (i.e. +/// not a C++ or ObjC instance method) of the given type. +static const CGFunctionInfo &arrangeCXXMethodType(CodeGenTypes &CGT, + SmallVectorImpl<CanQualType> &prefix, + CanQual<FunctionProtoType> FTP) { + FunctionType::ExtInfo extInfo = FTP->getExtInfo(); + adjustCXXMethodInfo(CGT, extInfo); + return arrangeLLVMFunctionInfo(CGT, prefix, FTP, extInfo); } /// Arrange the argument and result information for a value of the -/// given function type. +/// given freestanding function type. const CGFunctionInfo & -CodeGenTypes::arrangeFunctionType(CanQual<FunctionProtoType> FTP) { +CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP) { SmallVector<CanQualType, 16> argTypes; - return ::arrangeFunctionType(*this, argTypes, FTP); + return ::arrangeFreeFunctionType(*this, argTypes, FTP); } static CallingConv getCallingConventionForDecl(const Decl *D) { @@ -134,7 +159,7 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD, // Add the 'this' pointer. argTypes.push_back(GetThisType(Context, RD)); - return ::arrangeFunctionType(*this, argTypes, + return ::arrangeCXXMethodType(*this, argTypes, FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>()); } @@ -154,7 +179,7 @@ CodeGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *MD) { return arrangeCXXMethodType(MD->getParent(), prototype.getTypePtr()); } - return arrangeFunctionType(prototype); + return arrangeFreeFunctionType(prototype); } /// Arrange the argument and result information for a declaration @@ -176,7 +201,9 @@ CodeGenTypes::arrangeCXXConstructorDeclaration(const CXXConstructorDecl *D, for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) argTypes.push_back(FTP->getArgType(i)); - return arrangeFunctionType(resultType, argTypes, FTP->getExtInfo(), required); + FunctionType::ExtInfo extInfo = FTP->getExtInfo(); + adjustCXXMethodInfo(*this, extInfo); + return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo, required); } /// Arrange the argument and result information for a declaration, @@ -194,8 +221,10 @@ CodeGenTypes::arrangeCXXDestructor(const CXXDestructorDecl *D, CanQual<FunctionProtoType> FTP = GetFormalType(D); assert(FTP->getNumArgs() == 0 && "dtor with formal parameters"); - return arrangeFunctionType(resultType, argTypes, FTP->getExtInfo(), - RequiredArgs::All); + FunctionType::ExtInfo extInfo = FTP->getExtInfo(); + adjustCXXMethodInfo(*this, extInfo); + return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo, + RequiredArgs::All); } /// Arrange the argument and result information for the declaration or @@ -214,14 +243,14 @@ CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) { // non-variadic type. if (isa<FunctionNoProtoType>(FTy)) { CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>(); - return arrangeFunctionType(noProto->getResultType(), - ArrayRef<CanQualType>(), - noProto->getExtInfo(), - RequiredArgs::All); + return arrangeLLVMFunctionInfo(noProto->getResultType(), + ArrayRef<CanQualType>(), + noProto->getExtInfo(), + RequiredArgs::All); } assert(isa<FunctionProtoType>(FTy)); - return arrangeFunctionType(FTy.getAs<FunctionProtoType>()); + return arrangeFreeFunctionType(FTy.getAs<FunctionProtoType>()); } /// Arrange the argument and result information for the declaration or @@ -261,8 +290,8 @@ CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, RequiredArgs required = (MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All); - return arrangeFunctionType(GetReturnType(MD->getResultType()), argTys, - einfo, required); + return arrangeLLVMFunctionInfo(GetReturnType(MD->getResultType()), argTys, + einfo, required); } const CGFunctionInfo & @@ -284,8 +313,8 @@ CodeGenTypes::arrangeGlobalDeclaration(GlobalDecl GD) { /// because the function might be unprototyped, in which case it's /// target-dependent in crazy ways. const CGFunctionInfo & -CodeGenTypes::arrangeFunctionCall(const CallArgList &args, - const FunctionType *fnType) { +CodeGenTypes::arrangeFreeFunctionCall(const CallArgList &args, + const FunctionType *fnType) { RequiredArgs required = RequiredArgs::All; if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) { if (proto->isVariadic()) @@ -295,22 +324,39 @@ CodeGenTypes::arrangeFunctionCall(const CallArgList &args, required = RequiredArgs(0); } - return arrangeFunctionCall(fnType->getResultType(), args, - fnType->getExtInfo(), required); + return arrangeFreeFunctionCall(fnType->getResultType(), args, + fnType->getExtInfo(), required); } const CGFunctionInfo & -CodeGenTypes::arrangeFunctionCall(QualType resultType, - const CallArgList &args, - const FunctionType::ExtInfo &info, - RequiredArgs required) { +CodeGenTypes::arrangeFreeFunctionCall(QualType resultType, + const CallArgList &args, + FunctionType::ExtInfo info, + RequiredArgs required) { // FIXME: Kill copy. SmallVector<CanQualType, 16> argTypes; for (CallArgList::const_iterator i = args.begin(), e = args.end(); i != e; ++i) argTypes.push_back(Context.getCanonicalParamType(i->Ty)); - return arrangeFunctionType(GetReturnType(resultType), argTypes, info, - required); + return arrangeLLVMFunctionInfo(GetReturnType(resultType), argTypes, info, + required); +} + +/// Arrange a call to a C++ method, passing the given arguments. +const CGFunctionInfo & +CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args, + const FunctionProtoType *FPT, + RequiredArgs required) { + // FIXME: Kill copy. + SmallVector<CanQualType, 16> argTypes; + for (CallArgList::const_iterator i = args.begin(), e = args.end(); + i != e; ++i) + argTypes.push_back(Context.getCanonicalParamType(i->Ty)); + + FunctionType::ExtInfo info = FPT->getExtInfo(); + adjustCXXMethodInfo(*this, info); + return arrangeLLVMFunctionInfo(GetReturnType(FPT->getResultType()), + argTypes, info, required); } const CGFunctionInfo & @@ -326,23 +372,23 @@ CodeGenTypes::arrangeFunctionDeclaration(QualType resultType, RequiredArgs required = (isVariadic ? RequiredArgs(args.size()) : RequiredArgs::All); - return arrangeFunctionType(GetReturnType(resultType), argTypes, info, - required); + return arrangeLLVMFunctionInfo(GetReturnType(resultType), argTypes, info, + required); } const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() { - return arrangeFunctionType(getContext().VoidTy, ArrayRef<CanQualType>(), - FunctionType::ExtInfo(), RequiredArgs::All); + return arrangeLLVMFunctionInfo(getContext().VoidTy, ArrayRef<CanQualType>(), + FunctionType::ExtInfo(), RequiredArgs::All); } /// Arrange the argument and result information for an abstract value /// of a given function type. This is the method which all of the /// above functions ultimately defer to. const CGFunctionInfo & -CodeGenTypes::arrangeFunctionType(CanQualType resultType, - ArrayRef<CanQualType> argTypes, - const FunctionType::ExtInfo &info, - RequiredArgs required) { +CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType, + ArrayRef<CanQualType> argTypes, + FunctionType::ExtInfo info, + RequiredArgs required) { #ifndef NDEBUG for (ArrayRef<CanQualType>::const_iterator I = argTypes.begin(), E = argTypes.end(); I != E; ++I) |