diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 65 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.h | 11 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.h | 23 |
3 files changed, 74 insertions, 25 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 2da16a15ac1..399624d2cfb 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -35,8 +35,10 @@ using namespace CodeGen; 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>()); + llvm::SmallVector<QualType, 16>(), 0); } const @@ -45,7 +47,20 @@ 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)); - return getFunctionInfo(FTP->getResultType(), ArgTys); + // FIXME: Set calling convention correctly, it needs to be associated with the + // type somehow. + return getFunctionInfo(FTP->getResultType(), ArgTys, 0); +} + +static unsigned getCallingConventionForDecl(const Decl *D) { + // Set the appropriate calling convention for the Function. + if (D->hasAttr<StdCallAttr>()) + return llvm::CallingConv::X86_StdCall; + + if (D->hasAttr<FastCallAttr>()) + return llvm::CallingConv::X86_FastCall; + + return llvm::CallingConv::C; } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) { @@ -57,7 +72,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) { const FunctionProtoType *FTP = MD->getType()->getAsFunctionProtoType(); for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) ArgTys.push_back(FTP->getArgType(i)); - return getFunctionInfo(FTP->getResultType(), ArgTys); + return getFunctionInfo(FTP->getResultType(), ArgTys, + getCallingConventionForDecl(MD)); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) { @@ -65,10 +81,19 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) { if (MD->isInstance()) return getFunctionInfo(MD); + unsigned CallingConvention = getCallingConventionForDecl(FD); const FunctionType *FTy = FD->getType()->getAsFunctionType(); - if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FTy)) - return getFunctionInfo(FTP); - return getFunctionInfo(cast<FunctionNoProtoType>(FTy)); + if (const FunctionNoProtoType *FNTP = dyn_cast<FunctionNoProtoType>(FTy)) + return getFunctionInfo(FNTP->getResultType(), + llvm::SmallVector<QualType, 16>(), + CallingConvention); + + 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); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { @@ -79,34 +104,39 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { for (ObjCMethodDecl::param_iterator i = MD->param_begin(), e = MD->param_end(); i != e; ++i) ArgTys.push_back((*i)->getType()); - return getFunctionInfo(MD->getResultType(), ArgTys); + return getFunctionInfo(MD->getResultType(), ArgTys, + getCallingConventionForDecl(MD)); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, - const CallArgList &Args) { + const CallArgList &Args, + unsigned CallingConvention){ // 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); + return getFunctionInfo(ResTy, ArgTys, CallingConvention); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, - const FunctionArgList &Args) { + const FunctionArgList &Args, + unsigned CallingConvention){ // 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); + return getFunctionInfo(ResTy, ArgTys, CallingConvention); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, - const llvm::SmallVector<QualType, 16> &ArgTys) { + const llvm::SmallVector<QualType, 16> &ArgTys, + unsigned CallingConvention){ // Lookup or create unique function info. llvm::FoldingSetNodeID ID; - CGFunctionInfo::Profile(ID, ResTy, ArgTys.begin(), ArgTys.end()); + CGFunctionInfo::Profile(ID, CallingConvention, ResTy, + ArgTys.begin(), ArgTys.end()); void *InsertPos = 0; CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, InsertPos); @@ -114,7 +144,7 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, return *FI; // Construct the function info. - FI = new CGFunctionInfo(ResTy, ArgTys); + FI = new CGFunctionInfo(CallingConvention, ResTy, ArgTys); FunctionInfos.InsertNode(FI, InsertPos); // Compute ABI information. @@ -123,8 +153,11 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, return *FI; } -CGFunctionInfo::CGFunctionInfo(QualType ResTy, - const llvm::SmallVector<QualType, 16> &ArgTys) { +CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention, + QualType ResTy, + const llvm::SmallVector<QualType, 16> &ArgTys) + : CallingConvention(_CallingConvention) +{ NumArgs = ArgTys.size(); Args = new ArgInfo[1 + NumArgs]; Args[0].type = ResTy; diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index 2c1048d935e..53432a2a9ef 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -60,6 +60,9 @@ namespace CodeGen { ABIArgInfo info; }; + /// The LLVM::CallingConv to use for this function. + unsigned CallingConvention; + unsigned NumArgs; ArgInfo *Args; @@ -67,7 +70,8 @@ namespace CodeGen { typedef const ArgInfo *const_arg_iterator; typedef ArgInfo *arg_iterator; - CGFunctionInfo(QualType ResTy, + CGFunctionInfo(unsigned CallingConvention, + QualType ResTy, const llvm::SmallVector<QualType, 16> &ArgTys); ~CGFunctionInfo() { delete[] Args; } @@ -78,21 +82,26 @@ namespace CodeGen { unsigned arg_size() const { return NumArgs; } + unsigned getCallingConvention() const { return CallingConvention; } + QualType getReturnType() const { return Args[0].type; } ABIArgInfo &getReturnInfo() { return Args[0].info; } const ABIArgInfo &getReturnInfo() const { return Args[0].info; } void Profile(llvm::FoldingSetNodeID &ID) { + ID.AddInteger(getCallingConvention()); getReturnType().Profile(ID); for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it) it->type.Profile(ID); } template<class Iterator> static void Profile(llvm::FoldingSetNodeID &ID, + unsigned CallingConvention, QualType ResTy, Iterator begin, Iterator end) { + ID.AddInteger(CallingConvention); ResTy.Profile(ID); for (; begin != end; ++begin) begin->Profile(ID); diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 0e73d481cd8..53df1068209 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -172,21 +172,28 @@ public: /// replace the 'opaque' type we previously made for it if applicable. void UpdateCompletedType(const TagDecl *TD); - /// getFunctionInfo - Get the CGFunctionInfo for this function signature. - const CGFunctionInfo &getFunctionInfo(QualType RetTy, - const llvm::SmallVector<QualType,16> - &ArgTys); - +private: const CGFunctionInfo &getFunctionInfo(const FunctionNoProtoType *FTNP); const CGFunctionInfo &getFunctionInfo(const FunctionProtoType *FTP); + +public: + /// getFunctionInfo - Get the function info for the specified function decl. const CGFunctionInfo &getFunctionInfo(const FunctionDecl *FD); const CGFunctionInfo &getFunctionInfo(const CXXMethodDecl *MD); const CGFunctionInfo &getFunctionInfo(const ObjCMethodDecl *MD); + + /// getFunctionInfo - Get the function info for a function described by a + /// return type and argument types. If the calling convention is not + /// specified, the "C" calling convention will be used. const CGFunctionInfo &getFunctionInfo(QualType ResTy, - const CallArgList &Args); -public: + const CallArgList &Args, + unsigned CallingConvention = 0); const CGFunctionInfo &getFunctionInfo(QualType ResTy, - const FunctionArgList &Args); + const FunctionArgList &Args, + unsigned CallingConvention = 0); + const CGFunctionInfo &getFunctionInfo(QualType RetTy, + const llvm::SmallVector<QualType, 16> &ArgTys, + unsigned CallingConvention = 0); public: // These are internal details of CGT that shouldn't be used externally. /// addFieldInfo - Assign field number to field FD. |