clang  9.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 FixedPoint: {
180  APFixedPoint FXCopy = RHS.getFixedPoint();
181  MakeFixedPoint(std::move(FXCopy));
182  break;
183  }
184  case Vector:
185  MakeVector();
186  setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
187  RHS.getVectorLength());
188  break;
189  case ComplexInt:
190  MakeComplexInt();
192  break;
193  case ComplexFloat:
194  MakeComplexFloat();
196  break;
197  case LValue:
198  MakeLValue();
199  if (RHS.hasLValuePath())
201  RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
202  else
204  RHS.isNullPointer());
205  break;
206  case Array:
207  MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
208  for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
210  if (RHS.hasArrayFiller())
211  getArrayFiller() = RHS.getArrayFiller();
212  break;
213  case Struct:
214  MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
215  for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
216  getStructBase(I) = RHS.getStructBase(I);
217  for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
218  getStructField(I) = RHS.getStructField(I);
219  break;
220  case Union:
221  MakeUnion();
222  setUnion(RHS.getUnionField(), RHS.getUnionValue());
223  break;
224  case MemberPointer:
225  MakeMemberPointer(RHS.getMemberPointerDecl(),
227  RHS.getMemberPointerPath());
228  break;
229  case AddrLabelDiff:
230  MakeAddrLabelDiff();
232  break;
233  }
234 }
235 
236 void APValue::DestroyDataAndMakeUninit() {
237  if (Kind == Int)
238  ((APSInt*)(char*)Data.buffer)->~APSInt();
239  else if (Kind == Float)
240  ((APFloat*)(char*)Data.buffer)->~APFloat();
241  else if (Kind == FixedPoint)
242  ((APFixedPoint *)(char *)Data.buffer)->~APFixedPoint();
243  else if (Kind == Vector)
244  ((Vec*)(char*)Data.buffer)->~Vec();
245  else if (Kind == ComplexInt)
246  ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
247  else if (Kind == ComplexFloat)
248  ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
249  else if (Kind == LValue)
250  ((LV*)(char*)Data.buffer)->~LV();
251  else if (Kind == Array)
252  ((Arr*)(char*)Data.buffer)->~Arr();
253  else if (Kind == Struct)
254  ((StructData*)(char*)Data.buffer)->~StructData();
255  else if (Kind == Union)
256  ((UnionData*)(char*)Data.buffer)->~UnionData();
257  else if (Kind == MemberPointer)
258  ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
259  else if (Kind == AddrLabelDiff)
260  ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
262 }
263 
264 bool APValue::needsCleanup() const {
265  switch (getKind()) {
266  case Uninitialized:
267  case AddrLabelDiff:
268  return false;
269  case Struct:
270  case Union:
271  case Array:
272  case Vector:
273  return true;
274  case Int:
275  return getInt().needsCleanup();
276  case Float:
277  return getFloat().needsCleanup();
278  case FixedPoint:
279  return getFixedPoint().getValue().needsCleanup();
280  case ComplexFloat:
281  assert(getComplexFloatImag().needsCleanup() ==
283  "In _Complex float types, real and imaginary values always have the "
284  "same size.");
285  return getComplexFloatReal().needsCleanup();
286  case ComplexInt:
287  assert(getComplexIntImag().needsCleanup() ==
289  "In _Complex int types, real and imaginary values must have the "
290  "same size.");
291  return getComplexIntReal().needsCleanup();
292  case LValue:
293  return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
294  case MemberPointer:
295  return reinterpret_cast<const MemberPointerData *>(Data.buffer)
296  ->hasPathPtr();
297  }
298  llvm_unreachable("Unknown APValue kind!");
299 }
300 
301 void APValue::swap(APValue &RHS) {
302  std::swap(Kind, RHS.Kind);
303  char TmpData[DataSize];
304  memcpy(TmpData, Data.buffer, DataSize);
305  memcpy(Data.buffer, RHS.Data.buffer, DataSize);
306  memcpy(RHS.Data.buffer, TmpData, DataSize);
307 }
308 
309 LLVM_DUMP_METHOD void APValue::dump() const {
310  dump(llvm::errs());
311  llvm::errs() << '\n';
312 }
313 
314 static double GetApproxValue(const llvm::APFloat &F) {
315  llvm::APFloat V = F;
316  bool ignored;
317  V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
318  &ignored);
319  return V.convertToDouble();
320 }
321 
322 void APValue::dump(raw_ostream &OS) const {
323  switch (getKind()) {
324  case Uninitialized:
325  OS << "Uninitialized";
326  return;
327  case Int:
328  OS << "Int: " << getInt();
329  return;
330  case Float:
331  OS << "Float: " << GetApproxValue(getFloat());
332  return;
333  case FixedPoint:
334  OS << "FixedPoint : " << getFixedPoint();
335  return;
336  case Vector:
337  OS << "Vector: ";
338  getVectorElt(0).dump(OS);
339  for (unsigned i = 1; i != getVectorLength(); ++i) {
340  OS << ", ";
341  getVectorElt(i).dump(OS);
342  }
343  return;
344  case ComplexInt:
345  OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
346  return;
347  case ComplexFloat:
348  OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
349  << ", " << GetApproxValue(getComplexFloatImag());
350  return;
351  case LValue:
352  OS << "LValue: <todo>";
353  return;
354  case Array:
355  OS << "Array: ";
356  for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) {
358  if (I != getArraySize() - 1) OS << ", ";
359  }
360  if (hasArrayFiller()) {
361  OS << getArraySize() - getArrayInitializedElts() << " x ";
362  getArrayFiller().dump(OS);
363  }
364  return;
365  case Struct:
366  OS << "Struct ";
367  if (unsigned N = getStructNumBases()) {
368  OS << " bases: ";
369  getStructBase(0).dump(OS);
370  for (unsigned I = 1; I != N; ++I) {
371  OS << ", ";
372  getStructBase(I).dump(OS);
373  }
374  }
375  if (unsigned N = getStructNumFields()) {
376  OS << " fields: ";
377  getStructField(0).dump(OS);
378  for (unsigned I = 1; I != N; ++I) {
379  OS << ", ";
380  getStructField(I).dump(OS);
381  }
382  }
383  return;
384  case Union:
385  OS << "Union: ";
386  getUnionValue().dump(OS);
387  return;
388  case MemberPointer:
389  OS << "MemberPointer: <todo>";
390  return;
391  case AddrLabelDiff:
392  OS << "AddrLabelDiff: <todo>";
393  return;
394  }
395  llvm_unreachable("Unknown APValue kind!");
396 }
397 
398 void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
399  switch (getKind()) {
401  Out << "<uninitialized>";
402  return;
403  case APValue::Int:
404  if (Ty->isBooleanType())
405  Out << (getInt().getBoolValue() ? "true" : "false");
406  else
407  Out << getInt();
408  return;
409  case APValue::Float:
410  Out << GetApproxValue(getFloat());
411  return;
412  case APValue::FixedPoint:
413  Out << getFixedPoint();
414  return;
415  case APValue::Vector: {
416  Out << '{';
417  QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
418  getVectorElt(0).printPretty(Out, Ctx, ElemTy);
419  for (unsigned i = 1; i != getVectorLength(); ++i) {
420  Out << ", ";
421  getVectorElt(i).printPretty(Out, Ctx, ElemTy);
422  }
423  Out << '}';
424  return;
425  }
426  case APValue::ComplexInt:
427  Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
428  return;
430  Out << GetApproxValue(getComplexFloatReal()) << "+"
431  << GetApproxValue(getComplexFloatImag()) << "i";
432  return;
433  case APValue::LValue: {
434  bool IsReference = Ty->isReferenceType();
435  QualType InnerTy
436  = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
437  if (InnerTy.isNull())
438  InnerTy = Ty;
439 
441  if (!Base) {
442  if (isNullPointer()) {
443  Out << (Ctx.getLangOpts().CPlusPlus11 ? "nullptr" : "0");
444  } else if (IsReference) {
445  Out << "*(" << InnerTy.stream(Ctx.getPrintingPolicy()) << "*)"
447  } else {
448  Out << "(" << Ty.stream(Ctx.getPrintingPolicy()) << ")"
450  }
451  return;
452  }
453 
454  if (!hasLValuePath()) {
455  // No lvalue path: just print the offset.
457  CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
458  if (!O.isZero()) {
459  if (IsReference)
460  Out << "*(";
461  if (O % S) {
462  Out << "(char*)";
463  S = CharUnits::One();
464  }
465  Out << '&';
466  } else if (!IsReference)
467  Out << '&';
468 
469  if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
470  Out << *VD;
471  else {
472  assert(Base.get<const Expr *>() != nullptr &&
473  "Expecting non-null Expr");
474  Base.get<const Expr*>()->printPretty(Out, nullptr,
475  Ctx.getPrintingPolicy());
476  }
477 
478  if (!O.isZero()) {
479  Out << " + " << (O / S);
480  if (IsReference)
481  Out << ')';
482  }
483  return;
484  }
485 
486  // We have an lvalue path. Print it out nicely.
487  if (!IsReference)
488  Out << '&';
489  else if (isLValueOnePastTheEnd())
490  Out << "*(&";
491 
492  QualType ElemTy;
493  if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
494  Out << *VD;
495  ElemTy = VD->getType();
496  } else {
497  const Expr *E = Base.get<const Expr*>();
498  assert(E != nullptr && "Expecting non-null Expr");
499  E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
500  ElemTy = E->getType();
501  }
502 
504  const CXXRecordDecl *CastToBase = nullptr;
505  for (unsigned I = 0, N = Path.size(); I != N; ++I) {
506  if (ElemTy->getAs<RecordType>()) {
507  // The lvalue refers to a class type, so the next path entry is a base
508  // or member.
509  const Decl *BaseOrMember =
510  BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
511  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
512  CastToBase = RD;
513  ElemTy = Ctx.getRecordType(RD);
514  } else {
515  const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
516  Out << ".";
517  if (CastToBase)
518  Out << *CastToBase << "::";
519  Out << *VD;
520  ElemTy = VD->getType();
521  }
522  } else {
523  // The lvalue must refer to an array.
524  Out << '[' << Path[I].ArrayIndex << ']';
525  ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
526  }
527  }
528 
529  // Handle formatting of one-past-the-end lvalues.
530  if (isLValueOnePastTheEnd()) {
531  // FIXME: If CastToBase is non-0, we should prefix the output with
532  // "(CastToBase*)".
533  Out << " + 1";
534  if (IsReference)
535  Out << ')';
536  }
537  return;
538  }
539  case APValue::Array: {
540  const ArrayType *AT = Ctx.getAsArrayType(Ty);
541  QualType ElemTy = AT->getElementType();
542  Out << '{';
543  if (unsigned N = getArrayInitializedElts()) {
544  getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy);
545  for (unsigned I = 1; I != N; ++I) {
546  Out << ", ";
547  if (I == 10) {
548  // Avoid printing out the entire contents of large arrays.
549  Out << "...";
550  break;
551  }
552  getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy);
553  }
554  }
555  Out << '}';
556  return;
557  }
558  case APValue::Struct: {
559  Out << '{';
560  const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
561  bool First = true;
562  if (unsigned N = getStructNumBases()) {
563  const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
565  for (unsigned I = 0; I != N; ++I, ++BI) {
566  assert(BI != CD->bases_end());
567  if (!First)
568  Out << ", ";
569  getStructBase(I).printPretty(Out, Ctx, BI->getType());
570  First = false;
571  }
572  }
573  for (const auto *FI : RD->fields()) {
574  if (!First)
575  Out << ", ";
576  if (FI->isUnnamedBitfield()) continue;
577  getStructField(FI->getFieldIndex()).
578  printPretty(Out, Ctx, FI->getType());
579  First = false;
580  }
581  Out << '}';
582  return;
583  }
584  case APValue::Union:
585  Out << '{';
586  if (const FieldDecl *FD = getUnionField()) {
587  Out << "." << *FD << " = ";
588  getUnionValue().printPretty(Out, Ctx, FD->getType());
589  }
590  Out << '}';
591  return;
593  // FIXME: This is not enough to unambiguously identify the member in a
594  // multiple-inheritance scenario.
595  if (const ValueDecl *VD = getMemberPointerDecl()) {
596  Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
597  return;
598  }
599  Out << "0";
600  return;
602  Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
603  Out << " - ";
604  Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
605  return;
606  }
607  llvm_unreachable("Unknown APValue kind!");
608 }
609 
610 std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
611  std::string Result;
612  llvm::raw_string_ostream Out(Result);
613  printPretty(Out, Ctx, Ty);
614  Out.flush();
615  return Result;
616 }
617 
619  assert(isLValue() && "Invalid accessor");
620  return ((const LV*)(const void*)Data.buffer)->Base;
621 }
622 
624  assert(isLValue() && "Invalid accessor");
625  return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
626 }
627 
629  assert(isLValue() && "Invalid accessor");
630  return ((LV*)(void*)Data.buffer)->Offset;
631 }
632 
634  assert(isLValue() && "Invalid accessor");
635  return ((const LV*)(const char*)Data.buffer)->hasPath();
636 }
637 
639  assert(isLValue() && hasLValuePath() && "Invalid accessor");
640  const LV &LVal = *((const LV*)(const char*)Data.buffer);
641  return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
642 }
643 
644 unsigned APValue::getLValueCallIndex() const {
645  assert(isLValue() && "Invalid accessor");
646  return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
647 }
648 
649 unsigned APValue::getLValueVersion() const {
650  assert(isLValue() && "Invalid accessor");
651  return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
652 }
653 
655  assert(isLValue() && "Invalid usage");
656  return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
657 }
658 
660  bool IsNullPtr) {
661  assert(isLValue() && "Invalid accessor");
662  LV &LVal = *((LV*)(char*)Data.buffer);
663  LVal.Base = B;
664  LVal.IsOnePastTheEnd = false;
665  LVal.Offset = O;
666  LVal.resizePath((unsigned)-1);
667  LVal.IsNullPtr = IsNullPtr;
668 }
669 
671  ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
672  bool IsNullPtr) {
673  assert(isLValue() && "Invalid accessor");
674  LV &LVal = *((LV*)(char*)Data.buffer);
675  LVal.Base = B;
676  LVal.IsOnePastTheEnd = IsOnePastTheEnd;
677  LVal.Offset = O;
678  LVal.resizePath(Path.size());
679  memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
680  LVal.IsNullPtr = IsNullPtr;
681 }
682 
684  assert(isMemberPointer() && "Invalid accessor");
685  const MemberPointerData &MPD =
686  *((const MemberPointerData *)(const char *)Data.buffer);
687  return MPD.MemberAndIsDerivedMember.getPointer();
688 }
689 
691  assert(isMemberPointer() && "Invalid accessor");
692  const MemberPointerData &MPD =
693  *((const MemberPointerData *)(const char *)Data.buffer);
694  return MPD.MemberAndIsDerivedMember.getInt();
695 }
696 
698  assert(isMemberPointer() && "Invalid accessor");
699  const MemberPointerData &MPD =
700  *((const MemberPointerData *)(const char *)Data.buffer);
701  return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
702 }
703 
704 void APValue::MakeLValue() {
705  assert(isUninit() && "Bad state change");
706  static_assert(sizeof(LV) <= DataSize, "LV too big");
707  new ((void*)(char*)Data.buffer) LV();
708  Kind = LValue;
709 }
710 
711 void APValue::MakeArray(unsigned InitElts, unsigned Size) {
712  assert(isUninit() && "Bad state change");
713  new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
714  Kind = Array;
715 }
716 
717 void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
719  assert(isUninit() && "Bad state change");
720  MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
722  MPD->MemberAndIsDerivedMember.setPointer(Member);
723  MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
724  MPD->resizePath(Path.size());
725  memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
726 }
unsigned getStructNumFields() const
Definition: APValue.h:371
Defines the clang::ASTContext interface.
void resizePath(unsigned Length)
Definition: APValue.cpp:92
A (possibly-)qualified type.
Definition: Type.h:638
llvm::APSInt getValue() const
Definition: FixedPoint.h:111
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:6248
bool isUninit() const
Definition: APValue.h:238
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:2815
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:406
QualType getElementType() const
Definition: Type.h:2850
APFloat & getComplexFloatReal()
Definition: APValue.h:298
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6755
void dump() const
Definition: APValue.cpp:309
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:638
static double GetApproxValue(const llvm::APFloat &F)
Definition: APValue.cpp:314
bool isLValueOnePastTheEnd() const
Definition: APValue.cpp:623
const ValueDecl * getMemberPointerDecl() const
Definition: APValue.cpp:683
Represents a struct/union/class.
Definition: Decl.h:3593
unsigned getVersion() const
Definition: APValue.h:96
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:155
field_range fields() const
Definition: Decl.h:3784
Represents a member of a struct/union/class.
Definition: Decl.h:2579
unsigned getCallIndex() const
Definition: APValue.h:88
bool isReferenceType() const
Definition: Type.h:6311
const PathElem * getPath() const
Definition: APValue.cpp:143
unsigned getArraySize() const
Definition: APValue.h:362
unsigned getLValueCallIndex() const
Definition: APValue.cpp:644
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:654
std::string getAsString(ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:610
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:398
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:264
APSInt & getComplexIntReal()
Definition: APValue.h:282
APValue & getVectorElt(unsigned I)
Definition: APValue.h:326
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
Definition: FixedPoint.h:96
unsigned getLValueVersion() const
Definition: APValue.cpp:649
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition: CharUnits.h:58
bool hasLValuePath() const
Definition: APValue.cpp:633
APValue & getArrayFiller()
Definition: APValue.h:350
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:347
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:637
This represents one expression.
Definition: Expr.h:107
bool hasPath() const
Definition: APValue.cpp:102
#define bool
Definition: stdbool.h:31
QualType getType() const
Definition: Expr.h:129
APValue & getStructField(unsigned i)
Definition: APValue.h:379
QualType getRecordType(const RecordDecl *Decl) const
Represents a GCC generic vector type.
Definition: Type.h:3171
bool isNullPointer() const
Definition: APValue.cpp:654
APSInt & getComplexIntImag()
Definition: APValue.h:290
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:703
const FieldDecl * getUnionField() const
Definition: APValue.h:390
void setVector(const APValue *E, unsigned N)
Definition: APValue.h:427
APValue & getStructBase(unsigned i)
Definition: APValue.h:375
unsigned getStructNumBases() const
Definition: APValue.h:367
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:339
Kind
const LValueBase getLValueBase() const
Definition: APValue.cpp:618
void * getOpaqueValue() const
Definition: APValue.cpp:34
void setInt(APSInt I)
Definition: APValue.h:415
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
Definition: APValue.cpp:659
const AddrLabelExpr * getAddrLabelDiffRHS() const
Definition: APValue.h:410
APValue & getUnionValue()
Definition: APValue.h:394
APFloat & getFloat()
Definition: APValue.h:266
bool isMemberPointer() const
Definition: APValue.h:249
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Definition: APValue.h:458
LValuePathEntry * getPath()
Definition: APValue.cpp:105
bool isLValue() const
Definition: APValue.h:244
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
bool isMemberPointerToDerivedMember() const
Definition: APValue.cpp:690
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:1027
Dataflow Directional Tag Classes.
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
Definition: APValue.cpp:301
bool isBooleanType() const
Definition: Type.h:6664
unsigned getArrayInitializedElts() const
Definition: APValue.h:358
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Definition: APValue.cpp:697
void resizePath(unsigned Length)
Definition: APValue.cpp:130
LabelDecl * getLabel() const
Definition: Expr.h:3786
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4373
const CXXRecordDecl * PathElem
Definition: APValue.cpp:121
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
Definition: APValue.h:39
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:237
APFloat & getComplexFloatImag()
Definition: APValue.h:306
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:276
void setFloat(APFloat F)
Definition: APValue.h:419
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:434
void setUnion(const FieldDecl *Field, const APValue &Value)
Definition: APValue.h:453
APSInt & getInt()
Definition: APValue.h:258
const LangOptions & getLangOpts() const
Definition: ASTContext.h:707
APFixedPoint & getFixedPoint()
Definition: APValue.h:274
void setComplexFloat(APFloat R, APFloat I)
Definition: APValue.h:441
CharUnits & getLValueOffset()
Definition: APValue.cpp:628
unsigned getVectorLength() const
Definition: APValue.h:334