clang  8.0.0svn
APValue.cpp
Go to the documentation of this file.
1 //===--- 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"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/CharUnits.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/Type.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/raw_ostream.h"
22 using namespace clang;
23 
24 namespace {
25  struct LVBase {
28  unsigned PathLength;
29  bool IsNullPtr : 1;
30  bool IsOnePastTheEnd : 1;
31  };
32 }
33 
35  return Ptr.getOpaqueValue();
36 }
37 
39  return Ptr.isNull();
40 }
41 
42 APValue::LValueBase::operator bool () const {
43  return static_cast<bool>(Ptr);
44 }
45 
52 }
53 
60 }
61 
64  llvm::FoldingSetNodeID ID;
65  ID.AddPointer(Base.getOpaqueValue());
66  ID.AddInteger(Base.getCallIndex());
67  ID.AddInteger(Base.getVersion());
68  return ID.ComputeHash();
69 }
70 
72  const clang::APValue::LValueBase &LHS,
73  const clang::APValue::LValueBase &RHS) {
74  return LHS == RHS;
75 }
76 
77 struct APValue::LV : LVBase {
78  static const unsigned InlinePathSpace =
79  (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
80 
81  /// Path - The sequence of base classes, fields and array indices to follow to
82  /// walk from Base to the subobject. When performing GCC-style folding, there
83  /// may not be such a path.
84  union {
85  LValuePathEntry Path[InlinePathSpace];
87  };
88 
89  LV() { PathLength = (unsigned)-1; }
90  ~LV() { resizePath(0); }
91 
92  void resizePath(unsigned Length) {
93  if (Length == PathLength)
94  return;
95  if (hasPathPtr())
96  delete [] PathPtr;
97  PathLength = Length;
98  if (hasPathPtr())
99  PathPtr = new LValuePathEntry[Length];
100  }
101 
102  bool hasPath() const { return PathLength != (unsigned)-1; }
103  bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }
104 
105  LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }
106  const LValuePathEntry *getPath() const {
107  return hasPathPtr() ? PathPtr : Path;
108  }
109 };
110 
111 namespace {
112  struct MemberPointerBase {
113  llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
114  unsigned PathLength;
115  };
116 }
117 
118 struct APValue::MemberPointerData : MemberPointerBase {
119  static const unsigned InlinePathSpace =
120  (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
121  typedef const CXXRecordDecl *PathElem;
122  union {
123  PathElem Path[InlinePathSpace];
124  PathElem *PathPtr;
125  };
126 
127  MemberPointerData() { PathLength = 0; }
128  ~MemberPointerData() { resizePath(0); }
129 
130  void resizePath(unsigned Length) {
131  if (Length == PathLength)
132  return;
133  if (hasPathPtr())
134  delete [] PathPtr;
135  PathLength = Length;
136  if (hasPathPtr())
137  PathPtr = new PathElem[Length];
138  }
139 
140  bool hasPathPtr() const { return PathLength > InlinePathSpace; }
141 
142  PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
143  const PathElem *getPath() const {
144  return hasPathPtr() ? PathPtr : Path;
145  }
146 };
147 
148 // FIXME: Reduce the malloc traffic here.
149 
150 APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
151  Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
152  NumElts(NumElts), ArrSize(Size) {}
153 APValue::Arr::~Arr() { delete [] Elts; }
154 
155 APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
156  Elts(new APValue[NumBases+NumFields]),
157  NumBases(NumBases), NumFields(NumFields) {}
158 APValue::StructData::~StructData() {
159  delete [] Elts;
160 }
161 
162 APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
163 APValue::UnionData::~UnionData () {
164  delete Value;
165 }
166 
168  switch (RHS.getKind()) {
169  case Uninitialized:
170  break;
171  case Int:
172  MakeInt();
173  setInt(RHS.getInt());
174  break;
175  case Float:
176  MakeFloat();
177  setFloat(RHS.getFloat());
178  break;
179  case Vector:
180  MakeVector();
181  setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
182  RHS.getVectorLength());
183  break;
184  case ComplexInt:
185  MakeComplexInt();
187  break;
188  case ComplexFloat:
189  MakeComplexFloat();
191  break;
192  case LValue:
193  MakeLValue();
194  if (RHS.hasLValuePath())
196  RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
197  else
199  RHS.isNullPointer());
200  break;
201  case Array:
202  MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
203  for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
205  if (RHS.hasArrayFiller())
206  getArrayFiller() = RHS.getArrayFiller();
207  break;
208  case Struct:
209  MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
210  for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
211  getStructBase(I) = RHS.getStructBase(I);
212  for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
213  getStructField(I) = RHS.getStructField(I);
214  break;
215  case Union:
216  MakeUnion();
217  setUnion(RHS.getUnionField(), RHS.getUnionValue());
218  break;
219  case MemberPointer:
220  MakeMemberPointer(RHS.getMemberPointerDecl(),
222  RHS.getMemberPointerPath());
223  break;
224  case AddrLabelDiff:
225  MakeAddrLabelDiff();
227  break;
228  }
229 }
230 
231 void APValue::DestroyDataAndMakeUninit() {
232  if (Kind == Int)
233  ((APSInt*)(char*)Data.buffer)->~APSInt();
234  else if (Kind == Float)
235  ((APFloat*)(char*)Data.buffer)->~APFloat();
236  else if (Kind == Vector)
237  ((Vec*)(char*)Data.buffer)->~Vec();
238  else if (Kind == ComplexInt)
239  ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
240  else if (Kind == ComplexFloat)
241  ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
242  else if (Kind == LValue)
243  ((LV*)(char*)Data.buffer)->~LV();
244  else if (Kind == Array)
245  ((Arr*)(char*)Data.buffer)->~Arr();
246  else if (Kind == Struct)
247  ((StructData*)(char*)Data.buffer)->~StructData();
248  else if (Kind == Union)
249  ((UnionData*)(char*)Data.buffer)->~UnionData();
250  else if (Kind == MemberPointer)
251  ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
252  else if (Kind == AddrLabelDiff)
253  ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
255 }
256 
257 bool APValue::needsCleanup() const {
258  switch (getKind()) {
259  case Uninitialized:
260  case AddrLabelDiff:
261  return false;
262  case Struct:
263  case Union:
264  case Array:
265  case Vector:
266  return true;
267  case Int:
268  return getInt().needsCleanup();
269  case Float:
270  return getFloat().needsCleanup();
271  case ComplexFloat:
272  assert(getComplexFloatImag().needsCleanup() ==
274  "In _Complex float types, real and imaginary values always have the "
275  "same size.");
276  return getComplexFloatReal().needsCleanup();
277  case ComplexInt:
278  assert(getComplexIntImag().needsCleanup() ==
280  "In _Complex int types, real and imaginary values must have the "
281  "same size.");
282  return getComplexIntReal().needsCleanup();
283  case LValue:
284  return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
285  case MemberPointer:
286  return reinterpret_cast<const MemberPointerData *>(Data.buffer)
287  ->hasPathPtr();
288  }
289  llvm_unreachable("Unknown APValue kind!");
290 }
291 
292 void APValue::swap(APValue &RHS) {
293  std::swap(Kind, RHS.Kind);
294  char TmpData[DataSize];
295  memcpy(TmpData, Data.buffer, DataSize);
296  memcpy(Data.buffer, RHS.Data.buffer, DataSize);
297  memcpy(RHS.Data.buffer, TmpData, DataSize);
298 }
299 
300 LLVM_DUMP_METHOD void APValue::dump() const {
301  dump(llvm::errs());
302  llvm::errs() << '\n';
303 }
304 
305 static double GetApproxValue(const llvm::APFloat &F) {
306  llvm::APFloat V = F;
307  bool ignored;
308  V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
309  &ignored);
310  return V.convertToDouble();
311 }
312 
313 void APValue::dump(raw_ostream &OS) const {
314  switch (getKind()) {
315  case Uninitialized:
316  OS << "Uninitialized";
317  return;
318  case Int:
319  OS << "Int: " << getInt();
320  return;
321  case Float:
322  OS << "Float: " << GetApproxValue(getFloat());
323  return;
324  case Vector:
325  OS << "Vector: ";
326  getVectorElt(0).dump(OS);
327  for (unsigned i = 1; i != getVectorLength(); ++i) {
328  OS << ", ";
329  getVectorElt(i).dump(OS);
330  }
331  return;
332  case ComplexInt:
333  OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
334  return;
335  case ComplexFloat:
336  OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
337  << ", " << GetApproxValue(getComplexFloatImag());
338  return;
339  case LValue:
340  OS << "LValue: <todo>";
341  return;
342  case Array:
343  OS << "Array: ";
344  for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) {
346  if (I != getArraySize() - 1) OS << ", ";
347  }
348  if (hasArrayFiller()) {
349  OS << getArraySize() - getArrayInitializedElts() << " x ";
350  getArrayFiller().dump(OS);
351  }
352  return;
353  case Struct:
354  OS << "Struct ";
355  if (unsigned N = getStructNumBases()) {
356  OS << " bases: ";
357  getStructBase(0).dump(OS);
358  for (unsigned I = 1; I != N; ++I) {
359  OS << ", ";
360  getStructBase(I).dump(OS);
361  }
362  }
363  if (unsigned N = getStructNumFields()) {
364  OS << " fields: ";
365  getStructField(0).dump(OS);
366  for (unsigned I = 1; I != N; ++I) {
367  OS << ", ";
368  getStructField(I).dump(OS);
369  }
370  }
371  return;
372  case Union:
373  OS << "Union: ";
374  getUnionValue().dump(OS);
375  return;
376  case MemberPointer:
377  OS << "MemberPointer: <todo>";
378  return;
379  case AddrLabelDiff:
380  OS << "AddrLabelDiff: <todo>";
381  return;
382  }
383  llvm_unreachable("Unknown APValue kind!");
384 }
385 
386 void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
387  switch (getKind()) {
389  Out << "<uninitialized>";
390  return;
391  case APValue::Int:
392  if (Ty->isBooleanType())
393  Out << (getInt().getBoolValue() ? "true" : "false");
394  else
395  Out << getInt();
396  return;
397  case APValue::Float:
398  Out << GetApproxValue(getFloat());
399  return;
400  case APValue::Vector: {
401  Out << '{';
402  QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
403  getVectorElt(0).printPretty(Out, Ctx, ElemTy);
404  for (unsigned i = 1; i != getVectorLength(); ++i) {
405  Out << ", ";
406  getVectorElt(i).printPretty(Out, Ctx, ElemTy);
407  }
408  Out << '}';
409  return;
410  }
411  case APValue::ComplexInt:
412  Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
413  return;
415  Out << GetApproxValue(getComplexFloatReal()) << "+"
416  << GetApproxValue(getComplexFloatImag()) << "i";
417  return;
418  case APValue::LValue: {
419  bool IsReference = Ty->isReferenceType();
420  QualType InnerTy
421  = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
422  if (InnerTy.isNull())
423  InnerTy = Ty;
424 
426  if (!Base) {
427  if (isNullPointer()) {
428  Out << (Ctx.getLangOpts().CPlusPlus11 ? "nullptr" : "0");
429  } else if (IsReference) {
430  Out << "*(" << InnerTy.stream(Ctx.getPrintingPolicy()) << "*)"
432  } else {
433  Out << "(" << Ty.stream(Ctx.getPrintingPolicy()) << ")"
435  }
436  return;
437  }
438 
439  if (!hasLValuePath()) {
440  // No lvalue path: just print the offset.
442  CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
443  if (!O.isZero()) {
444  if (IsReference)
445  Out << "*(";
446  if (O % S) {
447  Out << "(char*)";
448  S = CharUnits::One();
449  }
450  Out << '&';
451  } else if (!IsReference)
452  Out << '&';
453 
454  if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
455  Out << *VD;
456  else {
457  assert(Base.get<const Expr *>() != nullptr &&
458  "Expecting non-null Expr");
459  Base.get<const Expr*>()->printPretty(Out, nullptr,
460  Ctx.getPrintingPolicy());
461  }
462 
463  if (!O.isZero()) {
464  Out << " + " << (O / S);
465  if (IsReference)
466  Out << ')';
467  }
468  return;
469  }
470 
471  // We have an lvalue path. Print it out nicely.
472  if (!IsReference)
473  Out << '&';
474  else if (isLValueOnePastTheEnd())
475  Out << "*(&";
476 
477  QualType ElemTy;
478  if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
479  Out << *VD;
480  ElemTy = VD->getType();
481  } else {
482  const Expr *E = Base.get<const Expr*>();
483  assert(E != nullptr && "Expecting non-null Expr");
484  E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
485  ElemTy = E->getType();
486  }
487 
489  const CXXRecordDecl *CastToBase = nullptr;
490  for (unsigned I = 0, N = Path.size(); I != N; ++I) {
491  if (ElemTy->getAs<RecordType>()) {
492  // The lvalue refers to a class type, so the next path entry is a base
493  // or member.
494  const Decl *BaseOrMember =
495  BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
496  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
497  CastToBase = RD;
498  ElemTy = Ctx.getRecordType(RD);
499  } else {
500  const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
501  Out << ".";
502  if (CastToBase)
503  Out << *CastToBase << "::";
504  Out << *VD;
505  ElemTy = VD->getType();
506  }
507  } else {
508  // The lvalue must refer to an array.
509  Out << '[' << Path[I].ArrayIndex << ']';
510  ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
511  }
512  }
513 
514  // Handle formatting of one-past-the-end lvalues.
515  if (isLValueOnePastTheEnd()) {
516  // FIXME: If CastToBase is non-0, we should prefix the output with
517  // "(CastToBase*)".
518  Out << " + 1";
519  if (IsReference)
520  Out << ')';
521  }
522  return;
523  }
524  case APValue::Array: {
525  const ArrayType *AT = Ctx.getAsArrayType(Ty);
526  QualType ElemTy = AT->getElementType();
527  Out << '{';
528  if (unsigned N = getArrayInitializedElts()) {
529  getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy);
530  for (unsigned I = 1; I != N; ++I) {
531  Out << ", ";
532  if (I == 10) {
533  // Avoid printing out the entire contents of large arrays.
534  Out << "...";
535  break;
536  }
537  getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy);
538  }
539  }
540  Out << '}';
541  return;
542  }
543  case APValue::Struct: {
544  Out << '{';
545  const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
546  bool First = true;
547  if (unsigned N = getStructNumBases()) {
548  const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
550  for (unsigned I = 0; I != N; ++I, ++BI) {
551  assert(BI != CD->bases_end());
552  if (!First)
553  Out << ", ";
554  getStructBase(I).printPretty(Out, Ctx, BI->getType());
555  First = false;
556  }
557  }
558  for (const auto *FI : RD->fields()) {
559  if (!First)
560  Out << ", ";
561  if (FI->isUnnamedBitfield()) continue;
562  getStructField(FI->getFieldIndex()).
563  printPretty(Out, Ctx, FI->getType());
564  First = false;
565  }
566  Out << '}';
567  return;
568  }
569  case APValue::Union:
570  Out << '{';
571  if (const FieldDecl *FD = getUnionField()) {
572  Out << "." << *FD << " = ";
573  getUnionValue().printPretty(Out, Ctx, FD->getType());
574  }
575  Out << '}';
576  return;
578  // FIXME: This is not enough to unambiguously identify the member in a
579  // multiple-inheritance scenario.
580  if (const ValueDecl *VD = getMemberPointerDecl()) {
581  Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
582  return;
583  }
584  Out << "0";
585  return;
587  Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
588  Out << " - ";
589  Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
590  return;
591  }
592  llvm_unreachable("Unknown APValue kind!");
593 }
594 
595 std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
596  std::string Result;
597  llvm::raw_string_ostream Out(Result);
598  printPretty(Out, Ctx, Ty);
599  Out.flush();
600  return Result;
601 }
602 
604  assert(isLValue() && "Invalid accessor");
605  return ((const LV*)(const void*)Data.buffer)->Base;
606 }
607 
609  assert(isLValue() && "Invalid accessor");
610  return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
611 }
612 
614  assert(isLValue() && "Invalid accessor");
615  return ((LV*)(void*)Data.buffer)->Offset;
616 }
617 
619  assert(isLValue() && "Invalid accessor");
620  return ((const LV*)(const char*)Data.buffer)->hasPath();
621 }
622 
624  assert(isLValue() && hasLValuePath() && "Invalid accessor");
625  const LV &LVal = *((const LV*)(const char*)Data.buffer);
626  return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
627 }
628 
629 unsigned APValue::getLValueCallIndex() const {
630  assert(isLValue() && "Invalid accessor");
631  return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
632 }
633 
634 unsigned APValue::getLValueVersion() const {
635  assert(isLValue() && "Invalid accessor");
636  return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
637 }
638 
640  assert(isLValue() && "Invalid usage");
641  return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
642 }
643 
645  bool IsNullPtr) {
646  assert(isLValue() && "Invalid accessor");
647  LV &LVal = *((LV*)(char*)Data.buffer);
648  LVal.Base = B;
649  LVal.IsOnePastTheEnd = false;
650  LVal.Offset = O;
651  LVal.resizePath((unsigned)-1);
652  LVal.IsNullPtr = IsNullPtr;
653 }
654 
656  ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
657  bool IsNullPtr) {
658  assert(isLValue() && "Invalid accessor");
659  LV &LVal = *((LV*)(char*)Data.buffer);
660  LVal.Base = B;
661  LVal.IsOnePastTheEnd = IsOnePastTheEnd;
662  LVal.Offset = O;
663  LVal.resizePath(Path.size());
664  memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
665  LVal.IsNullPtr = IsNullPtr;
666 }
667 
669  assert(isMemberPointer() && "Invalid accessor");
670  const MemberPointerData &MPD =
671  *((const MemberPointerData *)(const char *)Data.buffer);
672  return MPD.MemberAndIsDerivedMember.getPointer();
673 }
674 
676  assert(isMemberPointer() && "Invalid accessor");
677  const MemberPointerData &MPD =
678  *((const MemberPointerData *)(const char *)Data.buffer);
679  return MPD.MemberAndIsDerivedMember.getInt();
680 }
681 
683  assert(isMemberPointer() && "Invalid accessor");
684  const MemberPointerData &MPD =
685  *((const MemberPointerData *)(const char *)Data.buffer);
686  return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
687 }
688 
689 void APValue::MakeLValue() {
690  assert(isUninit() && "Bad state change");
691  static_assert(sizeof(LV) <= DataSize, "LV too big");
692  new ((void*)(char*)Data.buffer) LV();
693  Kind = LValue;
694 }
695 
696 void APValue::MakeArray(unsigned InitElts, unsigned Size) {
697  assert(isUninit() && "Bad state change");
698  new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
699  Kind = Array;
700 }
701 
702 void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
704  assert(isUninit() && "Bad state change");
705  MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
707  MPD->MemberAndIsDerivedMember.setPointer(Member);
708  MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
709  MPD->resizePath(Path.size());
710  memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
711 }
unsigned getStructNumFields() const
Definition: APValue.h:357
Defines the clang::ASTContext interface.
void resizePath(unsigned Length)
Definition: APValue.cpp:92
A (possibly-)qualified type.
Definition: Type.h:642
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:505
C Language Family Type Representation.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:6231
bool isUninit() const
Definition: APValue.h:233
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:2818
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:116
bool hasPathPtr() const
Definition: APValue.cpp:103
const LValuePathEntry * getPath() const
Definition: APValue.cpp:106
const AddrLabelExpr * getAddrLabelDiffLHS() const
Definition: APValue.h:392
QualType getElementType() const
Definition: Type.h:2853
APFloat & getComplexFloatReal()
Definition: APValue.h:284
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6716
void dump() const
Definition: APValue.cpp:300
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:623
static double GetApproxValue(const llvm::APFloat &F)
Definition: APValue.cpp:305
bool isLValueOnePastTheEnd() const
Definition: APValue.cpp:608
const ValueDecl * getMemberPointerDecl() const
Definition: APValue.cpp:668
Represents a struct/union/class.
Definition: Decl.h:3602
unsigned getVersion() const
Definition: APValue.h:94
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
field_range fields() const
Definition: Decl.h:3793
Represents a member of a struct/union/class.
Definition: Decl.h:2588
unsigned getCallIndex() const
Definition: APValue.h:86
bool isReferenceType() const
Definition: Type.h:6294
const PathElem * getPath() const
Definition: APValue.cpp:143
unsigned getArraySize() const
Definition: APValue.h:348
unsigned getLValueCallIndex() const
Definition: APValue.cpp:629
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:653
std::string getAsString(ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:595
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:386
base_class_iterator bases_begin()
Definition: DeclCXX.h:830
LValuePathEntry * PathPtr
Definition: APValue.cpp:86
bool needsCleanup() const
Returns whether the object performed allocations.
Definition: APValue.cpp:257
APSInt & getComplexIntReal()
Definition: APValue.h:268
APValue & getVectorElt(unsigned I)
Definition: APValue.h:312
unsigned getLValueVersion() const
Definition: APValue.cpp:634
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition: CharUnits.h:58
bool hasLValuePath() const
Definition: APValue.cpp:618
APValue & getArrayFiller()
Definition: APValue.h:336
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:179
unsigned Offset
Definition: Format.cpp:1631
bool hasArrayFiller() const
Definition: APValue.h:333
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:636
This represents one expression.
Definition: Expr.h:106
bool hasPath() const
Definition: APValue.cpp:102
#define bool
Definition: stdbool.h:31
QualType getType() const
Definition: Expr.h:128
APValue & getStructField(unsigned i)
Definition: APValue.h:365
QualType getRecordType(const RecordDecl *Decl) const
Represents a GCC generic vector type.
Definition: Type.h:3174
bool isNullPointer() const
Definition: APValue.cpp:639
APSInt & getComplexIntImag()
Definition: APValue.h:276
The result type of a method or function.
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:707
const FieldDecl * getUnionField() const
Definition: APValue.h:376
void setVector(const APValue *E, unsigned N)
Definition: APValue.h:409
APValue & getStructBase(unsigned i)
Definition: APValue.h:361
unsigned getStructNumBases() const
Definition: APValue.h:353
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:325
Kind
const LValueBase getLValueBase() const
Definition: APValue.cpp:603
void * getOpaqueValue() const
Definition: APValue.cpp:34
void setInt(APSInt I)
Definition: APValue.h:401
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
Definition: APValue.cpp:644
const AddrLabelExpr * getAddrLabelDiffRHS() const
Definition: APValue.h:396
APValue & getUnionValue()
Definition: APValue.h:380
APFloat & getFloat()
Definition: APValue.h:260
bool isMemberPointer() const
Definition: APValue.h:243
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Definition: APValue.h:440
LValuePathEntry * getPath()
Definition: APValue.cpp:105
bool isLValue() const
Definition: APValue.h:238
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
bool isMemberPointerToDerivedMember() const
Definition: APValue.cpp:675
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:1035
Dataflow Directional Tag Classes.
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
Definition: APValue.cpp:292
bool isBooleanType() const
Definition: Type.h:6643
unsigned getArrayInitializedElts() const
Definition: APValue.h:344
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Definition: APValue.cpp:682
void resizePath(unsigned Length)
Definition: APValue.cpp:130
LabelDecl * getLabel() const
Definition: Expr.h:3725
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4356
const CXXRecordDecl * PathElem
Definition: APValue.cpp:121
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
Definition: APValue.h:38
Represents a base class of a C++ class.
Definition: DeclCXX.h:192
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
ValueKind getKind() const
Definition: APValue.h:232
APFloat & getComplexFloatImag()
Definition: APValue.h:292
Represents a C++ struct/union/class.
Definition: DeclCXX.h:300
base_class_iterator bases_end()
Definition: DeclCXX.h:832
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:275
void setFloat(APFloat F)
Definition: APValue.h:405
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
void setComplexInt(APSInt R, APSInt I)
Definition: APValue.h:416
void setUnion(const FieldDecl *Field, const APValue &Value)
Definition: APValue.h:435
APSInt & getInt()
Definition: APValue.h:252
const LangOptions & getLangOpts() const
Definition: ASTContext.h:706
void setComplexFloat(APFloat R, APFloat I)
Definition: APValue.h:423
CharUnits & getLValueOffset()
Definition: APValue.cpp:613
unsigned getVectorLength() const
Definition: APValue.h:320