Set function attributes (sext, zext, etc.) on Objective-C methods.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55812 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2008-09-04 23:41:35 +00:00
Родитель c34fcedc5f
Коммит f80519b919
3 изменённых файлов: 73 добавлений и 31 удалений

Просмотреть файл

@ -106,6 +106,9 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
// FIXME: This should really be merged with GenerateCode. // FIXME: This should really be merged with GenerateCode.
void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD) { void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD) {
CurFn = CGM.getObjCRuntime().GenerateMethod(OMD); CurFn = CGM.getObjCRuntime().GenerateMethod(OMD);
CGM.SetMethodAttributes(OMD, CurFn);
llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn); llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
// Create a marker to make it easy to insert allocas into the entryblock // Create a marker to make it easy to insert allocas into the entryblock

Просмотреть файл

@ -196,9 +196,10 @@ void CodeGenModule::SetGlobalValueAttributes(const FunctionDecl *FD,
} }
} }
void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, static void
SetFunctionAttributesFromTypes(const Decl *FD,
llvm::Function *F, llvm::Function *F,
const llvm::FunctionType *FTy) { const llvm::SmallVector<QualType, 16> &ArgTypes) {
unsigned FuncAttrs = 0; unsigned FuncAttrs = 0;
if (FD->getAttr<NoThrowAttr>()) if (FD->getAttr<NoThrowAttr>())
FuncAttrs |= llvm::ParamAttr::NoUnwind; FuncAttrs |= llvm::ParamAttr::NoUnwind;
@ -209,15 +210,14 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
if (FuncAttrs) if (FuncAttrs)
ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs)); ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs));
// Note that there is parallel code in CodeGenFunction::EmitCallExpr // Note that there is parallel code in CodeGenFunction::EmitCallExpr
bool AggregateReturn = CodeGenFunction::hasAggregateLLVMType(FD->getResultType()); bool AggregateReturn = CodeGenFunction::hasAggregateLLVMType(ArgTypes[0]);
if (AggregateReturn) if (AggregateReturn)
ParamAttrList.push_back( ParamAttrList.push_back(
llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet)); llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet));
unsigned increment = AggregateReturn ? 2 : 1; unsigned increment = AggregateReturn ? 2 : 1;
const FunctionTypeProto* FTP = dyn_cast<FunctionTypeProto>(FD->getType()); for (llvm::SmallVector<QualType, 8>::const_iterator i = ArgTypes.begin() + 1,
if (FTP) { e = ArgTypes.end(); i != e; ++i, ++increment) {
for (unsigned i = 0; i < FTP->getNumArgs(); i++) { QualType ParamType = *i;
QualType ParamType = FTP->getArgType(i);
unsigned ParamAttrs = 0; unsigned ParamAttrs = 0;
if (ParamType->isRecordType()) if (ParamType->isRecordType())
ParamAttrs |= llvm::ParamAttr::ByVal; ParamAttrs |= llvm::ParamAttr::ByVal;
@ -228,10 +228,9 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
ParamType->isPromotableIntegerType()) ParamType->isPromotableIntegerType())
ParamAttrs |= llvm::ParamAttr::ZExt; ParamAttrs |= llvm::ParamAttr::ZExt;
if (ParamAttrs) if (ParamAttrs)
ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(i + increment, ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(increment,
ParamAttrs)); ParamAttrs));
} }
}
F->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(), F->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
ParamAttrList.size())); ParamAttrList.size()));
@ -239,6 +238,45 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
// Set the appropriate calling convention for the Function. // Set the appropriate calling convention for the Function.
if (FD->getAttr<FastCallAttr>()) if (FD->getAttr<FastCallAttr>())
F->setCallingConv(llvm::CallingConv::Fast); 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<QualType, 16> 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<QualType, 16> ArgTypes;
const FunctionType *FTy = FD->getType()->getAsFunctionType();
const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(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); SetGlobalValueAttributes(FD, F);
} }
@ -533,12 +571,11 @@ CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D) {
return alias; return alias;
} else { } else {
const llvm::Type *Ty = getTypes().ConvertType(D->getType()); const llvm::Type *Ty = getTypes().ConvertType(D->getType());
const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
llvm::Function *F = llvm::Function::Create(FTy,
llvm::Function::ExternalLinkage, llvm::Function::ExternalLinkage,
D->getName(), &getModule()); D->getName(), &getModule());
SetFunctionAttributes(D, F, FTy); SetFunctionAttributes(D, F);
return F; return F;
} }
} }
@ -601,11 +638,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
llvm::Function *Fn = cast<llvm::Function>(Entry); llvm::Function *Fn = cast<llvm::Function>(Entry);
CodeGenFunction(*this).GenerateCode(D, Fn); CodeGenFunction(*this).GenerateCode(D, Fn);
// Set attributes specific to definition. SetFunctionAttributesForDefinition(Fn);
// 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);
if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>()) { if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>()) {
AddGlobalCtor(Fn, CA->getPriority()); AddGlobalCtor(Fn, CA->getPriority());

Просмотреть файл

@ -207,10 +207,16 @@ public:
void ErrorUnsupported(const Decl *D, const char *Type, void ErrorUnsupported(const Decl *D, const char *Type,
bool OmitOnError=false); bool OmitOnError=false);
void SetMethodAttributes(const ObjCMethodDecl *MD,
llvm::Function *F);
private: private:
/// SetFunctionAttributesForDefinition - Set function attributes
/// specific to a function definition.
void SetFunctionAttributesForDefinition(llvm::Function *F);
void SetFunctionAttributes(const FunctionDecl *FD, void SetFunctionAttributes(const FunctionDecl *FD,
llvm::Function *F, llvm::Function *F);
const llvm::FunctionType *FTy);
void SetGlobalValueAttributes(const FunctionDecl *FD, void SetGlobalValueAttributes(const FunctionDecl *FD,
llvm::GlobalValue *GV); llvm::GlobalValue *GV);