summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp56
1 files changed, 33 insertions, 23 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 5ff523e9f7a..25ca4df3a15 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -24,21 +24,21 @@
using namespace clang;
using namespace CodeGen;
-RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
- SourceLocation CallLoc,
- llvm::Value *Callee,
- ReturnValueSlot ReturnValue,
- llvm::Value *This,
- llvm::Value *ImplicitParam,
- QualType ImplicitParamTy,
- CallExpr::const_arg_iterator ArgBeg,
- CallExpr::const_arg_iterator ArgEnd) {
+RValue CodeGenFunction::EmitCXXMemberOrOperatorCall(
+ const CXXMethodDecl *MD, llvm::Value *Callee, ReturnValueSlot ReturnValue,
+ llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy,
+ const CallExpr *CE) {
+ assert(CE == nullptr || isa<CXXMemberCallExpr>(CE) ||
+ isa<CXXOperatorCallExpr>(CE));
assert(MD->isInstance() &&
- "Trying to emit a member call expr on a static method!");
+ "Trying to emit a member or operator call expr on a static method!");
// C++11 [class.mfct.non-static]p2:
// If a non-static member function of a class X is called for an object that
// is not of type X, or of a type derived from X, the behavior is undefined.
+ SourceLocation CallLoc;
+ if (CE)
+ CallLoc = CE->getExprLoc();
EmitTypeCheck(isa<CXXConstructorDecl>(MD) ? TCK_ConstructorCall
: TCK_MemberCall,
CallLoc, This, getContext().getRecordType(MD->getParent()));
@@ -57,6 +57,17 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size());
// And the rest of the call args.
+ CallExpr::const_arg_iterator ArgBeg, ArgEnd;
+ if (CE == nullptr) {
+ ArgBeg = ArgEnd = nullptr;
+ } else if (auto OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
+ // Special case: skip first argument of CXXOperatorCall (it is "this").
+ ArgBeg = OCE->arg_begin() + 1;
+ ArgEnd = OCE->arg_end();
+ } else {
+ ArgBeg = CE->arg_begin();
+ ArgEnd = CE->arg_end();
+ }
EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required),
@@ -184,7 +195,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
assert(ReturnValue.isNull() && "Destructor shouldn't have return value");
if (UseVirtualCall) {
CGM.getCXXABI().EmitVirtualDestructorCall(*this, Dtor, Dtor_Complete,
- CE->getExprLoc(), This);
+ This, CE);
} else {
if (getLangOpts().AppleKext &&
MD->isVirtual() &&
@@ -197,8 +208,8 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
cast<CXXDestructorDecl>(DevirtualizedMethod);
Callee = CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty);
}
- EmitCXXMemberCall(MD, CE->getExprLoc(), Callee, ReturnValue, This,
- /*ImplicitParam=*/nullptr, QualType(), nullptr,nullptr);
+ EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This,
+ /*ImplicitParam=*/nullptr, QualType(), CE);
}
return RValue::get(nullptr);
}
@@ -224,9 +235,8 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
*this, MD, This, UseVirtualCall);
}
- return EmitCXXMemberCall(MD, CE->getExprLoc(), Callee, ReturnValue, This,
- /*ImplicitParam=*/nullptr, QualType(),
- CE->arg_begin(), CE->arg_end());
+ return EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This,
+ /*ImplicitParam=*/nullptr, QualType(), CE);
}
RValue
@@ -297,9 +307,8 @@ CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
}
llvm::Value *Callee = EmitCXXOperatorMemberCallee(E, MD, This);
- return EmitCXXMemberCall(MD, E->getExprLoc(), Callee, ReturnValue, This,
- /*ImplicitParam=*/nullptr, QualType(),
- E->arg_begin() + 1, E->arg_end());
+ return EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This,
+ /*ImplicitParam=*/nullptr, QualType(), E);
}
RValue CodeGenFunction::EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E,
@@ -1412,15 +1421,16 @@ static void EmitObjectDelete(CodeGenFunction &CGF,
ElementType);
}
- // FIXME: Provide a source location here.
+ // FIXME: Provide a source location here even though there's no
+ // CXXMemberCallExpr for dtor call.
CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
- CGF.CGM.getCXXABI().EmitVirtualDestructorCall(CGF, Dtor, DtorType,
- SourceLocation(), Ptr);
+ CGF.CGM.getCXXABI().EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
+ nullptr);
if (UseGlobalDelete) {
CGF.PopCleanupBlock();
}
-
+
return;
}
}
OpenPOWER on IntegriCloud