From: Ken Dyck Date: Fri, 15 Jan 2010 12:37:54 +0000 (+0000) Subject: Convert the type of the LValue offset variable in APValue to CharUnits, moving X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a73058324197b7bdfd19307965954f626e26199d;p=clang Convert the type of the LValue offset variable in APValue to CharUnits, moving the LValue-related methods of APValue out of line to avoid header file leaching. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93512 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index 94d258d9e4..9d4bff893f 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -18,6 +18,7 @@ #include "llvm/ADT/APFloat.h" namespace clang { + class CharUnits; class Expr; /// APValue - This class implements a discriminated union of [uninitialized] @@ -47,10 +48,6 @@ private: ComplexAPFloat() : Real(0.0), Imag(0.0) {} }; - struct LV { - Expr* Base; - uint64_t Offset; - }; struct Vec { APValue *Elts; unsigned NumElts; @@ -88,9 +85,11 @@ public: APValue(const APValue &RHS) : Kind(Uninitialized) { *this = RHS; } - APValue(Expr* B, uint64_t O) : Kind(Uninitialized) { + APValue(Expr* B, const CharUnits &O) : Kind(Uninitialized) { MakeLValue(); setLValue(B, O); } + APValue(Expr* B); + ~APValue() { MakeUninit(); } @@ -164,14 +163,8 @@ public: return const_cast(this)->getComplexFloatImag(); } - Expr* getLValueBase() const { - assert(isLValue() && "Invalid accessor"); - return ((const LV*)(const void*)Data)->Base; - } - uint64_t getLValueOffset() const { - assert(isLValue() && "Invalid accessor"); - return ((const LV*)(const void*)Data)->Offset; - } + Expr* getLValueBase() const; + CharUnits getLValueOffset() const; void setInt(const APSInt &I) { assert(isInt() && "Invalid accessor"); @@ -202,11 +195,7 @@ public: ((ComplexAPFloat*)(char*)Data)->Real = R; ((ComplexAPFloat*)(char*)Data)->Imag = I; } - void setLValue(Expr *B, uint64_t O) { - assert(isLValue() && "Invalid accessor"); - ((LV*)(char*)Data)->Base = B; - ((LV*)(char*)Data)->Offset = O; - } + void setLValue(Expr *B, const CharUnits &O); const APValue &operator=(const APValue &RHS); @@ -237,11 +226,7 @@ private: new ((void*)(char*)Data) ComplexAPFloat(); Kind = ComplexFloat; } - void MakeLValue() { - assert(isUninit() && "Bad state change"); - new ((void*)(char*)Data) LV(); - Kind = LValue; - } + void MakeLValue(); }; inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) { diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp index 772a884c90..50a6e0a50d 100644 --- a/lib/AST/APValue.cpp +++ b/lib/AST/APValue.cpp @@ -12,9 +12,20 @@ //===----------------------------------------------------------------------===// #include "clang/AST/APValue.h" +#include "clang/AST/CharUnits.h" #include "llvm/Support/raw_ostream.h" using namespace clang; +namespace { + struct LV { + Expr* Base; + CharUnits Offset; + }; +} + +APValue::APValue(Expr* B) : Kind(Uninitialized) { + MakeLValue(); setLValue(B, CharUnits::Zero()); +} const APValue &APValue::operator=(const APValue &RHS) { if (Kind != RHS.Kind) { @@ -106,3 +117,25 @@ void APValue::print(llvm::raw_ostream &OS) const { } } +Expr* APValue::getLValueBase() const { + assert(isLValue() && "Invalid accessor"); + return ((const LV*)(const void*)Data)->Base; +} + +CharUnits APValue::getLValueOffset() const { + assert(isLValue() && "Invalid accessor"); + return ((const LV*)(const void*)Data)->Offset; +} + +void APValue::setLValue(Expr *B, const CharUnits &O) { + assert(isLValue() && "Invalid accessor"); + ((LV*)(char*)Data)->Base = B; + ((LV*)(char*)Data)->Offset = O; +} + +void APValue::MakeLValue() { + assert(isUninit() && "Bad state change"); + new ((void*)(char*)Data) LV(); + Kind = LValue; +} + diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index c40feb4c28..dfff2099cb 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -70,7 +70,7 @@ static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info); static bool EvalPointerValueAsBool(APValue& Value, bool& Result) { // FIXME: Is this accurate for all kinds of bases? If not, what would // the check look like? - Result = Value.getLValueBase() || Value.getLValueOffset(); + Result = Value.getLValueBase() || !Value.getLValueOffset().isZero(); return true; } @@ -224,11 +224,11 @@ public: APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } APValue VisitDeclRefExpr(DeclRefExpr *E); - APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E, 0); } + APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E); } APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E); APValue VisitMemberExpr(MemberExpr *E); - APValue VisitStringLiteral(StringLiteral *E) { return APValue(E, 0); } - APValue VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return APValue(E, 0); } + APValue VisitStringLiteral(StringLiteral *E) { return APValue(E); } + APValue VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return APValue(E); } APValue VisitArraySubscriptExpr(ArraySubscriptExpr *E); APValue VisitUnaryDeref(UnaryOperator *E); APValue VisitUnaryExtension(const UnaryOperator *E) @@ -256,12 +256,12 @@ static bool EvaluateLValue(const Expr* E, APValue& Result, EvalInfo &Info) { APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) { if (isa(E->getDecl())) { - return APValue(E, 0); + return APValue(E); } else if (VarDecl* VD = dyn_cast(E->getDecl())) { if (!Info.AnyLValue && !VD->hasGlobalStorage()) return APValue(); if (!VD->getType()->isReferenceType()) - return APValue(E, 0); + return APValue(E); // FIXME: Check whether VD might be overridden! const VarDecl *Def = 0; if (const Expr *Init = VD->getDefinition(Def)) @@ -274,7 +274,7 @@ APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) { APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { if (!Info.AnyLValue && !E->isFileScope()) return APValue(); - return APValue(E, 0); + return APValue(E); } APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) { @@ -311,7 +311,8 @@ APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) { } result.setLValue(result.getLValueBase(), - result.getLValueOffset() + RL.getFieldOffset(i) / 8); + result.getLValueOffset() + + CharUnits::fromQuantity(RL.getFieldOffset(i) / 8)); return result; } @@ -330,7 +331,7 @@ APValue LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { CharUnits Offset = Index.getSExtValue() * ElementSize; Result.setLValue(Result.getLValueBase(), - Result.getLValueOffset() + Offset.getQuantity()); + Result.getLValueOffset() + Offset); return Result; } @@ -365,22 +366,22 @@ public: { return Visit(E->getSubExpr()); } APValue VisitUnaryAddrOf(const UnaryOperator *E); APValue VisitObjCStringLiteral(ObjCStringLiteral *E) - { return APValue(E, 0); } + { return APValue(E); } APValue VisitAddrLabelExpr(AddrLabelExpr *E) - { return APValue(E, 0); } + { return APValue(E); } APValue VisitCallExpr(CallExpr *E); APValue VisitBlockExpr(BlockExpr *E) { if (!E->hasBlockDeclRefExprs()) - return APValue(E, 0); + return APValue(E); return APValue(); } APValue VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) - { return APValue((Expr*)0, 0); } + { return APValue((Expr*)0); } APValue VisitConditionalOperator(ConditionalOperator *E); APValue VisitChooseExpr(ChooseExpr *E) { return Visit(E->getChosenSubExpr(Info.Ctx)); } APValue VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) - { return APValue((Expr*)0, 0); } + { return APValue((Expr*)0); } // FIXME: Missing: @protocol, @selector }; } // end anonymous namespace @@ -419,14 +420,14 @@ APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { else SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType); - CharUnits Offset = CharUnits::fromQuantity(ResultLValue.getLValueOffset()); + CharUnits Offset = ResultLValue.getLValueOffset(); if (E->getOpcode() == BinaryOperator::Add) Offset += AdditionalOffset.getLimitedValue() * SizeOfPointee; else Offset -= AdditionalOffset.getLimitedValue() * SizeOfPointee; - return APValue(ResultLValue.getLValueBase(), Offset.getQuantity()); + return APValue(ResultLValue.getLValueBase(), Offset); } APValue PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) { @@ -461,7 +462,8 @@ APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) { if (Result.isInt()) { Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType())); - return APValue(0, Result.getInt().getZExtValue()); + return APValue(0, + CharUnits::fromQuantity(Result.getInt().getZExtValue())); } // Cast is of an lvalue, no need to change value. @@ -483,7 +485,8 @@ APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) { if (Result.isInt()) { Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType())); - return APValue(0, Result.getInt().getZExtValue()); + return APValue(0, + CharUnits::fromQuantity(Result.getInt().getZExtValue())); } // Cast is of an lvalue, no need to change value. @@ -504,7 +507,7 @@ APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) { APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) { if (E->isBuiltinCall(Info.Ctx) == Builtin::BI__builtin___CFStringMakeConstantString) - return APValue(E, 0); + return APValue(E); return APValue(); } @@ -979,8 +982,7 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { && !VD->getType()->isVariablyModifiedType() && !VD->getType()->isDependentType()) { CharUnits Size = Info.Ctx.getTypeSizeInChars(VD->getType()); - CharUnits Offset = - CharUnits::fromQuantity(Base.Val.getLValueOffset()); + CharUnits Offset = Base.Val.getLValueOffset(); if (!Offset.isNegative() && Offset <= Size) Size -= Offset; else @@ -1154,7 +1156,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { if (LHSValue.getLValueBase()) { if (!E->isEqualityOp()) return false; - if (RHSValue.getLValueBase() || RHSValue.getLValueOffset()) + if (RHSValue.getLValueBase() || !RHSValue.getLValueOffset().isZero()) return false; bool bres; if (!EvalPointerValueAsBool(LHSValue, bres)) @@ -1163,7 +1165,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { } else if (RHSValue.getLValueBase()) { if (!E->isEqualityOp()) return false; - if (LHSValue.getLValueBase() || LHSValue.getLValueOffset()) + if (LHSValue.getLValueBase() || !LHSValue.getLValueOffset().isZero()) return false; bool bres; if (!EvalPointerValueAsBool(RHSValue, bres)) @@ -1175,11 +1177,13 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { const QualType Type = E->getLHS()->getType(); const QualType ElementType = Type->getAs()->getPointeeType(); - uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset(); + CharUnits ElementSize = CharUnits::One(); if (!ElementType->isVoidType() && !ElementType->isFunctionType()) - D /= Info.Ctx.getTypeSizeInChars(ElementType).getQuantity(); + ElementSize = Info.Ctx.getTypeSizeInChars(ElementType); - return Success(D, E); + CharUnits Diff = LHSValue.getLValueOffset() - + RHSValue.getLValueOffset(); + return Success(Diff / ElementSize, E); } bool Result; if (E->getOpcode() == BinaryOperator::EQ) { @@ -1207,21 +1211,23 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { // Handle cases like (unsigned long)&a + 4. if (E->isAdditiveOp() && Result.isLValue() && RHSVal.isInt()) { - uint64_t offset = Result.getLValueOffset(); + CharUnits Offset = Result.getLValueOffset(); + CharUnits AdditionalOffset = CharUnits::fromQuantity( + RHSVal.getInt().getZExtValue()); if (E->getOpcode() == BinaryOperator::Add) - offset += RHSVal.getInt().getZExtValue(); + Offset += AdditionalOffset; else - offset -= RHSVal.getInt().getZExtValue(); - Result = APValue(Result.getLValueBase(), offset); + Offset -= AdditionalOffset; + Result = APValue(Result.getLValueBase(), Offset); return true; } // Handle cases like 4 + (unsigned long)&a if (E->getOpcode() == BinaryOperator::Add && RHSVal.isLValue() && Result.isInt()) { - uint64_t offset = RHSVal.getLValueOffset(); - offset += Result.getInt().getZExtValue(); - Result = APValue(RHSVal.getLValueBase(), offset); + CharUnits Offset = RHSVal.getLValueOffset(); + Offset += CharUnits::fromQuantity(Result.getInt().getZExtValue()); + Result = APValue(RHSVal.getLValueBase(), Offset); return true; } @@ -1351,7 +1357,7 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { return false; if (LV.getLValueBase()) return false; - return Success(LV.getLValueOffset(), E); + return Success(LV.getLValueOffset().getQuantity(), E); } if (E->getOpcode() == UnaryOperator::LNot) { @@ -1434,7 +1440,8 @@ bool IntExprEvaluator::VisitCastExpr(CastExpr *E) { return true; } - APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset(), SrcType); + APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(), + SrcType); return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E); } diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index d1330e066d..dec06e2953 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -810,7 +810,7 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E, const llvm::Type *DestTy = getTypes().ConvertTypeForMem(DestType); llvm::Constant *Offset = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - Result.Val.getLValueOffset()); + Result.Val.getLValueOffset().getQuantity()); llvm::Constant *C; if (const Expr *LVBase = Result.Val.getLValueBase()) {