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