CGCall.cpp revision 46f45b9bec4a265ad8400a538e5ec3a5683617f1
1//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// These classes wrap the information about a call or function 11// definition used to handle ABI compliancy. 12// 13//===----------------------------------------------------------------------===// 14 15#include "CGCall.h" 16#include "CodeGenFunction.h" 17#include "clang/AST/ASTContext.h" 18#include "clang/AST/Decl.h" 19#include "clang/AST/DeclObjC.h" 20#include "llvm/ParameterAttributes.h" 21using namespace clang; 22using namespace CodeGen; 23 24/***/ 25 26static void 27constructParamAttrListInternal(const Decl *TargetDecl, 28 const llvm::SmallVector<QualType, 16> &ArgTypes, 29 ParamAttrListType &PAL) { 30 unsigned FuncAttrs = 0; 31 32 if (TargetDecl) { 33 if (TargetDecl->getAttr<NoThrowAttr>()) 34 FuncAttrs |= llvm::ParamAttr::NoUnwind; 35 if (TargetDecl->getAttr<NoReturnAttr>()) 36 FuncAttrs |= llvm::ParamAttr::NoReturn; 37 } 38 39 unsigned Index = 1; 40 if (CodeGenFunction::hasAggregateLLVMType(ArgTypes[0])) { 41 PAL.push_back(llvm::ParamAttrsWithIndex::get(Index, 42 llvm::ParamAttr::StructRet)); 43 ++Index; 44 } else if (ArgTypes[0]->isPromotableIntegerType()) { 45 if (ArgTypes[0]->isSignedIntegerType()) { 46 FuncAttrs |= llvm::ParamAttr::SExt; 47 } else if (ArgTypes[0]->isUnsignedIntegerType()) { 48 FuncAttrs |= llvm::ParamAttr::ZExt; 49 } 50 } 51 if (FuncAttrs) 52 PAL.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs)); 53 for (llvm::SmallVector<QualType, 8>::const_iterator i = ArgTypes.begin() + 1, 54 e = ArgTypes.end(); i != e; ++i, ++Index) { 55 QualType ParamType = *i; 56 unsigned ParamAttrs = 0; 57 if (ParamType->isRecordType()) 58 ParamAttrs |= llvm::ParamAttr::ByVal; 59 if (ParamType->isPromotableIntegerType()) { 60 if (ParamType->isSignedIntegerType()) { 61 ParamAttrs |= llvm::ParamAttr::SExt; 62 } else if (ParamType->isUnsignedIntegerType()) { 63 ParamAttrs |= llvm::ParamAttr::ZExt; 64 } 65 } 66 if (ParamAttrs) 67 PAL.push_back(llvm::ParamAttrsWithIndex::get(Index, ParamAttrs)); 68 } 69} 70 71/***/ 72 73// FIXME: Use iterator and sidestep silly type array creation. 74 75CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD) 76 : TheDecl(FD) 77{ 78 const FunctionType *FTy = FD->getType()->getAsFunctionType(); 79 const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy); 80 81 ArgTypes.push_back(FTy->getResultType()); 82 if (FTP) 83 for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) 84 ArgTypes.push_back(FTP->getArgType(i)); 85} 86 87CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD, 88 const ASTContext &Context) 89 : TheDecl(MD) 90{ 91 ArgTypes.push_back(MD->getResultType()); 92 ArgTypes.push_back(MD->getSelfDecl()->getType()); 93 ArgTypes.push_back(Context.getObjCSelType()); 94 for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(), 95 e = MD->param_end(); i != e; ++i) 96 ArgTypes.push_back((*i)->getType()); 97} 98 99void CGFunctionInfo::constructParamAttrList(ParamAttrListType &PAL) const { 100 constructParamAttrListInternal(TheDecl, ArgTypes, PAL); 101} 102 103/***/ 104 105CGCallInfo::CGCallInfo(QualType _ResultType, const CallArgList &_Args) 106 : ResultType(_ResultType), 107 Args(_Args) { 108 ArgTypes.push_back(ResultType); 109 for (CallArgList::const_iterator i = Args.begin(), e = Args.end(); i!=e; ++i) 110 ArgTypes.push_back(i->second); 111} 112 113void CGCallInfo::constructParamAttrList(ParamAttrListType &PAL) const { 114 // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set. 115 constructParamAttrListInternal(0, ArgTypes, PAL); 116} 117