clang  3.9.0
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 "clang/Basic/Diagnostic.h"
21 #include "llvm/ADT/SmallString.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/raw_ostream.h"
24 using namespace clang;
25 
26 namespace {
27  struct LVBase {
28  llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
30  unsigned PathLength;
31  unsigned CallIndex;
32  };
33 }
34 
35 struct APValue::LV : LVBase {
36  static const unsigned InlinePathSpace =
37  (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
38 
39  /// Path - The sequence of base classes, fields and array indices to follow to
40  /// walk from Base to the subobject. When performing GCC-style folding, there
41  /// may not be such a path.
42  union {
45  };
46 
47  LV() { PathLength = (unsigned)-1; }
48  ~LV() { resizePath(0); }
49 
50  void resizePath(unsigned Length) {
51  if (Length == PathLength)
52  return;
53  if (hasPathPtr())
54  delete [] PathPtr;
55  PathLength = Length;
56  if (hasPathPtr())
58  }
59 
60  bool hasPath() const { return PathLength != (unsigned)-1; }
61  bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }
62 
64  const LValuePathEntry *getPath() const {
65  return hasPathPtr() ? PathPtr : Path;
66  }
67 };
68 
69 namespace {
70  struct MemberPointerBase {
71  llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
72  unsigned PathLength;
73  };
74 }
75 
76 struct APValue::MemberPointerData : MemberPointerBase {
77  static const unsigned InlinePathSpace =
78  (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
79  typedef const CXXRecordDecl *PathElem;
80  union {
83  };
84 
85  MemberPointerData() { PathLength = 0; }
87 
88  void resizePath(unsigned Length) {
89  if (Length == PathLength)
90  return;
91  if (hasPathPtr())
92  delete [] PathPtr;
93  PathLength = Length;
94  if (hasPathPtr())
95  PathPtr = new PathElem[Length];
96  }
97 
98  bool hasPathPtr() const { return PathLength > InlinePathSpace; }
99 
100  PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
101  const PathElem *getPath() const {
102  return hasPathPtr() ? PathPtr : Path;
103  }
104 };
105 
106 // FIXME: Reduce the malloc traffic here.
107 
108 APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
109  Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
110  NumElts(NumElts), ArrSize(Size) {}
111 APValue::Arr::~Arr() { delete [] Elts; }
112 
113 APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
114  Elts(new APValue[NumBases+NumFields]),
115  NumBases(NumBases), NumFields(NumFields) {}
116 APValue::StructData::~StructData() {
117  delete [] Elts;
118 }
119 
120 APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
121 APValue::UnionData::~UnionData () {
122  delete Value;
123 }
124 
125 APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
126  switch (RHS.getKind()) {
127  case Uninitialized:
128  break;
129  case Int:
130  MakeInt();
131  setInt(RHS.getInt());
132  break;
133  case Float:
134  MakeFloat();
135  setFloat(RHS.getFloat());
136  break;
137  case Vector:
138  MakeVector();
139  setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
140  RHS.getVectorLength());
141  break;
142  case ComplexInt:
143  MakeComplexInt();
145  break;
146  case ComplexFloat:
147  MakeComplexFloat();
149  break;
150  case LValue:
151  MakeLValue();
152  if (RHS.hasLValuePath())
155  else
157  RHS.getLValueCallIndex());
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)
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  unsigned CallIndex) {
586  assert(isLValue() && "Invalid accessor");
587  LV &LVal = *((LV*)(char*)Data.buffer);
588  LVal.BaseAndIsOnePastTheEnd.setPointer(B);
589  LVal.BaseAndIsOnePastTheEnd.setInt(false);
590  LVal.Offset = O;
591  LVal.CallIndex = CallIndex;
592  LVal.resizePath((unsigned)-1);
593 }
594 
596  ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
597  unsigned CallIndex) {
598  assert(isLValue() && "Invalid accessor");
599  LV &LVal = *((LV*)(char*)Data.buffer);
600  LVal.BaseAndIsOnePastTheEnd.setPointer(B);
601  LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
602  LVal.Offset = O;
603  LVal.CallIndex = CallIndex;
604  LVal.resizePath(Path.size());
605  memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
606 }
607 
609  assert(isMemberPointer() && "Invalid accessor");
610  const MemberPointerData &MPD =
611  *((const MemberPointerData *)(const char *)Data.buffer);
612  return MPD.MemberAndIsDerivedMember.getPointer();
613 }
614 
616  assert(isMemberPointer() && "Invalid accessor");
617  const MemberPointerData &MPD =
618  *((const MemberPointerData *)(const char *)Data.buffer);
619  return MPD.MemberAndIsDerivedMember.getInt();
620 }
621 
623  assert(isMemberPointer() && "Invalid accessor");
624  const MemberPointerData &MPD =
625  *((const MemberPointerData *)(const char *)Data.buffer);
626  return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
627 }
628 
629 void APValue::MakeLValue() {
630  assert(isUninit() && "Bad state change");
631  static_assert(sizeof(LV) <= DataSize, "LV too big");
632  new ((void*)(char*)Data.buffer) LV();
633  Kind = LValue;
634 }
635 
636 void APValue::MakeArray(unsigned InitElts, unsigned Size) {
637  assert(isUninit() && "Bad state change");
638  new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
639  Kind = Array;
640 }
641 
642 void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
643  ArrayRef<const CXXRecordDecl*> Path) {
644  assert(isUninit() && "Bad state change");
645  MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
647  MPD->MemberAndIsDerivedMember.setPointer(Member);
648  MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
649  MPD->resizePath(Path.size());
650  memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
651 }
Defines the clang::ASTContext interface.
void resizePath(unsigned Length)
Definition: APValue.cpp:50
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:237
const FieldDecl * getUnionField() const
Definition: APValue.h:322
unsigned Length
A (possibly-)qualified type.
Definition: Type.h:598
C Language Family Type Representation.
bool isMemberPointer() const
Definition: APValue.h:191
QualType getRecordType(const RecordDecl *Decl) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:2456
bool hasLValuePath() const
Definition: APValue.cpp:568
bool isBooleanType() const
Definition: Type.h:5743
bool hasPath() const
Definition: APValue.cpp:60
const LValuePathEntry * getPath() const
Definition: APValue.cpp:64
APFloat & getComplexFloatReal()
Definition: APValue.h:232
static double GetApproxValue(const llvm::APFloat &F)
Definition: APValue.cpp:263
RecordDecl - Represents a struct/union/class.
Definition: Decl.h:3253
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Definition: APValue.cpp:622
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
bool isReferenceType() const
Definition: Type.h:5491
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Definition: Decl.h:2293
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:44
const ValueDecl * getMemberPointerDecl() const
Definition: APValue.cpp:608
unsigned getStructNumFields() const
Definition: APValue.h:303
field_range fields() const
Definition: Decl.h:3382
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
bool needsCleanup() const
Returns whether the object performed allocations.
Definition: APValue.cpp:215
LValuePathEntry Path[InlinePathSpace]
Definition: APValue.cpp:43
base_class_iterator bases_begin()
Definition: DeclCXX.h:725
LValuePathEntry * PathPtr
Definition: APValue.cpp:44
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
detail::InMemoryDirectory::const_iterator I
APSInt & getComplexIntReal()
Definition: APValue.h:216
void dump() const
Definition: APValue.cpp:258
APValue & getVectorElt(unsigned I)
Definition: APValue.h:258
static const unsigned InlinePathSpace
Definition: APValue.cpp:77
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition: CharUnits.h:58
APValue & getArrayFiller()
Definition: APValue.h:282
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:415
unsigned getArrayInitializedElts() const
Definition: APValue.h:290
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Definition: Decl.h:590
Expr - This represents one expression.
Definition: Expr.h:105
bool isMemberPointerToDerivedMember() const
Definition: APValue.cpp:615
bool hasPathPtr() const
Definition: APValue.cpp:61
APValue & getStructField(unsigned i)
Definition: APValue.h:311
Represents a GCC generic vector type.
Definition: Type.h:2756
PathElem Path[InlinePathSpace]
Definition: APValue.cpp:81
APSInt & getComplexIntImag()
Definition: APValue.h:224
The result type of a method or function.
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:553
bool isLValueOnePastTheEnd() const
Definition: APValue.cpp:558
void setVector(const APValue *E, unsigned N)
Definition: APValue.h:355
APValue & getStructBase(unsigned i)
Definition: APValue.h:307
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:271
Kind
bool isUninit() const
Definition: APValue.h:181
void setInt(APSInt I)
Definition: APValue.h:347
unsigned getStructNumBases() const
Definition: APValue.h:299
const AddrLabelExpr * getAddrLabelDiffLHS() const
Definition: APValue.h:338
APValue & getUnionValue()
Definition: APValue.h:326
ValueKind getKind() const
Definition: APValue.h:180
APFloat & getFloat()
Definition: APValue.h:208
const PathElem * getPath() const
Definition: APValue.cpp:101
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, unsigned CallIndex)
Definition: APValue.cpp:584
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Definition: APValue.h:386
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:344
LValuePathEntry * getPath()
Definition: APValue.cpp:63
const AddrLabelExpr * getAddrLabelDiffRHS() const
Definition: APValue.h:342
QualType getType() const
Definition: Expr.h:126
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:116
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
Definition: APValue.cpp:250
std::string getAsString(ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:545
detail::InMemoryDirectory::const_iterator E
Defines the Diagnostic-related interfaces.
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:5432
void resizePath(unsigned Length)
Definition: APValue.cpp:88
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:573
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:3707
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:5818
llvm::PointerUnion< const ValueDecl *, const Expr * > LValueBase
Definition: APValue.h:56
const CXXRecordDecl * PathElem
Definition: APValue.cpp:79
LabelDecl * getLabel() const
Definition: Expr.h:3361
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:159
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
APFloat & getComplexFloatImag()
Definition: APValue.h:240
const LValueBase getLValueBase() const
Definition: APValue.cpp:553
Represents a C++ struct/union/class.
Definition: DeclCXX.h:263
base_class_iterator bases_end()
Definition: DeclCXX.h:727
QualType getElementType() const
Definition: Type.h:2490
void setFloat(APFloat F)
Definition: APValue.h:351
void setComplexInt(APSInt R, APSInt I)
Definition: APValue.h:362
void setUnion(const FieldDecl *Field, const APValue &Value)
Definition: APValue.h:381
APSInt & getInt()
Definition: APValue.h:200
unsigned getArraySize() const
Definition: APValue.h:294
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:665
unsigned getVectorLength() const
Definition: APValue.h:266
bool hasArrayFiller() const
Definition: APValue.h:279
void setComplexFloat(APFloat R, APFloat I)
Definition: APValue.h:369
static const unsigned InlinePathSpace
Definition: APValue.cpp:36
CharUnits & getLValueOffset()
Definition: APValue.cpp:563
bool isLValue() const
Definition: APValue.h:186