mirror of
https://github.com/intel/llvm.git
synced 2026-02-04 11:38:04 +08:00
ABI handling API changes.
- Lift CGFunctionInfo creation up to callers of EmitCall. - Move isVariadic bit out of CGFunctionInfo, take as argument to GetFunctionType instead. No functionality change. llvm-svn: 63550
This commit is contained in:
@@ -31,40 +31,30 @@ using namespace CodeGen;
|
||||
|
||||
// FIXME: Use iterator and sidestep silly type array creation.
|
||||
|
||||
CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP)
|
||||
: IsVariadic(true)
|
||||
{
|
||||
CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP) {
|
||||
ArgTypes.push_back(FTNP->getResultType());
|
||||
}
|
||||
|
||||
CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP)
|
||||
: IsVariadic(FTP->isVariadic())
|
||||
{
|
||||
CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP) {
|
||||
ArgTypes.push_back(FTP->getResultType());
|
||||
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
|
||||
ArgTypes.push_back(FTP->getArgType(i));
|
||||
}
|
||||
|
||||
// FIXME: Is there really any reason to have this still?
|
||||
CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD)
|
||||
{
|
||||
CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD) {
|
||||
const FunctionType *FTy = FD->getType()->getAsFunctionType();
|
||||
const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy);
|
||||
|
||||
ArgTypes.push_back(FTy->getResultType());
|
||||
if (FTP) {
|
||||
IsVariadic = FTP->isVariadic();
|
||||
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
|
||||
ArgTypes.push_back(FTP->getArgType(i));
|
||||
} else {
|
||||
IsVariadic = true;
|
||||
}
|
||||
}
|
||||
|
||||
CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
|
||||
const ASTContext &Context)
|
||||
: IsVariadic(MD->isVariadic())
|
||||
{
|
||||
const ASTContext &Context) {
|
||||
ArgTypes.push_back(MD->getResultType());
|
||||
ArgTypes.push_back(MD->getSelfDecl()->getType());
|
||||
ArgTypes.push_back(Context.getObjCSelType());
|
||||
@@ -73,16 +63,20 @@ CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD,
|
||||
ArgTypes.push_back((*i)->getType());
|
||||
}
|
||||
|
||||
CGFunctionInfo::CGFunctionInfo(QualType ResTy, const CallArgList &Args,
|
||||
bool _IsVariadic)
|
||||
: IsVariadic(_IsVariadic)
|
||||
{
|
||||
CGFunctionInfo::CGFunctionInfo(QualType ResTy, const CallArgList &Args) {
|
||||
ArgTypes.push_back(ResTy);
|
||||
for (CallArgList::const_iterator i = Args.begin(), e = Args.end();
|
||||
i != e; ++i)
|
||||
ArgTypes.push_back(i->second);
|
||||
}
|
||||
|
||||
CGFunctionInfo::CGFunctionInfo(QualType ResTy, const FunctionArgList &Args) {
|
||||
ArgTypes.push_back(ResTy);
|
||||
for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
|
||||
i != e; ++i)
|
||||
ArgTypes.push_back(i->second);
|
||||
}
|
||||
|
||||
ArgTypeIterator CGFunctionInfo::argtypes_begin() const {
|
||||
return ArgTypes.begin();
|
||||
}
|
||||
@@ -941,8 +935,12 @@ static void CreateCoercedStore(llvm::Value *Src,
|
||||
|
||||
/***/
|
||||
|
||||
bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
|
||||
return getABIReturnInfo(RetTy, getTypes()).isStructRet();
|
||||
}
|
||||
|
||||
const llvm::FunctionType *
|
||||
CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
|
||||
CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
|
||||
std::vector<const llvm::Type*> ArgTys;
|
||||
|
||||
const llvm::Type *ResultType = 0;
|
||||
@@ -1007,11 +1005,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
|
||||
}
|
||||
}
|
||||
|
||||
return llvm::FunctionType::get(ResultType, ArgTys, FI.isVariadic());
|
||||
}
|
||||
|
||||
bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
|
||||
return getABIReturnInfo(RetTy, getTypes()).isStructRet();
|
||||
return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic);
|
||||
}
|
||||
|
||||
void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl,
|
||||
@@ -1116,6 +1110,8 @@ void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl,
|
||||
void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn,
|
||||
QualType RetTy,
|
||||
const FunctionArgList &Args) {
|
||||
CGFunctionInfo FnInfo(RetTy, Args);
|
||||
|
||||
// Emit allocs for param decls. Give the LLVM Argument nodes names.
|
||||
llvm::Function::arg_iterator AI = Fn->arg_begin();
|
||||
|
||||
@@ -1225,12 +1221,13 @@ void CodeGenFunction::EmitFunctionEpilog(QualType RetTy,
|
||||
}
|
||||
|
||||
RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
|
||||
QualType RetTy,
|
||||
const CGFunctionInfo &CallInfo,
|
||||
const CallArgList &CallArgs) {
|
||||
llvm::SmallVector<llvm::Value*, 16> Args;
|
||||
|
||||
// Handle struct-return functions by passing a pointer to the
|
||||
// location that we would like to return into.
|
||||
QualType RetTy = CallInfo.getReturnType();
|
||||
ABIArgInfo RetAI = getABIReturnInfo(RetTy, CGM.getTypes());
|
||||
switch (RetAI.getKind()) {
|
||||
case ABIArgInfo::StructRet:
|
||||
@@ -1282,10 +1279,6 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
|
||||
}
|
||||
|
||||
llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
|
||||
const llvm::Type *FnType =
|
||||
cast<llvm::PointerType>(Callee->getType())->getElementType();
|
||||
CGFunctionInfo CallInfo(RetTy, CallArgs,
|
||||
cast<llvm::FunctionType>(FnType)->isVarArg());
|
||||
|
||||
// FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set.
|
||||
CodeGen::AttributeListType AttributeList;
|
||||
|
||||
@@ -54,23 +54,20 @@ namespace CodeGen {
|
||||
/// CGFunctionInfo - Class to encapsulate the information about a
|
||||
/// function definition.
|
||||
class CGFunctionInfo {
|
||||
bool IsVariadic;
|
||||
|
||||
llvm::SmallVector<QualType, 16> ArgTypes;
|
||||
|
||||
public:
|
||||
CGFunctionInfo(const FunctionTypeNoProto *FTNP);
|
||||
CGFunctionInfo(const FunctionTypeProto *FTP);
|
||||
CGFunctionInfo(const FunctionDecl *FD);
|
||||
CGFunctionInfo(const ObjCMethodDecl *MD,
|
||||
const ASTContext &Context);
|
||||
CGFunctionInfo(QualType ResTy, const CallArgList &Args,
|
||||
bool _IsVariadic);
|
||||
|
||||
bool isVariadic() const { return IsVariadic; }
|
||||
CGFunctionInfo(const ObjCMethodDecl *MD, const ASTContext &Context);
|
||||
CGFunctionInfo(QualType ResTy, const CallArgList &Args);
|
||||
CGFunctionInfo(QualType ResTy, const FunctionArgList &Args);
|
||||
|
||||
ArgTypeIterator argtypes_begin() const;
|
||||
ArgTypeIterator argtypes_end() const;
|
||||
|
||||
QualType getReturnType() const { return ArgTypes[0]; }
|
||||
};
|
||||
} // end namespace CodeGen
|
||||
} // end namespace clang
|
||||
|
||||
@@ -1102,5 +1102,5 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType CalleeType,
|
||||
Args.push_back(std::make_pair(EmitAnyExprToTemp(*I),
|
||||
I->getType()));
|
||||
|
||||
return EmitCall(Callee, ResultType, Args);
|
||||
return EmitCall(Callee, CGFunctionInfo(ResultType, Args), Args);
|
||||
}
|
||||
|
||||
@@ -183,7 +183,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
|
||||
Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
|
||||
Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
|
||||
Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy));
|
||||
RValue RV = EmitCall(GetPropertyFn, PD->getType(), Args);
|
||||
RValue RV = EmitCall(GetPropertyFn, CGFunctionInfo(PD->getType(), Args),
|
||||
Args);
|
||||
// We need to fix the type here. Ivars with copy & retain are
|
||||
// always objects so we don't need to worry about complex or
|
||||
// aggregates.
|
||||
@@ -267,7 +268,7 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
|
||||
getContext().BoolTy));
|
||||
Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False),
|
||||
getContext().BoolTy));
|
||||
EmitCall(SetPropertyFn, PD->getType(), Args);
|
||||
EmitCall(SetPropertyFn, CGFunctionInfo(PD->getType(), Args), Args);
|
||||
} else {
|
||||
SourceLocation Loc = PD->getLocation();
|
||||
ValueDecl *Self = OMD->getSelfDecl();
|
||||
|
||||
@@ -311,7 +311,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
|
||||
ActualArgs.push_back(std::make_pair(RValue::get(cmd),
|
||||
CGF.getContext().getObjCSelType()));
|
||||
ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
|
||||
return CGF.EmitCall(imp, ResultType, ActualArgs);
|
||||
return CGF.EmitCall(imp, CGFunctionInfo(ResultType, ActualArgs), ActualArgs);
|
||||
}
|
||||
|
||||
/// Generate code for a message send expression.
|
||||
@@ -358,7 +358,7 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||
ActualArgs.push_back(std::make_pair(RValue::get(cmd),
|
||||
CGF.getContext().getObjCSelType()));
|
||||
ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
|
||||
return CGF.EmitCall(imp, ResultType, ActualArgs);
|
||||
return CGF.EmitCall(imp, CGFunctionInfo(ResultType, ActualArgs), ActualArgs);
|
||||
}
|
||||
|
||||
/// Generates a MethodList. Used in construction of a objc_class and
|
||||
@@ -970,7 +970,8 @@ llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
|
||||
bool isClassMethod = !OMD->isInstanceMethod();
|
||||
|
||||
const llvm::FunctionType *MethodTy =
|
||||
CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()));
|
||||
CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()),
|
||||
OMD->isVariadic());
|
||||
std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
|
||||
MethodName, isClassMethod);
|
||||
|
||||
|
||||
@@ -806,9 +806,8 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||
CGF.getContext().getObjCSelType()));
|
||||
ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
|
||||
|
||||
const llvm::FunctionType *FTy =
|
||||
CGM.getTypes().GetFunctionType(CGFunctionInfo(ResultType, ActualArgs,
|
||||
false));
|
||||
CGFunctionInfo FnInfo(ResultType, ActualArgs);
|
||||
const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FnInfo, false);
|
||||
|
||||
llvm::Constant *Fn;
|
||||
if (CGM.ReturnTypeUsesSret(ResultType)) {
|
||||
@@ -821,7 +820,7 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
|
||||
Fn = ObjCTypes.getSendFn(IsSuper);
|
||||
}
|
||||
Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
|
||||
return CGF.EmitCall(Fn, ResultType, ActualArgs);
|
||||
return CGF.EmitCall(Fn, FnInfo, ActualArgs);
|
||||
}
|
||||
|
||||
llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
|
||||
@@ -1665,12 +1664,13 @@ llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
|
||||
}
|
||||
|
||||
llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
|
||||
const ObjCContainerDecl *CD) {
|
||||
const ObjCContainerDecl *CD) {
|
||||
std::string Name;
|
||||
GetNameForMethod(OMD, CD, Name);
|
||||
|
||||
const llvm::FunctionType *MethodTy =
|
||||
CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()));
|
||||
CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()),
|
||||
OMD->isVariadic());
|
||||
llvm::Function *Method =
|
||||
llvm::Function::Create(MethodTy,
|
||||
llvm::GlobalValue::InternalLinkage,
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace clang {
|
||||
namespace CodeGen {
|
||||
class CodeGenModule;
|
||||
class CodeGenTypes;
|
||||
class CGFunctionInfo;
|
||||
class CGRecordLayout;
|
||||
|
||||
/// CodeGenFunction - This class organizes the per-function state that is used
|
||||
@@ -543,7 +544,7 @@ public:
|
||||
/// specifies both the LLVM arguments and the types they were
|
||||
/// derived from.
|
||||
RValue EmitCall(llvm::Value *Callee,
|
||||
QualType ResultType,
|
||||
const CGFunctionInfo &FnInfo,
|
||||
const CallArgList &Args);
|
||||
|
||||
RValue EmitCallExpr(const CallExpr *E);
|
||||
|
||||
@@ -256,9 +256,12 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
|
||||
VT.getNumElements());
|
||||
}
|
||||
case Type::FunctionNoProto:
|
||||
return GetFunctionType(CGFunctionInfo(cast<FunctionTypeNoProto>(&Ty)));
|
||||
case Type::FunctionProto:
|
||||
return GetFunctionType(CGFunctionInfo(cast<FunctionTypeProto>(&Ty)));
|
||||
return GetFunctionType(CGFunctionInfo(cast<FunctionTypeNoProto>(&Ty)),
|
||||
true);
|
||||
case Type::FunctionProto: {
|
||||
const FunctionTypeProto *FTP = cast<FunctionTypeProto>(&Ty);
|
||||
return GetFunctionType(CGFunctionInfo(FTP), FTP->isVariadic());
|
||||
}
|
||||
|
||||
case Type::ASQual:
|
||||
return
|
||||
|
||||
@@ -144,7 +144,8 @@ public:
|
||||
const llvm::Type *ConvertTypeForMem(QualType T);
|
||||
|
||||
/// GetFunctionType - Get the LLVM function type for \arg Info.
|
||||
const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info);
|
||||
const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info,
|
||||
bool IsVariadic);
|
||||
|
||||
const CGRecordLayout *getCGRecordLayout(const TagDecl*) const;
|
||||
/// Returns a StructType representing an Objective-C object
|
||||
|
||||
Reference in New Issue
Block a user