зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
d3ff325a8d
Коммит
d4ec562b3a
|
@ -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) &&
|
||||
|
|
|
@ -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<VarDecl>(D));
|
||||
EmitStoreThroughLValue(rvalue, lvalue, true);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ExprWithCleanups>(E)) {
|
||||
CGF.enterFullExpression(EWC);
|
||||
CodeGenFunction::RunCleanupsScope Scope(CGF);
|
||||
return emitExprForReferenceBinding(CGF, EWC->getSubExpr(), InitializedDecl);
|
||||
}
|
||||
LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
|
||||
const MaterializeTemporaryExpr *M) {
|
||||
const Expr *E = M->GetTemporaryExpr();
|
||||
|
||||
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");
|
||||
|
||||
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<ValueDecl>(InitializedDecl),
|
||||
RefTempDst, false);
|
||||
EmitScalarInit(E, M->getExtendingDecl(), RefTempDst, false);
|
||||
|
||||
pushTemporaryCleanup(CGF, M, E, Object);
|
||||
return Object;
|
||||
pushTemporaryCleanup(*this, M, E, Object);
|
||||
return RefTempDst;
|
||||
}
|
||||
|
||||
SmallVector<const Expr *, 2> 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<OpaqueValueExpr>(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();
|
||||
|
|
|
@ -1062,7 +1062,7 @@ AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
|
|||
} else if (isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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())) {
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче