diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index f7b8efbfe7..8660d96443 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -106,6 +106,9 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { // FIXME: This should really be merged with GenerateCode. void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD) { CurFn = CGM.getObjCRuntime().GenerateMethod(OMD); + + CGM.SetMethodAttributes(OMD, CurFn); + llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn); // Create a marker to make it easy to insert allocas into the entryblock diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 87f5c24b82..4c12011c4b 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -196,9 +196,10 @@ void CodeGenModule::SetGlobalValueAttributes(const FunctionDecl *FD, } } -void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, - llvm::Function *F, - const llvm::FunctionType *FTy) { +static void +SetFunctionAttributesFromTypes(const Decl *FD, + llvm::Function *F, + const llvm::SmallVector &ArgTypes) { unsigned FuncAttrs = 0; if (FD->getAttr()) FuncAttrs |= llvm::ParamAttr::NoUnwind; @@ -209,28 +210,26 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, if (FuncAttrs) ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs)); // Note that there is parallel code in CodeGenFunction::EmitCallExpr - bool AggregateReturn = CodeGenFunction::hasAggregateLLVMType(FD->getResultType()); + bool AggregateReturn = CodeGenFunction::hasAggregateLLVMType(ArgTypes[0]); if (AggregateReturn) ParamAttrList.push_back( llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet)); unsigned increment = AggregateReturn ? 2 : 1; - const FunctionTypeProto* FTP = dyn_cast(FD->getType()); - if (FTP) { - for (unsigned i = 0; i < FTP->getNumArgs(); i++) { - QualType ParamType = FTP->getArgType(i); - unsigned ParamAttrs = 0; - if (ParamType->isRecordType()) - ParamAttrs |= llvm::ParamAttr::ByVal; - if (ParamType->isSignedIntegerType() && - ParamType->isPromotableIntegerType()) - ParamAttrs |= llvm::ParamAttr::SExt; - if (ParamType->isUnsignedIntegerType() && - ParamType->isPromotableIntegerType()) - ParamAttrs |= llvm::ParamAttr::ZExt; - if (ParamAttrs) - ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(i + increment, - ParamAttrs)); - } + for (llvm::SmallVector::const_iterator i = ArgTypes.begin() + 1, + e = ArgTypes.end(); i != e; ++i, ++increment) { + QualType ParamType = *i; + unsigned ParamAttrs = 0; + if (ParamType->isRecordType()) + ParamAttrs |= llvm::ParamAttr::ByVal; + if (ParamType->isSignedIntegerType() && + ParamType->isPromotableIntegerType()) + ParamAttrs |= llvm::ParamAttr::SExt; + if (ParamType->isUnsignedIntegerType() && + ParamType->isPromotableIntegerType()) + ParamAttrs |= llvm::ParamAttr::ZExt; + if (ParamAttrs) + ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(increment, + ParamAttrs)); } F->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(), @@ -239,6 +238,45 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, // Set the appropriate calling convention for the Function. if (FD->getAttr()) F->setCallingConv(llvm::CallingConv::Fast); +} + +/// SetFunctionAttributesForDefinition - Set function attributes +/// specific to a function definition. +void CodeGenModule::SetFunctionAttributesForDefinition(llvm::Function *F) { + if (!Features.Exceptions) + F->addParamAttr(0, llvm::ParamAttr::NoUnwind); +} + +void CodeGenModule::SetMethodAttributes(const ObjCMethodDecl *MD, + llvm::Function *F) { + llvm::SmallVector ArgTypes; + + ArgTypes.push_back(MD->getResultType()); + ArgTypes.push_back(MD->getSelfDecl()->getType()); + ArgTypes.push_back(Context.getObjCSelType()); + for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(), + e = MD->param_end(); i != e; ++i) + ArgTypes.push_back((*i)->getType()); + + SetFunctionAttributesFromTypes(MD, F, ArgTypes); + + SetFunctionAttributesForDefinition(F); + + // FIXME: set visibility +} + +void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, + llvm::Function *F) { + llvm::SmallVector ArgTypes; + const FunctionType *FTy = FD->getType()->getAsFunctionType(); + const FunctionTypeProto *FTP = dyn_cast(FTy); + + ArgTypes.push_back(FTy->getResultType()); + if (FTP) + for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) + ArgTypes.push_back(FTP->getArgType(i)); + + SetFunctionAttributesFromTypes(FD, F, ArgTypes); SetGlobalValueAttributes(FD, F); } @@ -533,12 +571,11 @@ CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D) { return alias; } else { const llvm::Type *Ty = getTypes().ConvertType(D->getType()); - const llvm::FunctionType *FTy = cast(Ty); - llvm::Function *F = llvm::Function::Create(FTy, + llvm::Function *F = llvm::Function::Create(cast(Ty), llvm::Function::ExternalLinkage, D->getName(), &getModule()); - SetFunctionAttributes(D, F, FTy); + SetFunctionAttributes(D, F); return F; } } @@ -601,11 +638,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { llvm::Function *Fn = cast(Entry); CodeGenFunction(*this).GenerateCode(D, Fn); - // Set attributes specific to definition. - // FIXME: This needs to be cleaned up by clearly emitting the - // declaration / definition at separate times. - if (!Features.Exceptions) - Fn->addParamAttr(0, llvm::ParamAttr::NoUnwind); + SetFunctionAttributesForDefinition(Fn); if (const ConstructorAttr *CA = D->getAttr()) { AddGlobalCtor(Fn, CA->getPriority()); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 70a91b6a99..a6308736cc 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -207,10 +207,16 @@ public: void ErrorUnsupported(const Decl *D, const char *Type, bool OmitOnError=false); + void SetMethodAttributes(const ObjCMethodDecl *MD, + llvm::Function *F); + private: + /// SetFunctionAttributesForDefinition - Set function attributes + /// specific to a function definition. + void SetFunctionAttributesForDefinition(llvm::Function *F); + void SetFunctionAttributes(const FunctionDecl *FD, - llvm::Function *F, - const llvm::FunctionType *FTy); + llvm::Function *F); void SetGlobalValueAttributes(const FunctionDecl *FD, llvm::GlobalValue *GV);