summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-12 23:38:09 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-12 23:38:09 +0000
commita1c9d4d9325de9c6e12aea4c02f4c15aa0615bf2 (patch)
treea9757beb8bbd90ed01eafee161a6c6b5c25af6d7
parent0603bbb53c53c2670695a68c1d3b7b9970de1795 (diff)
downloadbcm5719-llvm-a1c9d4d9325de9c6e12aea4c02f4c15aa0615bf2.tar.gz
bcm5719-llvm-a1c9d4d9325de9c6e12aea4c02f4c15aa0615bf2.zip
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. llvm-svn: 183875
-rw-r--r--clang/lib/CodeGen/CGCall.cpp3
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp2
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp2
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp81
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp2
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp2
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h6
7 files changed, 36 insertions, 62 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 77a43a2fc4a..80446393d5b 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/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/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 4d14014f9c9..7fdd334e04c 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/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<VarDecl>(D));
EmitStoreThroughLValue(rvalue, lvalue, true);
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 9ffcff27662..d61755c0804 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/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/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index f88da33fbf5..034525cff67 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/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<ExprWithCleanups>(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<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();
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index f3eb34567bd..8efe018fcab 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -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);
}
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index f104acb1990..b33028b59db 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/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/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 4619322e1e1..508e6a4ec34 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/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
OpenPOWER on IntegriCloud