зеркало из 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()) {
|
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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче