summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 9348b174620..782273f8cac 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3049,7 +3049,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
const Decl *TargetDecl = E->getCalleeDecl();
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
if (unsigned builtinID = FD->getBuiltinID())
- return EmitBuiltinExpr(FD, builtinID, E);
+ return EmitBuiltinExpr(FD, builtinID, E, ReturnValue);
}
if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(E))
@@ -3286,7 +3286,7 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {
RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
const CallExpr *E, ReturnValueSlot ReturnValue,
- const Decl *TargetDecl) {
+ const Decl *TargetDecl, llvm::Value *Chain) {
// Get the actual function type. The callee type will always be a pointer to
// function type or a block pointer type.
assert(CalleeType->isFunctionPointerType() &&
@@ -3351,12 +3351,15 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
}
CallArgList Args;
+ if (Chain)
+ Args.add(RValue::get(Builder.CreateBitCast(Chain, CGM.VoidPtrTy)),
+ CGM.getContext().VoidPtrTy);
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), E->arg_begin(),
E->arg_end(), E->getDirectCallee(), /*ParamsToSkip*/ 0,
ForceColumnInfo);
- const CGFunctionInfo &FnInfo =
- CGM.getTypes().arrangeFreeFunctionCall(Args, FnType);
+ const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionCall(
+ Args, FnType, /*isChainCall=*/Chain);
// C99 6.5.2.2p6:
// If the expression that denotes the called function has a type
@@ -3375,7 +3378,10 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
// through an unprototyped function type works like a *non-variadic*
// call. The way we make this work is to cast to the exact type
// of the promoted arguments.
- if (isa<FunctionNoProtoType>(FnType)) {
+ //
+ // Chain calls use this same code path to add the invisible chain parameter
+ // to the function type.
+ if (isa<FunctionNoProtoType>(FnType) || Chain) {
llvm::Type *CalleeTy = getTypes().GetFunctionType(FnInfo);
CalleeTy = CalleeTy->getPointerTo();
Callee = Builder.CreateBitCast(Callee, CalleeTy, "callee.knr.cast");
OpenPOWER on IntegriCloud