aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/APValue.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-11-07 09:22:26 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-11-07 09:22:26 +0000
commitcc5d4f637cdf83adc174b96d2bfe27cef1cf0f36 (patch)
treedc9ff424a78517434c2b6ba0eb90c8f8ddc8f405 /lib/AST/APValue.cpp
parent07643086c6460095855573902d66aae1b08a6182 (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.cpp45
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;
+}