clang 20.0.0git
APValue.h
Go to the documentation of this file.
1//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
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 defines the APValue class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_APVALUE_H
14#define LLVM_CLANG_AST_APVALUE_H
15
16#include "clang/Basic/LLVM.h"
17#include "llvm/ADT/APFixedPoint.h"
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APSInt.h"
20#include "llvm/ADT/FoldingSet.h"
21#include "llvm/ADT/PointerIntPair.h"
22#include "llvm/ADT/PointerUnion.h"
23#include "llvm/Support/AlignOf.h"
24
25namespace clang {
26namespace serialization {
27template <typename T> class BasicReaderBase;
28} // end namespace serialization
29
30 class AddrLabelExpr;
31 class ASTContext;
32 class CharUnits;
33 class CXXRecordDecl;
34 class Decl;
36 class Expr;
37 class FieldDecl;
38 struct PrintingPolicy;
39 class Type;
40 class ValueDecl;
41 class QualType;
42
43/// Symbolic representation of typeid(T) for some type T.
45 const Type *T;
46
47public:
49 explicit TypeInfoLValue(const Type *T);
50
51 const Type *getType() const { return T; }
52 explicit operator bool() const { return T; }
53
54 void *getOpaqueValue() { return const_cast<Type*>(T); }
57 V.T = reinterpret_cast<const Type*>(Value);
58 return V;
59 }
60
61 void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
62};
63
64/// Symbolic representation of a dynamic allocation.
66 unsigned Index;
67
68public:
69 DynamicAllocLValue() : Index(0) {}
70 explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
71 unsigned getIndex() { return Index - 1; }
72
73 explicit operator bool() const { return Index != 0; }
74
76 return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
78 }
81 V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
82 return V;
83 }
84
85 static unsigned getMaxIndex() {
86 return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
87 }
88
89 static constexpr int NumLowBitsAvailable = 3;
90};
91}
92
93namespace llvm {
94template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
96 return V.getOpaqueValue();
97 }
100 }
101 // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
102 // to include Type.h.
103 static constexpr int NumLowBitsAvailable = 3;
104};
105
106template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
108 return V.getOpaqueValue();
109 }
112 }
113 static constexpr int NumLowBitsAvailable =
115};
116}
117
118namespace clang {
119/// APValue - This class implements a discriminated union of [uninitialized]
120/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
121/// [Vector: N * APValue], [Array: N * APValue]
122class APValue {
123 typedef llvm::APFixedPoint APFixedPoint;
124 typedef llvm::APSInt APSInt;
125 typedef llvm::APFloat APFloat;
126public:
128 /// There is no such object (it's outside its lifetime).
130 /// This object has an indeterminate value (C++ [basic.indet]).
144 };
145
147 typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
149 PtrTy;
150
151 public:
153 LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
154 LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
157
158 void Profile(llvm::FoldingSetNodeID &ID) const;
159
160 template <class T> bool is() const { return isa<T>(Ptr); }
161
162 template <class T> T get() const { return cast<T>(Ptr); }
163
164 template <class T>
165 T dyn_cast() const { return Ptr.dyn_cast<T>(); }
166
167 void *getOpaqueValue() const;
168
169 bool isNull() const;
170
171 explicit operator bool() const;
172
173 unsigned getCallIndex() const;
174 unsigned getVersion() const;
177
178 QualType getType() const;
179
180 friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
181 friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
182 return !(LHS == RHS);
183 }
184 friend llvm::hash_code hash_value(const LValueBase &Base);
185 friend struct llvm::DenseMapInfo<LValueBase>;
186
187 private:
188 PtrTy Ptr;
189 struct LocalState {
190 unsigned CallIndex, Version;
191 };
192 union {
193 LocalState Local;
194 /// The type std::type_info, if this is a TypeInfoLValue.
196 /// The QualType, if this is a DynamicAllocLValue.
198 };
199 };
200
201 /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
202 /// mean a virtual or non-virtual base class subobject.
203 typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
204
205 /// A non-discriminated union of a base, field, or array index.
207 static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
208 "pointer doesn't fit in 64 bits?");
209 uint64_t Value;
210
211 public:
213 LValuePathEntry(BaseOrMemberType BaseOrMember);
214 static LValuePathEntry ArrayIndex(uint64_t Index) {
216 Result.Value = Index;
217 return Result;
218 }
219
221 return BaseOrMemberType::getFromOpaqueValue(
222 reinterpret_cast<void *>(Value));
223 }
224 uint64_t getAsArrayIndex() const { return Value; }
225
226 void Profile(llvm::FoldingSetNodeID &ID) const;
227
229 return A.Value == B.Value;
230 }
232 return A.Value != B.Value;
233 }
234 friend llvm::hash_code hash_value(LValuePathEntry A) {
235 return llvm::hash_value(A.Value);
236 }
237 };
239 const void *Ty;
240
241 public:
243
246 };
247 struct NoLValuePath {};
248 struct UninitArray {};
249 struct UninitStruct {};
250
251 template <typename Impl> friend class clang::serialization::BasicReaderBase;
252 friend class ASTImporter;
253 friend class ASTNodeImporter;
254
255private:
257
258 struct ComplexAPSInt {
259 APSInt Real, Imag;
260 ComplexAPSInt() : Real(1), Imag(1) {}
261 };
262 struct ComplexAPFloat {
263 APFloat Real, Imag;
264 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
265 };
266 struct LV;
267 struct Vec {
268 APValue *Elts = nullptr;
269 unsigned NumElts = 0;
270 Vec() = default;
271 Vec(const Vec &) = delete;
272 Vec &operator=(const Vec &) = delete;
273 ~Vec() { delete[] Elts; }
274 };
275 struct Arr {
276 APValue *Elts;
277 unsigned NumElts, ArrSize;
278 Arr(unsigned NumElts, unsigned ArrSize);
279 Arr(const Arr &) = delete;
280 Arr &operator=(const Arr &) = delete;
281 ~Arr();
282 };
283 struct StructData {
284 APValue *Elts;
285 unsigned NumBases;
286 unsigned NumFields;
287 StructData(unsigned NumBases, unsigned NumFields);
288 StructData(const StructData &) = delete;
289 StructData &operator=(const StructData &) = delete;
290 ~StructData();
291 };
292 struct UnionData {
293 const FieldDecl *Field;
294 APValue *Value;
295 UnionData();
296 UnionData(const UnionData &) = delete;
297 UnionData &operator=(const UnionData &) = delete;
298 ~UnionData();
299 };
300 struct AddrLabelDiffData {
301 const AddrLabelExpr* LHSExpr;
302 const AddrLabelExpr* RHSExpr;
303 };
304 struct MemberPointerData;
305
306 // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
307 typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
308 ComplexAPFloat, Vec, Arr, StructData,
309 UnionData, AddrLabelDiffData> DataType;
310 static const size_t DataSize = sizeof(DataType);
311
312 DataType Data;
313
314public:
315 /// Creates an empty APValue of type None.
317 /// Creates an integer APValue holding the given value.
318 explicit APValue(APSInt I) : Kind(None) {
319 MakeInt(); setInt(std::move(I));
320 }
321 /// Creates a float APValue holding the given value.
322 explicit APValue(APFloat F) : Kind(None) {
323 MakeFloat(); setFloat(std::move(F));
324 }
325 /// Creates a fixed-point APValue holding the given value.
326 explicit APValue(APFixedPoint FX) : Kind(None) {
327 MakeFixedPoint(std::move(FX));
328 }
329 /// Creates a vector APValue with \p N elements. The elements
330 /// are read from \p E.
331 explicit APValue(const APValue *E, unsigned N) : Kind(None) {
332 MakeVector(); setVector(E, N);
333 }
334 /// Creates an integer complex APValue with the given real and imaginary
335 /// values.
336 APValue(APSInt R, APSInt I) : Kind(None) {
337 MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
338 }
339 /// Creates a float complex APValue with the given real and imaginary values.
340 APValue(APFloat R, APFloat I) : Kind(None) {
341 MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
342 }
343 APValue(const APValue &RHS);
344 APValue(APValue &&RHS);
345 /// Creates an lvalue APValue without an lvalue path.
346 /// \param Base The base of the lvalue.
347 /// \param Offset The offset of the lvalue.
348 /// \param IsNullPtr Whether this lvalue is a null pointer.
350 bool IsNullPtr = false)
351 : Kind(None) {
352 MakeLValue();
353 setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
354 }
355 /// Creates an lvalue APValue with an lvalue path.
356 /// \param Base The base of the lvalue.
357 /// \param Offset The offset of the lvalue.
358 /// \param Path The lvalue path.
359 /// \param OnePastTheEnd Whether this lvalue is one-past-the-end of the
360 /// subobject it points to.
361 /// \param IsNullPtr Whether this lvalue is a null pointer.
363 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
364 bool IsNullPtr = false)
365 : Kind(None) {
366 MakeLValue();
367 setLValue(Base, Offset, Path, OnePastTheEnd, IsNullPtr);
368 }
369 /// Creates a new array APValue.
370 /// \param UninitArray Marker. Pass an empty UninitArray.
371 /// \param InitElts Number of elements you're going to initialize in the
372 /// array.
373 /// \param Size Full size of the array.
374 APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
375 MakeArray(InitElts, Size);
376 }
377 /// Creates a new struct APValue.
378 /// \param UninitStruct Marker. Pass an empty UninitStruct.
379 /// \param NumBases Number of bases.
380 /// \param NumMembers Number of members.
381 APValue(UninitStruct, unsigned NumBases, unsigned NumMembers) : Kind(None) {
382 MakeStruct(NumBases, NumMembers);
383 }
384 /// Creates a new union APValue.
385 /// \param ActiveDecl The FieldDecl of the active union member.
386 /// \param ActiveValue The value of the active union member.
387 explicit APValue(const FieldDecl *ActiveDecl,
388 const APValue &ActiveValue = APValue())
389 : Kind(None) {
390 MakeUnion();
391 setUnion(ActiveDecl, ActiveValue);
392 }
393 /// Creates a new member pointer APValue.
394 /// \param Member Declaration of the member
395 /// \param IsDerivedMember Whether member is a derived one.
396 /// \param Path The path of the member.
397 APValue(const ValueDecl *Member, bool IsDerivedMember,
399 MakeMemberPointer(Member, IsDerivedMember, Path);
400 }
401 /// Creates a new address label diff APValue.
402 /// \param LHSExpr The left-hand side of the difference.
403 /// \param RHSExpr The right-hand side of the difference.
404 APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
405 : Kind(None) {
406 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
407 }
410 Result.Kind = Indeterminate;
411 return Result;
412 }
413
414 APValue &operator=(const APValue &RHS);
415 APValue &operator=(APValue &&RHS);
416
418 if (Kind != None && Kind != Indeterminate)
419 DestroyDataAndMakeUninit();
420 }
421
422 /// Returns whether the object performed allocations.
423 ///
424 /// If APValues are constructed via placement new, \c needsCleanup()
425 /// indicates whether the destructor must be called in order to correctly
426 /// free all allocated memory.
427 bool needsCleanup() const;
428
429 /// Swaps the contents of this and the given APValue.
430 void swap(APValue &RHS);
431
432 /// profile this value. There is no guarantee that values of different
433 /// types will not produce the same profiled value, so the type should
434 /// typically also be profiled if it's not implied by the context.
435 void Profile(llvm::FoldingSetNodeID &ID) const;
436
437 ValueKind getKind() const { return Kind; }
438
439 bool isAbsent() const { return Kind == None; }
440 bool isIndeterminate() const { return Kind == Indeterminate; }
441 bool hasValue() const { return Kind != None && Kind != Indeterminate; }
442
443 bool isInt() const { return Kind == Int; }
444 bool isFloat() const { return Kind == Float; }
445 bool isFixedPoint() const { return Kind == FixedPoint; }
446 bool isComplexInt() const { return Kind == ComplexInt; }
447 bool isComplexFloat() const { return Kind == ComplexFloat; }
448 bool isLValue() const { return Kind == LValue; }
449 bool isVector() const { return Kind == Vector; }
450 bool isArray() const { return Kind == Array; }
451 bool isStruct() const { return Kind == Struct; }
452 bool isUnion() const { return Kind == Union; }
453 bool isMemberPointer() const { return Kind == MemberPointer; }
454 bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
455
456 void dump() const;
457 void dump(raw_ostream &OS, const ASTContext &Context) const;
458
459 void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
460 void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
461 const ASTContext *Ctx = nullptr) const;
462
463 std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
464
465 APSInt &getInt() {
466 assert(isInt() && "Invalid accessor");
467 return *(APSInt *)(char *)&Data;
468 }
469 const APSInt &getInt() const {
470 return const_cast<APValue*>(this)->getInt();
471 }
472
473 /// Try to convert this value to an integral constant. This works if it's an
474 /// integer, null pointer, or offset from a null pointer. Returns true on
475 /// success.
477 const ASTContext &Ctx) const;
478
479 APFloat &getFloat() {
480 assert(isFloat() && "Invalid accessor");
481 return *(APFloat *)(char *)&Data;
482 }
483 const APFloat &getFloat() const {
484 return const_cast<APValue*>(this)->getFloat();
485 }
486
487 APFixedPoint &getFixedPoint() {
488 assert(isFixedPoint() && "Invalid accessor");
489 return *(APFixedPoint *)(char *)&Data;
490 }
491 const APFixedPoint &getFixedPoint() const {
492 return const_cast<APValue *>(this)->getFixedPoint();
493 }
494
496 assert(isComplexInt() && "Invalid accessor");
497 return ((ComplexAPSInt *)(char *)&Data)->Real;
498 }
499 const APSInt &getComplexIntReal() const {
500 return const_cast<APValue*>(this)->getComplexIntReal();
501 }
502
504 assert(isComplexInt() && "Invalid accessor");
505 return ((ComplexAPSInt *)(char *)&Data)->Imag;
506 }
507 const APSInt &getComplexIntImag() const {
508 return const_cast<APValue*>(this)->getComplexIntImag();
509 }
510
512 assert(isComplexFloat() && "Invalid accessor");
513 return ((ComplexAPFloat *)(char *)&Data)->Real;
514 }
515 const APFloat &getComplexFloatReal() const {
516 return const_cast<APValue*>(this)->getComplexFloatReal();
517 }
518
520 assert(isComplexFloat() && "Invalid accessor");
521 return ((ComplexAPFloat *)(char *)&Data)->Imag;
522 }
523 const APFloat &getComplexFloatImag() const {
524 return const_cast<APValue*>(this)->getComplexFloatImag();
525 }
526
527 const LValueBase getLValueBase() const;
529 const CharUnits &getLValueOffset() const {
530 return const_cast<APValue*>(this)->getLValueOffset();
531 }
532 bool isLValueOnePastTheEnd() const;
533 bool hasLValuePath() const;
535 unsigned getLValueCallIndex() const;
536 unsigned getLValueVersion() const;
537 bool isNullPointer() const;
538
539 APValue &getVectorElt(unsigned I) {
540 assert(isVector() && "Invalid accessor");
541 assert(I < getVectorLength() && "Index out of range");
542 return ((Vec *)(char *)&Data)->Elts[I];
543 }
544 const APValue &getVectorElt(unsigned I) const {
545 return const_cast<APValue*>(this)->getVectorElt(I);
546 }
547 unsigned getVectorLength() const {
548 assert(isVector() && "Invalid accessor");
549 return ((const Vec *)(const void *)&Data)->NumElts;
550 }
551
553 assert(isArray() && "Invalid accessor");
554 assert(I < getArrayInitializedElts() && "Index out of range");
555 return ((Arr *)(char *)&Data)->Elts[I];
556 }
557 const APValue &getArrayInitializedElt(unsigned I) const {
558 return const_cast<APValue*>(this)->getArrayInitializedElt(I);
559 }
560 bool hasArrayFiller() const {
562 }
564 assert(isArray() && "Invalid accessor");
565 assert(hasArrayFiller() && "No array filler");
566 return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
567 }
568 const APValue &getArrayFiller() const {
569 return const_cast<APValue*>(this)->getArrayFiller();
570 }
571 unsigned getArrayInitializedElts() const {
572 assert(isArray() && "Invalid accessor");
573 return ((const Arr *)(const void *)&Data)->NumElts;
574 }
575 unsigned getArraySize() const {
576 assert(isArray() && "Invalid accessor");
577 return ((const Arr *)(const void *)&Data)->ArrSize;
578 }
579
580 unsigned getStructNumBases() const {
581 assert(isStruct() && "Invalid accessor");
582 return ((const StructData *)(const char *)&Data)->NumBases;
583 }
584 unsigned getStructNumFields() const {
585 assert(isStruct() && "Invalid accessor");
586 return ((const StructData *)(const char *)&Data)->NumFields;
587 }
588 APValue &getStructBase(unsigned i) {
589 assert(isStruct() && "Invalid accessor");
590 assert(i < getStructNumBases() && "base class index OOB");
591 return ((StructData *)(char *)&Data)->Elts[i];
592 }
593 APValue &getStructField(unsigned i) {
594 assert(isStruct() && "Invalid accessor");
595 assert(i < getStructNumFields() && "field index OOB");
596 return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
597 }
598 const APValue &getStructBase(unsigned i) const {
599 return const_cast<APValue*>(this)->getStructBase(i);
600 }
601 const APValue &getStructField(unsigned i) const {
602 return const_cast<APValue*>(this)->getStructField(i);
603 }
604
605 const FieldDecl *getUnionField() const {
606 assert(isUnion() && "Invalid accessor");
607 return ((const UnionData *)(const char *)&Data)->Field;
608 }
610 assert(isUnion() && "Invalid accessor");
611 return *((UnionData *)(char *)&Data)->Value;
612 }
613 const APValue &getUnionValue() const {
614 return const_cast<APValue*>(this)->getUnionValue();
615 }
616
617 const ValueDecl *getMemberPointerDecl() const;
620
622 assert(isAddrLabelDiff() && "Invalid accessor");
623 return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
624 }
626 assert(isAddrLabelDiff() && "Invalid accessor");
627 return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
628 }
629
630 void setInt(APSInt I) {
631 assert(isInt() && "Invalid accessor");
632 *(APSInt *)(char *)&Data = std::move(I);
633 }
634 void setFloat(APFloat F) {
635 assert(isFloat() && "Invalid accessor");
636 *(APFloat *)(char *)&Data = std::move(F);
637 }
638 void setFixedPoint(APFixedPoint FX) {
639 assert(isFixedPoint() && "Invalid accessor");
640 *(APFixedPoint *)(char *)&Data = std::move(FX);
641 }
642 void setVector(const APValue *E, unsigned N) {
643 MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
644 for (unsigned i = 0; i != N; ++i)
645 InternalElts[i] = E[i];
646 }
647 void setComplexInt(APSInt R, APSInt I) {
648 assert(R.getBitWidth() == I.getBitWidth() &&
649 "Invalid complex int (type mismatch).");
650 assert(isComplexInt() && "Invalid accessor");
651 ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
652 ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
653 }
654 void setComplexFloat(APFloat R, APFloat I) {
655 assert(&R.getSemantics() == &I.getSemantics() &&
656 "Invalid complex float (type mismatch).");
657 assert(isComplexFloat() && "Invalid accessor");
658 ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
659 ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
660 }
661 void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
662 bool IsNullPtr);
663 void setLValue(LValueBase B, const CharUnits &O,
664 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
665 bool IsNullPtr);
666 void setUnion(const FieldDecl *Field, const APValue &Value);
667 void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
668 const AddrLabelExpr* RHSExpr) {
669 ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
670 ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
671 }
672
673private:
674 void DestroyDataAndMakeUninit();
675 void MakeInt() {
676 assert(isAbsent() && "Bad state change");
677 new ((void *)&Data) APSInt(1);
678 Kind = Int;
679 }
680 void MakeFloat() {
681 assert(isAbsent() && "Bad state change");
682 new ((void *)(char *)&Data) APFloat(0.0);
683 Kind = Float;
684 }
685 void MakeFixedPoint(APFixedPoint &&FX) {
686 assert(isAbsent() && "Bad state change");
687 new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
689 }
690 void MakeVector() {
691 assert(isAbsent() && "Bad state change");
692 new ((void *)(char *)&Data) Vec();
693 Kind = Vector;
694 }
695 void MakeComplexInt() {
696 assert(isAbsent() && "Bad state change");
697 new ((void *)(char *)&Data) ComplexAPSInt();
699 }
700 void MakeComplexFloat() {
701 assert(isAbsent() && "Bad state change");
702 new ((void *)(char *)&Data) ComplexAPFloat();
704 }
705 void MakeLValue();
706 void MakeArray(unsigned InitElts, unsigned Size);
707 void MakeStruct(unsigned B, unsigned M) {
708 assert(isAbsent() && "Bad state change");
709 new ((void *)(char *)&Data) StructData(B, M);
710 Kind = Struct;
711 }
712 void MakeUnion() {
713 assert(isAbsent() && "Bad state change");
714 new ((void *)(char *)&Data) UnionData();
715 Kind = Union;
716 }
717 void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
718 ArrayRef<const CXXRecordDecl*> Path);
719 void MakeAddrLabelDiff() {
720 assert(isAbsent() && "Bad state change");
721 new ((void *)(char *)&Data) AddrLabelDiffData();
723 }
724
725private:
726 /// The following functions are used as part of initialization, during
727 /// deserialization and importing. Reserve the space so that it can be
728 /// filled in by those steps.
729 MutableArrayRef<APValue> setVectorUninit(unsigned N) {
730 assert(isVector() && "Invalid accessor");
731 Vec *V = ((Vec *)(char *)&Data);
732 V->Elts = new APValue[N];
733 V->NumElts = N;
734 return {V->Elts, V->NumElts};
735 }
736 MutableArrayRef<LValuePathEntry>
737 setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
738 bool OnePastTheEnd, bool IsNullPtr);
739 MutableArrayRef<const CXXRecordDecl *>
740 setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
741 unsigned Size);
742};
743
744} // end namespace clang.
745
746namespace llvm {
747template<> struct DenseMapInfo<clang::APValue::LValueBase> {
748 static clang::APValue::LValueBase getEmptyKey();
749 static clang::APValue::LValueBase getTombstoneKey();
750 static unsigned getHashValue(const clang::APValue::LValueBase &Base);
751 static bool isEqual(const clang::APValue::LValueBase &LHS,
752 const clang::APValue::LValueBase &RHS);
753};
754}
755
756#endif
#define V(N, I)
Definition: ASTContext.h:3443
StringRef P
static char ID
Definition: Arena.cpp:183
IndirectLocalPath & Path
Expr * E
enum clang::sema::@1718::IndirectLocalPathEntry::EntryKind Kind
llvm::APSInt APSInt
Definition: Compiler.cpp:23
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
const char * Data
#define bool
Definition: amdgpuintrin.h:20
friend llvm::hash_code hash_value(const LValueBase &Base)
Definition: APValue.cpp:202
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS)
Definition: APValue.h:181
void Profile(llvm::FoldingSetNodeID &ID) const
Definition: APValue.cpp:127
QualType getType() const
Definition: APValue.cpp:63
unsigned getVersion() const
Definition: APValue.cpp:113
QualType getDynamicAllocType() const
Definition: APValue.cpp:122
QualType getTypeInfoType() const
Definition: APValue.cpp:117
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS)
Definition: APValue.cpp:136
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
Definition: APValue.h:197
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
Definition: APValue.cpp:55
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
Definition: APValue.cpp:47
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
Definition: APValue.h:195
void * getOpaqueValue() const
Definition: APValue.cpp:175
unsigned getCallIndex() const
Definition: APValue.cpp:108
A non-discriminated union of a base, field, or array index.
Definition: APValue.h:206
BaseOrMemberType getAsBaseOrMember() const
Definition: APValue.h:220
uint64_t getAsArrayIndex() const
Definition: APValue.h:224
friend llvm::hash_code hash_value(LValuePathEntry A)
Definition: APValue.h:234
friend bool operator!=(LValuePathEntry A, LValuePathEntry B)
Definition: APValue.h:231
static LValuePathEntry ArrayIndex(uint64_t Index)
Definition: APValue.h:214
friend bool operator==(LValuePathEntry A, LValuePathEntry B)
Definition: APValue.h:228
void Profile(llvm::FoldingSetNodeID &ID) const
Definition: APValue.cpp:153
ArrayRef< LValuePathEntry > Path
Definition: APValue.h:242
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
const APSInt & getComplexIntReal() const
Definition: APValue.h:499
bool hasArrayFiller() const
Definition: APValue.h:560
const LValueBase getLValueBase() const
Definition: APValue.cpp:973
APValue(LValueBase Base, const CharUnits &Offset, NoLValuePath, bool IsNullPtr=false)
Creates an lvalue APValue without an lvalue path.
Definition: APValue.h:349
APValue(APFloat F)
Creates a float APValue holding the given value.
Definition: APValue.h:322
void setFloat(APFloat F)
Definition: APValue.h:634
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:552
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:993
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
Definition: APValue.cpp:468
APSInt & getInt()
Definition: APValue.h:465
APValue & getStructField(unsigned i)
Definition: APValue.h:593
void setInt(APSInt I)
Definition: APValue.h:630
APValue(APSInt I)
Creates an integer APValue holding the given value.
Definition: APValue.h:318
const FieldDecl * getUnionField() const
Definition: APValue.h:605
const APFloat & getFloat() const
Definition: APValue.h:483
bool isVector() const
Definition: APValue.h:449
APSInt & getComplexIntImag()
Definition: APValue.h:503
unsigned getStructNumFields() const
Definition: APValue.h:584
const APValue & getArrayInitializedElt(unsigned I) const
Definition: APValue.h:557
APValue(APFloat R, APFloat I)
Creates a float complex APValue with the given real and imaginary values.
Definition: APValue.h:340
bool isAbsent() const
Definition: APValue.h:439
APValue(const FieldDecl *ActiveDecl, const APValue &ActiveValue=APValue())
Creates a new union APValue.
Definition: APValue.h:387
bool isComplexInt() const
Definition: APValue.h:446
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
Definition: APValue.h:203
ValueKind getKind() const
Definition: APValue.h:437
bool isLValueOnePastTheEnd() const
Definition: APValue.cpp:978
bool isArray() const
Definition: APValue.h:450
APValue(const APValue *E, unsigned N)
Creates a vector APValue with N elements.
Definition: APValue.h:331
void setFixedPoint(APFixedPoint FX)
Definition: APValue.h:638
unsigned getLValueVersion() const
Definition: APValue.cpp:1004
bool isMemberPointerToDerivedMember() const
Definition: APValue.cpp:1063
unsigned getArrayInitializedElts() const
Definition: APValue.h:571
static APValue IndeterminateValue()
Definition: APValue.h:408
bool isFloat() const
Definition: APValue.h:444
void setComplexInt(APSInt R, APSInt I)
Definition: APValue.h:647
const APFixedPoint & getFixedPoint() const
Definition: APValue.h:491
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
Definition: APValue.cpp:479
unsigned getStructNumBases() const
Definition: APValue.h:580
APFixedPoint & getFixedPoint()
Definition: APValue.h:487
APValue(const ValueDecl *Member, bool IsDerivedMember, ArrayRef< const CXXRecordDecl * > Path)
Creates a new member pointer APValue.
Definition: APValue.h:397
bool needsCleanup() const
Returns whether the object performed allocations.
Definition: APValue.cpp:431
const APValue & getStructBase(unsigned i) const
Definition: APValue.h:598
bool hasValue() const
Definition: APValue.h:441
APValue(LValueBase Base, const CharUnits &Offset, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, bool IsNullPtr=false)
Creates an lvalue APValue with an lvalue path.
Definition: APValue.h:362
bool hasLValuePath() const
Definition: APValue.cpp:988
const ValueDecl * getMemberPointerDecl() const
Definition: APValue.cpp:1056
APValue & getUnionValue()
Definition: APValue.h:609
const AddrLabelExpr * getAddrLabelDiffRHS() const
Definition: APValue.h:625
CharUnits & getLValueOffset()
Definition: APValue.cpp:983
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:693
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Definition: APValue.h:667
void setComplexFloat(APFloat R, APFloat I)
Definition: APValue.h:654
bool isComplexFloat() const
Definition: APValue.h:447
APValue & getVectorElt(unsigned I)
Definition: APValue.h:539
APValue & getArrayFiller()
Definition: APValue.h:563
const APValue & getArrayFiller() const
Definition: APValue.h:568
const APFloat & getComplexFloatImag() const
Definition: APValue.h:523
unsigned getVectorLength() const
Definition: APValue.h:547
const APValue & getUnionValue() const
Definition: APValue.h:613
const APValue & getVectorElt(unsigned I) const
Definition: APValue.h:544
APValue(UninitArray, unsigned InitElts, unsigned Size)
Creates a new array APValue.
Definition: APValue.h:374
bool isLValue() const
Definition: APValue.h:448
APValue(UninitStruct, unsigned NumBases, unsigned NumMembers)
Creates a new struct APValue.
Definition: APValue.h:381
void setUnion(const FieldDecl *Field, const APValue &Value)
Definition: APValue.cpp:1049
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Creates a new address label diff APValue.
Definition: APValue.h:404
bool isIndeterminate() const
Definition: APValue.h:440
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
Definition: APValue.cpp:1014
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Definition: APValue.cpp:1070
bool isMemberPointer() const
Definition: APValue.h:453
const APSInt & getInt() const
Definition: APValue.h:469
const APFloat & getComplexFloatReal() const
Definition: APValue.h:515
bool isInt() const
Definition: APValue.h:443
unsigned getArraySize() const
Definition: APValue.h:575
APValue(APSInt R, APSInt I)
Creates an integer complex APValue with the given real and imaginary values.
Definition: APValue.h:336
bool isUnion() const
Definition: APValue.h:452
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
Definition: APValue.cpp:953
const CharUnits & getLValueOffset() const
Definition: APValue.h:529
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:946
bool isFixedPoint() const
Definition: APValue.h:445
APValue & operator=(const APValue &RHS)
Definition: APValue.cpp:386
unsigned getLValueCallIndex() const
Definition: APValue.cpp:999
void setVector(const APValue *E, unsigned N)
Definition: APValue.h:642
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
Definition: APValue.h:131
@ None
There is no such object (it's outside its lifetime).
Definition: APValue.h:129
const APValue & getStructField(unsigned i) const
Definition: APValue.h:601
const APSInt & getComplexIntImag() const
Definition: APValue.h:507
bool isStruct() const
Definition: APValue.h:451
bool isNullPointer() const
Definition: APValue.cpp:1009
APSInt & getComplexIntReal()
Definition: APValue.h:495
APFloat & getComplexFloatImag()
Definition: APValue.h:519
APFloat & getComplexFloatReal()
Definition: APValue.h:511
APFloat & getFloat()
Definition: APValue.h:479
APValue & getStructBase(unsigned i)
Definition: APValue.h:588
void dump() const
Definition: ASTDumper.cpp:337
APValue(APFixedPoint FX)
Creates a fixed-point APValue holding the given value.
Definition: APValue.h:326
const AddrLabelExpr * getAddrLabelDiffLHS() const
Definition: APValue.h:621
bool isAddrLabelDiff() const
Definition: APValue.h:454
APValue()
Creates an empty APValue of type None.
Definition: APValue.h:316
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
Imports selected nodes from one AST context into another context, merging AST nodes where appropriate...
Definition: ASTImporter.h:62
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4421
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:1220
Symbolic representation of a dynamic allocation.
Definition: APValue.h:65
static unsigned getMaxIndex()
Definition: APValue.h:85
static constexpr int NumLowBitsAvailable
Definition: APValue.h:89
DynamicAllocLValue(unsigned Index)
Definition: APValue.h:70
static DynamicAllocLValue getFromOpaqueValue(void *Value)
Definition: APValue.h:79
This represents one expression.
Definition: Expr.h:110
Represents a member of a struct/union/class.
Definition: Decl.h:3033
A (possibly-)qualified type.
Definition: Type.h:929
Symbolic representation of typeid(T) for some type T.
Definition: APValue.h:44
const Type * getType() const
Definition: APValue.h:51
static TypeInfoLValue getFromOpaqueValue(void *Value)
Definition: APValue.h:55
void * getOpaqueValue()
Definition: APValue.h:54
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
Definition: APValue.cpp:30
The base class of the type hierarchy.
Definition: Type.h:1828
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:671
llvm::APFloat APFloat
Definition: Floating.h:23
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
static void * getAsVoidPointer(clang::DynamicAllocLValue V)
Definition: APValue.h:107
static clang::DynamicAllocLValue getFromVoidPointer(void *P)
Definition: APValue.h:110
static void * getAsVoidPointer(clang::TypeInfoLValue V)
Definition: APValue.h:95
static clang::TypeInfoLValue getFromVoidPointer(void *P)
Definition: APValue.h:98