diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 88 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 10 |
3 files changed, 53 insertions, 59 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 8138c6fc8d2..3957eb76527 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2163,20 +2163,6 @@ CodeGenFunction::CanDevirtualizeMemberFunctionCall(const Expr *Base, return false; } -llvm::Value * -CodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E, - const CXXMethodDecl *MD, - llvm::Value *This) { - llvm::FunctionType *fnType = - CGM.getTypes().GetFunctionType( - CGM.getTypes().arrangeCXXMethodDeclaration(MD)); - - if (MD->isVirtual() && !CanDevirtualizeMemberFunctionCall(E->getArg(0), MD)) - return CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, fnType); - - return CGM.GetAddrOfFunction(MD, fnType); -} - void CodeGenFunction::EmitForwardingCallToLambda( const CXXMethodDecl *callOperator, CallArgList &callArgs) { diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index ff084de41c6..4a8fe9a954c 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -120,9 +120,23 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, ReturnValue); } - // Compute the object pointer. + bool HasQualifier = ME->hasQualifier(); + NestedNameSpecifier *Qualifier = HasQualifier ? ME->getQualifier() : nullptr; + bool IsArrow = ME->isArrow(); const Expr *Base = ME->getBase(); - bool CanUseVirtualCall = MD->isVirtual() && !ME->hasQualifier(); + + return EmitCXXMemberOrOperatorMemberCallExpr( + CE, MD, ReturnValue, HasQualifier, Qualifier, IsArrow, Base); +} + +RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( + const CallExpr *CE, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, + bool HasQualifier, NestedNameSpecifier *Qualifier, bool IsArrow, + const Expr *Base) { + assert(isa<CXXMemberCallExpr>(CE) || isa<CXXOperatorCallExpr>(CE)); + + // Compute the object pointer. + bool CanUseVirtualCall = MD->isVirtual() && !HasQualifier; const CXXMethodDecl *DevirtualizedMethod = nullptr; if (CanUseVirtualCall && CanDevirtualizeMemberFunctionCall(Base, MD)) { @@ -153,7 +167,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, } llvm::Value *This; - if (ME->isArrow()) + if (IsArrow) This = EmitScalarExpr(Base); else This = EmitLValue(Base).getAddress(); @@ -165,23 +179,28 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, cast<CXXConstructorDecl>(MD)->isDefaultConstructor()) return RValue::get(nullptr); - if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()) { - // We don't like to generate the trivial copy/move assignment operator - // when it isn't necessary; just produce the proper effect here. - llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress(); - EmitAggregateAssign(This, RHS, CE->getType()); - return RValue::get(This); - } + if (!MD->getParent()->mayInsertExtraPadding()) { + if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()) { + // We don't like to generate the trivial copy/move assignment operator + // when it isn't necessary; just produce the proper effect here. + // Special case: skip first argument of CXXOperatorCall (it is "this"). + unsigned ArgsToSkip = isa<CXXOperatorCallExpr>(CE) ? 1 : 0; + llvm::Value *RHS = + EmitLValue(*(CE->arg_begin() + ArgsToSkip)).getAddress(); + EmitAggregateAssign(This, RHS, CE->getType()); + return RValue::get(This); + } - if (isa<CXXConstructorDecl>(MD) && - cast<CXXConstructorDecl>(MD)->isCopyOrMoveConstructor()) { - // Trivial move and copy ctor are the same. - assert(CE->getNumArgs() == 1 && "unexpected argcount for trivial ctor"); - llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress(); - EmitAggregateCopy(This, RHS, CE->arg_begin()->getType()); - return RValue::get(This); + if (isa<CXXConstructorDecl>(MD) && + cast<CXXConstructorDecl>(MD)->isCopyOrMoveConstructor()) { + // Trivial move and copy ctor are the same. + assert(CE->getNumArgs() == 1 && "unexpected argcount for trivial ctor"); + llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress(); + EmitAggregateCopy(This, RHS, CE->arg_begin()->getType()); + return RValue::get(This); + } + llvm_unreachable("unknown trivial member function"); } - llvm_unreachable("unknown trivial member function"); } // Compute the function type we're calling. @@ -213,13 +232,11 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, "Destructor shouldn't have explicit parameters"); assert(ReturnValue.isNull() && "Destructor shouldn't have return value"); if (UseVirtualCall) { - CGM.getCXXABI().EmitVirtualDestructorCall(*this, Dtor, Dtor_Complete, - This, CE); + CGM.getCXXABI().EmitVirtualDestructorCall( + *this, Dtor, Dtor_Complete, This, cast<CXXMemberCallExpr>(CE)); } else { - if (getLangOpts().AppleKext && - MD->isVirtual() && - ME->hasQualifier()) - Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), Ty); + if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier) + Callee = BuildAppleKextVirtualCall(MD, Qualifier, Ty); else if (!DevirtualizedMethod) Callee = CGM.getAddrOfCXXStructor(Dtor, StructorType::Complete, FInfo, Ty); @@ -239,10 +256,8 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, } else if (UseVirtualCall) { Callee = CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, Ty); } else { - if (getLangOpts().AppleKext && - MD->isVirtual() && - ME->hasQualifier()) - Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), Ty); + if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier) + Callee = BuildAppleKextVirtualCall(MD, Qualifier, Ty); else if (!DevirtualizedMethod) Callee = CGM.GetAddrOfFunction(MD, Ty); else { @@ -315,20 +330,9 @@ CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, ReturnValueSlot ReturnValue) { assert(MD->isInstance() && "Trying to emit a member call expr on a static method!"); - LValue LV = EmitLValue(E->getArg(0)); - llvm::Value *This = LV.getAddress(); - - if ((MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()) && - MD->isTrivial() && !MD->getParent()->mayInsertExtraPadding()) { - llvm::Value *Src = EmitLValue(E->getArg(1)).getAddress(); - QualType Ty = E->getType(); - EmitAggregateAssign(This, Src, Ty); - return RValue::get(This); - } - - llvm::Value *Callee = EmitCXXOperatorMemberCallee(E, MD, This); - return EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This, - /*ImplicitParam=*/nullptr, QualType(), E); + return EmitCXXMemberOrOperatorMemberCallExpr( + E, MD, ReturnValue, /*HasQualifier=*/false, /*Qualifier=*/nullptr, + /*IsArrow=*/false, E->getArg(0)); } RValue CodeGenFunction::EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 4575e31dbd2..e74abc9be6c 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2329,12 +2329,16 @@ public: StructorType Type); RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue); + RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE, + const CXXMethodDecl *MD, + ReturnValueSlot ReturnValue, + bool HasQualifier, + NestedNameSpecifier *Qualifier, + bool IsArrow, const Expr *Base); + // Compute the object pointer. RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue); - llvm::Value *EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E, - const CXXMethodDecl *MD, - llvm::Value *This); RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue); |