diff options
author | John McCall <rjmccall@apple.com> | 2010-02-05 21:31:56 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-02-05 21:31:56 +0000 |
commit | 04a67a6aa3dfdc92d57f7f8d93ba397348c868a4 (patch) | |
tree | 2d199d8d6541ce97e1858876523c9ca2bd5a260e /lib/CodeGen/CGCall.cpp | |
parent | e50187a987dadb6a3b6f673125617c8f42ff3560 (diff) |
Standardize the parsing of function type attributes in a way that
follows (as conservatively as possible) gcc's current behavior: attributes
written on return types that don't apply there are applied to the function
instead, etc. Only parse CC attributes as type attributes, not as decl attributes;
don't accepet noreturn as a decl attribute on ValueDecls, either (it still
needs to apply to other decls, like blocks). Consistently consume CC/noreturn
information throughout codegen; enforce this by removing their default values
in CodeGenTypes::getFunctionInfo().
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95436 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index ce361f08fe..7a47d5bcc0 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -33,12 +33,19 @@ using namespace CodeGen; // FIXME: Use iterator and sidestep silly type array creation. +static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) { + switch (CC) { + default: return llvm::CallingConv::C; + case CC_X86StdCall: return llvm::CallingConv::X86_StdCall; + case CC_X86FastCall: return llvm::CallingConv::X86_FastCall; + } +} + const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) { - // FIXME: Set calling convention correctly, it needs to be associated with the - // type somehow. return getFunctionInfo(FTNP->getResultType(), - llvm::SmallVector<QualType, 16>(), 0); + llvm::SmallVector<QualType, 16>(), + FTNP->getCallConv(), FTNP->getNoReturnAttr()); } const @@ -47,20 +54,19 @@ CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionProtoType *FTP) { // FIXME: Kill copy. for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) ArgTys.push_back(FTP->getArgType(i)); - // FIXME: Set calling convention correctly, it needs to be associated with the - // type somehow. - return getFunctionInfo(FTP->getResultType(), ArgTys, 0); + return getFunctionInfo(FTP->getResultType(), ArgTys, + FTP->getCallConv(), FTP->getNoReturnAttr()); } -static unsigned getCallingConventionForDecl(const Decl *D) { +static CallingConv getCallingConventionForDecl(const Decl *D) { // Set the appropriate calling convention for the Function. if (D->hasAttr<StdCallAttr>()) - return llvm::CallingConv::X86_StdCall; + return CC_X86StdCall; if (D->hasAttr<FastCallAttr>()) - return llvm::CallingConv::X86_FastCall; + return CC_X86FastCall; - return llvm::CallingConv::C; + return CC_C; } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD, @@ -75,7 +81,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD, // FIXME: Set calling convention correctly, it needs to be associated with the // type somehow. - return getFunctionInfo(FTP->getResultType(), ArgTys, 0); + return getFunctionInfo(FTP->getResultType(), ArgTys, + FTP->getCallConv(), FTP->getNoReturnAttr()); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) { @@ -87,8 +94,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) { const FunctionProtoType *FTP = MD->getType()->getAs<FunctionProtoType>(); for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) ArgTys.push_back(FTP->getArgType(i)); - return getFunctionInfo(FTP->getResultType(), ArgTys, - getCallingConventionForDecl(MD)); + return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(), + FTP->getNoReturnAttr()); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D, @@ -105,8 +112,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D, const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>(); for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) ArgTys.push_back(FTP->getArgType(i)); - return getFunctionInfo(FTP->getResultType(), ArgTys, - getCallingConventionForDecl(D)); + return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(), + FTP->getNoReturnAttr()); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D, @@ -123,8 +130,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D, const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>(); for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) ArgTys.push_back(FTP->getArgType(i)); - return getFunctionInfo(FTP->getResultType(), ArgTys, - getCallingConventionForDecl(D)); + return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(), + FTP->getNoReturnAttr()); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) { @@ -132,19 +139,19 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) { if (MD->isInstance()) return getFunctionInfo(MD); - unsigned CallingConvention = getCallingConventionForDecl(FD); const FunctionType *FTy = FD->getType()->getAs<FunctionType>(); if (const FunctionNoProtoType *FNTP = dyn_cast<FunctionNoProtoType>(FTy)) return getFunctionInfo(FNTP->getResultType(), llvm::SmallVector<QualType, 16>(), - CallingConvention); + FNTP->getCallConv(), FNTP->getNoReturnAttr()); const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy); llvm::SmallVector<QualType, 16> ArgTys; // FIXME: Kill copy. for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i) ArgTys.push_back(FPT->getArgType(i)); - return getFunctionInfo(FPT->getResultType(), ArgTys, CallingConvention); + return getFunctionInfo(FPT->getResultType(), ArgTys, + FPT->getCallConv(), FPT->getNoReturnAttr()); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { @@ -156,37 +163,43 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { e = MD->param_end(); i != e; ++i) ArgTys.push_back((*i)->getType()); return getFunctionInfo(MD->getResultType(), ArgTys, - getCallingConventionForDecl(MD)); + getCallingConventionForDecl(MD), + /*NoReturn*/ false); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, const CallArgList &Args, - unsigned CallingConvention){ + CallingConv CC, + bool NoReturn) { // FIXME: Kill copy. llvm::SmallVector<QualType, 16> ArgTys; for (CallArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) ArgTys.push_back(i->second); - return getFunctionInfo(ResTy, ArgTys, CallingConvention); + return getFunctionInfo(ResTy, ArgTys, CC, NoReturn); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, const FunctionArgList &Args, - unsigned CallingConvention){ + CallingConv CC, + bool NoReturn) { // FIXME: Kill copy. llvm::SmallVector<QualType, 16> ArgTys; for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) ArgTys.push_back(i->second); - return getFunctionInfo(ResTy, ArgTys, CallingConvention); + return getFunctionInfo(ResTy, ArgTys, CC, NoReturn); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, const llvm::SmallVector<QualType, 16> &ArgTys, - unsigned CallingConvention){ + CallingConv CallConv, + bool NoReturn) { + unsigned CC = ClangCallConvToLLVMCallConv(CallConv); + // Lookup or create unique function info. llvm::FoldingSetNodeID ID; - CGFunctionInfo::Profile(ID, CallingConvention, ResTy, + CGFunctionInfo::Profile(ID, CC, NoReturn, ResTy, ArgTys.begin(), ArgTys.end()); void *InsertPos = 0; @@ -195,7 +208,7 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, return *FI; // Construct the function info. - FI = new CGFunctionInfo(CallingConvention, ResTy, ArgTys); + FI = new CGFunctionInfo(CC, NoReturn, ResTy, ArgTys); FunctionInfos.InsertNode(FI, InsertPos); // Compute ABI information. @@ -205,10 +218,12 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, } CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention, + bool _NoReturn, QualType ResTy, const llvm::SmallVector<QualType, 16> &ArgTys) : CallingConvention(_CallingConvention), - EffectiveCallingConvention(_CallingConvention) + EffectiveCallingConvention(_CallingConvention), + NoReturn(_NoReturn) { NumArgs = ArgTys.size(); Args = new ArgInfo[1 + NumArgs]; @@ -490,6 +505,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, CallingConv = FI.getEffectiveCallingConvention(); + if (FI.isNoReturn()) + FuncAttrs |= llvm::Attribute::NoReturn; + // FIXME: handle sseregparm someday... if (TargetDecl) { if (TargetDecl->hasAttr<NoThrowAttr>()) |