[cfe-commits] r133144 - in /cfe/trunk: include/clang/AST/Type.h lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGObjCRuntime.cpp lib/CodeGen/CGValue.h lib/CodeGen/CodeGenFunction.h test/CodeGenObjCXX/gc.mm

John McCall rjmccall at apple.com
Wed Jun 15 21:16:24 PDT 2011


Author: rjmccall
Date: Wed Jun 15 23:16:24 2011
New Revision: 133144

URL: http://llvm.org/viewvc/llvm-project?rev=133144&view=rev
Log:
Restore correct use of GC barriers.


Added:
    cfe/trunk/test/CodeGenObjCXX/gc.mm
Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
    cfe/trunk/lib/CodeGen/CGValue.h
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Jun 15 23:16:24 2011
@@ -641,6 +641,10 @@
     return withFastQualifiers(Qualifiers::Volatile);
   }
 
+  QualType withCVRQualifiers(unsigned CVR) const {
+    return withFastQualifiers(CVR);
+  }
+
   void addFastQualifiers(unsigned TQs) {
     assert(!(TQs & ~Qualifiers::FastMask)
            && "non-fast qualifier bits set in mask!");

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Wed Jun 15 23:16:24 2011
@@ -618,8 +618,11 @@
 
       ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
                            declRef, VK_RValue);
-      EmitExprAsInit(&l2r, &blockFieldPseudoVar, blockField,
-                     getContext().getDeclAlign(variable),
+      EmitExprAsInit(&l2r, &blockFieldPseudoVar,
+                     LValue::MakeAddr(blockField, type,
+                                      getContext().getDeclAlign(variable)
+                                                  .getQuantity(),
+                                      getContext()),
                      /*captured by init*/ false);
     }
 

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Jun 15 23:16:24 2011
@@ -430,10 +430,8 @@
     }
 
     if (!CGF.hasAggregateLLVMType(T)) {
-      CGF.EmitScalarInit(MemberInit->getInit(), 0, Dest, false, 
-                         LHS.isVolatileQualified(), 
-                         CGF.getContext().getTypeAlign(T),
-                         T);
+      LValue lvalue = CGF.MakeAddrLValue(Dest, T);
+      CGF.EmitScalarInit(MemberInit->getInit(), /*decl*/ 0, lvalue, false);
     } else if (T->isAnyComplexType()) {
       CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), Dest, 
                                   LHS.isVolatileQualified());
@@ -555,8 +553,7 @@
     CGF.EmitNullInitialization(LHS.getAddress(), Field->getType());
   } else if (!CGF.hasAggregateLLVMType(Field->getType())) {
     if (LHS.isSimple()) {
-      CGF.EmitExprAsInit(MemberInit->getInit(), Field, LHS.getAddress(),
-                         CGF.getContext().getDeclAlign(Field), false);
+      CGF.EmitExprAsInit(MemberInit->getInit(), Field, LHS, false);
     } else {
       RValue RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit()));
       CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Jun 15 23:16:24 2011
@@ -453,16 +453,23 @@
   return isAccessedBy(*var, e);
 }
 
+static void drillIntoBlockVariable(CodeGenFunction &CGF,
+                                   LValue &lvalue,
+                                   const VarDecl *var) {
+  lvalue.setAddress(CGF.BuildBlockByrefAddress(lvalue.getAddress(), var));
+}
+
 void CodeGenFunction::EmitScalarInit(const Expr *init,
                                      const ValueDecl *D,
-                                     llvm::Value *addr, bool capturedByInit,
-                                     bool isVolatile, unsigned alignment, 
-                                     QualType type) {
-  Qualifiers::ObjCLifetime lifetime = type.getQualifiers().getObjCLifetime();
+                                     LValue lvalue,
+                                     bool capturedByInit) {
+  QualType type = lvalue.getType();
+  Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
   if (!lifetime) {
     llvm::Value *value = EmitScalarExpr(init);
-    if (capturedByInit) addr = BuildBlockByrefAddress(addr, cast<VarDecl>(D));
-    EmitStoreOfScalar(value, addr, isVolatile, alignment, type);
+    if (capturedByInit)
+      drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
+    EmitStoreThroughLValue(RValue::get(value), lvalue, lvalue.getType());
     return;
   }
 
@@ -480,27 +487,28 @@
   if (lifetime != Qualifiers::OCL_ExplicitNone)
     accessedByInit = isAccessedBy(D, init);
   if (accessedByInit) {
+    LValue tempLV = lvalue;
     // Drill down to the __block object if necessary.
-    llvm::Value *tempAddr = addr;
     if (capturedByInit) {
       // We can use a simple GEP for this because it can't have been
       // moved yet.
-      tempAddr = Builder.CreateStructGEP(tempAddr,
-                                   getByRefValueLLVMField(cast<VarDecl>(D)));
+      tempLV.setAddress(Builder.CreateStructGEP(tempLV.getAddress(),
+                                   getByRefValueLLVMField(cast<VarDecl>(D))));
     }
 
-    const llvm::PointerType *ty = cast<llvm::PointerType>(tempAddr->getType());
+    const llvm::PointerType *ty
+      = cast<llvm::PointerType>(tempLV.getAddress()->getType());
     ty = cast<llvm::PointerType>(ty->getElementType());
 
     llvm::Value *zero = llvm::ConstantPointerNull::get(ty);
     
     // If __weak, we want to use a barrier under certain conditions.
     if (lifetime == Qualifiers::OCL_Weak)
-      EmitARCInitWeak(tempAddr, zero);
+      EmitARCInitWeak(tempLV.getAddress(), zero);
 
     // Otherwise just do a simple store.
     else
-      EmitStoreOfScalar(zero, tempAddr, isVolatile, alignment, type);
+      EmitStoreOfScalar(zero, tempLV);
   }
 
   // Emit the initializer.
@@ -526,11 +534,11 @@
     // disappear in the common case.
     value = EmitScalarExpr(init);
 
-    if (capturedByInit) addr = BuildBlockByrefAddress(addr, cast<VarDecl>(D));
+    if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
     if (accessedByInit)
-      EmitARCStoreWeak(addr, value, /*ignored*/ true);
+      EmitARCStoreWeak(lvalue.getAddress(), value, /*ignored*/ true);
     else
-      EmitARCInitWeak(addr, value);
+      EmitARCInitWeak(lvalue.getAddress(), value);
     return;
   }
 
@@ -539,22 +547,19 @@
     break;
   }
 
-  if (capturedByInit) addr = BuildBlockByrefAddress(addr, cast<VarDecl>(D));
-
-  llvm::MDNode *tbaa = CGM.getTBAAInfo(type);
+  if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
 
   // If the variable might have been accessed by its initializer, we
   // might have to initialize with a barrier.  We have to do this for
   // both __weak and __strong, but __weak got filtered out above.
   if (accessedByInit && lifetime == Qualifiers::OCL_Strong) {
-    llvm::Value *oldValue
-      = EmitLoadOfScalar(addr, isVolatile, alignment, type, tbaa);
-    EmitStoreOfScalar(value, addr, isVolatile, alignment, type, tbaa);
+    llvm::Value *oldValue = EmitLoadOfScalar(lvalue);
+    EmitStoreOfScalar(value, lvalue);
     EmitARCRelease(oldValue, /*precise*/ false);
     return;
   }
 
-  EmitStoreOfScalar(value, addr, isVolatile, alignment, type, tbaa);  
+  EmitStoreOfScalar(value, lvalue);
 }
 
 /// canEmitInitWithFewStoresAfterMemset - Decide whether we can emit the
@@ -860,8 +865,11 @@
   llvm::Value *Loc =
     capturedByInit ? emission.Address : emission.getObjectAddress(*this);
 
-  if (!emission.IsConstantAggregate)
-    return EmitExprAsInit(Init, &D, Loc, alignment, capturedByInit);
+  if (!emission.IsConstantAggregate) {
+    LValue lv = MakeAddrLValue(Loc, type, alignment.getQuantity());
+    lv.setNonGC(true);
+    return EmitExprAsInit(Init, &D, lv, capturedByInit);
+  }
 
   // If this is a simple aggregate initialization, we can optimize it
   // in various ways.
@@ -924,29 +932,25 @@
 ///   whose address is potentially changed by the initializer
 void CodeGenFunction::EmitExprAsInit(const Expr *init,
                                      const ValueDecl *D,
-                                     llvm::Value *loc,
-                                     CharUnits alignment,
+                                     LValue lvalue,
                                      bool capturedByInit) {
   QualType type = D->getType();
-  bool isVolatile = type.isVolatileQualified();
 
   if (type->isReferenceType()) {
-    RValue RV = EmitReferenceBindingToExpr(init, D);
+    RValue rvalue = EmitReferenceBindingToExpr(init, D);
     if (capturedByInit) 
-      loc = BuildBlockByrefAddress(loc, cast<VarDecl>(D));
-    EmitStoreOfScalar(RV.getScalarVal(), loc, false,
-                      alignment.getQuantity(), type);
+      drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
+    EmitStoreThroughLValue(rvalue, lvalue, type);
   } else if (!hasAggregateLLVMType(type)) {
-    EmitScalarInit(init, D, loc, capturedByInit, isVolatile,
-                   alignment.getQuantity(), type);
+    EmitScalarInit(init, D, lvalue, capturedByInit);
   } else if (type->isAnyComplexType()) {
     ComplexPairTy complex = EmitComplexExpr(init);
-    if (capturedByInit) loc = BuildBlockByrefAddress(loc, cast<VarDecl>(D));
-    StoreComplexToAddr(complex, loc, isVolatile);
+    if (capturedByInit)
+      drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
+    StoreComplexToAddr(complex, lvalue.getAddress(), lvalue.isVolatile());
   } else {
     // TODO: how can we delay here if D is captured by its initializer?
-    EmitAggExpr(init, AggValueSlot::forAddr(loc, type.getQualifiers(), true, 
-                                            false));
+    EmitAggExpr(init, AggValueSlot::forLValue(lvalue, true, false));
   }
 }
 

Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Wed Jun 15 23:16:24 2011
@@ -27,29 +27,26 @@
          "Should not call EmitDeclInit on a reference!");
   
   ASTContext &Context = CGF.getContext();
-    
-  const Expr *Init = D.getInit();
-  QualType T = D.getType();
-  bool isVolatile = Context.getCanonicalType(T).isVolatileQualified();
 
-  unsigned Alignment = Context.getDeclAlign(&D).getQuantity();
-  if (!CGF.hasAggregateLLVMType(T)) {
+  unsigned alignment = Context.getDeclAlign(&D).getQuantity();
+  QualType type = D.getType();
+  LValue lv = CGF.MakeAddrLValue(DeclPtr, type, alignment);
+
+  const Expr *Init = D.getInit();
+  if (!CGF.hasAggregateLLVMType(type)) {
     CodeGenModule &CGM = CGF.CGM;
-    Qualifiers::GC GCAttr = CGM.getContext().getObjCGCAttrKind(T);
-    if (GCAttr == Qualifiers::Strong)
+    if (lv.isObjCStrong())
       CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init),
                                                 DeclPtr, D.isThreadSpecified());
-    else if (GCAttr == Qualifiers::Weak)
-        CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init),
-                                                DeclPtr);
+    else if (lv.isObjCWeak())
+      CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init),
+                                              DeclPtr);
     else
-      CGF.EmitScalarInit(Init, &D, DeclPtr, false, isVolatile, Alignment,
-                         D.getType());
-  } else if (T->isAnyComplexType()) {
-    CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
+      CGF.EmitScalarInit(Init, &D, lv, false);
+  } else if (type->isAnyComplexType()) {
+    CGF.EmitComplexExprIntoAddr(Init, DeclPtr, lv.isVolatile());
   } else {
-    CGF.EmitAggExpr(Init, AggValueSlot::forAddr(DeclPtr, T.getQualifiers(),
-                                                true));
+    CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv, true));
   }
 }
 

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Jun 15 23:16:24 2011
@@ -313,9 +313,10 @@
 
               unsigned Alignment =
                 CGF.getContext().getTypeAlignInChars(PointeeType).getQuantity();
-              CGF.EmitScalarInit(E, InitVD, ReferenceTemporary, false,
-                                 PointeeType.isVolatileQualified(), 
-                                 Alignment, PointeeType);
+              LValue lvalue =
+                CGF.MakeAddrLValue(ReferenceTemporary, PointeeType, Alignment);
+
+              CGF.EmitScalarInit(E, InitVD, lvalue, false);
               return ReferenceTemporary;
             }
           }
@@ -669,6 +670,12 @@
   }
 }
 
+llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) {
+  return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
+                          lvalue.getAlignment(), lvalue.getType(),
+                          lvalue.getTBAAInfo());
+}
+
 llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
                                               unsigned Alignment, QualType Ty,
                                               llvm::MDNode *TBAAInfo) {
@@ -724,6 +731,12 @@
     CGM.DecorateInstruction(Store, TBAAInfo);
 }
 
+void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue) {
+  EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
+                    lvalue.getAlignment(), lvalue.getType(),
+                    lvalue.getTBAAInfo());
+}
+
 /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
 /// method emits the address of the lvalue, then loads the result as an rvalue,
 /// returning the rvalue.
@@ -964,9 +977,7 @@
   }
 
   assert(Src.isScalar() && "Can't emit an agg store with this method");
-  EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(),
-                    Dst.isVolatileQualified(), Dst.getAlignment(), Ty,
-                    Dst.getTBAAInfo());
+  EmitStoreOfScalar(Src.getScalarVal(), Dst);
 }
 
 void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
@@ -1498,7 +1509,7 @@
     assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
     Idx = Builder.CreateIntCast(Idx, Int32Ty, IdxSigned, "vidx");
     return LValue::MakeVectorElt(LHS.getAddress(), Idx,
-                                 E->getBase()->getType().getCVRQualifiers());
+                                 E->getBase()->getType());
   }
 
   // Extend or truncate the index type to 32 or 64-bits.
@@ -1637,7 +1648,7 @@
     Base = EmitLValue(E->getBase());
   } else {
     // Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such.
-    assert(E->getBase()->getType()->getAs<VectorType>() &&
+    assert(E->getBase()->getType()->isVectorType() &&
            "Result must be a vector");
     llvm::Value *Vec = EmitScalarExpr(E->getBase());
     
@@ -1646,6 +1657,9 @@
     Builder.CreateStore(Vec, VecMem);
     Base = MakeAddrLValue(VecMem, E->getBase()->getType());
   }
+
+  QualType type =
+    E->getType().withCVRQualifiers(Base.getQuals().getCVRQualifiers());
   
   // Encode the element access list into a vector of unsigned indices.
   llvm::SmallVector<unsigned, 4> Indices;
@@ -1653,8 +1667,7 @@
 
   if (Base.isSimple()) {
     llvm::Constant *CV = GenerateConstantVector(getLLVMContext(), Indices);
-    return LValue::MakeExtVectorElt(Base.getAddress(), CV,
-                                    Base.getVRQualifiers());
+    return LValue::MakeExtVectorElt(Base.getAddress(), CV, type);
   }
   assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
 
@@ -1668,8 +1681,7 @@
       CElts.push_back(cast<llvm::Constant>(BaseElts->getOperand(Indices[i])));
   }
   llvm::Constant *CV = llvm::ConstantVector::get(CElts);
-  return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV,
-                                  Base.getVRQualifiers());
+  return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV, type);
 }
 
 LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
@@ -1720,7 +1732,7 @@
     CGM.getTypes().getCGRecordLayout(Field->getParent());
   const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
   return LValue::MakeBitfield(BaseValue, Info,
-                             Field->getType().getCVRQualifiers()|CVRQualifiers);
+                          Field->getType().withCVRQualifiers(CVRQualifiers));
 }
 
 /// EmitLValueForAnonRecordField - Given that the field is a member of

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Wed Jun 15 23:16:24 2011
@@ -136,8 +136,8 @@
 
   void VisitVAArgExpr(VAArgExpr *E);
 
-  void EmitInitializationToLValue(Expr *E, LValue Address, QualType T);
-  void EmitNullInitializationToLValue(LValue Address, QualType T);
+  void EmitInitializationToLValue(Expr *E, LValue Address);
+  void EmitNullInitializationToLValue(LValue Address);
   //  case Expr::ChooseExprClass:
   void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
 };
@@ -271,8 +271,8 @@
     QualType PtrTy = CGF.getContext().getPointerType(Ty);
     llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(),
                                                  CGF.ConvertType(PtrTy));
-    EmitInitializationToLValue(E->getSubExpr(), CGF.MakeAddrLValue(CastPtr, Ty),
-                               Ty);
+    EmitInitializationToLValue(E->getSubExpr(),
+                               CGF.MakeAddrLValue(CastPtr, Ty));
     break;
   }
 
@@ -521,13 +521,13 @@
 void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   QualType T = E->getType();
   AggValueSlot Slot = EnsureSlot(T);
-  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T);
+  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T));
 }
 
 void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
   QualType T = E->getType();
   AggValueSlot Slot = EnsureSlot(T);
-  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T);
+  EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T));
 }
 
 /// isSimpleZero - If emitting this value will obviously just cause a store of
@@ -559,46 +559,46 @@
 
 
 void 
-AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) {
+AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
+  QualType type = LV.getType();
   // FIXME: Ignore result?
   // FIXME: Are initializers affected by volatile?
   if (Dest.isZeroed() && isSimpleZero(E, CGF)) {
     // Storing "i32 0" to a zero'd memory location is a noop.
   } else if (isa<ImplicitValueInitExpr>(E)) {
-    EmitNullInitializationToLValue(LV, T);
-  } else if (T->isReferenceType()) {
+    EmitNullInitializationToLValue(LV);
+  } else if (type->isReferenceType()) {
     RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0);
-    CGF.EmitStoreThroughLValue(RV, LV, T);
-  } else if (T->isAnyComplexType()) {
+    CGF.EmitStoreThroughLValue(RV, LV, type);
+  } else if (type->isAnyComplexType()) {
     CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
-  } else if (CGF.hasAggregateLLVMType(T)) {
-    CGF.EmitAggExpr(E, AggValueSlot::forAddr(LV.getAddress(), 
-                                             T.getQualifiers(), true,
-                                             false, Dest.isZeroed()));
+  } else if (CGF.hasAggregateLLVMType(type)) {
+    CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV, true, false,
+                                               Dest.isZeroed()));
   } else if (LV.isSimple()) {
-    CGF.EmitScalarInit(E, /*D=*/0, LV.getAddress(), /*Captured=*/false, 
-                       LV.isVolatileQualified(), LV.getAlignment(),
-                       T);
+    CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false);
   } else {
-    CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV, T);
+    CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV, type);
   }
 }
 
-void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
+void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) {
+  QualType type = lv.getType();
+
   // If the destination slot is already zeroed out before the aggregate is
   // copied into it, we don't have to emit any zeros here.
-  if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(T))
+  if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(type))
     return;
   
-  if (!CGF.hasAggregateLLVMType(T)) {
+  if (!CGF.hasAggregateLLVMType(type)) {
     // For non-aggregates, we can store zero
-    llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T));
-    CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T);
+    llvm::Value *null = llvm::Constant::getNullValue(CGF.ConvertType(type));
+    CGF.EmitStoreThroughLValue(RValue::get(null), lv, type);
   } else {
     // There's a potential optimization opportunity in combining
     // memsets; that would be easy for arrays, but relatively
     // difficult for structures with the current code.
-    CGF.EmitNullInitialization(LV.getAddress(), T);
+    CGF.EmitNullInitialization(lv.getAddress(), lv.getType());
   }
 }
 
@@ -667,11 +667,11 @@
       LValue LV = CGF.MakeAddrLValue(NextVal, ElementType);
       
       if (i < NumInitElements)
-        EmitInitializationToLValue(E->getInit(i), LV, ElementType);
+        EmitInitializationToLValue(E->getInit(i), LV);
       else if (Expr *filler = E->getArrayFiller())
-        EmitInitializationToLValue(filler, LV, ElementType);
+        EmitInitializationToLValue(filler, LV);
       else
-        EmitNullInitializationToLValue(LV, ElementType);
+        EmitNullInitializationToLValue(LV);
       
       // If the GEP didn't get used because of a dead zero init or something
       // else, clean it up for -O0 builds and general tidiness.
@@ -715,10 +715,10 @@
     LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
     if (NumInitElements) {
       // Store the initializer into the field
-      EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType());
+      EmitInitializationToLValue(E->getInit(0), FieldLoc);
     } else {
       // Default-initialize to null.
-      EmitNullInitializationToLValue(FieldLoc, Field->getType());
+      EmitNullInitializationToLValue(FieldLoc);
     }
 
     return;
@@ -749,11 +749,10 @@
     
     if (CurInitVal < NumInitElements) {
       // Store the initializer into the field.
-      EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
-                                 Field->getType());
+      EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc);
     } else {
       // We're out of initalizers; default-initialize to null
-      EmitNullInitializationToLValue(FieldLoc, Field->getType());
+      EmitNullInitializationToLValue(FieldLoc);
     }
     
     // If the GEP didn't get used because of a dead zero init or something

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed Jun 15 23:16:24 2011
@@ -707,9 +707,9 @@
 
   unsigned Alignment =
     CGF.getContext().getTypeAlignInChars(AllocType).getQuantity();
-  if (!CGF.hasAggregateLLVMType(AllocType)) 
-    CGF.EmitScalarInit(Init, 0, NewPtr, false, AllocType.isVolatileQualified(),
-                       Alignment, AllocType);
+  if (!CGF.hasAggregateLLVMType(AllocType))
+    CGF.EmitScalarInit(Init, 0, CGF.MakeAddrLValue(NewPtr, AllocType, Alignment),
+                       false);
   else if (AllocType->isAnyComplexType())
     CGF.EmitComplexExprIntoAddr(Init, NewPtr, 
                                 AllocType.isVolatileQualified());

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp Wed Jun 15 23:16:24 2011
@@ -134,7 +134,7 @@
                              ContainingTypeSize, ContainingTypeAlign));
 
   return LValue::MakeBitfield(V, *Info,
-                              IvarTy.getCVRQualifiers() | CVRQualifiers);
+                              IvarTy.withCVRQualifiers(CVRQualifiers));
 }
 
 namespace {

Modified: cfe/trunk/lib/CodeGen/CGValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGValue.h?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGValue.h (original)
+++ cfe/trunk/lib/CodeGen/CGValue.h Wed Jun 15 23:16:24 2011
@@ -126,6 +126,8 @@
     const ObjCPropertyRefExpr *PropertyRefExpr;
   };
 
+  QualType Type;
+
   // 'const' is unused here
   Qualifiers Quals;
 
@@ -154,8 +156,9 @@
   llvm::MDNode *TBAAInfo;
 
 private:
-  void Initialize(Qualifiers Quals, unsigned Alignment = 0,
+  void Initialize(QualType Type, Qualifiers Quals, unsigned Alignment = 0,
                   llvm::MDNode *TBAAInfo = 0) {
+    this->Type = Type;
     this->Quals = Quals;
     this->Alignment = Alignment;
     assert(this->Alignment == Alignment && "Alignment exceeds allowed max!");
@@ -180,6 +183,12 @@
     return Quals.getCVRQualifiers() & ~Qualifiers::Const;
   }
 
+  QualType getType() const { return Type; }
+
+  Qualifiers::ObjCLifetime getObjCLifetime() const {
+    return Quals.getObjCLifetime();
+  }
+
   bool isObjCIvar() const { return Ivar; }
   void setObjCIvar(bool Value) { Ivar = Value; }
 
@@ -201,6 +210,10 @@
   bool isObjCStrong() const {
     return Quals.getObjCGCAttr() == Qualifiers::Strong;
   }
+
+  bool isVolatile() const {
+    return Quals.hasVolatile();
+  }
   
   Expr *getBaseIvarExp() const { return BaseIvarExp; }
   void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
@@ -217,6 +230,10 @@
 
   // simple lvalue
   llvm::Value *getAddress() const { assert(isSimple()); return V; }
+  void setAddress(llvm::Value *address) {
+    assert(isSimple());
+    V = address;
+  }
 
   // vector elt lvalue
   llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
@@ -249,36 +266,36 @@
     return PropertyRefExpr;
   }
 
-  static LValue MakeAddr(llvm::Value *V, QualType T, unsigned Alignment,
-                         ASTContext &Context,
+  static LValue MakeAddr(llvm::Value *address, QualType type,
+                         unsigned alignment, ASTContext &Context,
                          llvm::MDNode *TBAAInfo = 0) {
-    Qualifiers Quals = T.getQualifiers();
-    Quals.setObjCGCAttr(Context.getObjCGCAttrKind(T));
+    Qualifiers qs = type.getQualifiers();
+    qs.setObjCGCAttr(Context.getObjCGCAttrKind(type));
 
     LValue R;
     R.LVType = Simple;
-    R.V = V;
-    R.Initialize(Quals, Alignment, TBAAInfo);
+    R.V = address;
+    R.Initialize(type, qs, alignment, TBAAInfo);
     return R;
   }
 
   static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
-                              unsigned CVR) {
+                              QualType type) {
     LValue R;
     R.LVType = VectorElt;
     R.V = Vec;
     R.VectorIdx = Idx;
-    R.Initialize(Qualifiers::fromCVRMask(CVR));
+    R.Initialize(type, type.getQualifiers());
     return R;
   }
 
   static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
-                                 unsigned CVR) {
+                                 QualType type) {
     LValue R;
     R.LVType = ExtVectorElt;
     R.V = Vec;
     R.VectorElts = Elts;
-    R.Initialize(Qualifiers::fromCVRMask(CVR));
+    R.Initialize(type, type.getQualifiers());
     return R;
   }
 
@@ -288,13 +305,14 @@
   /// bit-field.
   /// \param Info - The information describing how to perform the bit-field
   /// access.
-  static LValue MakeBitfield(llvm::Value *BaseValue, const CGBitFieldInfo &Info,
-                             unsigned CVR) {
+  static LValue MakeBitfield(llvm::Value *BaseValue,
+                             const CGBitFieldInfo &Info,
+                             QualType type) {
     LValue R;
     R.LVType = BitField;
     R.V = BaseValue;
     R.BitFieldInfo = &Info;
-    R.Initialize(Qualifiers::fromCVRMask(CVR));
+    R.Initialize(type, type.getQualifiers());
     return R;
   }
 
@@ -307,7 +325,7 @@
     R.LVType = PropertyRef;
     R.V = Base;
     R.PropertyRefExpr = E;
-    R.Initialize(Qualifiers());
+    R.Initialize(QualType(), Qualifiers());
     return R;
   }
 };
@@ -367,9 +385,10 @@
   }
 
   static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged,
-                                bool RequiresGCollection = false) {
+                                bool RequiresGCollection = false,
+                                bool IsZeroed = false) {
     return forAddr(LV.getAddress(), LV.getQuals(),
-                   LifetimeExternallyManaged, RequiresGCollection);
+                   LifetimeExternallyManaged, RequiresGCollection, IsZeroed);
   }
 
   bool isLifetimeExternallyManaged() const {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Jun 15 23:16:24 2011
@@ -1397,8 +1397,7 @@
   /// EmitExprAsInit - Emits the code necessary to initialize a
   /// location in memory with the given initializer.
   void EmitExprAsInit(const Expr *init, const ValueDecl *D,
-                      llvm::Value *loc, CharUnits alignment,
-                      bool capturedByInit);
+                      LValue lvalue, bool capturedByInit);
 
   /// EmitAggregateCopy - Emit an aggrate copy.
   ///
@@ -1597,8 +1596,7 @@
   void EmitVarDecl(const VarDecl &D);
 
   void EmitScalarInit(const Expr *init, const ValueDecl *D,
-                      llvm::Value *addr, bool capturedByInit,
-                      bool isVolatile, unsigned alignment, QualType type);
+                      LValue lvalue, bool capturedByInit);
 
   typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D,
                              llvm::Value *Address);
@@ -1791,6 +1789,7 @@
   llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
                                 unsigned Alignment, QualType Ty,
                                 llvm::MDNode *TBAAInfo = 0);
+  llvm::Value *EmitLoadOfScalar(LValue lvalue);
 
   /// EmitStoreOfScalar - Store a scalar value to an address, taking
   /// care to appropriately convert from the memory representation to
@@ -1798,6 +1797,7 @@
   void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
                          bool Volatile, unsigned Alignment, QualType Ty,
                          llvm::MDNode *TBAAInfo = 0);
+  void EmitStoreOfScalar(llvm::Value *value, LValue lvalue);
 
   /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
   /// this method emits the address of the lvalue, then loads the result as an

Added: cfe/trunk/test/CodeGenObjCXX/gc.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/gc.mm?rev=133144&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/gc.mm (added)
+++ cfe/trunk/test/CodeGenObjCXX/gc.mm Wed Jun 15 23:16:24 2011
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fobjc-gc -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+namespace test0 {
+  extern id x;
+
+  struct A {
+    id x;
+    A();
+  };
+  A::A() : x(test0::x) {}
+
+// CHECK:    define void @_ZN5test01AC2Ev(
+// CHECK:      [[THIS:%.*]] = alloca [[TEST0:%.*]]*, align 8
+// CHECK-NEXT: store 
+// CHECK-NEXT: [[T0:%.*]] = load [[TEST0]]** [[THIS]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[TEST0]]* [[T0]], i32 0, i32 0
+// CHECK-NEXT: [[T2:%.*]] = load i8** @_ZN5test01xE
+// CHECK-NEXT: call i8* @objc_assign_strongCast(i8* [[T2]], i8** [[T1]])
+// CHECK-NEXT: ret void
+}





More information about the cfe-commits mailing list