diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-11-07 09:22:26 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-11-07 09:22:26 +0000 |
commit | cc5d4f637cdf83adc174b96d2bfe27cef1cf0f36 (patch) | |
tree | dc9ff424a78517434c2b6ba0eb90c8f8ddc8f405 /lib/AST/APValue.cpp | |
parent | 07643086c6460095855573902d66aae1b08a6182 (diff) |
Constant expression evaluation: support for arrays.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143922 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/APValue.cpp')
-rw-r--r-- | lib/AST/APValue.cpp | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp index e2f7c61937..af34642bea 100644 --- a/lib/AST/APValue.cpp +++ b/lib/AST/APValue.cpp @@ -55,6 +55,13 @@ struct APValue::LV : LVBase { } }; +// FIXME: Reduce the malloc traffic here. + +APValue::Arr::Arr(unsigned NumElts, unsigned Size) : + Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]), + NumElts(NumElts), ArrSize(Size) {} +APValue::Arr::~Arr() { delete [] Elts; } + APValue::APValue(const Expr* B) : Kind(Uninitialized) { MakeLValue(); setLValue(B, CharUnits::Zero(), ArrayRef<LValuePathEntry>()); @@ -75,6 +82,8 @@ const APValue &APValue::operator=(const APValue &RHS) { MakeComplexFloat(); else if (RHS.isLValue()) MakeLValue(); + else if (RHS.isArray()) + MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize()); } if (isInt()) setInt(RHS.getInt()); @@ -92,6 +101,11 @@ const APValue &APValue::operator=(const APValue &RHS) { setLValue(RHS.getLValueBase(), RHS.getLValueOffset(),RHS.getLValuePath()); else setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath()); + } else if (isArray()) { + for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I) + getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I); + if (RHS.hasArrayFiller()) + getArrayFiller() = RHS.getArrayFiller(); } return *this; } @@ -107,9 +121,10 @@ void APValue::MakeUninit() { ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt(); else if (Kind == ComplexFloat) ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat(); - else if (Kind == LValue) { + else if (Kind == LValue) ((LV*)(char*)Data)->~LV(); - } + else if (Kind == Array) + ((Arr*)(char*)Data)->~Arr(); Kind = Uninitialized; } @@ -149,9 +164,20 @@ void APValue::print(raw_ostream &OS) const { case ComplexFloat: OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) << ", " << GetApproxValue(getComplexFloatImag()); + return; case LValue: OS << "LValue: <todo>"; return; + case Array: + OS << "Array: "; + for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) { + OS << getArrayInitializedElt(I); + if (I != getArraySize() - 1) OS << ", "; + } + if (hasArrayFiller()) + OS << getArraySize() - getArrayInitializedElts() << " x " + << getArrayFiller(); + return; } } @@ -187,6 +213,15 @@ static void WriteShortAPValueToStream(raw_ostream& Out, case APValue::LValue: Out << "LValue: <todo>"; break; + case APValue::Array: + Out << '{'; + if (unsigned N = V.getArrayInitializedElts()) { + Out << V.getArrayInitializedElt(0); + for (unsigned I = 1; I != N; ++I) + Out << ", " << V.getArrayInitializedElt(I); + } + Out << '}'; + break; } } @@ -244,3 +279,9 @@ void APValue::MakeLValue() { new ((void*)(char*)Data) LV(); Kind = LValue; } + +void APValue::MakeArray(unsigned InitElts, unsigned Size) { + assert(isUninit() && "Bad state change"); + new ((void*)(char*)Data) Arr(InitElts, Size); + Kind = Array; +} |