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