blob: b99a66267cd6b46e24f605b17149c9e498ce9e00 [file] [log] [blame]
Chris Lattner64c34f12008-11-16 07:46:48 +00001//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the APValue class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/APValue.h"
Ken Dycka7305832010-01-15 12:37:54 +000015#include "clang/AST/CharUnits.h"
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +000016#include "clang/Basic/Diagnostic.h"
17#include "llvm/ADT/SmallString.h"
Chris Lattner64c34f12008-11-16 07:46:48 +000018#include "llvm/Support/raw_ostream.h"
David Blaikie9fe8c742011-09-23 05:35:21 +000019#include "llvm/Support/ErrorHandling.h"
Chris Lattner64c34f12008-11-16 07:46:48 +000020using namespace clang;
21
Ken Dycka7305832010-01-15 12:37:54 +000022namespace {
Richard Smith9a17a682011-11-07 05:07:52 +000023 struct LVBase {
Richard Smithe24f5fc2011-11-17 22:56:20 +000024 llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
Ken Dycka7305832010-01-15 12:37:54 +000025 CharUnits Offset;
Richard Smith9a17a682011-11-07 05:07:52 +000026 unsigned PathLength;
Ken Dycka7305832010-01-15 12:37:54 +000027 };
28}
29
Richard Smith9a17a682011-11-07 05:07:52 +000030struct APValue::LV : LVBase {
31 static const unsigned InlinePathSpace =
32 (MaxSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
33
34 /// Path - The sequence of base classes, fields and array indices to follow to
35 /// walk from Base to the subobject. When performing GCC-style folding, there
36 /// may not be such a path.
37 union {
38 LValuePathEntry Path[InlinePathSpace];
39 LValuePathEntry *PathPtr;
40 };
41
42 LV() { PathLength = (unsigned)-1; }
Richard Smithe24f5fc2011-11-17 22:56:20 +000043 ~LV() { resizePath(0); }
Richard Smith9a17a682011-11-07 05:07:52 +000044
Richard Smithe24f5fc2011-11-17 22:56:20 +000045 void resizePath(unsigned Length) {
46 if (Length == PathLength)
47 return;
48 if (hasPathPtr())
49 delete [] PathPtr;
50 PathLength = Length;
51 if (hasPathPtr())
52 PathPtr = new LValuePathEntry[Length];
Richard Smith9a17a682011-11-07 05:07:52 +000053 }
54
55 bool hasPath() const { return PathLength != (unsigned)-1; }
56 bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }
57
58 LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }
Richard Smith38dce9b2011-11-07 07:31:09 +000059 const LValuePathEntry *getPath() const {
60 return hasPathPtr() ? PathPtr : Path;
61 }
Richard Smith9a17a682011-11-07 05:07:52 +000062};
63
Richard Smithe24f5fc2011-11-17 22:56:20 +000064namespace {
65 struct MemberPointerBase {
66 llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
67 unsigned PathLength;
68 };
69}
70
71struct APValue::MemberPointerData : MemberPointerBase {
72 static const unsigned InlinePathSpace =
73 (MaxSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
74 typedef const CXXRecordDecl *PathElem;
75 union {
76 PathElem Path[InlinePathSpace];
77 PathElem *PathPtr;
78 };
79
80 MemberPointerData() { PathLength = 0; }
81 ~MemberPointerData() { resizePath(0); }
82
83 void resizePath(unsigned Length) {
84 if (Length == PathLength)
85 return;
86 if (hasPathPtr())
87 delete [] PathPtr;
88 PathLength = Length;
89 if (hasPathPtr())
90 PathPtr = new PathElem[Length];
91 }
92
93 bool hasPathPtr() const { return PathLength > InlinePathSpace; }
94
95 PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
96 const PathElem *getPath() const {
97 return hasPathPtr() ? PathPtr : Path;
98 }
99};
100
Richard Smithcc5d4f62011-11-07 09:22:26 +0000101// FIXME: Reduce the malloc traffic here.
102
103APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
104 Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
105 NumElts(NumElts), ArrSize(Size) {}
106APValue::Arr::~Arr() { delete [] Elts; }
107
Richard Smith180f4792011-11-10 06:34:14 +0000108APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
109 Elts(new APValue[NumBases+NumFields]),
110 NumBases(NumBases), NumFields(NumFields) {}
111APValue::StructData::~StructData() {
112 delete [] Elts;
113}
114
115APValue::UnionData::UnionData() : Field(0), Value(new APValue) {}
116APValue::UnionData::~UnionData () {
117 delete Value;
118}
119
Chris Lattner64c34f12008-11-16 07:46:48 +0000120const APValue &APValue::operator=(const APValue &RHS) {
Richard Smith180f4792011-11-10 06:34:14 +0000121 if (this == &RHS)
122 return *this;
Richard Smithe24f5fc2011-11-17 22:56:20 +0000123 if (Kind != RHS.Kind || Kind == Array || Kind == Struct ||
124 Kind == MemberPointer) {
Chris Lattner64c34f12008-11-16 07:46:48 +0000125 MakeUninit();
126 if (RHS.isInt())
127 MakeInt();
128 else if (RHS.isFloat())
129 MakeFloat();
Nate Begeman3d309f92009-01-18 01:01:34 +0000130 else if (RHS.isVector())
131 MakeVector();
Chris Lattner64c34f12008-11-16 07:46:48 +0000132 else if (RHS.isComplexInt())
133 MakeComplexInt();
134 else if (RHS.isComplexFloat())
135 MakeComplexFloat();
136 else if (RHS.isLValue())
137 MakeLValue();
Richard Smithcc5d4f62011-11-07 09:22:26 +0000138 else if (RHS.isArray())
139 MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
Richard Smith180f4792011-11-10 06:34:14 +0000140 else if (RHS.isStruct())
141 MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
142 else if (RHS.isUnion())
143 MakeUnion();
Richard Smithe24f5fc2011-11-17 22:56:20 +0000144 else if (RHS.isMemberPointer())
145 MakeMemberPointer(RHS.getMemberPointerDecl(),
146 RHS.isMemberPointerToDerivedMember(),
147 RHS.getMemberPointerPath());
Chris Lattner64c34f12008-11-16 07:46:48 +0000148 }
149 if (isInt())
150 setInt(RHS.getInt());
151 else if (isFloat())
152 setFloat(RHS.getFloat());
Nate Begeman3d309f92009-01-18 01:01:34 +0000153 else if (isVector())
Dan Gohmancb421fa2010-04-19 16:39:44 +0000154 setVector(((const Vec *)(const char *)RHS.Data)->Elts,
155 RHS.getVectorLength());
Chris Lattner64c34f12008-11-16 07:46:48 +0000156 else if (isComplexInt())
157 setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
158 else if (isComplexFloat())
159 setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
Richard Smith9a17a682011-11-07 05:07:52 +0000160 else if (isLValue()) {
161 if (RHS.hasLValuePath())
Richard Smithe24f5fc2011-11-17 22:56:20 +0000162 setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
163 RHS.isLValueOnePastTheEnd());
Richard Smith9a17a682011-11-07 05:07:52 +0000164 else
165 setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath());
Richard Smithcc5d4f62011-11-07 09:22:26 +0000166 } else if (isArray()) {
167 for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
168 getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
169 if (RHS.hasArrayFiller())
170 getArrayFiller() = RHS.getArrayFiller();
Richard Smith180f4792011-11-10 06:34:14 +0000171 } else if (isStruct()) {
172 for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
173 getStructBase(I) = RHS.getStructBase(I);
174 for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
175 getStructField(I) = RHS.getStructField(I);
176 } else if (isUnion())
177 setUnion(RHS.getUnionField(), RHS.getUnionValue());
Chris Lattner64c34f12008-11-16 07:46:48 +0000178 return *this;
179}
180
181void APValue::MakeUninit() {
182 if (Kind == Int)
Douglas Gregor98300462009-09-08 19:57:33 +0000183 ((APSInt*)(char*)Data)->~APSInt();
Chris Lattner64c34f12008-11-16 07:46:48 +0000184 else if (Kind == Float)
Douglas Gregor98300462009-09-08 19:57:33 +0000185 ((APFloat*)(char*)Data)->~APFloat();
Nate Begeman3d309f92009-01-18 01:01:34 +0000186 else if (Kind == Vector)
Douglas Gregor98300462009-09-08 19:57:33 +0000187 ((Vec*)(char*)Data)->~Vec();
Chris Lattner64c34f12008-11-16 07:46:48 +0000188 else if (Kind == ComplexInt)
Douglas Gregor98300462009-09-08 19:57:33 +0000189 ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
Chris Lattner64c34f12008-11-16 07:46:48 +0000190 else if (Kind == ComplexFloat)
Douglas Gregor98300462009-09-08 19:57:33 +0000191 ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
Richard Smithcc5d4f62011-11-07 09:22:26 +0000192 else if (Kind == LValue)
Douglas Gregor98300462009-09-08 19:57:33 +0000193 ((LV*)(char*)Data)->~LV();
Richard Smithcc5d4f62011-11-07 09:22:26 +0000194 else if (Kind == Array)
195 ((Arr*)(char*)Data)->~Arr();
Richard Smith180f4792011-11-10 06:34:14 +0000196 else if (Kind == Struct)
197 ((StructData*)(char*)Data)->~StructData();
198 else if (Kind == Union)
199 ((UnionData*)(char*)Data)->~UnionData();
Richard Smithe24f5fc2011-11-17 22:56:20 +0000200 else if (Kind == MemberPointer)
201 ((MemberPointerData*)(char*)Data)->~MemberPointerData();
Nate Begeman3d309f92009-01-18 01:01:34 +0000202 Kind = Uninitialized;
Chris Lattner64c34f12008-11-16 07:46:48 +0000203}
204
205void APValue::dump() const {
206 print(llvm::errs());
207 llvm::errs() << '\n';
Chris Lattner64c34f12008-11-16 07:46:48 +0000208}
209
210static double GetApproxValue(const llvm::APFloat &F) {
211 llvm::APFloat V = F;
212 bool ignored;
213 V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
214 &ignored);
215 return V.convertToDouble();
216}
217
Chris Lattner5f9e2722011-07-23 10:55:15 +0000218void APValue::print(raw_ostream &OS) const {
Chris Lattner64c34f12008-11-16 07:46:48 +0000219 switch (getKind()) {
Chris Lattner64c34f12008-11-16 07:46:48 +0000220 case Uninitialized:
221 OS << "Uninitialized";
222 return;
223 case Int:
224 OS << "Int: " << getInt();
225 return;
226 case Float:
227 OS << "Float: " << GetApproxValue(getFloat());
228 return;
Nate Begeman3d309f92009-01-18 01:01:34 +0000229 case Vector:
Nate Begeman59b5da62009-01-18 03:20:47 +0000230 OS << "Vector: " << getVectorElt(0);
Mike Stump1eb44332009-09-09 15:08:12 +0000231 for (unsigned i = 1; i != getVectorLength(); ++i)
Nate Begeman59b5da62009-01-18 03:20:47 +0000232 OS << ", " << getVectorElt(i);
Nate Begeman3d309f92009-01-18 01:01:34 +0000233 return;
Chris Lattner64c34f12008-11-16 07:46:48 +0000234 case ComplexInt:
235 OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
236 return;
237 case ComplexFloat:
238 OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
239 << ", " << GetApproxValue(getComplexFloatImag());
Richard Smithcc5d4f62011-11-07 09:22:26 +0000240 return;
Chris Lattner64c34f12008-11-16 07:46:48 +0000241 case LValue:
242 OS << "LValue: <todo>";
243 return;
Richard Smithcc5d4f62011-11-07 09:22:26 +0000244 case Array:
245 OS << "Array: ";
246 for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) {
247 OS << getArrayInitializedElt(I);
248 if (I != getArraySize() - 1) OS << ", ";
249 }
250 if (hasArrayFiller())
251 OS << getArraySize() - getArrayInitializedElts() << " x "
252 << getArrayFiller();
253 return;
Richard Smith180f4792011-11-10 06:34:14 +0000254 case Struct:
255 OS << "Struct ";
256 if (unsigned N = getStructNumBases()) {
257 OS << " bases: " << getStructBase(0);
258 for (unsigned I = 1; I != N; ++I)
259 OS << ", " << getStructBase(I);
260 }
261 if (unsigned N = getStructNumFields()) {
262 OS << " fields: " << getStructField(0);
263 for (unsigned I = 1; I != N; ++I)
264 OS << ", " << getStructField(I);
265 }
266 return;
267 case Union:
268 OS << "Union: " << getUnionValue();
269 return;
Richard Smithe24f5fc2011-11-17 22:56:20 +0000270 case MemberPointer:
271 OS << "MemberPointer: <todo>";
272 return;
Chris Lattner64c34f12008-11-16 07:46:48 +0000273 }
Richard Smith180f4792011-11-10 06:34:14 +0000274 llvm_unreachable("Unknown APValue kind!");
Chris Lattner64c34f12008-11-16 07:46:48 +0000275}
276
Chris Lattner5f9e2722011-07-23 10:55:15 +0000277static void WriteShortAPValueToStream(raw_ostream& Out,
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000278 const APValue& V) {
279 switch (V.getKind()) {
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000280 case APValue::Uninitialized:
281 Out << "Uninitialized";
Richard Smith180f4792011-11-10 06:34:14 +0000282 return;
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000283 case APValue::Int:
284 Out << V.getInt();
Richard Smith180f4792011-11-10 06:34:14 +0000285 return;
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000286 case APValue::Float:
287 Out << GetApproxValue(V.getFloat());
Richard Smith180f4792011-11-10 06:34:14 +0000288 return;
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000289 case APValue::Vector:
290 Out << '[';
291 WriteShortAPValueToStream(Out, V.getVectorElt(0));
292 for (unsigned i = 1; i != V.getVectorLength(); ++i) {
293 Out << ", ";
294 WriteShortAPValueToStream(Out, V.getVectorElt(i));
295 }
296 Out << ']';
Richard Smith180f4792011-11-10 06:34:14 +0000297 return;
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000298 case APValue::ComplexInt:
299 Out << V.getComplexIntReal() << "+" << V.getComplexIntImag() << "i";
Richard Smith180f4792011-11-10 06:34:14 +0000300 return;
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000301 case APValue::ComplexFloat:
302 Out << GetApproxValue(V.getComplexFloatReal()) << "+"
303 << GetApproxValue(V.getComplexFloatImag()) << "i";
Richard Smith180f4792011-11-10 06:34:14 +0000304 return;
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000305 case APValue::LValue:
306 Out << "LValue: <todo>";
Richard Smith180f4792011-11-10 06:34:14 +0000307 return;
Richard Smithcc5d4f62011-11-07 09:22:26 +0000308 case APValue::Array:
309 Out << '{';
310 if (unsigned N = V.getArrayInitializedElts()) {
311 Out << V.getArrayInitializedElt(0);
312 for (unsigned I = 1; I != N; ++I)
313 Out << ", " << V.getArrayInitializedElt(I);
314 }
315 Out << '}';
Richard Smith180f4792011-11-10 06:34:14 +0000316 return;
317 case APValue::Struct:
318 Out << '{';
319 if (unsigned N = V.getStructNumBases()) {
320 Out << V.getStructBase(0);
321 for (unsigned I = 1; I != N; ++I)
322 Out << ", " << V.getStructBase(I);
323 if (V.getStructNumFields())
324 Out << ", ";
325 }
326 if (unsigned N = V.getStructNumFields()) {
327 Out << V.getStructField(0);
328 for (unsigned I = 1; I != N; ++I)
329 Out << ", " << V.getStructField(I);
330 }
331 Out << '}';
332 return;
333 case APValue::Union:
334 Out << '{' << V.getUnionValue() << '}';
335 return;
Richard Smithe24f5fc2011-11-17 22:56:20 +0000336 case APValue::MemberPointer:
337 Out << "MemberPointer: <todo>";
338 return;
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000339 }
Richard Smith180f4792011-11-10 06:34:14 +0000340 llvm_unreachable("Unknown APValue kind!");
Jeffrey Yasskin5b106a82011-07-18 16:43:53 +0000341}
342
343const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
344 const APValue &V) {
345 llvm::SmallString<64> Buffer;
346 llvm::raw_svector_ostream Out(Buffer);
347 WriteShortAPValueToStream(Out, V);
348 return DB << Out.str();
349}
350
Richard Smith1bf9a9e2011-11-12 22:28:03 +0000351const APValue::LValueBase APValue::getLValueBase() const {
Ken Dycka7305832010-01-15 12:37:54 +0000352 assert(isLValue() && "Invalid accessor");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000353 return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getPointer();
354}
355
356bool APValue::isLValueOnePastTheEnd() const {
357 assert(isLValue() && "Invalid accessor");
358 return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getInt();
Ken Dycka7305832010-01-15 12:37:54 +0000359}
360
Richard Smith47a1eed2011-10-29 20:57:55 +0000361CharUnits &APValue::getLValueOffset() {
362 assert(isLValue() && "Invalid accessor");
363 return ((LV*)(void*)Data)->Offset;
Ken Dycka7305832010-01-15 12:37:54 +0000364}
365
Richard Smith9a17a682011-11-07 05:07:52 +0000366bool APValue::hasLValuePath() const {
Ken Dycka7305832010-01-15 12:37:54 +0000367 assert(isLValue() && "Invalid accessor");
Richard Smith38dce9b2011-11-07 07:31:09 +0000368 return ((const LV*)(const char*)Data)->hasPath();
Richard Smith9a17a682011-11-07 05:07:52 +0000369}
370
371ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
372 assert(isLValue() && hasLValuePath() && "Invalid accessor");
Richard Smith38dce9b2011-11-07 07:31:09 +0000373 const LV &LVal = *((const LV*)(const char*)Data);
Richard Smith9a17a682011-11-07 05:07:52 +0000374 return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength);
375}
376
Richard Smith1bf9a9e2011-11-12 22:28:03 +0000377void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath) {
Richard Smith9a17a682011-11-07 05:07:52 +0000378 assert(isLValue() && "Invalid accessor");
379 LV &LVal = *((LV*)(char*)Data);
Richard Smithe24f5fc2011-11-17 22:56:20 +0000380 LVal.BaseAndIsOnePastTheEnd.setPointer(B);
381 LVal.BaseAndIsOnePastTheEnd.setInt(false);
Richard Smith9a17a682011-11-07 05:07:52 +0000382 LVal.Offset = O;
Richard Smithe24f5fc2011-11-17 22:56:20 +0000383 LVal.resizePath((unsigned)-1);
Richard Smith9a17a682011-11-07 05:07:52 +0000384}
385
Richard Smith1bf9a9e2011-11-12 22:28:03 +0000386void APValue::setLValue(LValueBase B, const CharUnits &O,
Richard Smithe24f5fc2011-11-17 22:56:20 +0000387 ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd) {
Richard Smith9a17a682011-11-07 05:07:52 +0000388 assert(isLValue() && "Invalid accessor");
389 LV &LVal = *((LV*)(char*)Data);
Richard Smithe24f5fc2011-11-17 22:56:20 +0000390 LVal.BaseAndIsOnePastTheEnd.setPointer(B);
391 LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
Richard Smith9a17a682011-11-07 05:07:52 +0000392 LVal.Offset = O;
Richard Smithe24f5fc2011-11-17 22:56:20 +0000393 LVal.resizePath(Path.size());
Richard Smith9a17a682011-11-07 05:07:52 +0000394 memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
Ken Dycka7305832010-01-15 12:37:54 +0000395}
396
Richard Smithe24f5fc2011-11-17 22:56:20 +0000397const ValueDecl *APValue::getMemberPointerDecl() const {
398 assert(isMemberPointer() && "Invalid accessor");
399 const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
400 return MPD.MemberAndIsDerivedMember.getPointer();
401}
402
403bool APValue::isMemberPointerToDerivedMember() const {
404 assert(isMemberPointer() && "Invalid accessor");
405 const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
406 return MPD.MemberAndIsDerivedMember.getInt();
407}
408
409ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
410 assert(isMemberPointer() && "Invalid accessor");
411 const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
412 return ArrayRef<const CXXRecordDecl*>(MPD.getPath(), MPD.PathLength);
413}
414
Ken Dycka7305832010-01-15 12:37:54 +0000415void APValue::MakeLValue() {
416 assert(isUninit() && "Bad state change");
Richard Smith9a17a682011-11-07 05:07:52 +0000417 assert(sizeof(LV) <= MaxSize && "LV too big");
Ken Dycka7305832010-01-15 12:37:54 +0000418 new ((void*)(char*)Data) LV();
419 Kind = LValue;
420}
Richard Smithcc5d4f62011-11-07 09:22:26 +0000421
422void APValue::MakeArray(unsigned InitElts, unsigned Size) {
423 assert(isUninit() && "Bad state change");
424 new ((void*)(char*)Data) Arr(InitElts, Size);
425 Kind = Array;
426}
Richard Smithe24f5fc2011-11-17 22:56:20 +0000427
428void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
429 ArrayRef<const CXXRecordDecl*> Path) {
430 assert(isUninit() && "Bad state change");
431 MemberPointerData *MPD = new ((void*)(char*)Data) MemberPointerData;
432 Kind = MemberPointer;
433 MPD->MemberAndIsDerivedMember.setPointer(Member);
434 MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
435 MPD->resizePath(Path.size());
436 memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
437}