summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
commit9092c3e0fa01f3139b016d05d267a89e3b07747a (patch)
tree137ebebcae16fb0ce7ab4af456992bbd8d22fced /lib/CodeGen/CGCall.cpp
parent4981926bf654fe5a2c3893f24ca44106b217e71e (diff)
downloadFreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.zip
FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.tar.gz
Update clang to r84119.
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r--lib/CodeGen/CGCall.cpp268
1 files changed, 168 insertions, 100 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 97391bc..bad166f 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -33,19 +33,49 @@ using namespace CodeGen;
// FIXME: Use iterator and sidestep silly type array creation.
-const
+const
CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) {
- return getFunctionInfo(FTNP->getResultType(),
- llvm::SmallVector<QualType, 16>());
+ // FIXME: Set calling convention correctly, it needs to be associated with the
+ // type somehow.
+ return getFunctionInfo(FTNP->getResultType(),
+ llvm::SmallVector<QualType, 16>(), 0);
}
-const
+const
CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionProtoType *FTP) {
llvm::SmallVector<QualType, 16> ArgTys;
// FIXME: Kill copy.
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
ArgTys.push_back(FTP->getArgType(i));
- return getFunctionInfo(FTP->getResultType(), ArgTys);
+ // FIXME: Set calling convention correctly, it needs to be associated with the
+ // type somehow.
+ return getFunctionInfo(FTP->getResultType(), ArgTys, 0);
+}
+
+static unsigned getCallingConventionForDecl(const Decl *D) {
+ // Set the appropriate calling convention for the Function.
+ if (D->hasAttr<StdCallAttr>())
+ return llvm::CallingConv::X86_StdCall;
+
+ if (D->hasAttr<FastCallAttr>())
+ return llvm::CallingConv::X86_FastCall;
+
+ return llvm::CallingConv::C;
+}
+
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD,
+ const FunctionProtoType *FTP) {
+ llvm::SmallVector<QualType, 16> ArgTys;
+
+ // Add the 'this' pointer.
+ ArgTys.push_back(Context.getPointerType(Context.getTagDeclType(RD)));
+
+ for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
+ ArgTys.push_back(FTP->getArgType(i));
+
+ // FIXME: Set calling convention correctly, it needs to be associated with the
+ // type somehow.
+ return getFunctionInfo(FTP->getResultType(), ArgTys, 0);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) {
@@ -53,22 +83,32 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) {
// Add the 'this' pointer unless this is a static method.
if (MD->isInstance())
ArgTys.push_back(MD->getThisType(Context));
-
- const FunctionProtoType *FTP = MD->getType()->getAsFunctionProtoType();
+
+ const FunctionProtoType *FTP = MD->getType()->getAs<FunctionProtoType>();
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
ArgTys.push_back(FTP->getArgType(i));
- return getFunctionInfo(FTP->getResultType(), ArgTys);
+ return getFunctionInfo(FTP->getResultType(), ArgTys,
+ getCallingConventionForDecl(MD));
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
if (MD->isInstance())
return getFunctionInfo(MD);
+
+ unsigned CallingConvention = getCallingConventionForDecl(FD);
+ const FunctionType *FTy = FD->getType()->getAs<FunctionType>();
+ if (const FunctionNoProtoType *FNTP = dyn_cast<FunctionNoProtoType>(FTy))
+ return getFunctionInfo(FNTP->getResultType(),
+ llvm::SmallVector<QualType, 16>(),
+ CallingConvention);
- const FunctionType *FTy = FD->getType()->getAsFunctionType();
- if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FTy))
- return getFunctionInfo(FTP);
- return getFunctionInfo(cast<FunctionNoProtoType>(FTy));
+ const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy);
+ llvm::SmallVector<QualType, 16> ArgTys;
+ // FIXME: Kill copy.
+ for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
+ ArgTys.push_back(FPT->getArgType(i));
+ return getFunctionInfo(FPT->getResultType(), ArgTys, CallingConvention);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
@@ -79,34 +119,39 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
for (ObjCMethodDecl::param_iterator i = MD->param_begin(),
e = MD->param_end(); i != e; ++i)
ArgTys.push_back((*i)->getType());
- return getFunctionInfo(MD->getResultType(), ArgTys);
+ return getFunctionInfo(MD->getResultType(), ArgTys,
+ getCallingConventionForDecl(MD));
}
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
- const CallArgList &Args) {
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
+ const CallArgList &Args,
+ unsigned CallingConvention){
// FIXME: Kill copy.
llvm::SmallVector<QualType, 16> ArgTys;
- for (CallArgList::const_iterator i = Args.begin(), e = Args.end();
+ for (CallArgList::const_iterator i = Args.begin(), e = Args.end();
i != e; ++i)
ArgTys.push_back(i->second);
- return getFunctionInfo(ResTy, ArgTys);
+ return getFunctionInfo(ResTy, ArgTys, CallingConvention);
}
-const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
- const FunctionArgList &Args) {
+const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
+ const FunctionArgList &Args,
+ unsigned CallingConvention){
// FIXME: Kill copy.
llvm::SmallVector<QualType, 16> ArgTys;
- for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
+ for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
i != e; ++i)
ArgTys.push_back(i->second);
- return getFunctionInfo(ResTy, ArgTys);
+ return getFunctionInfo(ResTy, ArgTys, CallingConvention);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
- const llvm::SmallVector<QualType, 16> &ArgTys) {
+ const llvm::SmallVector<QualType, 16> &ArgTys,
+ unsigned CallingConvention){
// Lookup or create unique function info.
llvm::FoldingSetNodeID ID;
- CGFunctionInfo::Profile(ID, ResTy, ArgTys.begin(), ArgTys.end());
+ CGFunctionInfo::Profile(ID, CallingConvention, ResTy,
+ ArgTys.begin(), ArgTys.end());
void *InsertPos = 0;
CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, InsertPos);
@@ -114,17 +159,21 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
return *FI;
// Construct the function info.
- FI = new CGFunctionInfo(ResTy, ArgTys);
+ FI = new CGFunctionInfo(CallingConvention, ResTy, ArgTys);
FunctionInfos.InsertNode(FI, InsertPos);
// Compute ABI information.
- getABIInfo().computeInfo(*FI, getContext());
+ getABIInfo().computeInfo(*FI, getContext(), TheModule.getContext());
return *FI;
}
-CGFunctionInfo::CGFunctionInfo(QualType ResTy,
- const llvm::SmallVector<QualType, 16> &ArgTys) {
+CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention,
+ QualType ResTy,
+ const llvm::SmallVector<QualType, 16> &ArgTys)
+ : CallingConvention(_CallingConvention),
+ EffectiveCallingConvention(_CallingConvention)
+{
NumArgs = ArgTys.size();
Args = new ArgInfo[1 + NumArgs];
Args[0].type = ResTy;
@@ -134,20 +183,20 @@ CGFunctionInfo::CGFunctionInfo(QualType ResTy,
/***/
-void CodeGenTypes::GetExpandedTypes(QualType Ty,
+void CodeGenTypes::GetExpandedTypes(QualType Ty,
std::vector<const llvm::Type*> &ArgTys) {
const RecordType *RT = Ty->getAsStructureType();
assert(RT && "Can only expand structure types.");
const RecordDecl *RD = RT->getDecl();
- assert(!RD->hasFlexibleArrayMember() &&
+ assert(!RD->hasFlexibleArrayMember() &&
"Cannot expand structure with flexible array.");
-
+
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
const FieldDecl *FD = *i;
- assert(!FD->isBitField() &&
+ assert(!FD->isBitField() &&
"Cannot expand structure with bit-field members.");
-
+
QualType FT = FD->getType();
if (CodeGenFunction::hasAggregateLLVMType(FT)) {
GetExpandedTypes(FT, ArgTys);
@@ -157,19 +206,19 @@ void CodeGenTypes::GetExpandedTypes(QualType Ty,
}
}
-llvm::Function::arg_iterator
+llvm::Function::arg_iterator
CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
llvm::Function::arg_iterator AI) {
const RecordType *RT = Ty->getAsStructureType();
assert(RT && "Can only expand structure types.");
RecordDecl *RD = RT->getDecl();
- assert(LV.isSimple() &&
- "Unexpected non-simple lvalue during struct expansion.");
+ assert(LV.isSimple() &&
+ "Unexpected non-simple lvalue during struct expansion.");
llvm::Value *Addr = LV.getAddress();
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
- FieldDecl *FD = *i;
+ FieldDecl *FD = *i;
QualType FT = FD->getType();
// FIXME: What are the right qualifiers here?
@@ -185,8 +234,8 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
return AI;
}
-void
-CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
+void
+CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
llvm::SmallVector<llvm::Value*, 16> &Args) {
const RecordType *RT = Ty->getAsStructureType();
assert(RT && "Can only expand structure types.");
@@ -196,16 +245,16 @@ CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
llvm::Value *Addr = RV.getAggregateAddr();
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i) {
- FieldDecl *FD = *i;
+ FieldDecl *FD = *i;
QualType FT = FD->getType();
-
+
// FIXME: What are the right qualifiers here?
LValue LV = EmitLValueForField(Addr, FD, false, 0);
if (CodeGenFunction::hasAggregateLLVMType(FT)) {
ExpandTypeToArgs(FT, RValue::getAggregate(LV.getAddress()), Args);
} else {
RValue RV = EmitLoadOfLValue(LV, FT);
- assert(RV.isScalar() &&
+ assert(RV.isScalar() &&
"Unexpected non-scalar rvalue during struct expansion.");
Args.push_back(RV.getScalarVal());
}
@@ -221,7 +270,7 @@ CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
const llvm::Type *Ty,
CodeGenFunction &CGF) {
- const llvm::Type *SrcTy =
+ const llvm::Type *SrcTy =
cast<llvm::PointerType>(SrcPtr->getType())->getElementType();
uint64_t SrcSize = CGF.CGM.getTargetData().getTypeAllocSize(SrcTy);
uint64_t DstSize = CGF.CGM.getTargetData().getTypeAllocSize(Ty);
@@ -244,9 +293,9 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
// Otherwise do coercion through memory. This is stupid, but
// simple.
llvm::Value *Tmp = CGF.CreateTempAlloca(Ty);
- llvm::Value *Casted =
+ llvm::Value *Casted =
CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(SrcTy));
- llvm::StoreInst *Store =
+ llvm::StoreInst *Store =
CGF.Builder.CreateStore(CGF.Builder.CreateLoad(SrcPtr), Casted);
// FIXME: Use better alignment / avoid requiring aligned store.
Store->setAlignment(1);
@@ -263,7 +312,7 @@ static void CreateCoercedStore(llvm::Value *Src,
llvm::Value *DstPtr,
CodeGenFunction &CGF) {
const llvm::Type *SrcTy = Src->getType();
- const llvm::Type *DstTy =
+ const llvm::Type *DstTy =
cast<llvm::PointerType>(DstPtr->getType())->getElementType();
uint64_t SrcSize = CGF.CGM.getTargetData().getTypeAllocSize(SrcTy);
@@ -287,7 +336,7 @@ static void CreateCoercedStore(llvm::Value *Src,
// to that information.
llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy);
CGF.Builder.CreateStore(Src, Tmp);
- llvm::Value *Casted =
+ llvm::Value *Casted =
CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(DstTy));
llvm::LoadInst *Load = CGF.Builder.CreateLoad(Casted);
// FIXME: Use better alignment / avoid requiring aligned load.
@@ -321,25 +370,25 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
case ABIArgInfo::Indirect: {
assert(!RetAI.getIndirectAlign() && "Align unused on indirect return.");
- ResultType = llvm::Type::VoidTy;
+ ResultType = llvm::Type::getVoidTy(getLLVMContext());
const llvm::Type *STy = ConvertType(RetTy);
ArgTys.push_back(llvm::PointerType::get(STy, RetTy.getAddressSpace()));
break;
}
case ABIArgInfo::Ignore:
- ResultType = llvm::Type::VoidTy;
+ ResultType = llvm::Type::getVoidTy(getLLVMContext());
break;
case ABIArgInfo::Coerce:
ResultType = RetAI.getCoerceToType();
break;
}
-
- for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
+
+ for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
ie = FI.arg_end(); it != ie; ++it) {
const ABIArgInfo &AI = it->info;
-
+
switch (AI.getKind()) {
case ABIArgInfo::Ignore:
break;
@@ -359,7 +408,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
case ABIArgInfo::Direct:
ArgTys.push_back(ConvertType(it->type));
break;
-
+
case ABIArgInfo::Expand:
GetExpandedTypes(it->type, ArgTys);
break;
@@ -371,10 +420,13 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
const Decl *TargetDecl,
- AttributeListType &PAL) {
+ AttributeListType &PAL,
+ unsigned &CallingConv) {
unsigned FuncAttrs = 0;
unsigned RetAttrs = 0;
+ CallingConv = FI.getEffectiveCallingConvention();
+
// FIXME: handle sseregparm someday...
if (TargetDecl) {
if (TargetDecl->hasAttr<NoThrowAttr>())
@@ -385,6 +437,8 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
FuncAttrs |= llvm::Attribute::ReadNone;
else if (TargetDecl->hasAttr<PureAttr>())
FuncAttrs |= llvm::Attribute::ReadOnly;
+ if (TargetDecl->hasAttr<MallocAttr>())
+ RetAttrs |= llvm::Attribute::NoAlias;
}
if (CompileOpts.DisableRedZone)
@@ -412,7 +466,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
break;
case ABIArgInfo::Indirect:
- PAL.push_back(llvm::AttributeWithIndex::get(Index,
+ PAL.push_back(llvm::AttributeWithIndex::get(Index,
llvm::Attribute::StructRet |
llvm::Attribute::NoAlias));
++Index;
@@ -426,7 +480,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
break;
case ABIArgInfo::Expand:
- assert(0 && "Invalid ABI kind for return argument");
+ assert(0 && "Invalid ABI kind for return argument");
}
if (RetAttrs)
@@ -437,12 +491,12 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
// register variable.
signed RegParm = 0;
if (TargetDecl)
- if (const RegparmAttr *RegParmAttr
+ if (const RegparmAttr *RegParmAttr
= TargetDecl->getAttr<RegparmAttr>())
RegParm = RegParmAttr->getNumParams();
unsigned PointerWidth = getContext().Target.getPointerWidth(0);
- for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
+ for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
ie = FI.arg_end(); it != ie; ++it) {
QualType ParamType = it->type;
const ABIArgInfo &AI = it->info;
@@ -453,7 +507,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
break;
case ABIArgInfo::Indirect:
- Attributes |= llvm::Attribute::ByVal;
+ if (AI.getIndirectByVal())
+ Attributes |= llvm::Attribute::ByVal;
+
Attributes |=
llvm::Attribute::constructAlignmentFromInt(AI.getIndirectAlign());
// byval disables readnone and readonly.
@@ -481,10 +537,10 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
case ABIArgInfo::Ignore:
// Skip increment, no matching LLVM parameter.
- continue;
+ continue;
case ABIArgInfo::Expand: {
- std::vector<const llvm::Type*> Tys;
+ std::vector<const llvm::Type*> Tys;
// FIXME: This is rather inefficient. Do we ever actually need to do
// anything here? The result should be just reconstructed on the other
// side, so extension should be a non-issue.
@@ -493,7 +549,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
continue;
}
}
-
+
if (Attributes)
PAL.push_back(llvm::AttributeWithIndex::get(Index, Attributes));
++Index;
@@ -505,18 +561,31 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
llvm::Function *Fn,
const FunctionArgList &Args) {
+ // If this is an implicit-return-zero function, go ahead and
+ // initialize the return value. TODO: it might be nice to have
+ // a more general mechanism for this that didn't require synthesized
+ // return statements.
+ if (const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
+ if (FD->hasImplicitReturnZero()) {
+ QualType RetTy = FD->getResultType().getUnqualifiedType();
+ const llvm::Type* LLVMTy = CGM.getTypes().ConvertType(RetTy);
+ llvm::Constant* Zero = llvm::Constant::getNullValue(LLVMTy);
+ Builder.CreateStore(Zero, ReturnValue);
+ }
+ }
+
// FIXME: We no longer need the types from FunctionArgList; lift up and
// simplify.
// Emit allocs for param decls. Give the LLVM Argument nodes names.
llvm::Function::arg_iterator AI = Fn->arg_begin();
-
+
// Name the struct return argument.
if (CGM.ReturnTypeUsesSret(FI)) {
AI->setName("agg.result");
++AI;
}
-
+
assert(FI.arg_size() == Args.size() &&
"Mismatch between function signature & arguments.");
CGFunctionInfo::const_arg_iterator info_it = FI.arg_begin();
@@ -541,7 +610,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
V = EmitScalarConversion(V, Ty, Arg->getType());
}
}
- EmitParmDecl(*Arg, V);
+ EmitParmDecl(*Arg, V);
break;
}
@@ -565,36 +634,36 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
EmitParmDecl(*Arg, V);
break;
}
-
+
case ABIArgInfo::Expand: {
// If this structure was expanded into multiple arguments then
// we need to create a temporary and reconstruct it from the
// arguments.
std::string Name = Arg->getNameAsString();
- llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(Ty),
+ llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(Ty),
(Name + ".addr").c_str());
// FIXME: What are the right qualifiers here?
- llvm::Function::arg_iterator End =
- ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp,0), AI);
+ llvm::Function::arg_iterator End =
+ ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp, Qualifiers()), AI);
EmitParmDecl(*Arg, Temp);
// Name the arguments used in expansion and increment AI.
unsigned Index = 0;
for (; AI != End; ++AI, ++Index)
- AI->setName(Name + "." + llvm::utostr(Index));
+ AI->setName(Name + "." + llvm::Twine(Index));
continue;
}
case ABIArgInfo::Ignore:
// Initialize the local variable appropriately.
- if (hasAggregateLLVMType(Ty)) {
+ if (hasAggregateLLVMType(Ty)) {
EmitParmDecl(*Arg, CreateTempAlloca(ConvertTypeForMem(Ty)));
} else {
EmitParmDecl(*Arg, llvm::UndefValue::get(ConvertType(Arg->getType())));
}
-
+
// Skip increment, no matching LLVM parameter.
- continue;
+ continue;
case ABIArgInfo::Coerce: {
assert(AI != Fn->arg_end() && "Argument mismatch!");
@@ -653,16 +722,16 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
case ABIArgInfo::Ignore:
break;
-
+
case ABIArgInfo::Coerce:
RV = CreateCoercedLoad(ReturnValue, RetAI.getCoerceToType(), *this);
break;
case ABIArgInfo::Expand:
- assert(0 && "Invalid ABI kind for return argument");
+ assert(0 && "Invalid ABI kind for return argument");
}
}
-
+
if (RV) {
Builder.CreateRet(RV);
} else {
@@ -673,12 +742,12 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) {
if (ArgType->isReferenceType())
return EmitReferenceBindingToExpr(E, ArgType);
-
+
return EmitAnyExprToTemp(E);
}
RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
- llvm::Value *Callee,
+ llvm::Value *Callee,
const CallArgList &CallArgs,
const Decl *TargetDecl) {
// FIXME: We no longer need the types from CallArgs; lift up and simplify.
@@ -688,17 +757,17 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// location that we would like to return into.
QualType RetTy = CallInfo.getReturnType();
const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
-
-
+
+
// If the call returns a temporary with struct return, create a temporary
// alloca to hold the result.
if (CGM.ReturnTypeUsesSret(CallInfo))
Args.push_back(CreateTempAlloca(ConvertTypeForMem(RetTy)));
-
+
assert(CallInfo.arg_size() == CallArgs.size() &&
"Mismatch between function signature & arguments.");
CGFunctionInfo::const_arg_iterator info_it = CallInfo.arg_begin();
- for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
+ for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
I != E; ++I, ++info_it) {
const ABIArgInfo &ArgInfo = info_it->info;
RValue RV = I->first;
@@ -711,7 +780,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (RV.isScalar())
EmitStoreOfScalar(RV.getScalarVal(), Args.back(), false, I->second);
else
- StoreComplexToAddr(RV.getComplexVal(), Args.back(), false);
+ StoreComplexToAddr(RV.getComplexVal(), Args.back(), false);
} else {
Args.push_back(RV.getAggregateAddr());
}
@@ -730,7 +799,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
Args.push_back(Builder.CreateLoad(RV.getAggregateAddr()));
}
break;
-
+
case ABIArgInfo::Ignore:
break;
@@ -743,9 +812,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
} else if (RV.isComplex()) {
SrcPtr = CreateTempAlloca(ConvertTypeForMem(I->second), "coerce");
StoreComplexToAddr(RV.getComplexVal(), SrcPtr, false);
- } else
+ } else
SrcPtr = RV.getAggregateAddr();
- Args.push_back(CreateCoercedLoad(SrcPtr, ArgInfo.getCoerceToType(),
+ Args.push_back(CreateCoercedLoad(SrcPtr, ArgInfo.getCoerceToType(),
*this));
break;
}
@@ -755,7 +824,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
break;
}
}
-
+
// If the callee is a bitcast of a function to a varargs pointer to function
// type, check to see if we can remove the bitcast. This handles some cases
// with unprototyped functions.
@@ -765,7 +834,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
const llvm::FunctionType *CurFT =
cast<llvm::FunctionType>(CurPT->getElementType());
const llvm::FunctionType *ActualFT = CalleeF->getFunctionType();
-
+
if (CE->getOpcode() == llvm::Instruction::BitCast &&
ActualFT->getReturnType() == CurFT->getReturnType() &&
ActualFT->getNumParams() == CurFT->getNumParams() &&
@@ -776,7 +845,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
ArgsMatch = false;
break;
}
-
+
// Strip the cast if we can get away with it. This is a nice cleanup,
// but also allows us to inline the function at -O0 if it is marked
// always_inline.
@@ -784,28 +853,27 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
Callee = CalleeF;
}
}
-
+
llvm::BasicBlock *InvokeDest = getInvokeDest();
+ unsigned CallingConv;
CodeGen::AttributeListType AttributeList;
- CGM.ConstructAttributeList(CallInfo, TargetDecl, AttributeList);
+ CGM.ConstructAttributeList(CallInfo, TargetDecl, AttributeList, CallingConv);
llvm::AttrListPtr Attrs = llvm::AttrListPtr::get(AttributeList.begin(),
AttributeList.end());
-
+
llvm::CallSite CS;
if (!InvokeDest || (Attrs.getFnAttributes() & llvm::Attribute::NoUnwind)) {
CS = Builder.CreateCall(Callee, Args.data(), Args.data()+Args.size());
} else {
llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
- CS = Builder.CreateInvoke(Callee, Cont, InvokeDest,
+ CS = Builder.CreateInvoke(Callee, Cont, InvokeDest,
Args.data(), Args.data()+Args.size());
EmitBlock(Cont);
}
CS.setAttributes(Attrs);
- if (const llvm::Function *F =
- dyn_cast<llvm::Function>(Callee->stripPointerCasts()))
- CS.setCallingConv(F->getCallingConv());
+ CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
// If the call doesn't return, finish the basic block and clear the
// insertion point; this allows the rest of IRgen to discard
@@ -813,18 +881,18 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (CS.doesNotReturn()) {
Builder.CreateUnreachable();
Builder.ClearInsertionPoint();
-
+
// FIXME: For now, emit a dummy basic block because expr emitters in
// generally are not ready to handle emitting expressions at unreachable
// points.
EnsureInsertPoint();
-
+
// Return a reasonable RValue.
return GetUndefRValue(RetTy);
- }
+ }
llvm::Instruction *CI = CS.getInstruction();
- if (Builder.isNamePreserving() && CI->getType() != llvm::Type::VoidTy)
+ if (Builder.isNamePreserving() && !CI->getType()->isVoidTy())
CI->setName("call");
switch (RetAI.getKind()) {
@@ -866,7 +934,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
}
case ABIArgInfo::Expand:
- assert(0 && "Invalid ABI kind for return argument");
+ assert(0 && "Invalid ABI kind for return argument");
}
assert(0 && "Unhandled ABIArgInfo::Kind");
OpenPOWER on IntegriCloud