xref: /aosp_15_r20/external/clang/lib/AST/APValue.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li //  This file implements the APValue class.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li 
14*67e74705SXin Li #include "clang/AST/APValue.h"
15*67e74705SXin Li #include "clang/AST/ASTContext.h"
16*67e74705SXin Li #include "clang/AST/CharUnits.h"
17*67e74705SXin Li #include "clang/AST/DeclCXX.h"
18*67e74705SXin Li #include "clang/AST/Expr.h"
19*67e74705SXin Li #include "clang/AST/Type.h"
20*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
21*67e74705SXin Li #include "llvm/ADT/SmallString.h"
22*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
23*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
24*67e74705SXin Li using namespace clang;
25*67e74705SXin Li 
26*67e74705SXin Li namespace {
27*67e74705SXin Li   struct LVBase {
28*67e74705SXin Li     llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
29*67e74705SXin Li     CharUnits Offset;
30*67e74705SXin Li     unsigned PathLength;
31*67e74705SXin Li     unsigned CallIndex;
32*67e74705SXin Li   };
33*67e74705SXin Li }
34*67e74705SXin Li 
35*67e74705SXin Li struct APValue::LV : LVBase {
36*67e74705SXin Li   static const unsigned InlinePathSpace =
37*67e74705SXin Li       (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
38*67e74705SXin Li 
39*67e74705SXin Li   /// Path - The sequence of base classes, fields and array indices to follow to
40*67e74705SXin Li   /// walk from Base to the subobject. When performing GCC-style folding, there
41*67e74705SXin Li   /// may not be such a path.
42*67e74705SXin Li   union {
43*67e74705SXin Li     LValuePathEntry Path[InlinePathSpace];
44*67e74705SXin Li     LValuePathEntry *PathPtr;
45*67e74705SXin Li   };
46*67e74705SXin Li 
LVAPValue::LV47*67e74705SXin Li   LV() { PathLength = (unsigned)-1; }
~LVAPValue::LV48*67e74705SXin Li   ~LV() { resizePath(0); }
49*67e74705SXin Li 
resizePathAPValue::LV50*67e74705SXin Li   void resizePath(unsigned Length) {
51*67e74705SXin Li     if (Length == PathLength)
52*67e74705SXin Li       return;
53*67e74705SXin Li     if (hasPathPtr())
54*67e74705SXin Li       delete [] PathPtr;
55*67e74705SXin Li     PathLength = Length;
56*67e74705SXin Li     if (hasPathPtr())
57*67e74705SXin Li       PathPtr = new LValuePathEntry[Length];
58*67e74705SXin Li   }
59*67e74705SXin Li 
hasPathAPValue::LV60*67e74705SXin Li   bool hasPath() const { return PathLength != (unsigned)-1; }
hasPathPtrAPValue::LV61*67e74705SXin Li   bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }
62*67e74705SXin Li 
getPathAPValue::LV63*67e74705SXin Li   LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }
getPathAPValue::LV64*67e74705SXin Li   const LValuePathEntry *getPath() const {
65*67e74705SXin Li     return hasPathPtr() ? PathPtr : Path;
66*67e74705SXin Li   }
67*67e74705SXin Li };
68*67e74705SXin Li 
69*67e74705SXin Li namespace {
70*67e74705SXin Li   struct MemberPointerBase {
71*67e74705SXin Li     llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
72*67e74705SXin Li     unsigned PathLength;
73*67e74705SXin Li   };
74*67e74705SXin Li }
75*67e74705SXin Li 
76*67e74705SXin Li struct APValue::MemberPointerData : MemberPointerBase {
77*67e74705SXin Li   static const unsigned InlinePathSpace =
78*67e74705SXin Li       (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
79*67e74705SXin Li   typedef const CXXRecordDecl *PathElem;
80*67e74705SXin Li   union {
81*67e74705SXin Li     PathElem Path[InlinePathSpace];
82*67e74705SXin Li     PathElem *PathPtr;
83*67e74705SXin Li   };
84*67e74705SXin Li 
MemberPointerDataAPValue::MemberPointerData85*67e74705SXin Li   MemberPointerData() { PathLength = 0; }
~MemberPointerDataAPValue::MemberPointerData86*67e74705SXin Li   ~MemberPointerData() { resizePath(0); }
87*67e74705SXin Li 
resizePathAPValue::MemberPointerData88*67e74705SXin Li   void resizePath(unsigned Length) {
89*67e74705SXin Li     if (Length == PathLength)
90*67e74705SXin Li       return;
91*67e74705SXin Li     if (hasPathPtr())
92*67e74705SXin Li       delete [] PathPtr;
93*67e74705SXin Li     PathLength = Length;
94*67e74705SXin Li     if (hasPathPtr())
95*67e74705SXin Li       PathPtr = new PathElem[Length];
96*67e74705SXin Li   }
97*67e74705SXin Li 
hasPathPtrAPValue::MemberPointerData98*67e74705SXin Li   bool hasPathPtr() const { return PathLength > InlinePathSpace; }
99*67e74705SXin Li 
getPathAPValue::MemberPointerData100*67e74705SXin Li   PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
getPathAPValue::MemberPointerData101*67e74705SXin Li   const PathElem *getPath() const {
102*67e74705SXin Li     return hasPathPtr() ? PathPtr : Path;
103*67e74705SXin Li   }
104*67e74705SXin Li };
105*67e74705SXin Li 
106*67e74705SXin Li // FIXME: Reduce the malloc traffic here.
107*67e74705SXin Li 
Arr(unsigned NumElts,unsigned Size)108*67e74705SXin Li APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
109*67e74705SXin Li   Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
110*67e74705SXin Li   NumElts(NumElts), ArrSize(Size) {}
~Arr()111*67e74705SXin Li APValue::Arr::~Arr() { delete [] Elts; }
112*67e74705SXin Li 
StructData(unsigned NumBases,unsigned NumFields)113*67e74705SXin Li APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
114*67e74705SXin Li   Elts(new APValue[NumBases+NumFields]),
115*67e74705SXin Li   NumBases(NumBases), NumFields(NumFields) {}
~StructData()116*67e74705SXin Li APValue::StructData::~StructData() {
117*67e74705SXin Li   delete [] Elts;
118*67e74705SXin Li }
119*67e74705SXin Li 
UnionData()120*67e74705SXin Li APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
~UnionData()121*67e74705SXin Li APValue::UnionData::~UnionData () {
122*67e74705SXin Li   delete Value;
123*67e74705SXin Li }
124*67e74705SXin Li 
APValue(const APValue & RHS)125*67e74705SXin Li APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
126*67e74705SXin Li   switch (RHS.getKind()) {
127*67e74705SXin Li   case Uninitialized:
128*67e74705SXin Li     break;
129*67e74705SXin Li   case Int:
130*67e74705SXin Li     MakeInt();
131*67e74705SXin Li     setInt(RHS.getInt());
132*67e74705SXin Li     break;
133*67e74705SXin Li   case Float:
134*67e74705SXin Li     MakeFloat();
135*67e74705SXin Li     setFloat(RHS.getFloat());
136*67e74705SXin Li     break;
137*67e74705SXin Li   case Vector:
138*67e74705SXin Li     MakeVector();
139*67e74705SXin Li     setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
140*67e74705SXin Li               RHS.getVectorLength());
141*67e74705SXin Li     break;
142*67e74705SXin Li   case ComplexInt:
143*67e74705SXin Li     MakeComplexInt();
144*67e74705SXin Li     setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
145*67e74705SXin Li     break;
146*67e74705SXin Li   case ComplexFloat:
147*67e74705SXin Li     MakeComplexFloat();
148*67e74705SXin Li     setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
149*67e74705SXin Li     break;
150*67e74705SXin Li   case LValue:
151*67e74705SXin Li     MakeLValue();
152*67e74705SXin Li     if (RHS.hasLValuePath())
153*67e74705SXin Li       setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
154*67e74705SXin Li                 RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex());
155*67e74705SXin Li     else
156*67e74705SXin Li       setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
157*67e74705SXin Li                 RHS.getLValueCallIndex());
158*67e74705SXin Li     break;
159*67e74705SXin Li   case Array:
160*67e74705SXin Li     MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
161*67e74705SXin Li     for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
162*67e74705SXin Li       getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
163*67e74705SXin Li     if (RHS.hasArrayFiller())
164*67e74705SXin Li       getArrayFiller() = RHS.getArrayFiller();
165*67e74705SXin Li     break;
166*67e74705SXin Li   case Struct:
167*67e74705SXin Li     MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
168*67e74705SXin Li     for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
169*67e74705SXin Li       getStructBase(I) = RHS.getStructBase(I);
170*67e74705SXin Li     for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
171*67e74705SXin Li       getStructField(I) = RHS.getStructField(I);
172*67e74705SXin Li     break;
173*67e74705SXin Li   case Union:
174*67e74705SXin Li     MakeUnion();
175*67e74705SXin Li     setUnion(RHS.getUnionField(), RHS.getUnionValue());
176*67e74705SXin Li     break;
177*67e74705SXin Li   case MemberPointer:
178*67e74705SXin Li     MakeMemberPointer(RHS.getMemberPointerDecl(),
179*67e74705SXin Li                       RHS.isMemberPointerToDerivedMember(),
180*67e74705SXin Li                       RHS.getMemberPointerPath());
181*67e74705SXin Li     break;
182*67e74705SXin Li   case AddrLabelDiff:
183*67e74705SXin Li     MakeAddrLabelDiff();
184*67e74705SXin Li     setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());
185*67e74705SXin Li     break;
186*67e74705SXin Li   }
187*67e74705SXin Li }
188*67e74705SXin Li 
DestroyDataAndMakeUninit()189*67e74705SXin Li void APValue::DestroyDataAndMakeUninit() {
190*67e74705SXin Li   if (Kind == Int)
191*67e74705SXin Li     ((APSInt*)(char*)Data.buffer)->~APSInt();
192*67e74705SXin Li   else if (Kind == Float)
193*67e74705SXin Li     ((APFloat*)(char*)Data.buffer)->~APFloat();
194*67e74705SXin Li   else if (Kind == Vector)
195*67e74705SXin Li     ((Vec*)(char*)Data.buffer)->~Vec();
196*67e74705SXin Li   else if (Kind == ComplexInt)
197*67e74705SXin Li     ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
198*67e74705SXin Li   else if (Kind == ComplexFloat)
199*67e74705SXin Li     ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
200*67e74705SXin Li   else if (Kind == LValue)
201*67e74705SXin Li     ((LV*)(char*)Data.buffer)->~LV();
202*67e74705SXin Li   else if (Kind == Array)
203*67e74705SXin Li     ((Arr*)(char*)Data.buffer)->~Arr();
204*67e74705SXin Li   else if (Kind == Struct)
205*67e74705SXin Li     ((StructData*)(char*)Data.buffer)->~StructData();
206*67e74705SXin Li   else if (Kind == Union)
207*67e74705SXin Li     ((UnionData*)(char*)Data.buffer)->~UnionData();
208*67e74705SXin Li   else if (Kind == MemberPointer)
209*67e74705SXin Li     ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
210*67e74705SXin Li   else if (Kind == AddrLabelDiff)
211*67e74705SXin Li     ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
212*67e74705SXin Li   Kind = Uninitialized;
213*67e74705SXin Li }
214*67e74705SXin Li 
needsCleanup() const215*67e74705SXin Li bool APValue::needsCleanup() const {
216*67e74705SXin Li   switch (getKind()) {
217*67e74705SXin Li   case Uninitialized:
218*67e74705SXin Li   case AddrLabelDiff:
219*67e74705SXin Li     return false;
220*67e74705SXin Li   case Struct:
221*67e74705SXin Li   case Union:
222*67e74705SXin Li   case Array:
223*67e74705SXin Li   case Vector:
224*67e74705SXin Li     return true;
225*67e74705SXin Li   case Int:
226*67e74705SXin Li     return getInt().needsCleanup();
227*67e74705SXin Li   case Float:
228*67e74705SXin Li     return getFloat().needsCleanup();
229*67e74705SXin Li   case ComplexFloat:
230*67e74705SXin Li     assert(getComplexFloatImag().needsCleanup() ==
231*67e74705SXin Li                getComplexFloatReal().needsCleanup() &&
232*67e74705SXin Li            "In _Complex float types, real and imaginary values always have the "
233*67e74705SXin Li            "same size.");
234*67e74705SXin Li     return getComplexFloatReal().needsCleanup();
235*67e74705SXin Li   case ComplexInt:
236*67e74705SXin Li     assert(getComplexIntImag().needsCleanup() ==
237*67e74705SXin Li                getComplexIntReal().needsCleanup() &&
238*67e74705SXin Li            "In _Complex int types, real and imaginary values must have the "
239*67e74705SXin Li            "same size.");
240*67e74705SXin Li     return getComplexIntReal().needsCleanup();
241*67e74705SXin Li   case LValue:
242*67e74705SXin Li     return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
243*67e74705SXin Li   case MemberPointer:
244*67e74705SXin Li     return reinterpret_cast<const MemberPointerData *>(Data.buffer)
245*67e74705SXin Li         ->hasPathPtr();
246*67e74705SXin Li   }
247*67e74705SXin Li   llvm_unreachable("Unknown APValue kind!");
248*67e74705SXin Li }
249*67e74705SXin Li 
swap(APValue & RHS)250*67e74705SXin Li void APValue::swap(APValue &RHS) {
251*67e74705SXin Li   std::swap(Kind, RHS.Kind);
252*67e74705SXin Li   char TmpData[DataSize];
253*67e74705SXin Li   memcpy(TmpData, Data.buffer, DataSize);
254*67e74705SXin Li   memcpy(Data.buffer, RHS.Data.buffer, DataSize);
255*67e74705SXin Li   memcpy(RHS.Data.buffer, TmpData, DataSize);
256*67e74705SXin Li }
257*67e74705SXin Li 
dump() const258*67e74705SXin Li LLVM_DUMP_METHOD void APValue::dump() const {
259*67e74705SXin Li   dump(llvm::errs());
260*67e74705SXin Li   llvm::errs() << '\n';
261*67e74705SXin Li }
262*67e74705SXin Li 
GetApproxValue(const llvm::APFloat & F)263*67e74705SXin Li static double GetApproxValue(const llvm::APFloat &F) {
264*67e74705SXin Li   llvm::APFloat V = F;
265*67e74705SXin Li   bool ignored;
266*67e74705SXin Li   V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
267*67e74705SXin Li             &ignored);
268*67e74705SXin Li   return V.convertToDouble();
269*67e74705SXin Li }
270*67e74705SXin Li 
dump(raw_ostream & OS) const271*67e74705SXin Li void APValue::dump(raw_ostream &OS) const {
272*67e74705SXin Li   switch (getKind()) {
273*67e74705SXin Li   case Uninitialized:
274*67e74705SXin Li     OS << "Uninitialized";
275*67e74705SXin Li     return;
276*67e74705SXin Li   case Int:
277*67e74705SXin Li     OS << "Int: " << getInt();
278*67e74705SXin Li     return;
279*67e74705SXin Li   case Float:
280*67e74705SXin Li     OS << "Float: " << GetApproxValue(getFloat());
281*67e74705SXin Li     return;
282*67e74705SXin Li   case Vector:
283*67e74705SXin Li     OS << "Vector: ";
284*67e74705SXin Li     getVectorElt(0).dump(OS);
285*67e74705SXin Li     for (unsigned i = 1; i != getVectorLength(); ++i) {
286*67e74705SXin Li       OS << ", ";
287*67e74705SXin Li       getVectorElt(i).dump(OS);
288*67e74705SXin Li     }
289*67e74705SXin Li     return;
290*67e74705SXin Li   case ComplexInt:
291*67e74705SXin Li     OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
292*67e74705SXin Li     return;
293*67e74705SXin Li   case ComplexFloat:
294*67e74705SXin Li     OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
295*67e74705SXin Li        << ", " << GetApproxValue(getComplexFloatImag());
296*67e74705SXin Li     return;
297*67e74705SXin Li   case LValue:
298*67e74705SXin Li     OS << "LValue: <todo>";
299*67e74705SXin Li     return;
300*67e74705SXin Li   case Array:
301*67e74705SXin Li     OS << "Array: ";
302*67e74705SXin Li     for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) {
303*67e74705SXin Li       getArrayInitializedElt(I).dump(OS);
304*67e74705SXin Li       if (I != getArraySize() - 1) OS << ", ";
305*67e74705SXin Li     }
306*67e74705SXin Li     if (hasArrayFiller()) {
307*67e74705SXin Li       OS << getArraySize() - getArrayInitializedElts() << " x ";
308*67e74705SXin Li       getArrayFiller().dump(OS);
309*67e74705SXin Li     }
310*67e74705SXin Li     return;
311*67e74705SXin Li   case Struct:
312*67e74705SXin Li     OS << "Struct ";
313*67e74705SXin Li     if (unsigned N = getStructNumBases()) {
314*67e74705SXin Li       OS << " bases: ";
315*67e74705SXin Li       getStructBase(0).dump(OS);
316*67e74705SXin Li       for (unsigned I = 1; I != N; ++I) {
317*67e74705SXin Li         OS << ", ";
318*67e74705SXin Li         getStructBase(I).dump(OS);
319*67e74705SXin Li       }
320*67e74705SXin Li     }
321*67e74705SXin Li     if (unsigned N = getStructNumFields()) {
322*67e74705SXin Li       OS << " fields: ";
323*67e74705SXin Li       getStructField(0).dump(OS);
324*67e74705SXin Li       for (unsigned I = 1; I != N; ++I) {
325*67e74705SXin Li         OS << ", ";
326*67e74705SXin Li         getStructField(I).dump(OS);
327*67e74705SXin Li       }
328*67e74705SXin Li     }
329*67e74705SXin Li     return;
330*67e74705SXin Li   case Union:
331*67e74705SXin Li     OS << "Union: ";
332*67e74705SXin Li     getUnionValue().dump(OS);
333*67e74705SXin Li     return;
334*67e74705SXin Li   case MemberPointer:
335*67e74705SXin Li     OS << "MemberPointer: <todo>";
336*67e74705SXin Li     return;
337*67e74705SXin Li   case AddrLabelDiff:
338*67e74705SXin Li     OS << "AddrLabelDiff: <todo>";
339*67e74705SXin Li     return;
340*67e74705SXin Li   }
341*67e74705SXin Li   llvm_unreachable("Unknown APValue kind!");
342*67e74705SXin Li }
343*67e74705SXin Li 
printPretty(raw_ostream & Out,ASTContext & Ctx,QualType Ty) const344*67e74705SXin Li void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
345*67e74705SXin Li   switch (getKind()) {
346*67e74705SXin Li   case APValue::Uninitialized:
347*67e74705SXin Li     Out << "<uninitialized>";
348*67e74705SXin Li     return;
349*67e74705SXin Li   case APValue::Int:
350*67e74705SXin Li     if (Ty->isBooleanType())
351*67e74705SXin Li       Out << (getInt().getBoolValue() ? "true" : "false");
352*67e74705SXin Li     else
353*67e74705SXin Li       Out << getInt();
354*67e74705SXin Li     return;
355*67e74705SXin Li   case APValue::Float:
356*67e74705SXin Li     Out << GetApproxValue(getFloat());
357*67e74705SXin Li     return;
358*67e74705SXin Li   case APValue::Vector: {
359*67e74705SXin Li     Out << '{';
360*67e74705SXin Li     QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
361*67e74705SXin Li     getVectorElt(0).printPretty(Out, Ctx, ElemTy);
362*67e74705SXin Li     for (unsigned i = 1; i != getVectorLength(); ++i) {
363*67e74705SXin Li       Out << ", ";
364*67e74705SXin Li       getVectorElt(i).printPretty(Out, Ctx, ElemTy);
365*67e74705SXin Li     }
366*67e74705SXin Li     Out << '}';
367*67e74705SXin Li     return;
368*67e74705SXin Li   }
369*67e74705SXin Li   case APValue::ComplexInt:
370*67e74705SXin Li     Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
371*67e74705SXin Li     return;
372*67e74705SXin Li   case APValue::ComplexFloat:
373*67e74705SXin Li     Out << GetApproxValue(getComplexFloatReal()) << "+"
374*67e74705SXin Li         << GetApproxValue(getComplexFloatImag()) << "i";
375*67e74705SXin Li     return;
376*67e74705SXin Li   case APValue::LValue: {
377*67e74705SXin Li     LValueBase Base = getLValueBase();
378*67e74705SXin Li     if (!Base) {
379*67e74705SXin Li       Out << "0";
380*67e74705SXin Li       return;
381*67e74705SXin Li     }
382*67e74705SXin Li 
383*67e74705SXin Li     bool IsReference = Ty->isReferenceType();
384*67e74705SXin Li     QualType InnerTy
385*67e74705SXin Li       = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
386*67e74705SXin Li     if (InnerTy.isNull())
387*67e74705SXin Li       InnerTy = Ty;
388*67e74705SXin Li 
389*67e74705SXin Li     if (!hasLValuePath()) {
390*67e74705SXin Li       // No lvalue path: just print the offset.
391*67e74705SXin Li       CharUnits O = getLValueOffset();
392*67e74705SXin Li       CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
393*67e74705SXin Li       if (!O.isZero()) {
394*67e74705SXin Li         if (IsReference)
395*67e74705SXin Li           Out << "*(";
396*67e74705SXin Li         if (O % S) {
397*67e74705SXin Li           Out << "(char*)";
398*67e74705SXin Li           S = CharUnits::One();
399*67e74705SXin Li         }
400*67e74705SXin Li         Out << '&';
401*67e74705SXin Li       } else if (!IsReference)
402*67e74705SXin Li         Out << '&';
403*67e74705SXin Li 
404*67e74705SXin Li       if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
405*67e74705SXin Li         Out << *VD;
406*67e74705SXin Li       else {
407*67e74705SXin Li         assert(Base.get<const Expr *>() != nullptr &&
408*67e74705SXin Li                "Expecting non-null Expr");
409*67e74705SXin Li         Base.get<const Expr*>()->printPretty(Out, nullptr,
410*67e74705SXin Li                                              Ctx.getPrintingPolicy());
411*67e74705SXin Li       }
412*67e74705SXin Li 
413*67e74705SXin Li       if (!O.isZero()) {
414*67e74705SXin Li         Out << " + " << (O / S);
415*67e74705SXin Li         if (IsReference)
416*67e74705SXin Li           Out << ')';
417*67e74705SXin Li       }
418*67e74705SXin Li       return;
419*67e74705SXin Li     }
420*67e74705SXin Li 
421*67e74705SXin Li     // We have an lvalue path. Print it out nicely.
422*67e74705SXin Li     if (!IsReference)
423*67e74705SXin Li       Out << '&';
424*67e74705SXin Li     else if (isLValueOnePastTheEnd())
425*67e74705SXin Li       Out << "*(&";
426*67e74705SXin Li 
427*67e74705SXin Li     QualType ElemTy;
428*67e74705SXin Li     if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
429*67e74705SXin Li       Out << *VD;
430*67e74705SXin Li       ElemTy = VD->getType();
431*67e74705SXin Li     } else {
432*67e74705SXin Li       const Expr *E = Base.get<const Expr*>();
433*67e74705SXin Li       assert(E != nullptr && "Expecting non-null Expr");
434*67e74705SXin Li       E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
435*67e74705SXin Li       ElemTy = E->getType();
436*67e74705SXin Li     }
437*67e74705SXin Li 
438*67e74705SXin Li     ArrayRef<LValuePathEntry> Path = getLValuePath();
439*67e74705SXin Li     const CXXRecordDecl *CastToBase = nullptr;
440*67e74705SXin Li     for (unsigned I = 0, N = Path.size(); I != N; ++I) {
441*67e74705SXin Li       if (ElemTy->getAs<RecordType>()) {
442*67e74705SXin Li         // The lvalue refers to a class type, so the next path entry is a base
443*67e74705SXin Li         // or member.
444*67e74705SXin Li         const Decl *BaseOrMember =
445*67e74705SXin Li         BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
446*67e74705SXin Li         if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
447*67e74705SXin Li           CastToBase = RD;
448*67e74705SXin Li           ElemTy = Ctx.getRecordType(RD);
449*67e74705SXin Li         } else {
450*67e74705SXin Li           const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
451*67e74705SXin Li           Out << ".";
452*67e74705SXin Li           if (CastToBase)
453*67e74705SXin Li             Out << *CastToBase << "::";
454*67e74705SXin Li           Out << *VD;
455*67e74705SXin Li           ElemTy = VD->getType();
456*67e74705SXin Li         }
457*67e74705SXin Li       } else {
458*67e74705SXin Li         // The lvalue must refer to an array.
459*67e74705SXin Li         Out << '[' << Path[I].ArrayIndex << ']';
460*67e74705SXin Li         ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
461*67e74705SXin Li       }
462*67e74705SXin Li     }
463*67e74705SXin Li 
464*67e74705SXin Li     // Handle formatting of one-past-the-end lvalues.
465*67e74705SXin Li     if (isLValueOnePastTheEnd()) {
466*67e74705SXin Li       // FIXME: If CastToBase is non-0, we should prefix the output with
467*67e74705SXin Li       // "(CastToBase*)".
468*67e74705SXin Li       Out << " + 1";
469*67e74705SXin Li       if (IsReference)
470*67e74705SXin Li         Out << ')';
471*67e74705SXin Li     }
472*67e74705SXin Li     return;
473*67e74705SXin Li   }
474*67e74705SXin Li   case APValue::Array: {
475*67e74705SXin Li     const ArrayType *AT = Ctx.getAsArrayType(Ty);
476*67e74705SXin Li     QualType ElemTy = AT->getElementType();
477*67e74705SXin Li     Out << '{';
478*67e74705SXin Li     if (unsigned N = getArrayInitializedElts()) {
479*67e74705SXin Li       getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy);
480*67e74705SXin Li       for (unsigned I = 1; I != N; ++I) {
481*67e74705SXin Li         Out << ", ";
482*67e74705SXin Li         if (I == 10) {
483*67e74705SXin Li           // Avoid printing out the entire contents of large arrays.
484*67e74705SXin Li           Out << "...";
485*67e74705SXin Li           break;
486*67e74705SXin Li         }
487*67e74705SXin Li         getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy);
488*67e74705SXin Li       }
489*67e74705SXin Li     }
490*67e74705SXin Li     Out << '}';
491*67e74705SXin Li     return;
492*67e74705SXin Li   }
493*67e74705SXin Li   case APValue::Struct: {
494*67e74705SXin Li     Out << '{';
495*67e74705SXin Li     const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
496*67e74705SXin Li     bool First = true;
497*67e74705SXin Li     if (unsigned N = getStructNumBases()) {
498*67e74705SXin Li       const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
499*67e74705SXin Li       CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();
500*67e74705SXin Li       for (unsigned I = 0; I != N; ++I, ++BI) {
501*67e74705SXin Li         assert(BI != CD->bases_end());
502*67e74705SXin Li         if (!First)
503*67e74705SXin Li           Out << ", ";
504*67e74705SXin Li         getStructBase(I).printPretty(Out, Ctx, BI->getType());
505*67e74705SXin Li         First = false;
506*67e74705SXin Li       }
507*67e74705SXin Li     }
508*67e74705SXin Li     for (const auto *FI : RD->fields()) {
509*67e74705SXin Li       if (!First)
510*67e74705SXin Li         Out << ", ";
511*67e74705SXin Li       if (FI->isUnnamedBitfield()) continue;
512*67e74705SXin Li       getStructField(FI->getFieldIndex()).
513*67e74705SXin Li         printPretty(Out, Ctx, FI->getType());
514*67e74705SXin Li       First = false;
515*67e74705SXin Li     }
516*67e74705SXin Li     Out << '}';
517*67e74705SXin Li     return;
518*67e74705SXin Li   }
519*67e74705SXin Li   case APValue::Union:
520*67e74705SXin Li     Out << '{';
521*67e74705SXin Li     if (const FieldDecl *FD = getUnionField()) {
522*67e74705SXin Li       Out << "." << *FD << " = ";
523*67e74705SXin Li       getUnionValue().printPretty(Out, Ctx, FD->getType());
524*67e74705SXin Li     }
525*67e74705SXin Li     Out << '}';
526*67e74705SXin Li     return;
527*67e74705SXin Li   case APValue::MemberPointer:
528*67e74705SXin Li     // FIXME: This is not enough to unambiguously identify the member in a
529*67e74705SXin Li     // multiple-inheritance scenario.
530*67e74705SXin Li     if (const ValueDecl *VD = getMemberPointerDecl()) {
531*67e74705SXin Li       Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
532*67e74705SXin Li       return;
533*67e74705SXin Li     }
534*67e74705SXin Li     Out << "0";
535*67e74705SXin Li     return;
536*67e74705SXin Li   case APValue::AddrLabelDiff:
537*67e74705SXin Li     Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
538*67e74705SXin Li     Out << " - ";
539*67e74705SXin Li     Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
540*67e74705SXin Li     return;
541*67e74705SXin Li   }
542*67e74705SXin Li   llvm_unreachable("Unknown APValue kind!");
543*67e74705SXin Li }
544*67e74705SXin Li 
getAsString(ASTContext & Ctx,QualType Ty) const545*67e74705SXin Li std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
546*67e74705SXin Li   std::string Result;
547*67e74705SXin Li   llvm::raw_string_ostream Out(Result);
548*67e74705SXin Li   printPretty(Out, Ctx, Ty);
549*67e74705SXin Li   Out.flush();
550*67e74705SXin Li   return Result;
551*67e74705SXin Li }
552*67e74705SXin Li 
getLValueBase() const553*67e74705SXin Li const APValue::LValueBase APValue::getLValueBase() const {
554*67e74705SXin Li   assert(isLValue() && "Invalid accessor");
555*67e74705SXin Li   return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
556*67e74705SXin Li }
557*67e74705SXin Li 
isLValueOnePastTheEnd() const558*67e74705SXin Li bool APValue::isLValueOnePastTheEnd() const {
559*67e74705SXin Li   assert(isLValue() && "Invalid accessor");
560*67e74705SXin Li   return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
561*67e74705SXin Li }
562*67e74705SXin Li 
getLValueOffset()563*67e74705SXin Li CharUnits &APValue::getLValueOffset() {
564*67e74705SXin Li   assert(isLValue() && "Invalid accessor");
565*67e74705SXin Li   return ((LV*)(void*)Data.buffer)->Offset;
566*67e74705SXin Li }
567*67e74705SXin Li 
hasLValuePath() const568*67e74705SXin Li bool APValue::hasLValuePath() const {
569*67e74705SXin Li   assert(isLValue() && "Invalid accessor");
570*67e74705SXin Li   return ((const LV*)(const char*)Data.buffer)->hasPath();
571*67e74705SXin Li }
572*67e74705SXin Li 
getLValuePath() const573*67e74705SXin Li ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
574*67e74705SXin Li   assert(isLValue() && hasLValuePath() && "Invalid accessor");
575*67e74705SXin Li   const LV &LVal = *((const LV*)(const char*)Data.buffer);
576*67e74705SXin Li   return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
577*67e74705SXin Li }
578*67e74705SXin Li 
getLValueCallIndex() const579*67e74705SXin Li unsigned APValue::getLValueCallIndex() const {
580*67e74705SXin Li   assert(isLValue() && "Invalid accessor");
581*67e74705SXin Li   return ((const LV*)(const char*)Data.buffer)->CallIndex;
582*67e74705SXin Li }
583*67e74705SXin Li 
setLValue(LValueBase B,const CharUnits & O,NoLValuePath,unsigned CallIndex)584*67e74705SXin Li void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
585*67e74705SXin Li                         unsigned CallIndex) {
586*67e74705SXin Li   assert(isLValue() && "Invalid accessor");
587*67e74705SXin Li   LV &LVal = *((LV*)(char*)Data.buffer);
588*67e74705SXin Li   LVal.BaseAndIsOnePastTheEnd.setPointer(B);
589*67e74705SXin Li   LVal.BaseAndIsOnePastTheEnd.setInt(false);
590*67e74705SXin Li   LVal.Offset = O;
591*67e74705SXin Li   LVal.CallIndex = CallIndex;
592*67e74705SXin Li   LVal.resizePath((unsigned)-1);
593*67e74705SXin Li }
594*67e74705SXin Li 
setLValue(LValueBase B,const CharUnits & O,ArrayRef<LValuePathEntry> Path,bool IsOnePastTheEnd,unsigned CallIndex)595*67e74705SXin Li void APValue::setLValue(LValueBase B, const CharUnits &O,
596*67e74705SXin Li                         ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
597*67e74705SXin Li                         unsigned CallIndex) {
598*67e74705SXin Li   assert(isLValue() && "Invalid accessor");
599*67e74705SXin Li   LV &LVal = *((LV*)(char*)Data.buffer);
600*67e74705SXin Li   LVal.BaseAndIsOnePastTheEnd.setPointer(B);
601*67e74705SXin Li   LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
602*67e74705SXin Li   LVal.Offset = O;
603*67e74705SXin Li   LVal.CallIndex = CallIndex;
604*67e74705SXin Li   LVal.resizePath(Path.size());
605*67e74705SXin Li   memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
606*67e74705SXin Li }
607*67e74705SXin Li 
getMemberPointerDecl() const608*67e74705SXin Li const ValueDecl *APValue::getMemberPointerDecl() const {
609*67e74705SXin Li   assert(isMemberPointer() && "Invalid accessor");
610*67e74705SXin Li   const MemberPointerData &MPD =
611*67e74705SXin Li       *((const MemberPointerData *)(const char *)Data.buffer);
612*67e74705SXin Li   return MPD.MemberAndIsDerivedMember.getPointer();
613*67e74705SXin Li }
614*67e74705SXin Li 
isMemberPointerToDerivedMember() const615*67e74705SXin Li bool APValue::isMemberPointerToDerivedMember() const {
616*67e74705SXin Li   assert(isMemberPointer() && "Invalid accessor");
617*67e74705SXin Li   const MemberPointerData &MPD =
618*67e74705SXin Li       *((const MemberPointerData *)(const char *)Data.buffer);
619*67e74705SXin Li   return MPD.MemberAndIsDerivedMember.getInt();
620*67e74705SXin Li }
621*67e74705SXin Li 
getMemberPointerPath() const622*67e74705SXin Li ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
623*67e74705SXin Li   assert(isMemberPointer() && "Invalid accessor");
624*67e74705SXin Li   const MemberPointerData &MPD =
625*67e74705SXin Li       *((const MemberPointerData *)(const char *)Data.buffer);
626*67e74705SXin Li   return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
627*67e74705SXin Li }
628*67e74705SXin Li 
MakeLValue()629*67e74705SXin Li void APValue::MakeLValue() {
630*67e74705SXin Li   assert(isUninit() && "Bad state change");
631*67e74705SXin Li   static_assert(sizeof(LV) <= DataSize, "LV too big");
632*67e74705SXin Li   new ((void*)(char*)Data.buffer) LV();
633*67e74705SXin Li   Kind = LValue;
634*67e74705SXin Li }
635*67e74705SXin Li 
MakeArray(unsigned InitElts,unsigned Size)636*67e74705SXin Li void APValue::MakeArray(unsigned InitElts, unsigned Size) {
637*67e74705SXin Li   assert(isUninit() && "Bad state change");
638*67e74705SXin Li   new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
639*67e74705SXin Li   Kind = Array;
640*67e74705SXin Li }
641*67e74705SXin Li 
MakeMemberPointer(const ValueDecl * Member,bool IsDerivedMember,ArrayRef<const CXXRecordDecl * > Path)642*67e74705SXin Li void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
643*67e74705SXin Li                                 ArrayRef<const CXXRecordDecl*> Path) {
644*67e74705SXin Li   assert(isUninit() && "Bad state change");
645*67e74705SXin Li   MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
646*67e74705SXin Li   Kind = MemberPointer;
647*67e74705SXin Li   MPD->MemberAndIsDerivedMember.setPointer(Member);
648*67e74705SXin Li   MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
649*67e74705SXin Li   MPD->resizePath(Path.size());
650*67e74705SXin Li   memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
651*67e74705SXin Li }
652