clang  10.0.0svn
APValue.cpp
Go to the documentation of this file.
1 //===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the APValue class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/APValue.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/CharUnits.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/AST/Type.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
21 using namespace clang;
22 
23 /// The identity of a type_info object depends on the canonical unqualified
24 /// type only.
26  : T(T->getCanonicalTypeUnqualified().getTypePtr()) {}
27 
28 void TypeInfoLValue::print(llvm::raw_ostream &Out,
29  const PrintingPolicy &Policy) const {
30  Out << "typeid(";
31  QualType(getType(), 0).print(Out, Policy);
32  Out << ")";
33 }
34 
35 static_assert(
37  alignof(Type),
38  "Type is insufficiently aligned");
39 
40 APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)
41  : Ptr(P), Local{I, V} {}
42 APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
43  : Ptr(P), Local{I, V} {}
44 
46  QualType Type) {
48  Base.Ptr = LV;
49  Base.DynamicAllocType = Type.getAsOpaquePtr();
50  return Base;
51 }
52 
56  Base.Ptr = LV;
57  Base.TypeInfoType = TypeInfo.getAsOpaquePtr();
58  return Base;
59 }
60 
62  return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0
63  : Local.CallIndex;
64 }
65 
67  return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 : Local.Version;
68 }
69 
71  assert(is<TypeInfoLValue>() && "not a type_info lvalue");
73 }
74 
76  assert(is<DynamicAllocLValue>() && "not a dynamic allocation lvalue");
78 }
79 
80 namespace clang {
82  const APValue::LValueBase &RHS) {
83  if (LHS.Ptr != RHS.Ptr)
84  return false;
85  if (LHS.is<TypeInfoLValue>())
86  return true;
87  return LHS.Local.CallIndex == RHS.Local.CallIndex &&
88  LHS.Local.Version == RHS.Local.Version;
89 }
90 }
91 
92 namespace {
93  struct LVBase {
96  unsigned PathLength;
97  bool IsNullPtr : 1;
98  bool IsOnePastTheEnd : 1;
99  };
100 }
101 
103  return Ptr.getOpaqueValue();
104 }
105 
107  return Ptr.isNull();
108 }
109 
110 APValue::LValueBase::operator bool () const {
111  return static_cast<bool>(Ptr);
112 }
113 
118 }
119 
124 }
125 
126 namespace clang {
127 llvm::hash_code hash_value(const APValue::LValueBase &Base) {
128  if (Base.is<TypeInfoLValue>() || Base.is<DynamicAllocLValue>())
129  return llvm::hash_value(Base.getOpaqueValue());
130  return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(),
131  Base.getVersion());
132 }
133 }
134 
137  return hash_value(Base);
138 }
139 
141  const clang::APValue::LValueBase &LHS,
142  const clang::APValue::LValueBase &RHS) {
143  return LHS == RHS;
144 }
145 
146 struct APValue::LV : LVBase {
147  static const unsigned InlinePathSpace =
148  (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
149 
150  /// Path - The sequence of base classes, fields and array indices to follow to
151  /// walk from Base to the subobject. When performing GCC-style folding, there
152  /// may not be such a path.
153  union {
154  LValuePathEntry Path[InlinePathSpace];
156  };
157 
158  LV() { PathLength = (unsigned)-1; }
159  ~LV() { resizePath(0); }
160 
161  void resizePath(unsigned Length) {
162  if (Length == PathLength)
163  return;
164  if (hasPathPtr())
165  delete [] PathPtr;
166  PathLength = Length;
167  if (hasPathPtr())
168  PathPtr = new LValuePathEntry[Length];
169  }
170 
171  bool hasPath() const { return PathLength != (unsigned)-1; }
172  bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }
173 
174  LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }
175  const LValuePathEntry *getPath() const {
176  return hasPathPtr() ? PathPtr : Path;
177  }
178 };
179 
180 namespace {
181  struct MemberPointerBase {
182  llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
183  unsigned PathLength;
184  };
185 }
186 
187 struct APValue::MemberPointerData : MemberPointerBase {
188  static const unsigned InlinePathSpace =
189  (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
190  typedef const CXXRecordDecl *PathElem;
191  union {
192  PathElem Path[InlinePathSpace];
193  PathElem *PathPtr;
194  };
195 
196  MemberPointerData() { PathLength = 0; }
197  ~MemberPointerData() { resizePath(0); }
198 
199  void resizePath(unsigned Length) {
200  if (Length == PathLength)
201  return;
202  if (hasPathPtr())
203  delete [] PathPtr;
204  PathLength = Length;
205  if (hasPathPtr())
206  PathPtr = new PathElem[Length];
207  }
208 
209  bool hasPathPtr() const { return PathLength > InlinePathSpace; }
210 
211  PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
212  const PathElem *getPath() const {
213  return hasPathPtr() ? PathPtr : Path;
214  }
215 };
216 
217 // FIXME: Reduce the malloc traffic here.
218 
219 APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
220  Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
221  NumElts(NumElts), ArrSize(Size) {}
222 APValue::Arr::~Arr() { delete [] Elts; }
223 
224 APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
225  Elts(new APValue[NumBases+NumFields]),
226  NumBases(NumBases), NumFields(NumFields) {}
227 APValue::StructData::~StructData() {
228  delete [] Elts;
229 }
230 
231 APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
232 APValue::UnionData::~UnionData () {
233  delete Value;
234 }
235 
237  switch (RHS.getKind()) {
238  case None:
239  case Indeterminate:
240  Kind = RHS.getKind();
241  break;
242  case Int:
243  MakeInt();
244  setInt(RHS.getInt());
245  break;
246  case Float:
247  MakeFloat();
248  setFloat(RHS.getFloat());
249  break;
250  case FixedPoint: {
251  APFixedPoint FXCopy = RHS.getFixedPoint();
252  MakeFixedPoint(std::move(FXCopy));
253  break;
254  }
255  case Vector:
256  MakeVector();
257  setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
258  RHS.getVectorLength());
259  break;
260  case ComplexInt:
261  MakeComplexInt();
263  break;
264  case ComplexFloat:
265  MakeComplexFloat();
267  break;
268  case LValue:
269  MakeLValue();
270  if (RHS.hasLValuePath())
272  RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
273  else
275  RHS.isNullPointer());
276  break;
277  case Array:
278  MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
279  for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
281  if (RHS.hasArrayFiller())
282  getArrayFiller() = RHS.getArrayFiller();
283  break;
284  case Struct:
285  MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
286  for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
287  getStructBase(I) = RHS.getStructBase(I);
288  for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
289  getStructField(I) = RHS.getStructField(I);
290  break;
291  case Union:
292  MakeUnion();
293  setUnion(RHS.getUnionField(), RHS.getUnionValue());
294  break;
295  case MemberPointer:
296  MakeMemberPointer(RHS.getMemberPointerDecl(),
298  RHS.getMemberPointerPath());
299  break;
300  case AddrLabelDiff:
301  MakeAddrLabelDiff();
303  break;
304  }
305 }
306 
307 void APValue::DestroyDataAndMakeUninit() {
308  if (Kind == Int)
309  ((APSInt*)(char*)Data.buffer)->~APSInt();
310  else if (Kind == Float)
311  ((APFloat*)(char*)Data.buffer)->~APFloat();
312  else if (Kind == FixedPoint)
313  ((APFixedPoint *)(char *)Data.buffer)->~APFixedPoint();
314  else if (Kind == Vector)
315  ((Vec*)(char*)Data.buffer)->~Vec();
316  else if (Kind == ComplexInt)
317  ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
318  else if (Kind == ComplexFloat)
319  ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
320  else if (Kind == LValue)
321  ((LV*)(char*)Data.buffer)->~LV();
322  else if (Kind == Array)
323  ((Arr*)(char*)Data.buffer)->~Arr();
324  else if (Kind == Struct)
325  ((StructData*)(char*)Data.buffer)->~StructData();
326  else if (Kind == Union)
327  ((UnionData*)(char*)Data.buffer)->~UnionData();
328  else if (Kind == MemberPointer)
329  ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
330  else if (Kind == AddrLabelDiff)
331  ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
332  Kind = None;
333 }
334 
335 bool APValue::needsCleanup() const {
336  switch (getKind()) {
337  case None:
338  case Indeterminate:
339  case AddrLabelDiff:
340  return false;
341  case Struct:
342  case Union:
343  case Array:
344  case Vector:
345  return true;
346  case Int:
347  return getInt().needsCleanup();
348  case Float:
349  return getFloat().needsCleanup();
350  case FixedPoint:
351  return getFixedPoint().getValue().needsCleanup();
352  case ComplexFloat:
353  assert(getComplexFloatImag().needsCleanup() ==
355  "In _Complex float types, real and imaginary values always have the "
356  "same size.");
357  return getComplexFloatReal().needsCleanup();
358  case ComplexInt:
359  assert(getComplexIntImag().needsCleanup() ==
361  "In _Complex int types, real and imaginary values must have the "
362  "same size.");
363  return getComplexIntReal().needsCleanup();
364  case LValue:
365  return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
366  case MemberPointer:
367  return reinterpret_cast<const MemberPointerData *>(Data.buffer)
368  ->hasPathPtr();
369  }
370  llvm_unreachable("Unknown APValue kind!");
371 }
372 
373 void APValue::swap(APValue &RHS) {
374  std::swap(Kind, RHS.Kind);
375  char TmpData[DataSize];
376  memcpy(TmpData, Data.buffer, DataSize);
377  memcpy(Data.buffer, RHS.Data.buffer, DataSize);
378  memcpy(RHS.Data.buffer, TmpData, DataSize);
379 }
380 
381 LLVM_DUMP_METHOD void APValue::dump() const {
382  dump(llvm::errs());
383  llvm::errs() << '\n';
384 }
385 
386 static double GetApproxValue(const llvm::APFloat &F) {
387  llvm::APFloat V = F;
388  bool ignored;
389  V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
390  &ignored);
391  return V.convertToDouble();
392 }
393 
394 void APValue::dump(raw_ostream &OS) const {
395  switch (getKind()) {
396  case None:
397  OS << "None";
398  return;
399  case Indeterminate:
400  OS << "Indeterminate";
401  return;
402  case Int:
403  OS << "Int: " << getInt();
404  return;
405  case Float:
406  OS << "Float: " << GetApproxValue(getFloat());
407  return;
408  case FixedPoint:
409  OS << "FixedPoint : " << getFixedPoint();
410  return;
411  case Vector:
412  OS << "Vector: ";
413  getVectorElt(0).dump(OS);
414  for (unsigned i = 1; i != getVectorLength(); ++i) {
415  OS << ", ";
416  getVectorElt(i).dump(OS);
417  }
418  return;
419  case ComplexInt:
420  OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
421  return;
422  case ComplexFloat:
423  OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
424  << ", " << GetApproxValue(getComplexFloatImag());
425  return;
426  case LValue:
427  OS << "LValue: <todo>";
428  return;
429  case Array:
430  OS << "Array: ";
431  for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) {
433  if (I != getArraySize() - 1) OS << ", ";
434  }
435  if (hasArrayFiller()) {
436  OS << getArraySize() - getArrayInitializedElts() << " x ";
437  getArrayFiller().dump(OS);
438  }
439  return;
440  case Struct:
441  OS << "Struct ";
442  if (unsigned N = getStructNumBases()) {
443  OS << " bases: ";
444  getStructBase(0).dump(OS);
445  for (unsigned I = 1; I != N; ++I) {
446  OS << ", ";
447  getStructBase(I).dump(OS);
448  }
449  }
450  if (unsigned N = getStructNumFields()) {
451  OS << " fields: ";
452  getStructField(0).dump(OS);
453  for (unsigned I = 1; I != N; ++I) {
454  OS << ", ";
455  getStructField(I).dump(OS);
456  }
457  }
458  return;
459  case Union:
460  OS << "Union: ";
461  getUnionValue().dump(OS);
462  return;
463  case MemberPointer:
464  OS << "MemberPointer: <todo>";
465  return;
466  case AddrLabelDiff:
467  OS << "AddrLabelDiff: <todo>";
468  return;
469  }
470  llvm_unreachable("Unknown APValue kind!");
471 }
472 
473 void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx,
474  QualType Ty) const {
475  switch (getKind()) {
476  case APValue::None:
477  Out << "<out of lifetime>";
478  return;
480  Out << "<uninitialized>";
481  return;
482  case APValue::Int:
483  if (Ty->isBooleanType())
484  Out << (getInt().getBoolValue() ? "true" : "false");
485  else
486  Out << getInt();
487  return;
488  case APValue::Float:
489  Out << GetApproxValue(getFloat());
490  return;
491  case APValue::FixedPoint:
492  Out << getFixedPoint();
493  return;
494  case APValue::Vector: {
495  Out << '{';
496  QualType ElemTy = Ty->castAs<VectorType>()->getElementType();
497  getVectorElt(0).printPretty(Out, Ctx, ElemTy);
498  for (unsigned i = 1; i != getVectorLength(); ++i) {
499  Out << ", ";
500  getVectorElt(i).printPretty(Out, Ctx, ElemTy);
501  }
502  Out << '}';
503  return;
504  }
505  case APValue::ComplexInt:
506  Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
507  return;
509  Out << GetApproxValue(getComplexFloatReal()) << "+"
510  << GetApproxValue(getComplexFloatImag()) << "i";
511  return;
512  case APValue::LValue: {
513  bool IsReference = Ty->isReferenceType();
514  QualType InnerTy
515  = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
516  if (InnerTy.isNull())
517  InnerTy = Ty;
518 
520  if (!Base) {
521  if (isNullPointer()) {
522  Out << (Ctx.getLangOpts().CPlusPlus11 ? "nullptr" : "0");
523  } else if (IsReference) {
524  Out << "*(" << InnerTy.stream(Ctx.getPrintingPolicy()) << "*)"
526  } else {
527  Out << "(" << Ty.stream(Ctx.getPrintingPolicy()) << ")"
529  }
530  return;
531  }
532 
533  if (!hasLValuePath()) {
534  // No lvalue path: just print the offset.
536  CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
537  if (!O.isZero()) {
538  if (IsReference)
539  Out << "*(";
540  if (O % S) {
541  Out << "(char*)";
542  S = CharUnits::One();
543  }
544  Out << '&';
545  } else if (!IsReference) {
546  Out << '&';
547  }
548 
549  if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
550  Out << *VD;
551  else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
552  TI.print(Out, Ctx.getPrintingPolicy());
553  } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {
554  Out << "{*new "
555  << Base.getDynamicAllocType().stream(Ctx.getPrintingPolicy()) << "#"
556  << DA.getIndex() << "}";
557  } else {
558  assert(Base.get<const Expr *>() != nullptr &&
559  "Expecting non-null Expr");
560  Base.get<const Expr*>()->printPretty(Out, nullptr,
561  Ctx.getPrintingPolicy());
562  }
563 
564  if (!O.isZero()) {
565  Out << " + " << (O / S);
566  if (IsReference)
567  Out << ')';
568  }
569  return;
570  }
571 
572  // We have an lvalue path. Print it out nicely.
573  if (!IsReference)
574  Out << '&';
575  else if (isLValueOnePastTheEnd())
576  Out << "*(&";
577 
578  QualType ElemTy;
579  if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
580  Out << *VD;
581  ElemTy = VD->getType();
582  } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
583  TI.print(Out, Ctx.getPrintingPolicy());
584  ElemTy = Base.getTypeInfoType();
585  } else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {
586  Out << "{*new "
587  << Base.getDynamicAllocType().stream(Ctx.getPrintingPolicy()) << "#"
588  << DA.getIndex() << "}";
589  ElemTy = Base.getDynamicAllocType();
590  } else {
591  const Expr *E = Base.get<const Expr*>();
592  assert(E != nullptr && "Expecting non-null Expr");
593  E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
594  // FIXME: This is wrong if E is a MaterializeTemporaryExpr with an lvalue
595  // adjustment.
596  ElemTy = E->getType();
597  }
598 
600  const CXXRecordDecl *CastToBase = nullptr;
601  for (unsigned I = 0, N = Path.size(); I != N; ++I) {
602  if (ElemTy->getAs<RecordType>()) {
603  // The lvalue refers to a class type, so the next path entry is a base
604  // or member.
605  const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();
606  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
607  CastToBase = RD;
608  ElemTy = Ctx.getRecordType(RD);
609  } else {
610  const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
611  Out << ".";
612  if (CastToBase)
613  Out << *CastToBase << "::";
614  Out << *VD;
615  ElemTy = VD->getType();
616  }
617  } else {
618  // The lvalue must refer to an array.
619  Out << '[' << Path[I].getAsArrayIndex() << ']';
620  ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
621  }
622  }
623 
624  // Handle formatting of one-past-the-end lvalues.
625  if (isLValueOnePastTheEnd()) {
626  // FIXME: If CastToBase is non-0, we should prefix the output with
627  // "(CastToBase*)".
628  Out << " + 1";
629  if (IsReference)
630  Out << ')';
631  }
632  return;
633  }
634  case APValue::Array: {
635  const ArrayType *AT = Ctx.getAsArrayType(Ty);
636  QualType ElemTy = AT->getElementType();
637  Out << '{';
638  if (unsigned N = getArrayInitializedElts()) {
639  getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy);
640  for (unsigned I = 1; I != N; ++I) {
641  Out << ", ";
642  if (I == 10) {
643  // Avoid printing out the entire contents of large arrays.
644  Out << "...";
645  break;
646  }
647  getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy);
648  }
649  }
650  Out << '}';
651  return;
652  }
653  case APValue::Struct: {
654  Out << '{';
655  const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl();
656  bool First = true;
657  if (unsigned N = getStructNumBases()) {
658  const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
660  for (unsigned I = 0; I != N; ++I, ++BI) {
661  assert(BI != CD->bases_end());
662  if (!First)
663  Out << ", ";
664  getStructBase(I).printPretty(Out, Ctx, BI->getType());
665  First = false;
666  }
667  }
668  for (const auto *FI : RD->fields()) {
669  if (!First)
670  Out << ", ";
671  if (FI->isUnnamedBitfield()) continue;
672  getStructField(FI->getFieldIndex()).
673  printPretty(Out, Ctx, FI->getType());
674  First = false;
675  }
676  Out << '}';
677  return;
678  }
679  case APValue::Union:
680  Out << '{';
681  if (const FieldDecl *FD = getUnionField()) {
682  Out << "." << *FD << " = ";
683  getUnionValue().printPretty(Out, Ctx, FD->getType());
684  }
685  Out << '}';
686  return;
688  // FIXME: This is not enough to unambiguously identify the member in a
689  // multiple-inheritance scenario.
690  if (const ValueDecl *VD = getMemberPointerDecl()) {
691  Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
692  return;
693  }
694  Out << "0";
695  return;
697  Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
698  Out << " - ";
699  Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
700  return;
701  }
702  llvm_unreachable("Unknown APValue kind!");
703 }
704 
705 std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const {
706  std::string Result;
707  llvm::raw_string_ostream Out(Result);
708  printPretty(Out, Ctx, Ty);
709  Out.flush();
710  return Result;
711 }
712 
714  const ASTContext &Ctx) const {
715  if (isInt()) {
716  Result = getInt();
717  return true;
718  }
719 
720  if (isLValue() && isNullPointer()) {
721  Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy);
722  return true;
723  }
724 
725  if (isLValue() && !getLValueBase()) {
726  Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy);
727  return true;
728  }
729 
730  return false;
731 }
732 
734  assert(isLValue() && "Invalid accessor");
735  return ((const LV*)(const void*)Data.buffer)->Base;
736 }
737 
739  assert(isLValue() && "Invalid accessor");
740  return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
741 }
742 
744  assert(isLValue() && "Invalid accessor");
745  return ((LV*)(void*)Data.buffer)->Offset;
746 }
747 
749  assert(isLValue() && "Invalid accessor");
750  return ((const LV*)(const char*)Data.buffer)->hasPath();
751 }
752 
754  assert(isLValue() && hasLValuePath() && "Invalid accessor");
755  const LV &LVal = *((const LV*)(const char*)Data.buffer);
756  return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
757 }
758 
759 unsigned APValue::getLValueCallIndex() const {
760  assert(isLValue() && "Invalid accessor");
761  return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
762 }
763 
764 unsigned APValue::getLValueVersion() const {
765  assert(isLValue() && "Invalid accessor");
766  return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
767 }
768 
770  assert(isLValue() && "Invalid usage");
771  return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
772 }
773 
775  bool IsNullPtr) {
776  assert(isLValue() && "Invalid accessor");
777  LV &LVal = *((LV*)(char*)Data.buffer);
778  LVal.Base = B;
779  LVal.IsOnePastTheEnd = false;
780  LVal.Offset = O;
781  LVal.resizePath((unsigned)-1);
782  LVal.IsNullPtr = IsNullPtr;
783 }
784 
786  ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
787  bool IsNullPtr) {
788  assert(isLValue() && "Invalid accessor");
789  LV &LVal = *((LV*)(char*)Data.buffer);
790  LVal.Base = B;
791  LVal.IsOnePastTheEnd = IsOnePastTheEnd;
792  LVal.Offset = O;
793  LVal.resizePath(Path.size());
794  memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
795  LVal.IsNullPtr = IsNullPtr;
796 }
797 
799  assert(isMemberPointer() && "Invalid accessor");
800  const MemberPointerData &MPD =
801  *((const MemberPointerData *)(const char *)Data.buffer);
802  return MPD.MemberAndIsDerivedMember.getPointer();
803 }
804 
806  assert(isMemberPointer() && "Invalid accessor");
807  const MemberPointerData &MPD =
808  *((const MemberPointerData *)(const char *)Data.buffer);
809  return MPD.MemberAndIsDerivedMember.getInt();
810 }
811 
813  assert(isMemberPointer() && "Invalid accessor");
814  const MemberPointerData &MPD =
815  *((const MemberPointerData *)(const char *)Data.buffer);
816  return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
817 }
818 
819 void APValue::MakeLValue() {
820  assert(isAbsent() && "Bad state change");
821  static_assert(sizeof(LV) <= DataSize, "LV too big");
822  new ((void*)(char*)Data.buffer) LV();
823  Kind = LValue;
824 }
825 
826 void APValue::MakeArray(unsigned InitElts, unsigned Size) {
827  assert(isAbsent() && "Bad state change");
828  new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
829  Kind = Array;
830 }
831 
832 void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
834  assert(isAbsent() && "Bad state change");
835  MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
837  MPD->MemberAndIsDerivedMember.setPointer(Member);
838  MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
839  MPD->resizePath(Path.size());
840  memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
841 }
unsigned getStructNumFields() const
Definition: APValue.h:499
Defines the clang::ASTContext interface.
void resizePath(unsigned Length)
Definition: APValue.cpp:161
friend llvm::hash_code hash_value(const LValueBase &Base)
Definition: APValue.cpp:127
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS)
Definition: APValue.cpp:81
A (possibly-)qualified type.
Definition: Type.h:643
llvm::APSInt getValue() const
Definition: FixedPoint.h:110
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
Definition: APValue.cpp:45
unsigned getCallIndex() const
Definition: APValue.cpp:61
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:557
C Language Family Type Representation.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
StringRef P
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:6339
The base class of the type hierarchy.
Definition: Type.h:1436
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:2860
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:116
bool hasPathPtr() const
Definition: APValue.cpp:172
const LValuePathEntry * getPath() const
Definition: APValue.cpp:175
const AddrLabelExpr * getAddrLabelDiffLHS() const
Definition: APValue.h:534
QualType getElementType() const
Definition: Type.h:2881
APFloat & getComplexFloatReal()
Definition: APValue.h:426
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6858
void dump() const
Definition: APValue.cpp:381
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:753
static double GetApproxValue(const llvm::APFloat &F)
Definition: APValue.cpp:386
QualType getTypeInfoType() const
Definition: APValue.cpp:70
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:37
bool isLValueOnePastTheEnd() const
Definition: APValue.cpp:738
const ValueDecl * getMemberPointerDecl() const
Definition: APValue.cpp:798
Represents a struct/union/class.
Definition: Decl.h:3662
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
field_range fields() const
Definition: Decl.h:3877
Represents a member of a struct/union/class.
Definition: Decl.h:2643
bool isReferenceType() const
Definition: Type.h:6403
const PathElem * getPath() const
Definition: APValue.cpp:212
unsigned getArraySize() const
Definition: APValue.h:490
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type...
Definition: ASTContext.h:2683
unsigned getLValueCallIndex() const
Definition: APValue.cpp:759
Symbolic representation of typeid(T) for some type T.
Definition: APValue.h:37
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
Definition: APValue.h:184
llvm::hash_code hash_value(const APValue::LValueBase &Base)
Definition: APValue.cpp:127
static void hash_combine(std::size_t &seed, const T &v)
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:670
bool isInt() const
Definition: APValue.h:361
base_class_iterator bases_begin()
Definition: DeclCXX.h:593
LValuePathEntry * PathPtr
Definition: APValue.cpp:155
bool needsCleanup() const
Returns whether the object performed allocations.
Definition: APValue.cpp:335
void * getAsOpaquePtr() const
Definition: Type.h:688
APSInt & getComplexIntReal()
Definition: APValue.h:410
APValue & getVectorElt(unsigned I)
Definition: APValue.h:454
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
Definition: FixedPoint.h:95
unsigned getLValueVersion() const
Definition: APValue.cpp:764
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition: CharUnits.h:58
unsigned getVersion() const
Definition: APValue.cpp:66
bool hasLValuePath() const
Definition: APValue.cpp:748
APValue & getArrayFiller()
Definition: APValue.h:478
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:179
unsigned Offset
Definition: Format.cpp:1809
bool hasArrayFiller() const
Definition: APValue.h:475
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:644
This represents one expression.
Definition: Expr.h:108
const Type * getType() const
Definition: APValue.h:44
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:705
A non-discriminated union of a base, field, or array index.
Definition: APValue.h:195
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
Definition: APValue.cpp:53
bool hasPath() const
Definition: APValue.cpp:171
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
Definition: APValue.h:186
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:6923
#define V(N, I)
Definition: ASTContext.h:2921
#define bool
Definition: stdbool.h:15
QualType getType() const
Definition: Expr.h:137
APValue & getStructField(unsigned i)
Definition: APValue.h:507
QualType getRecordType(const RecordDecl *Decl) const
Represents a GCC generic vector type.
Definition: Type.h:3206
bool isNullPointer() const
Definition: APValue.cpp:769
APSInt & getComplexIntImag()
Definition: APValue.h:418
The result type of a method or function.
Symbolic representation of a dynamic allocation.
Definition: APValue.h:58
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:708
const FieldDecl * getUnionField() const
Definition: APValue.h:518
void setVector(const APValue *E, unsigned N)
Definition: APValue.h:555
APValue & getStructBase(unsigned i)
Definition: APValue.h:503
unsigned getStructNumBases() const
Definition: APValue.h:495
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:467
This object has an indeterminate value (C++ [basic.indet]).
Definition: APValue.h:123
Kind
const LValueBase getLValueBase() const
Definition: APValue.cpp:733
void * getOpaqueValue() const
Definition: APValue.cpp:102
void setInt(APSInt I)
Definition: APValue.h:543
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
Definition: APValue.cpp:774
const AddrLabelExpr * getAddrLabelDiffRHS() const
Definition: APValue.h:538
APValue & getUnionValue()
Definition: APValue.h:522
APFloat & getFloat()
Definition: APValue.h:394
bool isMemberPointer() const
Definition: APValue.h:371
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Definition: APValue.h:586
LValuePathEntry * getPath()
Definition: APValue.cpp:174
bool isLValue() const
Definition: APValue.h:366
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:473
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
static QualType getFromOpaquePtr(const void *Ptr)
Definition: Type.h:690
bool isMemberPointerToDerivedMember() const
Definition: APValue.cpp:805
QualType getDynamicAllocType() const
Definition: APValue.cpp:75
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:373
bool isAbsent() const
Definition: APValue.h:357
bool isBooleanType() const
Definition: Type.h:6767
unsigned getArrayInitializedElts() const
Definition: APValue.h:486
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
Definition: APValue.cpp:713
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Definition: APValue.cpp:812
void resizePath(unsigned Length)
Definition: APValue.cpp:199
LabelDecl * getLabel() const
Definition: Expr.h:3904
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4444
const CXXRecordDecl * PathElem
Definition: APValue.cpp:190
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
Definition: APValue.h:115
Represents a base class of a C++ class.
Definition: DeclCXX.h:147
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:355
APFloat & getComplexFloatImag()
Definition: APValue.h:434
Represents a C++ struct/union/class.
Definition: DeclCXX.h:255
There is no such object (it&#39;s outside its lifetime).
Definition: APValue.h:121
base_class_iterator bases_end()
Definition: DeclCXX.h:595
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
Definition: APValue.cpp:28
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:275
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
void setFloat(APFloat F)
Definition: APValue.h:547
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:562
void setUnion(const FieldDecl *Field, const APValue &Value)
Definition: APValue.h:581
APSInt & getInt()
Definition: APValue.h:380
const LangOptions & getLangOpts() const
Definition: ASTContext.h:723
APFixedPoint & getFixedPoint()
Definition: APValue.h:402
void setComplexFloat(APFloat R, APFloat I)
Definition: APValue.h:569
CharUnits & getLValueOffset()
Definition: APValue.cpp:743
unsigned getVectorLength() const
Definition: APValue.h:462