зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
c34fcedc5f
Коммит
f80519b919
|
@ -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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче