diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 16 |
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"); |