[llvm-branch-commits] [cfe-branch] r114004 - in /cfe/branches/Apple/whitney-IB/src/tools/clang: include/clang/AST/ lib/AST/ lib/CodeGen/ lib/Sema/ test/CodeGenCXX/ test/SemaCXX/
Daniel Dunbar
daniel at zuster.org
Wed Sep 15 12:25:15 PDT 2010
Author: ddunbar
Date: Wed Sep 15 14:25:15 2010
New Revision: 114004
URL: http://llvm.org/viewvc/llvm-project?rev=114004&view=rev
Log:
Cherry pick r113963 and r113962 out of branch, they are riskier than I care to
take at the moment.
ddunbar at lordcrumb:whitney-IB$ svn merge -c -113963 https://llvm.org/svn/llvm-project/cfe/trunk src/tools/clang
--- Reverse-merging r113963 into 'src/tools/clang':
U src/tools/clang/test/CodeGenCXX/temporaries.cpp
ddunbar at lordcrumb:whitney-IB$ svn merge -c -113962 https://llvm.org/svn/llvm-project/cfe/trunk src/tools/clang
--- Reverse-merging r113962 into 'src/tools/clang':
G src/tools/clang/test/CodeGenCXX/temporaries.cpp
U src/tools/clang/test/SemaCXX/warn-global-constructors.cpp
U src/tools/clang/include/clang/AST/Expr.h
U src/tools/clang/lib/Sema/SemaDeclCXX.cpp
U src/tools/clang/lib/Sema/SemaInit.cpp
U src/tools/clang/lib/AST/Expr.cpp
U src/tools/clang/lib/CodeGen/CGStmt.cpp
U src/tools/clang/lib/CodeGen/CGException.cpp
U src/tools/clang/lib/CodeGen/CGExprScalar.cpp
U src/tools/clang/lib/CodeGen/CGObjC.cpp
U src/tools/clang/lib/CodeGen/CGExpr.cpp
U src/tools/clang/lib/CodeGen/CGDeclCXX.cpp
U src/tools/clang/lib/CodeGen/CGTemporaries.cpp
U src/tools/clang/lib/CodeGen/CGExprAgg.cpp
U src/tools/clang/lib/CodeGen/CGExprCXX.cpp
U src/tools/clang/lib/CodeGen/CGClass.cpp
U src/tools/clang/lib/CodeGen/CodeGenFunction.h
U src/tools/clang/lib/CodeGen/CGDecl.cpp
U src/tools/clang/lib/CodeGen/CGBlocks.cpp
U src/tools/clang/lib/CodeGen/CGValue.h
ddunbar at lordcrumb:whitney-IB$
Modified:
cfe/branches/Apple/whitney-IB/src/tools/clang/include/clang/AST/Expr.h
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/AST/Expr.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGBlocks.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGClass.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDecl.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDeclCXX.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExpr.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprAgg.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprCXX.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprScalar.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGObjC.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGStmt.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGTemporaries.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGValue.h
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenFunction.h
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaDeclCXX.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaInit.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/test/CodeGenCXX/temporaries.cpp
cfe/branches/Apple/whitney-IB/src/tools/clang/test/SemaCXX/warn-global-constructors.cpp
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/include/clang/AST/Expr.h?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/include/clang/AST/Expr.h (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/include/clang/AST/Expr.h Wed Sep 15 14:25:15 2010
@@ -450,9 +450,14 @@
/// the expression is a default argument.
bool isDefaultArgument() const;
- /// \brief Determine whether the result of this expression is a
- /// temporary object of the given class type.
- bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const;
+ /// \brief Determine whether this expression directly creates a
+ /// temporary object (of class type).
+ bool isTemporaryObject() const { return getTemporaryObject() != 0; }
+
+ /// \brief If this expression directly creates a temporary object of
+ /// class type, return the expression that actually constructs that
+ /// temporary object.
+ const Expr *getTemporaryObject() const;
const Expr *IgnoreParens() const {
return const_cast<Expr*>(this)->IgnoreParens();
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/AST/Expr.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/AST/Expr.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/AST/Expr.cpp Wed Sep 15 14:25:15 2010
@@ -1648,31 +1648,46 @@
return E;
}
-/// isTemporaryObject - Determines if this expression produces a
-/// temporary of the given class type.
-bool Expr::isTemporaryObject(ASTContext &C, const CXXRecordDecl *TempTy) const {
- if (!C.hasSameUnqualifiedType(getType(), C.getTypeDeclType(TempTy)))
- return false;
-
+const Expr *Expr::getTemporaryObject() const {
const Expr *E = skipTemporaryBindingsAndNoOpCasts(this);
- // pr-values of class type are always temporaries.
- if (!E->Classify(C).isPRValue()) return false;
+ // A cast can produce a temporary object. The object's construction
+ // is represented as a CXXConstructExpr.
+ if (const CastExpr *Cast = dyn_cast<CastExpr>(E)) {
+ // Only user-defined and constructor conversions can produce
+ // temporary objects.
+ if (Cast->getCastKind() != CK_ConstructorConversion &&
+ Cast->getCastKind() != CK_UserDefinedConversion)
+ return 0;
+
+ // Strip off temporary bindings and no-op casts.
+ const Expr *Sub = skipTemporaryBindingsAndNoOpCasts(Cast->getSubExpr());
+
+ // If this is a constructor conversion, see if we have an object
+ // construction.
+ if (Cast->getCastKind() == CK_ConstructorConversion)
+ return dyn_cast<CXXConstructExpr>(Sub);
+
+ // If this is a user-defined conversion, see if we have a call to
+ // a function that itself returns a temporary object.
+ if (Cast->getCastKind() == CK_UserDefinedConversion)
+ if (const CallExpr *CE = dyn_cast<CallExpr>(Sub))
+ if (CE->getCallReturnType()->isRecordType())
+ return CE;
+
+ return 0;
+ }
+
+ // A call returning a class type returns a temporary.
+ if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+ if (CE->getCallReturnType()->isRecordType())
+ return CE;
- // Black-list implicit derived-to-base conversions, which are the
- // only way we can get a pr-value of class type that doesn't refer
- // to a temporary of that type.
- if (isa<ImplicitCastExpr>(E)) {
- switch (cast<ImplicitCastExpr>(E)->getCastKind()) {
- case CK_DerivedToBase:
- case CK_UncheckedDerivedToBase:
- return false;
- default:
- break;
- }
+ return 0;
}
- return true;
+ // Explicit temporary object constructors create temporaries.
+ return dyn_cast<CXXTemporaryObjectExpr>(E);
}
/// hasAnyTypeDependentArguments - Determines if any of the expressions
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGBlocks.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGBlocks.cpp Wed Sep 15 14:25:15 2010
@@ -352,7 +352,7 @@
SourceLocation());
}
- RValue r = EmitAnyExpr(E, AggValueSlot::forAddr(Addr, false, true));
+ RValue r = EmitAnyExpr(E, Addr, false);
if (r.isScalar()) {
llvm::Value *Loc = r.getScalarVal();
const llvm::Type *Ty = Types[i+BlockFields];
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGClass.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGClass.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGClass.cpp Wed Sep 15 14:25:15 2010
@@ -362,9 +362,7 @@
BaseClassDecl,
isBaseVirtual);
- AggValueSlot AggSlot = AggValueSlot::forAddr(V, false, /*Lifetime*/ true);
-
- CGF.EmitAggExpr(BaseInit->getInit(), AggSlot);
+ CGF.EmitAggExpr(BaseInit->getInit(), V, false, false, true);
if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor())
CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl,
@@ -390,11 +388,11 @@
Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");
CGF.Builder.CreateStore(Next, ArrayIndexVar);
}
-
- AggValueSlot Slot = AggValueSlot::forAddr(Dest, LHS.isVolatileQualified(),
- /*Lifetime*/ true);
- CGF.EmitAggExpr(MemberInit->getInit(), Slot);
+ CGF.EmitAggExpr(MemberInit->getInit(), Dest,
+ LHS.isVolatileQualified(),
+ /*IgnoreResult*/ false,
+ /*IsInitializer*/ true);
return;
}
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDecl.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDecl.cpp Wed Sep 15 14:25:15 2010
@@ -761,7 +761,7 @@
} else if (Init->getType()->isAnyComplexType()) {
EmitComplexExprIntoAddr(Init, Loc, isVolatile);
} else {
- EmitAggExpr(Init, AggValueSlot::forAddr(Loc, isVolatile, true));
+ EmitAggExpr(Init, Loc, isVolatile);
}
}
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDeclCXX.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGDeclCXX.cpp Wed Sep 15 14:25:15 2010
@@ -38,7 +38,7 @@
} else if (T->isAnyComplexType()) {
CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
} else {
- CGF.EmitAggExpr(Init, AggValueSlot::forAddr(DeclPtr, isVolatile, true));
+ CGF.EmitAggExpr(Init, DeclPtr, isVolatile);
}
}
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGException.cpp Wed Sep 15 14:25:15 2010
@@ -457,7 +457,7 @@
// evaluated but before the exception is caught. But the best way
// to handle that is to teach EmitAggExpr to do the final copy
// differently if it can't be elided.
- CGF.EmitAnyExprToMem(E, TypedExnLoc, /*Volatile*/ false, /*IsInit*/ true);
+ CGF.EmitAnyExprToMem(E, TypedExnLoc, /*Volatile*/ false);
CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(CGF.getLLVMContext()),
ShouldFreeVar);
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExpr.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExpr.cpp Wed Sep 15 14:25:15 2010
@@ -78,31 +78,35 @@
return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(),BoolTy);
}
-/// EmitAnyExpr - Emit code to compute the specified expression which
-/// can have any type. The result is returned as an RValue struct.
-/// If this is an aggregate expression, AggSlot indicates where the
+/// EmitAnyExpr - Emit code to compute the specified expression which can have
+/// any type. The result is returned as an RValue struct. If this is an
+/// aggregate expression, the aggloc/agglocvolatile arguments indicate where the
/// result should be returned.
-RValue CodeGenFunction::EmitAnyExpr(const Expr *E, AggValueSlot AggSlot,
- bool IgnoreResult) {
+RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc,
+ bool IsAggLocVolatile, bool IgnoreResult,
+ bool IsInitializer) {
if (!hasAggregateLLVMType(E->getType()))
return RValue::get(EmitScalarExpr(E, IgnoreResult));
else if (E->getType()->isAnyComplexType())
return RValue::getComplex(EmitComplexExpr(E, false, false,
IgnoreResult, IgnoreResult));
- EmitAggExpr(E, AggSlot, IgnoreResult);
- return AggSlot.asRValue();
+ EmitAggExpr(E, AggLoc, IsAggLocVolatile, IgnoreResult, IsInitializer);
+ return RValue::getAggregate(AggLoc, IsAggLocVolatile);
}
/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will
/// always be accessible even if no aggregate location is provided.
-RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E) {
- AggValueSlot AggSlot = AggValueSlot::ignored();
+RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E,
+ bool IsAggLocVolatile,
+ bool IsInitializer) {
+ llvm::Value *AggLoc = 0;
if (hasAggregateLLVMType(E->getType()) &&
!E->getType()->isAnyComplexType())
- AggSlot = CreateAggTemp(E->getType(), "agg.tmp");
- return EmitAnyExpr(E, AggSlot);
+ AggLoc = CreateMemTemp(E->getType(), "agg.tmp");
+ return EmitAnyExpr(E, AggLoc, IsAggLocVolatile, /*IgnoreResult=*/false,
+ IsInitializer);
}
/// EmitAnyExprToMem - Evaluate an expression into a given memory
@@ -114,7 +118,7 @@
if (E->getType()->isComplexType())
EmitComplexExprIntoAddr(E, Location, IsLocationVolatile);
else if (hasAggregateLLVMType(E->getType()))
- EmitAggExpr(E, AggValueSlot::forAddr(Location, IsLocationVolatile, IsInit));
+ EmitAggExpr(E, Location, IsLocationVolatile, /*Ignore*/ false, IsInit);
else {
RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false));
LValue LV = MakeAddrLValue(Location, E->getType());
@@ -243,16 +247,13 @@
}
// Create a reference temporary if necessary.
- AggValueSlot AggSlot = AggValueSlot::ignored();
if (CGF.hasAggregateLLVMType(E->getType()) &&
- !E->getType()->isAnyComplexType()) {
+ !E->getType()->isAnyComplexType())
ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(),
InitializedDecl);
- AggSlot = AggValueSlot::forAddr(ReferenceTemporary, false,
- InitializedDecl != 0);
- }
- RV = CGF.EmitAnyExpr(E, AggSlot);
+ RV = CGF.EmitAnyExpr(E, ReferenceTemporary, /*IsAggLocVolatile=*/false,
+ /*IgnoreResult=*/false, InitializedDecl);
if (InitializedDecl) {
// Get the destructor for the reference temporary.
@@ -1672,7 +1673,7 @@
const Expr *InitExpr = E->getInitializer();
LValue Result = MakeAddrLValue(DeclPtr, E->getType());
- EmitAnyExprToMem(InitExpr, DeclPtr, /*Volatile*/ false, /*Init*/ true);
+ EmitAnyExprToMem(InitExpr, DeclPtr, /*Volatile*/ false);
return Result;
}
@@ -1964,9 +1965,9 @@
}
LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
- AggValueSlot Slot = CreateAggTemp(E->getType(), "tmp");
- EmitCXXConstructExpr(E, Slot);
- return MakeAddrLValue(Slot.getAddr(), E->getType());
+ llvm::Value *Temp = CreateMemTemp(E->getType(), "tmp");
+ EmitCXXConstructExpr(Temp, E);
+ return MakeAddrLValue(Temp, E->getType());
}
LValue
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprAgg.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprAgg.cpp Wed Sep 15 14:25:15 2010
@@ -32,8 +32,10 @@
class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
CodeGenFunction &CGF;
CGBuilderTy &Builder;
- AggValueSlot Dest;
+ llvm::Value *DestPtr;
+ bool VolatileDest;
bool IgnoreResult;
+ bool IsInitializer;
bool RequiresGCollection;
ReturnValueSlot getReturnValueSlot() const {
@@ -42,19 +44,15 @@
// API.
if (RequiresGCollection) return ReturnValueSlot();
- return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile());
- }
-
- AggValueSlot EnsureSlot(QualType T) {
- if (!Dest.isIgnored()) return Dest;
- return CGF.CreateAggTemp(T, "agg.tmp.ensured");
+ return ReturnValueSlot(DestPtr, VolatileDest);
}
public:
- AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest,
- bool ignore, bool requiresGCollection)
- : CGF(cgf), Builder(CGF.Builder), Dest(Dest),
- IgnoreResult(ignore), RequiresGCollection(requiresGCollection) {
+ AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
+ bool ignore, bool isinit, bool requiresGCollection)
+ : CGF(cgf), Builder(CGF.Builder),
+ DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore),
+ IsInitializer(isinit), RequiresGCollection(requiresGCollection) {
}
//===--------------------------------------------------------------------===//
@@ -184,7 +182,7 @@
unsigned long size = TypeInfo.first/8;
const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
- CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, Dest.getAddr(),
+ CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, DestPtr,
Src.getAggregateAddr(),
SizeVal);
}
@@ -194,13 +192,13 @@
void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
assert(Src.isAggregate() && "value must be aggregate value!");
- // If Dest is ignored, then we're evaluating an aggregate expression
+ // If DestPtr is null, then we're evaluating an aggregate expression
// in a context (like an expression statement) that doesn't care
// about the result. C says that an lvalue-to-rvalue conversion is
// performed in these cases; C++ says that it is not. In either
// case, we don't actually need to do anything unless the value is
// volatile.
- if (Dest.isIgnored()) {
+ if (DestPtr == 0) {
if (!Src.isVolatileQualified() ||
CGF.CGM.getLangOptions().CPlusPlus ||
(IgnoreResult && Ignore))
@@ -208,7 +206,7 @@
// If the source is volatile, we must read from it; to do that, we need
// some place to put it.
- Dest = CGF.CreateAggTemp(E->getType(), "agg.tmp");
+ DestPtr = CGF.CreateMemTemp(E->getType(), "agg.tmp");
}
if (RequiresGCollection) {
@@ -218,17 +216,16 @@
const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size);
CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
- Dest.getAddr(),
- Src.getAggregateAddr(),
- SizeVal);
+ DestPtr, Src.getAggregateAddr(),
+ SizeVal);
return;
}
// If the result of the assignment is used, copy the LHS there also.
// FIXME: Pass VolatileDest as well. I think we also need to merge volatile
// from the source as well, as we can't eliminate it if either operand
// is volatile, unless copy has volatile for both source and destination..
- CGF.EmitAggregateCopy(Dest.getAddr(), Src.getAggregateAddr(), E->getType(),
- Dest.isVolatile()|Src.isVolatileQualified());
+ CGF.EmitAggregateCopy(DestPtr, Src.getAggregateAddr(), E->getType(),
+ VolatileDest|Src.isVolatileQualified());
}
/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
@@ -245,7 +242,7 @@
//===----------------------------------------------------------------------===//
void AggExprEmitter::VisitCastExpr(CastExpr *E) {
- if (Dest.isIgnored() && E->getCastKind() != CK_Dynamic) {
+ if (!DestPtr && E->getCastKind() != CK_Dynamic) {
Visit(E->getSubExpr());
return;
}
@@ -262,8 +259,8 @@
else
CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast");
- if (!Dest.isIgnored())
- CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");
+ if (DestPtr)
+ CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");
break;
}
@@ -271,7 +268,7 @@
// GCC union extension
QualType Ty = E->getSubExpr()->getType();
QualType PtrTy = CGF.getContext().getPointerType(Ty);
- llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(),
+ llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
CGF.ConvertType(PtrTy));
EmitInitializationToLValue(E->getSubExpr(), CGF.MakeAddrLValue(CastPtr, Ty),
Ty);
@@ -330,12 +327,13 @@
}
void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
- CGF.EmitAnyExpr(E->getLHS(), AggValueSlot::ignored(), true);
- Visit(E->getRHS());
+ CGF.EmitAnyExpr(E->getLHS(), 0, false, true);
+ CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest,
+ /*IgnoreResult=*/false, IsInitializer);
}
void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
- CGF.EmitCompoundStmt(*E->getSubStmt(), true, Dest);
+ CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
}
void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
@@ -362,21 +360,27 @@
// We have to special case property setters, otherwise we must have
// a simple lvalue (no aggregates inside vectors, bitfields).
if (LHS.isPropertyRef()) {
- AggValueSlot Slot = EnsureSlot(E->getRHS()->getType());
- CGF.EmitAggExpr(E->getRHS(), Slot);
- CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), Slot.asRValue());
+ llvm::Value *AggLoc = DestPtr;
+ if (!AggLoc)
+ AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
+ CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
+ CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
+ RValue::getAggregate(AggLoc, VolatileDest));
} else if (LHS.isKVCRef()) {
- AggValueSlot Slot = EnsureSlot(E->getRHS()->getType());
- CGF.EmitAggExpr(E->getRHS(), Slot);
- CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), Slot.asRValue());
+ llvm::Value *AggLoc = DestPtr;
+ if (!AggLoc)
+ AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
+ CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
+ CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
+ RValue::getAggregate(AggLoc, VolatileDest));
} else {
bool RequiresGCollection = false;
if (CGF.getContext().getLangOptions().getGCMode())
RequiresGCollection = TypeRequiresGCollection(E->getLHS()->getType());
// Codegen the RHS so that it stores directly into the LHS.
- AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true);
- CGF.EmitAggExpr(E->getRHS(), LHSSlot, false, RequiresGCollection);
+ CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(),
+ false, false, RequiresGCollection);
EmitFinalDestCopy(E, LHS, true);
}
}
@@ -430,40 +434,58 @@
}
void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
- // Ensure that we have a slot, but if we already do, remember
- // whether its lifetime was externally managed.
- bool WasManaged = Dest.isLifetimeExternallyManaged();
- Dest = EnsureSlot(E->getType());
- Dest.setLifetimeExternallyManaged();
-
- Visit(E->getSubExpr());
-
- // Set up the temporary's destructor if its lifetime wasn't already
- // being managed.
- if (!WasManaged)
- CGF.EmitCXXTemporary(E->getTemporary(), Dest.getAddr());
+ llvm::Value *Val = DestPtr;
+
+ if (!Val) {
+ // Create a temporary variable.
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
+
+ // FIXME: volatile
+ CGF.EmitAggExpr(E->getSubExpr(), Val, false);
+ } else
+ Visit(E->getSubExpr());
+
+ // Don't make this a live temporary if we're emitting an initializer expr.
+ if (!IsInitializer)
+ CGF.EmitCXXTemporary(E->getTemporary(), Val);
}
void
AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
- AggValueSlot Slot = EnsureSlot(E->getType());
- CGF.EmitCXXConstructExpr(E, Slot);
+ llvm::Value *Val = DestPtr;
+
+ if (!Val) // Create a temporary variable.
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
+
+ CGF.EmitCXXConstructExpr(Val, E);
}
void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
- CGF.EmitCXXExprWithTemporaries(E, Dest);
+ llvm::Value *Val = DestPtr;
+
+ CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer);
}
void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
- QualType T = E->getType();
- AggValueSlot Slot = EnsureSlot(T);
- EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T);
+ llvm::Value *Val = DestPtr;
+
+ if (!Val) {
+ // Create a temporary variable.
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
+ }
+ EmitNullInitializationToLValue(CGF.MakeAddrLValue(Val, E->getType()),
+ E->getType());
}
void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
- QualType T = E->getType();
- AggValueSlot Slot = EnsureSlot(T);
- EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T);
+ llvm::Value *Val = DestPtr;
+
+ if (!Val) {
+ // Create a temporary variable.
+ Val = CGF.CreateMemTemp(E->getType(), "tmp");
+ }
+ EmitNullInitializationToLValue(CGF.MakeAddrLValue(Val, E->getType()),
+ E->getType());
}
void
@@ -478,7 +500,7 @@
} else if (T->isAnyComplexType()) {
CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
} else if (CGF.hasAggregateLLVMType(T)) {
- CGF.EmitAggExpr(E, AggValueSlot::forAddr(LV.getAddress(), false, true));
+ CGF.EmitAnyExpr(E, LV.getAddress(), false);
} else {
CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(E), LV, T);
}
@@ -515,8 +537,6 @@
if (E->hadArrayRangeDesignator())
CGF.ErrorUnsupported(E, "GNU array range designator extension");
- llvm::Value *DestPtr = Dest.getAddr();
-
// Handle initialization of an array.
if (E->getType()->isArrayType()) {
const llvm::PointerType *APType =
@@ -640,20 +660,19 @@
/// type. The result is computed into DestPtr. Note that if DestPtr is null,
/// the value of the aggregate expression is not needed. If VolatileDest is
/// true, DestPtr cannot be 0.
-///
-/// \param IsInitializer - true if this evaluation is initializing an
-/// object whose lifetime is already being managed.
//
// FIXME: Take Qualifiers object.
-void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot,
- bool IgnoreResult,
+void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
+ bool VolatileDest, bool IgnoreResult,
+ bool IsInitializer,
bool RequiresGCollection) {
assert(E && hasAggregateLLVMType(E->getType()) &&
"Invalid aggregate expression to emit");
- assert((Slot.getAddr() != 0 || Slot.isIgnored())
- && "slot has bits but no address");
+ assert ((DestPtr != 0 || VolatileDest == false)
+ && "volatile aggregate can't be 0");
- AggExprEmitter(*this, Slot, IgnoreResult, RequiresGCollection)
+ AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer,
+ RequiresGCollection)
.Visit(const_cast<Expr*>(E));
}
@@ -661,9 +680,7 @@
assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
llvm::Value *Temp = CreateMemTemp(E->getType());
LValue LV = MakeAddrLValue(Temp, E->getType());
- AggValueSlot Slot
- = AggValueSlot::forAddr(Temp, LV.isVolatileQualified(), false);
- EmitAggExpr(E, Slot);
+ EmitAggExpr(E, Temp, LV.isVolatileQualified());
return LV;
}
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprCXX.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprCXX.cpp Wed Sep 15 14:25:15 2010
@@ -219,12 +219,16 @@
LValue LV = EmitLValue(E->getArg(0));
llvm::Value *This;
if (LV.isPropertyRef() || LV.isKVCRef()) {
- AggValueSlot Slot = CreateAggTemp(E->getArg(1)->getType());
- EmitAggExpr(E->getArg(1), Slot);
+ llvm::Value *AggLoc = CreateMemTemp(E->getArg(1)->getType());
+ EmitAggExpr(E->getArg(1), AggLoc, false /*VolatileDest*/);
if (LV.isPropertyRef())
- EmitObjCPropertySet(LV.getPropertyRefExpr(), Slot.asRValue());
+ EmitObjCPropertySet(LV.getPropertyRefExpr(),
+ RValue::getAggregate(AggLoc,
+ false /*VolatileDest*/));
else
- EmitObjCPropertySet(LV.getKVCRefExpr(), Slot.asRValue());
+ EmitObjCPropertySet(LV.getKVCRefExpr(),
+ RValue::getAggregate(AggLoc,
+ false /*VolatileDest*/));
return RValue::getAggregate(0, false);
}
else
@@ -265,16 +269,17 @@
}
void
-CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E,
- AggValueSlot Dest) {
- assert(!Dest.isIgnored() && "Must have a destination!");
+CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
+ const CXXConstructExpr *E) {
+ assert(Dest && "Must have a destination!");
const CXXConstructorDecl *CD = E->getConstructor();
// If we require zero initialization before (or instead of) calling the
// constructor, as can be the case with a non-user-provided default
// constructor, emit the zero initialization now.
if (E->requiresZeroInitialization())
- EmitNullInitialization(Dest.getAddr(), E->getType());
+ EmitNullInitialization(Dest, E->getType());
+
// If this is a call to a trivial default constructor, do nothing.
if (CD->isTrivial() && CD->isDefaultConstructor())
@@ -284,8 +289,8 @@
// its first argument instead, if in fact that argument is a temporary
// object.
if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
- if (E->getArg(0)->isTemporaryObject(getContext(), CD->getParent())) {
- EmitAggExpr(E->getArg(0), Dest);
+ if (const Expr *Arg = E->getArg(0)->getTemporaryObject()) {
+ EmitAggExpr(Arg, Dest, false);
return;
}
}
@@ -297,7 +302,7 @@
const llvm::Type *BasePtr = ConvertType(BaseElementTy);
BasePtr = llvm::PointerType::getUnqual(BasePtr);
llvm::Value *BaseAddrPtr =
- Builder.CreateBitCast(Dest.getAddr(), BasePtr);
+ Builder.CreateBitCast(Dest, BasePtr);
EmitCXXAggrConstructorCall(CD, Array, BaseAddrPtr,
E->arg_begin(), E->arg_end());
@@ -310,7 +315,7 @@
E->getConstructionKind() == CXXConstructExpr::CK_VirtualBase;
// Call the constructor.
- EmitCXXConstructorCall(CD, Type, ForVirtualBase, Dest.getAddr(),
+ EmitCXXConstructorCall(CD, Type, ForVirtualBase, Dest,
E->arg_begin(), E->arg_end());
}
}
@@ -534,11 +539,8 @@
else if (AllocType->isAnyComplexType())
CGF.EmitComplexExprIntoAddr(Init, NewPtr,
AllocType.isVolatileQualified());
- else {
- AggValueSlot Slot
- = AggValueSlot::forAddr(NewPtr, AllocType.isVolatileQualified(), true);
- CGF.EmitAggExpr(Init, Slot);
- }
+ else
+ CGF.EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
}
void
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprScalar.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGExprScalar.cpp Wed Sep 15 14:25:15 2010
@@ -1063,7 +1063,7 @@
CGF.EmitLoadOfKVCRefLValue(LV, E->getType());
}
else
- CGF.EmitAnyExpr(E, AggValueSlot::ignored(), true);
+ CGF.EmitAnyExpr(E, 0, false, true);
return 0;
}
case CK_VectorSplat: {
@@ -1127,7 +1127,7 @@
// Okay, this is a cast from an aggregate. It must be a cast to void. Just
// evaluate the result and return.
- CGF.EmitAggExpr(E, AggValueSlot::ignored(), true);
+ CGF.EmitAggExpr(E, 0, false, true);
return 0;
}
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGObjC.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGObjC.cpp Wed Sep 15 14:25:15 2010
@@ -386,7 +386,8 @@
FunctionType::ExtInfo()),
GetCopyStructFn, ReturnValueSlot(), Args);
} else if (PID->getSetterCXXAssignment()) {
- EmitAnyExpr(PID->getSetterCXXAssignment(), AggValueSlot::ignored(), true);
+ EmitAnyExpr(PID->getSetterCXXAssignment(), (llvm::Value *)0, false, true,
+ false);
} else {
// FIXME: Find a clean way to avoid AST node creation.
@@ -437,7 +438,8 @@
ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field);
LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
LoadObjCSelf(), Ivar, 0);
- EmitAggExpr(IvarInit->getInit(), AggValueSlot::forLValue(LV, true));
+ EmitAggExpr(IvarInit->getInit(), LV.getAddress(),
+ LV.isVolatileQualified(), false, true);
}
// constructor returns 'self'.
CodeGenTypes &Types = CGM.getTypes();
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGStmt.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGStmt.cpp Wed Sep 15 14:25:15 2010
@@ -75,7 +75,7 @@
if (!isa<Expr>(S))
ErrorUnsupported(S, "statement");
- EmitAnyExpr(cast<Expr>(S), AggValueSlot::ignored(), true);
+ EmitAnyExpr(cast<Expr>(S), 0, false, true);
// Expression emitters don't handle unreachable blocks yet, so look for one
// explicitly here. This handles the common case of a call to a noreturn
@@ -146,7 +146,7 @@
/// this captures the expression result of the last sub-statement and returns it
/// (for use by the statement expression extension).
RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
- AggValueSlot AggSlot) {
+ llvm::Value *AggLoc, bool isAggVol) {
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(),
"LLVM IR generation of compound statement ('{}')");
@@ -184,7 +184,7 @@
EnsureInsertPoint();
- RV = EmitAnyExpr(cast<Expr>(LastStmt), AggSlot);
+ RV = EmitAnyExpr(cast<Expr>(LastStmt), AggLoc);
}
return RV;
@@ -643,7 +643,7 @@
} else if (RV->getType()->isAnyComplexType()) {
EmitComplexExprIntoAddr(RV, ReturnValue, false);
} else {
- EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, false, true));
+ EmitAggExpr(RV, ReturnValue, false);
}
EmitBranchThroughCleanup(ReturnBlock);
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGTemporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGTemporaries.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGTemporaries.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGTemporaries.cpp Wed Sep 15 14:25:15 2010
@@ -77,9 +77,12 @@
RValue
CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
- AggValueSlot Slot) {
+ llvm::Value *AggLoc,
+ bool IsAggLocVolatile,
+ bool IsInitializer) {
RunCleanupsScope Scope(*this);
- return EmitAnyExpr(E->getSubExpr(), Slot);
+ return EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
+ /*IgnoreResult=*/false, IsInitializer);
}
LValue CodeGenFunction::EmitCXXExprWithTemporariesLValue(
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGValue.h?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGValue.h (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CGValue.h Wed Sep 15 14:25:15 2010
@@ -321,69 +321,6 @@
}
};
-/// An aggregate value slot.
-class AggValueSlot {
- /// The address and associated flags.
- uintptr_t AddrAndFlags;
-
- static const uintptr_t VolatileFlag = 0x1;
- static const uintptr_t LifetimeFlag = 0x2;
- static const uintptr_t AddrMask = ~(VolatileFlag | LifetimeFlag);
-
-public:
- /// ignored - Returns an aggregate value slot indicating that the
- /// aggregate value is being ignored.
- static AggValueSlot ignored() {
- AggValueSlot AV;
- AV.AddrAndFlags = 0;
- return AV;
- }
-
- /// forAddr - Make a slot for an aggregate value.
- ///
- /// \param Volatile - true if the slot should be volatile-initialized
- /// \param LifetimeExternallyManaged - true if the slot's lifetime
- /// is being externally managed; false if a destructor should be
- /// registered for any temporaries evaluated into the slot
- static AggValueSlot forAddr(llvm::Value *Addr, bool Volatile,
- bool LifetimeExternallyManaged) {
- AggValueSlot AV;
- AV.AddrAndFlags = reinterpret_cast<uintptr_t>(Addr);
- if (Volatile) AV.AddrAndFlags |= VolatileFlag;
- if (LifetimeExternallyManaged) AV.AddrAndFlags |= LifetimeFlag;
- return AV;
- }
-
- static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged) {
- return forAddr(LV.getAddress(), LV.isVolatileQualified(),
- LifetimeExternallyManaged);
- }
-
- bool isLifetimeExternallyManaged() const {
- return AddrAndFlags & LifetimeFlag;
- }
- void setLifetimeExternallyManaged() {
- AddrAndFlags |= LifetimeFlag;
- }
-
- bool isVolatile() const {
- return AddrAndFlags & VolatileFlag;
- }
-
- llvm::Value *getAddr() const {
- return reinterpret_cast<llvm::Value*>(AddrAndFlags & AddrMask);
- }
-
- bool isIgnored() const {
- return AddrAndFlags == 0;
- }
-
- RValue asRValue() const {
- return RValue::getAggregate(getAddr(), isVolatile());
- }
-
-};
-
} // end namespace CodeGen
} // end namespace clang
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenFunction.h?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/CodeGen/CodeGenFunction.h Wed Sep 15 14:25:15 2010
@@ -1024,12 +1024,6 @@
/// appropriate alignment.
llvm::AllocaInst *CreateMemTemp(QualType T, const llvm::Twine &Name = "tmp");
- /// CreateAggTemp - Create a temporary memory object for the given
- /// aggregate type.
- AggValueSlot CreateAggTemp(QualType T, const llvm::Twine &Name = "tmp") {
- return AggValueSlot::forAddr(CreateMemTemp(T, Name), false, false);
- }
-
/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
/// expression and compare the result against zero, returning an Int1Ty value.
llvm::Value *EvaluateExprAsBool(const Expr *E);
@@ -1040,9 +1034,9 @@
/// the result should be returned.
///
/// \param IgnoreResult - True if the resulting value isn't used.
- RValue EmitAnyExpr(const Expr *E,
- AggValueSlot AggSlot = AggValueSlot::ignored(),
- bool IgnoreResult = false);
+ RValue EmitAnyExpr(const Expr *E, llvm::Value *AggLoc = 0,
+ bool IsAggLocVolatile = false, bool IgnoreResult = false,
+ bool IsInitializer = false);
// EmitVAListRef - Emit a "reference" to a va_list; this is either the address
// or the value of the expression, depending on how va_list is defined.
@@ -1050,13 +1044,14 @@
/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will
/// always be accessible even if no aggregate location is provided.
- RValue EmitAnyExprToTemp(const Expr *E);
+ RValue EmitAnyExprToTemp(const Expr *E, bool IsAggLocVolatile = false,
+ bool IsInitializer = false);
/// EmitsAnyExprToMem - Emits the code necessary to evaluate an
/// arbitrary expression into the given memory location.
void EmitAnyExprToMem(const Expr *E, llvm::Value *Location,
- bool IsLocationVolatile,
- bool IsInitializer);
+ bool IsLocationVolatile = false,
+ bool IsInitializer = false);
/// EmitAggregateCopy - Emit an aggrate copy.
///
@@ -1259,7 +1254,7 @@
bool EmitSimpleStmt(const Stmt *S);
RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
- AggValueSlot AVS = AggValueSlot::ignored());
+ llvm::Value *AggLoc = 0, bool isAggVol = false);
/// EmitLabel - Emit the block for the given label. It is legal to call this
/// function even if there is no current insertion point.
@@ -1548,10 +1543,11 @@
QualType DstTy);
- /// EmitAggExpr - Emit the computation of the specified expression
- /// of aggregate type. The result is computed into the given slot,
- /// which may be null to indicate that the value is not needed.
- void EmitAggExpr(const Expr *E, AggValueSlot AS, bool IgnoreResult = false,
+ /// EmitAggExpr - Emit the computation of the specified expression of
+ /// aggregate type. The result is computed into DestPtr. Note that if
+ /// DestPtr is null, the value of the aggregate expression is not needed.
+ void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest,
+ bool IgnoreResult = false, bool IsInitializer = false,
bool RequiresGCollection = false);
/// EmitAggExprToLValue - Emit the computation of the specified expression of
@@ -1621,11 +1617,12 @@
void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D);
- void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest);
+ void EmitCXXConstructExpr(llvm::Value *Dest, const CXXConstructExpr *E);
RValue EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
- AggValueSlot Slot
- = AggValueSlot::ignored());
+ llvm::Value *AggLoc = 0,
+ bool IsAggLocVolatile = false,
+ bool IsInitializer = false);
void EmitCXXThrowExpr(const CXXThrowExpr *E);
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaDeclCXX.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaDeclCXX.cpp Wed Sep 15 14:25:15 2010
@@ -5462,10 +5462,12 @@
// with the same cv-unqualified type, the copy/move operation
// can be omitted by constructing the temporary object
// directly into the target of the omitted copy/move
- if (ConstructKind == CXXConstructExpr::CK_Complete &&
- Constructor->isCopyConstructor() && ExprArgs.size() >= 1) {
+ if (Constructor->isCopyConstructor() && ExprArgs.size() >= 1) {
Expr *SubExpr = ((Expr **)ExprArgs.get())[0];
- Elidable = SubExpr->isTemporaryObject(Context, Constructor->getParent());
+ Elidable = SubExpr->isTemporaryObject() &&
+ ConstructKind == CXXConstructExpr::CK_Complete &&
+ Context.hasSameUnqualifiedType(SubExpr->getType(),
+ Context.getTypeDeclType(Constructor->getParent()));
}
return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaInit.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaInit.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/lib/Sema/SemaInit.cpp Wed Sep 15 14:25:15 2010
@@ -3303,7 +3303,8 @@
// elision for return statements and throw expressions are handled as part
// of constructor initialization, while copy elision for exception handlers
// is handled by the run-time.
- bool Elidable = CurInitExpr->isTemporaryObject(S.Context, Class);
+ bool Elidable = CurInitExpr->isTemporaryObject() &&
+ S.Context.hasSameUnqualifiedType(T, CurInitExpr->getType());
SourceLocation Loc;
switch (Entity.getKind()) {
case InitializedEntity::EK_Result:
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/test/CodeGenCXX/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/test/CodeGenCXX/temporaries.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/test/CodeGenCXX/temporaries.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/test/CodeGenCXX/temporaries.cpp Wed Sep 15 14:25:15 2010
@@ -338,107 +338,3 @@
// CHECK-NEXT: ret void
}
}
-
-namespace Elision {
- struct A { A(); A(const A &); ~A(); void *p; };
-
- void foo();
- A fooA();
-
- // CHECK: define void @_ZN7Elision5test0Ev()
- void test0() {
- // CHECK: [[I:%.*]] = alloca [[A:%.*]], align 8
- // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[T0:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[K:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[T1:%.*]] = alloca [[A]], align 8
-
- // CHECK-NEXT: call void @_ZN7Elision3fooEv()
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
- A i = (foo(), A());
-
- // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]])
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
- A j = (fooA(), A());
-
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]])
- // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]])
- A k = (A(), fooA());
-
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
- }
-
-
- // CHECK: define void @_ZN7Elision5test1EbNS_1AE(
- void test1(bool c, A x) {
- // CHECK: [[I:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
-
- // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
- // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* [[X:%.*]])
- A i = (c ? A() : x);
-
- // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* [[X]])
- // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
- A j = (c ? x : A());
-
- // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
- }
-
- // CHECK: define void @_ZN7Elision5test2Ev([[A]]* sret
- A test2() {
- // CHECK: call void @_ZN7Elision3fooEv()
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
- // CHECK-NEXT: ret void
- return (foo(), A());
- }
-
- // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* sret
- A test3(int v, A x) {
- if (v < 5)
- // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
- // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X:%.*]])
- return (v < 0 ? A() : x);
- else
- // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X]])
- // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]])
- return (v > 10 ? x : A());
-
- // CHECK: ret void
- }
-
- // CHECK: define void @_ZN7Elision5test4Ev()
- void test4() {
- // CHECK: [[X:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16
- // CHECK-NEXT: [[I:%.*]] = alloca i64
-
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]])
- A x;
-
- // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
- // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 1
- // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* [[X]])
- // CHECK-NEXT: [[XSB:%.*]] = bitcast [2 x [[A]]]* [[XS]] to [[A]]*
- A xs[] = { A(), x };
-
- // CHECK-NEXT: store i64 2, i64* [[I]]
- // CHECK-NEXT: br label
- // CHECK: [[I0:%.*]] = load i64* [[I]]
- // CHECK-NEXT: icmp ne i64 [[I0]], 0
- // CHECK-NEXT: br i1
- // CHECK: [[I1:%.*]] = load i64* [[I]]
- // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I1]], 1
- // CHECK-NEXT: [[XSI:%.*]] = getelementptr inbounds [[A]]* [[XSB]], i64 [[I2]]
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[XSI]])
- // CHECK-NEXT: br label
-
- // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
- }
-}
Modified: cfe/branches/Apple/whitney-IB/src/tools/clang/test/SemaCXX/warn-global-constructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney-IB/src/tools/clang/test/SemaCXX/warn-global-constructors.cpp?rev=114004&r1=114003&r2=114004&view=diff
==============================================================================
--- cfe/branches/Apple/whitney-IB/src/tools/clang/test/SemaCXX/warn-global-constructors.cpp (original)
+++ cfe/branches/Apple/whitney-IB/src/tools/clang/test/SemaCXX/warn-global-constructors.cpp Wed Sep 15 14:25:15 2010
@@ -25,8 +25,8 @@
A e = A(A());
A f = A(a); // expected-warning {{global constructor}}
A g(a); // expected-warning {{global constructor}}
- A h((A())); // elided
- A i((A(A()))); // elided
+ A h((A())); // expected-warning {{global constructor}}
+ A i((A(A()))); // expected-warning {{global constructor}}
}
namespace test2 {
More information about the llvm-branch-commits
mailing list