From: Richard Smith Date: Wed, 12 Jun 2013 23:38:09 +0000 (+0000) Subject: Simplify: we don't need any special-case lifetime extension when initializing X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d4ec562b3aaf50ea9015f82c96ebfd05a35fc7ef;p=clang Simplify: we don't need any special-case lifetime extension when initializing declarations of reference type; they're handled by the general case handling of MaterializeTemporaryExpr. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183875 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 77a43a2fc4..80446393d5 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -2013,8 +2013,7 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, if (E->isGLValue()) { assert(E->getObjectKind() == OK_Ordinary); - return args.add(EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0), - type); + return args.add(EmitReferenceBindingToExpr(E), type); } if (hasAggregateEvaluationKind(type) && diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 4d14014f9c..7fdd334e04 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -1160,7 +1160,7 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init, QualType type = D->getType(); if (type->isReferenceType()) { - RValue rvalue = EmitReferenceBindingToExpr(init, D); + RValue rvalue = EmitReferenceBindingToExpr(init); if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast(D)); EmitStoreThroughLValue(rvalue, lvalue, true); diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 9ffcff2766..d61755c080 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -149,7 +149,7 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, assert(PerformInit && "cannot have constant initializer which needs " "destruction for reference"); unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); - RValue RV = EmitReferenceBindingToExpr(Init, &D); + RValue RV = EmitReferenceBindingToExpr(Init); EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); } diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index f88da33fbf..034525cff6 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -309,40 +309,22 @@ createReferenceTemporary(CodeGenFunction &CGF, llvm_unreachable("unknown storage duration"); } -static llvm::Value * -emitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, - const NamedDecl *InitializedDecl) { - if (const ExprWithCleanups *EWC = dyn_cast(E)) { - CGF.enterFullExpression(EWC); - CodeGenFunction::RunCleanupsScope Scope(CGF); - return emitExprForReferenceBinding(CGF, EWC->getSubExpr(), InitializedDecl); - } - - const MaterializeTemporaryExpr *M = 0; - E = E->findMaterializedTemporary(M); - - if (E->isGLValue()) { - // Emit the expression as an lvalue. - LValue LV = CGF.EmitLValue(E); - assert(LV.isSimple()); - return LV.getAddress(); - } - - assert(M && "prvalue reference initializer but not a materialized temporary"); +LValue CodeGenFunction::EmitMaterializeTemporaryExpr( + const MaterializeTemporaryExpr *M) { + const Expr *E = M->GetTemporaryExpr(); - if (CGF.getLangOpts().ObjCAutoRefCount && + if (getLangOpts().ObjCAutoRefCount && M->getType()->isObjCLifetimeType() && M->getType().getObjCLifetime() != Qualifiers::OCL_None && M->getType().getObjCLifetime() != Qualifiers::OCL_ExplicitNone) { // FIXME: Fold this into the general case below. - llvm::Value *Object = createReferenceTemporary(CGF, M, E); - LValue RefTempDst = CGF.MakeAddrLValue(Object, M->getType()); + llvm::Value *Object = createReferenceTemporary(*this, M, E); + LValue RefTempDst = MakeAddrLValue(Object, M->getType()); - CGF.EmitScalarInit(E, dyn_cast_or_null(InitializedDecl), - RefTempDst, false); + EmitScalarInit(E, M->getExtendingDecl(), RefTempDst, false); - pushTemporaryCleanup(CGF, M, E, Object); - return Object; + pushTemporaryCleanup(*this, M, E, Object); + return RefTempDst; } SmallVector CommaLHSs; @@ -350,19 +332,19 @@ emitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, E = E->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments); for (unsigned I = 0, N = CommaLHSs.size(); I != N; ++I) - CGF.EmitIgnoredExpr(CommaLHSs[I]); + EmitIgnoredExpr(CommaLHSs[I]); if (const OpaqueValueExpr *opaque = dyn_cast(E)) { if (opaque->getType()->isRecordType()) { assert(Adjustments.empty()); - return CGF.EmitOpaqueValueLValue(opaque).getAddress(); + return EmitOpaqueValueLValue(opaque); } } // Create and initialize the reference temporary. - llvm::Value *Object = createReferenceTemporary(CGF, M, E); - CGF.EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true); - pushTemporaryCleanup(CGF, M, E, Object); + llvm::Value *Object = createReferenceTemporary(*this, M, E); + EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true); + pushTemporaryCleanup(*this, M, E, Object); // Perform derived-to-base casts and/or field accesses, to get from the // temporary object we created (and, potentially, for which we extended @@ -372,16 +354,15 @@ emitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, switch (Adjustment.Kind) { case SubobjectAdjustment::DerivedToBaseAdjustment: Object = - CGF.GetAddressOfBaseClass(Object, - Adjustment.DerivedToBase.DerivedClass, - Adjustment.DerivedToBase.BasePath->path_begin(), - Adjustment.DerivedToBase.BasePath->path_end(), - /*NullCheckValue=*/false); + GetAddressOfBaseClass(Object, Adjustment.DerivedToBase.DerivedClass, + Adjustment.DerivedToBase.BasePath->path_begin(), + Adjustment.DerivedToBase.BasePath->path_end(), + /*NullCheckValue=*/ false); break; case SubobjectAdjustment::FieldAdjustment: { - LValue LV = CGF.MakeAddrLValue(Object, E->getType()); - LV = CGF.EmitLValueForField(LV, Adjustment.Field); + LValue LV = MakeAddrLValue(Object, E->getType()); + LV = EmitLValueForField(LV, Adjustment.Field); assert(LV.isSimple() && "materialized temporary field is not a simple lvalue"); Object = LV.getAddress(); @@ -389,21 +370,23 @@ emitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, } case SubobjectAdjustment::MemberPointerAdjustment: { - llvm::Value *Ptr = CGF.EmitScalarExpr(Adjustment.Ptr.RHS); - Object = CGF.CGM.getCXXABI().EmitMemberDataPointerAddress( - CGF, Object, Ptr, Adjustment.Ptr.MPT); + llvm::Value *Ptr = EmitScalarExpr(Adjustment.Ptr.RHS); + Object = CGM.getCXXABI().EmitMemberDataPointerAddress( + *this, Object, Ptr, Adjustment.Ptr.MPT); break; } } } - return Object; + return MakeAddrLValue(Object, M->getType()); } RValue -CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E, - const NamedDecl *InitializedDecl) { - llvm::Value *Value = emitExprForReferenceBinding(*this, E, InitializedDecl); +CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E) { + // Emit the expression as an lvalue. + LValue LV = EmitLValue(E); + assert(LV.isSimple()); + llvm::Value *Value = LV.getAddress(); if (SanitizePerformTypeCheck && !E->getType()->isFunctionType()) { // C++11 [dcl.ref]p5 (as amended by core issue 453): @@ -2831,12 +2814,6 @@ LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) { return getOpaqueLValueMapping(e); } -LValue CodeGenFunction::EmitMaterializeTemporaryExpr( - const MaterializeTemporaryExpr *E) { - RValue RV = EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); - return MakeAddrLValue(RV.getScalarVal(), E->getType()); -} - RValue CodeGenFunction::EmitRValueForField(LValue LV, const FieldDecl *FD) { QualType FT = FD->getType(); diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index f3eb34567b..8efe018fca 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -1062,7 +1062,7 @@ AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { } else if (isa(E) || isa(E)) { return EmitNullInitializationToLValue(LV); } else if (type->isReferenceType()) { - RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); + RValue RV = CGF.EmitReferenceBindingToExpr(E); return CGF.EmitStoreThroughLValue(RV, LV); } diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index f104acb199..b33028b59d 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -840,7 +840,7 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { } else if (FnRetTy->isReferenceType()) { // If this function returns a reference, take the address of the expression // rather than the value. - RValue Result = EmitReferenceBindingToExpr(RV, /*InitializedDecl=*/0); + RValue Result = EmitReferenceBindingToExpr(RV); Builder.CreateStore(Result.getScalarVal(), ReturnValue); } else { switch (getEvaluationKind(RV->getType())) { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 4619322e1e..508e6a4ec3 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2238,10 +2238,8 @@ public: void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr); void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr); - /// EmitReferenceBindingToExpr - Emits a reference binding to the passed in - /// expression. Will emit a temporary variable if E is not an LValue. - RValue EmitReferenceBindingToExpr(const Expr* E, - const NamedDecl *InitializedDecl); + /// \brief Emits a reference binding to the passed in expression. + RValue EmitReferenceBindingToExpr(const Expr *E); //===--------------------------------------------------------------------===// // Expression Emission