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
This commit is contained in:
Richard Smith 2013-06-12 23:38:09 +00:00
Родитель d3ff325a8d
Коммит d4ec562b3a
7 изменённых файлов: 36 добавлений и 62 удалений

Просмотреть файл

@ -2013,8 +2013,7 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
if (E->isGLValue()) { if (E->isGLValue()) {
assert(E->getObjectKind() == OK_Ordinary); assert(E->getObjectKind() == OK_Ordinary);
return args.add(EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0), return args.add(EmitReferenceBindingToExpr(E), type);
type);
} }
if (hasAggregateEvaluationKind(type) && if (hasAggregateEvaluationKind(type) &&

Просмотреть файл

@ -1160,7 +1160,7 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init,
QualType type = D->getType(); QualType type = D->getType();
if (type->isReferenceType()) { if (type->isReferenceType()) {
RValue rvalue = EmitReferenceBindingToExpr(init, D); RValue rvalue = EmitReferenceBindingToExpr(init);
if (capturedByInit) if (capturedByInit)
drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
EmitStoreThroughLValue(rvalue, lvalue, true); EmitStoreThroughLValue(rvalue, lvalue, true);

Просмотреть файл

@ -149,7 +149,7 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
assert(PerformInit && "cannot have constant initializer which needs " assert(PerformInit && "cannot have constant initializer which needs "
"destruction for reference"); "destruction for reference");
unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
RValue RV = EmitReferenceBindingToExpr(Init, &D); RValue RV = EmitReferenceBindingToExpr(Init);
EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T);
} }

Просмотреть файл

@ -309,40 +309,22 @@ createReferenceTemporary(CodeGenFunction &CGF,
llvm_unreachable("unknown storage duration"); llvm_unreachable("unknown storage duration");
} }
static llvm::Value * LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
emitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, const MaterializeTemporaryExpr *M) {
const NamedDecl *InitializedDecl) { const Expr *E = M->GetTemporaryExpr();
if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(E)) {
CGF.enterFullExpression(EWC);
CodeGenFunction::RunCleanupsScope Scope(CGF);
return emitExprForReferenceBinding(CGF, EWC->getSubExpr(), InitializedDecl);
}
const MaterializeTemporaryExpr *M = 0; if (getLangOpts().ObjCAutoRefCount &&
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");
if (CGF.getLangOpts().ObjCAutoRefCount &&
M->getType()->isObjCLifetimeType() && M->getType()->isObjCLifetimeType() &&
M->getType().getObjCLifetime() != Qualifiers::OCL_None && M->getType().getObjCLifetime() != Qualifiers::OCL_None &&
M->getType().getObjCLifetime() != Qualifiers::OCL_ExplicitNone) { M->getType().getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
// FIXME: Fold this into the general case below. // FIXME: Fold this into the general case below.
llvm::Value *Object = createReferenceTemporary(CGF, M, E); llvm::Value *Object = createReferenceTemporary(*this, M, E);
LValue RefTempDst = CGF.MakeAddrLValue(Object, M->getType()); LValue RefTempDst = MakeAddrLValue(Object, M->getType());
CGF.EmitScalarInit(E, dyn_cast_or_null<ValueDecl>(InitializedDecl), EmitScalarInit(E, M->getExtendingDecl(), RefTempDst, false);
RefTempDst, false);
pushTemporaryCleanup(CGF, M, E, Object); pushTemporaryCleanup(*this, M, E, Object);
return Object; return RefTempDst;
} }
SmallVector<const Expr *, 2> CommaLHSs; SmallVector<const Expr *, 2> CommaLHSs;
@ -350,19 +332,19 @@ emitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
E = E->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments); E = E->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
for (unsigned I = 0, N = CommaLHSs.size(); I != N; ++I) for (unsigned I = 0, N = CommaLHSs.size(); I != N; ++I)
CGF.EmitIgnoredExpr(CommaLHSs[I]); EmitIgnoredExpr(CommaLHSs[I]);
if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E)) { if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E)) {
if (opaque->getType()->isRecordType()) { if (opaque->getType()->isRecordType()) {
assert(Adjustments.empty()); assert(Adjustments.empty());
return CGF.EmitOpaqueValueLValue(opaque).getAddress(); return EmitOpaqueValueLValue(opaque);
} }
} }
// Create and initialize the reference temporary. // Create and initialize the reference temporary.
llvm::Value *Object = createReferenceTemporary(CGF, M, E); llvm::Value *Object = createReferenceTemporary(*this, M, E);
CGF.EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true); EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true);
pushTemporaryCleanup(CGF, M, E, Object); pushTemporaryCleanup(*this, M, E, Object);
// Perform derived-to-base casts and/or field accesses, to get from the // Perform derived-to-base casts and/or field accesses, to get from the
// temporary object we created (and, potentially, for which we extended // temporary object we created (and, potentially, for which we extended
@ -372,16 +354,15 @@ emitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
switch (Adjustment.Kind) { switch (Adjustment.Kind) {
case SubobjectAdjustment::DerivedToBaseAdjustment: case SubobjectAdjustment::DerivedToBaseAdjustment:
Object = Object =
CGF.GetAddressOfBaseClass(Object, GetAddressOfBaseClass(Object, Adjustment.DerivedToBase.DerivedClass,
Adjustment.DerivedToBase.DerivedClass, Adjustment.DerivedToBase.BasePath->path_begin(),
Adjustment.DerivedToBase.BasePath->path_begin(), Adjustment.DerivedToBase.BasePath->path_end(),
Adjustment.DerivedToBase.BasePath->path_end(), /*NullCheckValue=*/ false);
/*NullCheckValue=*/false);
break; break;
case SubobjectAdjustment::FieldAdjustment: { case SubobjectAdjustment::FieldAdjustment: {
LValue LV = CGF.MakeAddrLValue(Object, E->getType()); LValue LV = MakeAddrLValue(Object, E->getType());
LV = CGF.EmitLValueForField(LV, Adjustment.Field); LV = EmitLValueForField(LV, Adjustment.Field);
assert(LV.isSimple() && assert(LV.isSimple() &&
"materialized temporary field is not a simple lvalue"); "materialized temporary field is not a simple lvalue");
Object = LV.getAddress(); Object = LV.getAddress();
@ -389,21 +370,23 @@ emitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
} }
case SubobjectAdjustment::MemberPointerAdjustment: { case SubobjectAdjustment::MemberPointerAdjustment: {
llvm::Value *Ptr = CGF.EmitScalarExpr(Adjustment.Ptr.RHS); llvm::Value *Ptr = EmitScalarExpr(Adjustment.Ptr.RHS);
Object = CGF.CGM.getCXXABI().EmitMemberDataPointerAddress( Object = CGM.getCXXABI().EmitMemberDataPointerAddress(
CGF, Object, Ptr, Adjustment.Ptr.MPT); *this, Object, Ptr, Adjustment.Ptr.MPT);
break; break;
} }
} }
} }
return Object; return MakeAddrLValue(Object, M->getType());
} }
RValue RValue
CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E, CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E) {
const NamedDecl *InitializedDecl) { // Emit the expression as an lvalue.
llvm::Value *Value = emitExprForReferenceBinding(*this, E, InitializedDecl); LValue LV = EmitLValue(E);
assert(LV.isSimple());
llvm::Value *Value = LV.getAddress();
if (SanitizePerformTypeCheck && !E->getType()->isFunctionType()) { if (SanitizePerformTypeCheck && !E->getType()->isFunctionType()) {
// C++11 [dcl.ref]p5 (as amended by core issue 453): // C++11 [dcl.ref]p5 (as amended by core issue 453):
@ -2831,12 +2814,6 @@ LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) {
return getOpaqueLValueMapping(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, RValue CodeGenFunction::EmitRValueForField(LValue LV,
const FieldDecl *FD) { const FieldDecl *FD) {
QualType FT = FD->getType(); QualType FT = FD->getType();

Просмотреть файл

@ -1062,7 +1062,7 @@ AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
} else if (isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) { } else if (isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) {
return EmitNullInitializationToLValue(LV); return EmitNullInitializationToLValue(LV);
} else if (type->isReferenceType()) { } else if (type->isReferenceType()) {
RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); RValue RV = CGF.EmitReferenceBindingToExpr(E);
return CGF.EmitStoreThroughLValue(RV, LV); return CGF.EmitStoreThroughLValue(RV, LV);
} }

Просмотреть файл

@ -840,7 +840,7 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
} else if (FnRetTy->isReferenceType()) { } else if (FnRetTy->isReferenceType()) {
// If this function returns a reference, take the address of the expression // If this function returns a reference, take the address of the expression
// rather than the value. // rather than the value.
RValue Result = EmitReferenceBindingToExpr(RV, /*InitializedDecl=*/0); RValue Result = EmitReferenceBindingToExpr(RV);
Builder.CreateStore(Result.getScalarVal(), ReturnValue); Builder.CreateStore(Result.getScalarVal(), ReturnValue);
} else { } else {
switch (getEvaluationKind(RV->getType())) { switch (getEvaluationKind(RV->getType())) {

Просмотреть файл

@ -2238,10 +2238,8 @@ public:
void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr); void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr);
void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr); void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr);
/// EmitReferenceBindingToExpr - Emits a reference binding to the passed in /// \brief Emits a reference binding to the passed in expression.
/// expression. Will emit a temporary variable if E is not an LValue. RValue EmitReferenceBindingToExpr(const Expr *E);
RValue EmitReferenceBindingToExpr(const Expr* E,
const NamedDecl *InitializedDecl);
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Expression Emission // Expression Emission