From: John McCall Date: Thu, 25 Aug 2011 20:40:09 +0000 (+0000) Subject: Use stronger typing for the flags on AggValueSlot and require X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c2349be2d11143a2e59a167fd43362a3bf4585e;p=clang Use stronger typing for the flags on AggValueSlot and require creators to tell us whether something needs GC barriers. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138581 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 1acbb0886a..8e46fcd3ed 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -398,8 +398,10 @@ static void EmitBaseInitializer(CodeGenFunction &CGF, BaseClassDecl, isBaseVirtual); - AggValueSlot AggSlot = AggValueSlot::forAddr(V, Qualifiers(), - /*Lifetime*/ true); + AggValueSlot AggSlot = + AggValueSlot::forAddr(V, Qualifiers(), + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers); CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); @@ -436,8 +438,10 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF, CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), Dest, LHS.isVolatileQualified()); } else { - AggValueSlot Slot = AggValueSlot::forAddr(Dest, LHS.getQuals(), - /*Lifetime*/ true); + AggValueSlot Slot = + AggValueSlot::forAddr(Dest, LHS.getQuals(), + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers); CGF.EmitAggExpr(MemberInit->getInit(), Slot); } @@ -1324,7 +1328,9 @@ CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor llvm::Value *ThisPtr = LoadCXXThis(); AggValueSlot AggSlot = - AggValueSlot::forAddr(ThisPtr, Qualifiers(), /*Lifetime*/ true); + AggValueSlot::forAddr(ThisPtr, Qualifiers(), + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers); EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 8fcec30c6a..609542c9c6 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -1044,7 +1044,9 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init, StoreComplexToAddr(complex, lvalue.getAddress(), lvalue.isVolatile()); } else { // TODO: how can we delay here if D is captured by its initializer? - EmitAggExpr(init, AggValueSlot::forLValue(lvalue, true, false)); + EmitAggExpr(init, AggValueSlot::forLValue(lvalue, + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers)); } } diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 85f0e35dc7..f4bed79527 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -46,7 +46,8 @@ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, } else if (type->isAnyComplexType()) { CGF.EmitComplexExprIntoAddr(Init, DeclPtr, lv.isVolatile()); } else { - CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv, true)); + CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers)); } } diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 61c1739eab..263ac63ccc 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -1032,8 +1032,9 @@ static void InitCatchParam(CodeGenFunction &CGF, CGF.EHStack.pushTerminate(); // Perform the copy construction. - CGF.EmitAggExpr(copyExpr, AggValueSlot::forAddr(ParamAddr, Qualifiers(), - false)); + CGF.EmitAggExpr(copyExpr, AggValueSlot::forAddr(ParamAddr, Qualifiers(), + AggValueSlot::IsNotDestructed, + AggValueSlot::DoesNotNeedGCBarriers)); // Leave the terminate scope. CGF.EHStack.popTerminate(); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 7fcd404713..da892c7715 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -136,7 +136,9 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E, if (E->getType()->isAnyComplexType()) EmitComplexExprIntoAddr(E, Location, Quals.hasVolatile()); else if (hasAggregateLLVMType(E->getType())) - EmitAggExpr(E, AggValueSlot::forAddr(Location, Quals, IsInit)); + EmitAggExpr(E, AggValueSlot::forAddr(Location, Quals, + AggValueSlot::IsDestructed_t(IsInit), + AggValueSlot::DoesNotNeedGCBarriers)); else { RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false)); LValue LV = MakeAddrLValue(Location, E->getType()); @@ -354,8 +356,11 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, !E->getType()->isAnyComplexType()) { ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(), InitializedDecl); + AggValueSlot::IsDestructed_t isDestructed + = AggValueSlot::IsDestructed_t(InitializedDecl != 0); AggSlot = AggValueSlot::forAddr(ReferenceTemporary, Qualifiers(), - InitializedDecl != 0); + isDestructed, + AggValueSlot::DoesNotNeedGCBarriers); } if (InitializedDecl) { diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 245640bfcf..4a151fcfb8 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -71,6 +71,12 @@ public: void EmitGCMove(const Expr *E, RValue Src); + AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) { + if (CGF.getLangOptions().getGCMode() && TypeRequiresGCollection(T)) + return AggValueSlot::NeedsGCBarriers; + return AggValueSlot::DoesNotNeedGCBarriers; + } + bool TypeRequiresGCollection(QualType T); //===--------------------------------------------------------------------===// @@ -426,10 +432,8 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { // as it may change the 'forwarding' field via call to Block_copy. LValue RHS = CGF.EmitLValue(E->getRHS()); LValue LHS = CGF.EmitLValue(E->getLHS()); - bool GCollection = false; - if (CGF.getContext().getLangOptions().getGCMode()) - GCollection = TypeRequiresGCollection(E->getLHS()->getType()); - Dest = AggValueSlot::forLValue(LHS, true, GCollection); + Dest = AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, + needsGC(E->getLHS()->getType())); EmitFinalDestCopy(E, RHS, true); return; } @@ -451,13 +455,10 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { } CGF.EmitStoreThroughPropertyRefLValue(Src, LHS); } else { - bool GCollection = false; - if (CGF.getContext().getLangOptions().getGCMode()) - GCollection = TypeRequiresGCollection(E->getLHS()->getType()); - // Codegen the RHS so that it stores directly into the LHS. - AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true, - GCollection); + AggValueSlot LHSSlot = + AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, + needsGC(E->getLHS()->getType())); CGF.EmitAggExpr(E->getRHS(), LHSSlot, false); EmitFinalDestCopy(E, LHS, true); } @@ -596,7 +597,9 @@ AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { } else if (type->isAnyComplexType()) { CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false); } else if (CGF.hasAggregateLLVMType(type)) { - CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV, true, false, + CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV, + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers, Dest.isZeroed())); } else if (LV.isSimple()) { CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false); @@ -1036,7 +1039,8 @@ LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) { assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!"); llvm::Value *Temp = CreateMemTemp(E->getType()); LValue LV = MakeAddrLValue(Temp, E->getType()); - EmitAggExpr(E, AggValueSlot::forLValue(LV, false)); + EmitAggExpr(E, AggValueSlot::forLValue(LV, AggValueSlot::IsNotDestructed, + AggValueSlot::DoesNotNeedGCBarriers)); return LV; } diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 738aac2595..cdab82eaab 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -703,7 +703,9 @@ static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const CXXNewExpr *E, AllocType.isVolatileQualified()); else { AggValueSlot Slot - = AggValueSlot::forAddr(NewPtr, AllocType.getQualifiers(), true); + = AggValueSlot::forAddr(NewPtr, AllocType.getQualifiers(), + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers); CGF.EmitAggExpr(Init, Slot); } } diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 565cf3a5b2..83a42fb9c5 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -818,7 +818,9 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, ObjCIvarDecl *Ivar = cast(Field); LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0); - EmitAggExpr(IvarInit->getInit(), AggValueSlot::forLValue(LV, true)); + EmitAggExpr(IvarInit->getInit(), + AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers)); } // constructor returns 'self'. CodeGenTypes &Types = CGM.getTypes(); diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index e200305c0d..b7b127fc50 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -784,7 +784,9 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { } else if (RV->getType()->isAnyComplexType()) { EmitComplexExprIntoAddr(RV, ReturnValue, false); } else { - EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Qualifiers(), true)); + EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Qualifiers(), + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers)); } EmitBranchThroughCleanup(ReturnBlock); diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index 4d0b8410e4..dda9693f42 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -337,62 +337,63 @@ class AggValueSlot { // Qualifiers Qualifiers Quals; - + // Associated flags. bool LifetimeFlag : 1; bool RequiresGCollection : 1; - /// IsZeroed - This is set to true if the destination is known to be zero + /// ZeroedFlag - This is set to true if the destination is known to be zero /// before the assignment into it. This means that zero fields don't need to /// be set. - bool IsZeroed : 1; + bool ZeroedFlag : 1; public: + enum IsZeroed_t { IsNotZeroed, IsZeroed }; + enum IsDestructed_t { IsNotDestructed, IsDestructed }; + enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; + /// ignored - Returns an aggregate value slot indicating that the /// aggregate value is being ignored. static AggValueSlot ignored() { AggValueSlot AV; AV.Addr = 0; AV.Quals = Qualifiers(); - AV.LifetimeFlag = AV.RequiresGCollection = AV.IsZeroed =0; + AV.LifetimeFlag = AV.RequiresGCollection = AV.ZeroedFlag = 0; return AV; } /// forAddr - Make a slot for an aggregate value. /// - /// \param Volatile - true if the slot should be volatile-initialized - /// - /// \param Qualifiers - The qualifiers that dictate how the slot - /// should be initialied. Only 'volatile' and the Objective-C - /// lifetime qualifiers matter. + /// \param quals - The qualifiers that dictate how the slot should + /// be initialied. Only 'volatile' and the Objective-C lifetime + /// qualifiers matter. /// - /// \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 - /// \param RequiresGCollection - true if the slot is located + /// \param isDestructed - true if something else is responsible + /// for calling destructors on this object + /// \param needsGC - true if the slot is potentially located /// somewhere that ObjC GC calls should be emitted for - static AggValueSlot forAddr(llvm::Value *Addr, Qualifiers Quals, - bool LifetimeExternallyManaged, - bool RequiresGCollection = false, - bool IsZeroed = false) { + static AggValueSlot forAddr(llvm::Value *addr, Qualifiers quals, + IsDestructed_t isDestructed, + NeedsGCBarriers_t needsGC, + IsZeroed_t isZeroed = IsNotZeroed) { AggValueSlot AV; - AV.Addr = Addr; - AV.Quals = Quals; - AV.LifetimeFlag = LifetimeExternallyManaged; - AV.RequiresGCollection = RequiresGCollection; - AV.IsZeroed = IsZeroed; + AV.Addr = addr; + AV.Quals = quals; + AV.LifetimeFlag = isDestructed; + AV.RequiresGCollection = needsGC; + AV.ZeroedFlag = isZeroed; return AV; } - static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged, - bool RequiresGCollection = false, - bool IsZeroed = false) { + static AggValueSlot forLValue(LValue LV, IsDestructed_t isDestructed, + NeedsGCBarriers_t needsGC, + IsZeroed_t isZeroed = IsNotZeroed) { return forAddr(LV.getAddress(), LV.getQuals(), - LifetimeExternallyManaged, RequiresGCollection, IsZeroed); + isDestructed, needsGC, isZeroed); } - bool isLifetimeExternallyManaged() const { - return LifetimeFlag; + IsDestructed_t isLifetimeExternallyManaged() const { + return IsDestructed_t(LifetimeFlag); } void setLifetimeExternallyManaged(bool Managed = true) { LifetimeFlag = Managed; @@ -408,8 +409,8 @@ public: return Quals.getObjCLifetime(); } - bool requiresGCollection() const { - return RequiresGCollection; + NeedsGCBarriers_t requiresGCollection() const { + return NeedsGCBarriers_t(RequiresGCollection); } llvm::Value *getAddr() const { @@ -424,9 +425,9 @@ public: return RValue::getAggregate(getAddr(), isVolatile()); } - void setZeroed(bool V = true) { IsZeroed = V; } - bool isZeroed() const { - return IsZeroed; + void setZeroed(bool V = true) { ZeroedFlag = V; } + IsZeroed_t isZeroed() const { + return IsZeroed_t(ZeroedFlag); } }; diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 381842097f..2d47301ec5 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1465,7 +1465,8 @@ public: /// aggregate type. AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp") { return AggValueSlot::forAddr(CreateMemTemp(T, Name), T.getQualifiers(), - false); + AggValueSlot::IsNotDestructed, + AggValueSlot::DoesNotNeedGCBarriers); } /// Emit a cast to void* in the appropriate address space.