[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