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> T dyn_cast() const {
165 return dyn_cast_if_present<T>(Ptr);
166 }
167
168 void *getOpaqueValue() const;
169
170 bool isNull() const;
171
172 explicit operator bool() const;
173
174 unsigned getCallIndex() const;
175 unsigned getVersion() const;
178
179 QualType getType() const;
180
181 friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
182 friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
183 return !(LHS == RHS);
184 }
185 friend llvm::hash_code hash_value(const LValueBase &Base);
186 friend struct llvm::DenseMapInfo<LValueBase>;
187
188 private:
189 PtrTy Ptr;
190 struct LocalState {
191 unsigned CallIndex, Version;
192 };
193 union {
194 LocalState Local;
195 /// The type std::type_info, if this is a TypeInfoLValue.
197 /// The QualType, if this is a DynamicAllocLValue.
199 };
200 };
201
202 /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
203 /// mean a virtual or non-virtual base class subobject.
204 typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
205
206 /// A non-discriminated union of a base, field, or array index.
208 static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
209 "pointer doesn't fit in 64 bits?");
210 uint64_t Value;
211
212 public:
214 LValuePathEntry(BaseOrMemberType BaseOrMember);
215 static LValuePathEntry ArrayIndex(uint64_t Index) {
217 Result.Value = Index;
218 return Result;
219 }
220
222 return BaseOrMemberType::getFromOpaqueValue(
223 reinterpret_cast<void *>(Value));
224 }
225 uint64_t getAsArrayIndex() const { return Value; }
226
227 void Profile(llvm::FoldingSetNodeID &ID) const;
228
230 return A.Value == B.Value;
231 }
233 return A.Value != B.Value;
234 }
235 friend llvm::hash_code hash_value(LValuePathEntry A) {
236 return llvm::hash_value(A.Value);
237 }
238 };
240 const void *Ty;
241
242 public:
244
247 };
248 struct NoLValuePath {};
249 struct UninitArray {};
250 struct UninitStruct {};
252
253 template <typename Impl> friend class clang::serialization::BasicReaderBase;
254 friend class ASTImporter;
255 friend class ASTNodeImporter;
256
257private:
259 bool AllowConstexprUnknown : 1;
260
261 struct ComplexAPSInt {
262 APSInt Real, Imag;
263 ComplexAPSInt() : Real(1), Imag(1) {}
264 };
265 struct ComplexAPFloat {
266 APFloat Real, Imag;
267 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
268 };
269 struct LV;
270 struct Vec {
271 APValue *Elts = nullptr;
272 unsigned NumElts = 0;
273 Vec() = default;
274 Vec(const Vec &) = delete;
275 Vec &operator=(const Vec &) = delete;
276 ~Vec() { delete[] Elts; }
277 };
278 struct Arr {
279 APValue *Elts;
280 unsigned NumElts, ArrSize;
281 Arr(unsigned NumElts, unsigned ArrSize);
282 Arr(const Arr &) = delete;
283 Arr &operator=(const Arr &) = delete;
284 ~Arr();
285 };
286 struct StructData {
287 APValue *Elts;
288 unsigned NumBases;
289 unsigned NumFields;
290 StructData(unsigned NumBases, unsigned NumFields);
291 StructData(const StructData &) = delete;
292 StructData &operator=(const StructData &) = delete;
293 ~StructData();
294 };
295 struct UnionData {
296 const FieldDecl *Field;
297 APValue *Value;
298 UnionData();
299 UnionData(const UnionData &) = delete;
300 UnionData &operator=(const UnionData &) = delete;
301 ~UnionData();
302 };
303 struct AddrLabelDiffData {
304 const AddrLabelExpr* LHSExpr;
305 const AddrLabelExpr* RHSExpr;
306 };
307 struct MemberPointerData;
308
309 // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
310 typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
311 ComplexAPFloat, Vec, Arr, StructData,
312 UnionData, AddrLabelDiffData> DataType;
313 static const size_t DataSize = sizeof(DataType);
314
315 DataType Data;
316
317public:
318 bool allowConstexprUnknown() const { return AllowConstexprUnknown; }
319
320 void setConstexprUnknown(bool IsConstexprUnknown = true) {
321 AllowConstexprUnknown = IsConstexprUnknown;
322 }
323
324 /// Creates an empty APValue of type None.
325 APValue() : Kind(None), AllowConstexprUnknown(false) {}
326 /// Creates an integer APValue holding the given value.
327 explicit APValue(APSInt I) : Kind(None), AllowConstexprUnknown(false) {
328 MakeInt(); setInt(std::move(I));
329 }
330 /// Creates a float APValue holding the given value.
331 explicit APValue(APFloat F) : Kind(None), AllowConstexprUnknown(false) {
332 MakeFloat(); setFloat(std::move(F));
333 }
334 /// Creates a fixed-point APValue holding the given value.
335 explicit APValue(APFixedPoint FX) : Kind(None), AllowConstexprUnknown(false) {
336 MakeFixedPoint(std::move(FX));
337 }
338 /// Creates a vector APValue with \p N elements. The elements
339 /// are read from \p E.
340 explicit APValue(const APValue *E, unsigned N)
341 : Kind(None), AllowConstexprUnknown(false) {
342 MakeVector(); setVector(E, N);
343 }
344 /// Creates an integer complex APValue with the given real and imaginary
345 /// values.
346 APValue(APSInt R, APSInt I) : Kind(None), AllowConstexprUnknown(false) {
347 MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
348 }
349 /// Creates a float complex APValue with the given real and imaginary values.
350 APValue(APFloat R, APFloat I) : Kind(None), AllowConstexprUnknown(false) {
351 MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
352 }
353 APValue(const APValue &RHS);
354 APValue(APValue &&RHS);
355 /// Creates an lvalue APValue without an lvalue path.
356 /// \param Base The base of the lvalue.
357 /// \param Offset The offset of the lvalue.
358 /// \param IsNullPtr Whether this lvalue is a null pointer.
360 bool IsNullPtr = false)
361 : Kind(None), AllowConstexprUnknown(false) {
362 MakeLValue();
363 setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
364 }
365 /// Creates an lvalue APValue with an lvalue path.
366 /// \param Base The base of the lvalue.
367 /// \param Offset The offset of the lvalue.
368 /// \param Path The lvalue path.
369 /// \param OnePastTheEnd Whether this lvalue is one-past-the-end of the
370 /// subobject it points to.
371 /// \param IsNullPtr Whether this lvalue is a null pointer.
373 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
374 bool IsNullPtr = false)
375 : Kind(None), AllowConstexprUnknown(false) {
376 MakeLValue();
377 setLValue(Base, Offset, Path, OnePastTheEnd, IsNullPtr);
378 }
379 /// Creates a constexpr unknown lvalue APValue.
380 /// \param Base The base of the lvalue.
381 /// \param Offset The offset of the lvalue.
382 /// \param IsNullPtr Whether this lvalue is a null pointer.
384 bool IsNullPtr = false)
385 : Kind(None), AllowConstexprUnknown(true) {
386 MakeLValue();
387 setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
388 }
389
390 /// Creates a new array APValue.
391 /// \param UninitArray Marker. Pass an empty UninitArray.
392 /// \param InitElts Number of elements you're going to initialize in the
393 /// array.
394 /// \param Size Full size of the array.
395 APValue(UninitArray, unsigned InitElts, unsigned Size)
396 : Kind(None), AllowConstexprUnknown(false) {
397 MakeArray(InitElts, Size);
398 }
399 /// Creates a new struct APValue.
400 /// \param UninitStruct Marker. Pass an empty UninitStruct.
401 /// \param NumBases Number of bases.
402 /// \param NumMembers Number of members.
403 APValue(UninitStruct, unsigned NumBases, unsigned NumMembers)
404 : Kind(None), AllowConstexprUnknown(false) {
405 MakeStruct(NumBases, NumMembers);
406 }
407 /// Creates a new union APValue.
408 /// \param ActiveDecl The FieldDecl of the active union member.
409 /// \param ActiveValue The value of the active union member.
410 explicit APValue(const FieldDecl *ActiveDecl,
411 const APValue &ActiveValue = APValue())
412 : Kind(None), AllowConstexprUnknown(false) {
413 MakeUnion();
414 setUnion(ActiveDecl, ActiveValue);
415 }
416 /// Creates a new member pointer APValue.
417 /// \param Member Declaration of the member
418 /// \param IsDerivedMember Whether member is a derived one.
419 /// \param Path The path of the member.
420 APValue(const ValueDecl *Member, bool IsDerivedMember,
422 : Kind(None), AllowConstexprUnknown(false) {
423 MakeMemberPointer(Member, IsDerivedMember, Path);
424 }
425 /// Creates a new address label diff APValue.
426 /// \param LHSExpr The left-hand side of the difference.
427 /// \param RHSExpr The right-hand side of the difference.
428 APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
429 : Kind(None), AllowConstexprUnknown(false) {
430 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
431 }
434 Result.Kind = Indeterminate;
435 return Result;
436 }
437
438 APValue &operator=(const APValue &RHS);
439 APValue &operator=(APValue &&RHS);
440
442 if (Kind != None && Kind != Indeterminate)
443 DestroyDataAndMakeUninit();
444 }
445
446 /// Returns whether the object performed allocations.
447 ///
448 /// If APValues are constructed via placement new, \c needsCleanup()
449 /// indicates whether the destructor must be called in order to correctly
450 /// free all allocated memory.
451 bool needsCleanup() const;
452
453 /// Swaps the contents of this and the given APValue.
454 void swap(APValue &RHS);
455
456 /// profile this value. There is no guarantee that values of different
457 /// types will not produce the same profiled value, so the type should
458 /// typically also be profiled if it's not implied by the context.
459 void Profile(llvm::FoldingSetNodeID &ID) const;
460
461 ValueKind getKind() const { return Kind; }
462
463 bool isAbsent() const { return Kind == None; }
464 bool isIndeterminate() const { return Kind == Indeterminate; }
465 bool hasValue() const { return Kind != None && Kind != Indeterminate; }
466
467 bool isInt() const { return Kind == Int; }
468 bool isFloat() const { return Kind == Float; }
469 bool isFixedPoint() const { return Kind == FixedPoint; }
470 bool isComplexInt() const { return Kind == ComplexInt; }
471 bool isComplexFloat() const { return Kind == ComplexFloat; }
472 bool isLValue() const { return Kind == LValue; }
473 bool isVector() const { return Kind == Vector; }
474 bool isArray() const { return Kind == Array; }
475 bool isStruct() const { return Kind == Struct; }
476 bool isUnion() const { return Kind == Union; }
477 bool isMemberPointer() const { return Kind == MemberPointer; }
478 bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
479
480 void dump() const;
481 void dump(raw_ostream &OS, const ASTContext &Context) const;
482
483 void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
484 void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
485 const ASTContext *Ctx = nullptr) const;
486
487 std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
488
489 APSInt &getInt() {
490 assert(isInt() && "Invalid accessor");
491 return *(APSInt *)(char *)&Data;
492 }
493 const APSInt &getInt() const {
494 return const_cast<APValue*>(this)->getInt();
495 }
496
497 /// Try to convert this value to an integral constant. This works if it's an
498 /// integer, null pointer, or offset from a null pointer. Returns true on
499 /// success.
501 const ASTContext &Ctx) const;
502
503 APFloat &getFloat() {
504 assert(isFloat() && "Invalid accessor");
505 return *(APFloat *)(char *)&Data;
506 }
507 const APFloat &getFloat() const {
508 return const_cast<APValue*>(this)->getFloat();
509 }
510
511 APFixedPoint &getFixedPoint() {
512 assert(isFixedPoint() && "Invalid accessor");
513 return *(APFixedPoint *)(char *)&Data;
514 }
515 const APFixedPoint &getFixedPoint() const {
516 return const_cast<APValue *>(this)->getFixedPoint();
517 }
518
520 assert(isComplexInt() && "Invalid accessor");
521 return ((ComplexAPSInt *)(char *)&Data)->Real;
522 }
523 const APSInt &getComplexIntReal() const {
524 return const_cast<APValue*>(this)->getComplexIntReal();
525 }
526
528 assert(isComplexInt() && "Invalid accessor");
529 return ((ComplexAPSInt *)(char *)&Data)->Imag;
530 }
531 const APSInt &getComplexIntImag() const {
532 return const_cast<APValue*>(this)->getComplexIntImag();
533 }
534
536 assert(isComplexFloat() && "Invalid accessor");
537 return ((ComplexAPFloat *)(char *)&Data)->Real;
538 }
539 const APFloat &getComplexFloatReal() const {
540 return const_cast<APValue*>(this)->getComplexFloatReal();
541 }
542
544 assert(isComplexFloat() && "Invalid accessor");
545 return ((ComplexAPFloat *)(char *)&Data)->Imag;
546 }
547 const APFloat &getComplexFloatImag() const {
548 return const_cast<APValue*>(this)->getComplexFloatImag();
549 }
550
551 const LValueBase getLValueBase() const;
553 const CharUnits &getLValueOffset() const {
554 return const_cast<APValue*>(this)->getLValueOffset();
555 }
556 bool isLValueOnePastTheEnd() const;
557 bool hasLValuePath() const;
559 unsigned getLValueCallIndex() const;
560 unsigned getLValueVersion() const;
561 bool isNullPointer() const;
562
563 APValue &getVectorElt(unsigned I) {
564 assert(isVector() && "Invalid accessor");
565 assert(I < getVectorLength() && "Index out of range");
566 return ((Vec *)(char *)&Data)->Elts[I];
567 }
568 const APValue &getVectorElt(unsigned I) const {
569 return const_cast<APValue*>(this)->getVectorElt(I);
570 }
571 unsigned getVectorLength() const {
572 assert(isVector() && "Invalid accessor");
573 return ((const Vec *)(const void *)&Data)->NumElts;
574 }
575
577 assert(isArray() && "Invalid accessor");
578 assert(I < getArrayInitializedElts() && "Index out of range");
579 return ((Arr *)(char *)&Data)->Elts[I];
580 }
581 const APValue &getArrayInitializedElt(unsigned I) const {
582 return const_cast<APValue*>(this)->getArrayInitializedElt(I);
583 }
584 bool hasArrayFiller() const {
586 }
588 assert(isArray() && "Invalid accessor");
589 assert(hasArrayFiller() && "No array filler");
590 return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
591 }
592 const APValue &getArrayFiller() const {
593 return const_cast<APValue*>(this)->getArrayFiller();
594 }
595 unsigned getArrayInitializedElts() const {
596 assert(isArray() && "Invalid accessor");
597 return ((const Arr *)(const void *)&Data)->NumElts;
598 }
599 unsigned getArraySize() const {
600 assert(isArray() && "Invalid accessor");
601 return ((const Arr *)(const void *)&Data)->ArrSize;
602 }
603
604 unsigned getStructNumBases() const {
605 assert(isStruct() && "Invalid accessor");
606 return ((const StructData *)(const char *)&Data)->NumBases;
607 }
608 unsigned getStructNumFields() const {
609 assert(isStruct() && "Invalid accessor");
610 return ((const StructData *)(const char *)&Data)->NumFields;
611 }
612 APValue &getStructBase(unsigned i) {
613 assert(isStruct() && "Invalid accessor");
614 assert(i < getStructNumBases() && "base class index OOB");
615 return ((StructData *)(char *)&Data)->Elts[i];
616 }
617 APValue &getStructField(unsigned i) {
618 assert(isStruct() && "Invalid accessor");
619 assert(i < getStructNumFields() && "field index OOB");
620 return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
621 }
622 const APValue &getStructBase(unsigned i) const {
623 return const_cast<APValue*>(this)->getStructBase(i);
624 }
625 const APValue &getStructField(unsigned i) const {
626 return const_cast<APValue*>(this)->getStructField(i);
627 }
628
629 const FieldDecl *getUnionField() const {
630 assert(isUnion() && "Invalid accessor");
631 return ((const UnionData *)(const char *)&Data)->Field;
632 }
634 assert(isUnion() && "Invalid accessor");
635 return *((UnionData *)(char *)&Data)->Value;
636 }
637 const APValue &getUnionValue() const {
638 return const_cast<APValue*>(this)->getUnionValue();
639 }
640
641 const ValueDecl *getMemberPointerDecl() const;
644
646 assert(isAddrLabelDiff() && "Invalid accessor");
647 return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
648 }
650 assert(isAddrLabelDiff() && "Invalid accessor");
651 return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
652 }
653
654 void setInt(APSInt I) {
655 assert(isInt() && "Invalid accessor");
656 *(APSInt *)(char *)&Data = std::move(I);
657 }
658 void setFloat(APFloat F) {
659 assert(isFloat() && "Invalid accessor");
660 *(APFloat *)(char *)&Data = std::move(F);
661 }
662 void setFixedPoint(APFixedPoint FX) {
663 assert(isFixedPoint() && "Invalid accessor");
664 *(APFixedPoint *)(char *)&Data = std::move(FX);
665 }
666 void setVector(const APValue *E, unsigned N) {
667 MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
668 for (unsigned i = 0; i != N; ++i)
669 InternalElts[i] = E[i];
670 }
671 void setComplexInt(APSInt R, APSInt I) {
672 assert(R.getBitWidth() == I.getBitWidth() &&
673 "Invalid complex int (type mismatch).");
674 assert(isComplexInt() && "Invalid accessor");
675 ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
676 ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
677 }
678 void setComplexFloat(APFloat R, APFloat I) {
679 assert(&R.getSemantics() == &I.getSemantics() &&
680 "Invalid complex float (type mismatch).");
681 assert(isComplexFloat() && "Invalid accessor");
682 ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
683 ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
684 }
685 void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
686 bool IsNullPtr);
687 void setLValue(LValueBase B, const CharUnits &O,
688 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
689 bool IsNullPtr);
690 void setUnion(const FieldDecl *Field, const APValue &Value);
691 void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
692 const AddrLabelExpr* RHSExpr) {
693 ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
694 ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
695 }
696
697private:
698 void DestroyDataAndMakeUninit();
699 void MakeInt() {
700 assert(isAbsent() && "Bad state change");
701 new ((void *)&Data) APSInt(1);
702 Kind = Int;
703 }
704 void MakeFloat() {
705 assert(isAbsent() && "Bad state change");
706 new ((void *)(char *)&Data) APFloat(0.0);
707 Kind = Float;
708 }
709 void MakeFixedPoint(APFixedPoint &&FX) {
710 assert(isAbsent() && "Bad state change");
711 new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
713 }
714 void MakeVector() {
715 assert(isAbsent() && "Bad state change");
716 new ((void *)(char *)&Data) Vec();
717 Kind = Vector;
718 }
719 void MakeComplexInt() {
720 assert(isAbsent() && "Bad state change");
721 new ((void *)(char *)&Data) ComplexAPSInt();
723 }
724 void MakeComplexFloat() {
725 assert(isAbsent() && "Bad state change");
726 new ((void *)(char *)&Data) ComplexAPFloat();
728 }
729 void MakeLValue();
730 void MakeArray(unsigned InitElts, unsigned Size);
731 void MakeStruct(unsigned B, unsigned M) {
732 assert(isAbsent() && "Bad state change");
733 new ((void *)(char *)&Data) StructData(B, M);
734 Kind = Struct;
735 }
736 void MakeUnion() {
737 assert(isAbsent() && "Bad state change");
738 new ((void *)(char *)&Data) UnionData();
739 Kind = Union;
740 }
741 void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
742 ArrayRef<const CXXRecordDecl*> Path);
743 void MakeAddrLabelDiff() {
744 assert(isAbsent() && "Bad state change");
745 new ((void *)(char *)&Data) AddrLabelDiffData();
747 }
748
749private:
750 /// The following functions are used as part of initialization, during
751 /// deserialization and importing. Reserve the space so that it can be
752 /// filled in by those steps.
753 MutableArrayRef<APValue> setVectorUninit(unsigned N) {
754 assert(isVector() && "Invalid accessor");
755 Vec *V = ((Vec *)(char *)&Data);
756 V->Elts = new APValue[N];
757 V->NumElts = N;
758 return {V->Elts, V->NumElts};
759 }
760 MutableArrayRef<LValuePathEntry>
761 setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
762 bool OnePastTheEnd, bool IsNullPtr);
763 MutableArrayRef<const CXXRecordDecl *>
764 setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
765 unsigned Size);
766};
767
768} // end namespace clang.
769
770namespace llvm {
771template<> struct DenseMapInfo<clang::APValue::LValueBase> {
772 static clang::APValue::LValueBase getEmptyKey();
773 static clang::APValue::LValueBase getTombstoneKey();
774 static unsigned getHashValue(const clang::APValue::LValueBase &Base);
775 static bool isEqual(const clang::APValue::LValueBase &LHS,
776 const clang::APValue::LValueBase &RHS);
777};
778}
779
780#endif
#define V(N, I)
Definition: ASTContext.h:3460
StringRef P
static char ID
Definition: Arena.cpp:183
IndirectLocalPath & Path
enum clang::sema::@1727::IndirectLocalPathEntry::EntryKind Kind
Expr * E
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:182
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:198
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:196
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:207
BaseOrMemberType getAsBaseOrMember() const
Definition: APValue.h:221
uint64_t getAsArrayIndex() const
Definition: APValue.h:225
friend llvm::hash_code hash_value(LValuePathEntry A)
Definition: APValue.h:235
friend bool operator!=(LValuePathEntry A, LValuePathEntry B)
Definition: APValue.h:232
static LValuePathEntry ArrayIndex(uint64_t Index)
Definition: APValue.h:215
friend bool operator==(LValuePathEntry A, LValuePathEntry B)
Definition: APValue.h:229
void Profile(llvm::FoldingSetNodeID &ID) const
Definition: APValue.cpp:153
ArrayRef< LValuePathEntry > Path
Definition: APValue.h:243
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
const APSInt & getComplexIntReal() const
Definition: APValue.h:523
bool hasArrayFiller() const
Definition: APValue.h:584
const LValueBase getLValueBase() const
Definition: APValue.cpp:984
APValue(LValueBase Base, const CharUnits &Offset, NoLValuePath, bool IsNullPtr=false)
Creates an lvalue APValue without an lvalue path.
Definition: APValue.h:359
APValue(APFloat F)
Creates a float APValue holding the given value.
Definition: APValue.h:331
void setFloat(APFloat F)
Definition: APValue.h:658
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:576
ArrayRef< LValuePathEntry > getLValuePath() const
Definition: APValue.cpp:1004
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
Definition: APValue.cpp:475
APSInt & getInt()
Definition: APValue.h:489
APValue & getStructField(unsigned i)
Definition: APValue.h:617
void setInt(APSInt I)
Definition: APValue.h:654
APValue(APSInt I)
Creates an integer APValue holding the given value.
Definition: APValue.h:327
const FieldDecl * getUnionField() const
Definition: APValue.h:629
const APFloat & getFloat() const
Definition: APValue.h:507
bool isVector() const
Definition: APValue.h:473
APSInt & getComplexIntImag()
Definition: APValue.h:527
unsigned getStructNumFields() const
Definition: APValue.h:608
const APValue & getArrayInitializedElt(unsigned I) const
Definition: APValue.h:581
APValue(APFloat R, APFloat I)
Creates a float complex APValue with the given real and imaginary values.
Definition: APValue.h:350
void setConstexprUnknown(bool IsConstexprUnknown=true)
Definition: APValue.h:320
bool isAbsent() const
Definition: APValue.h:463
APValue(const FieldDecl *ActiveDecl, const APValue &ActiveValue=APValue())
Creates a new union APValue.
Definition: APValue.h:410
bool isComplexInt() const
Definition: APValue.h:470
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:204
ValueKind getKind() const
Definition: APValue.h:461
bool isLValueOnePastTheEnd() const
Definition: APValue.cpp:989
bool isArray() const
Definition: APValue.h:474
APValue(const APValue *E, unsigned N)
Creates a vector APValue with N elements.
Definition: APValue.h:340
void setFixedPoint(APFixedPoint FX)
Definition: APValue.h:662
unsigned getLValueVersion() const
Definition: APValue.cpp:1015
bool isMemberPointerToDerivedMember() const
Definition: APValue.cpp:1074
unsigned getArrayInitializedElts() const
Definition: APValue.h:595
static APValue IndeterminateValue()
Definition: APValue.h:432
bool isFloat() const
Definition: APValue.h:468
void setComplexInt(APSInt R, APSInt I)
Definition: APValue.h:671
const APFixedPoint & getFixedPoint() const
Definition: APValue.h:515
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
Definition: APValue.cpp:490
unsigned getStructNumBases() const
Definition: APValue.h:604
APFixedPoint & getFixedPoint()
Definition: APValue.h:511
APValue(const ValueDecl *Member, bool IsDerivedMember, ArrayRef< const CXXRecordDecl * > Path)
Creates a new member pointer APValue.
Definition: APValue.h:420
bool needsCleanup() const
Returns whether the object performed allocations.
Definition: APValue.cpp:438
const APValue & getStructBase(unsigned i) const
Definition: APValue.h:622
bool hasValue() const
Definition: APValue.h:465
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:372
bool hasLValuePath() const
Definition: APValue.cpp:999
const ValueDecl * getMemberPointerDecl() const
Definition: APValue.cpp:1067
APValue & getUnionValue()
Definition: APValue.h:633
const AddrLabelExpr * getAddrLabelDiffRHS() const
Definition: APValue.h:649
CharUnits & getLValueOffset()
Definition: APValue.cpp:994
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:704
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Definition: APValue.h:691
void setComplexFloat(APFloat R, APFloat I)
Definition: APValue.h:678
bool isComplexFloat() const
Definition: APValue.h:471
APValue & getVectorElt(unsigned I)
Definition: APValue.h:563
APValue & getArrayFiller()
Definition: APValue.h:587
APValue(LValueBase Base, const CharUnits &Offset, ConstexprUnknown, bool IsNullPtr=false)
Creates a constexpr unknown lvalue APValue.
Definition: APValue.h:383
const APValue & getArrayFiller() const
Definition: APValue.h:592
const APFloat & getComplexFloatImag() const
Definition: APValue.h:547
unsigned getVectorLength() const
Definition: APValue.h:571
const APValue & getUnionValue() const
Definition: APValue.h:637
const APValue & getVectorElt(unsigned I) const
Definition: APValue.h:568
APValue(UninitArray, unsigned InitElts, unsigned Size)
Creates a new array APValue.
Definition: APValue.h:395
bool isLValue() const
Definition: APValue.h:472
APValue(UninitStruct, unsigned NumBases, unsigned NumMembers)
Creates a new struct APValue.
Definition: APValue.h:403
void setUnion(const FieldDecl *Field, const APValue &Value)
Definition: APValue.cpp:1060
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Creates a new address label diff APValue.
Definition: APValue.h:428
bool isIndeterminate() const
Definition: APValue.h:464
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
Definition: APValue.cpp:1025
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Definition: APValue.cpp:1081
bool isMemberPointer() const
Definition: APValue.h:477
const APSInt & getInt() const
Definition: APValue.h:493
const APFloat & getComplexFloatReal() const
Definition: APValue.h:539
bool isInt() const
Definition: APValue.h:467
unsigned getArraySize() const
Definition: APValue.h:599
APValue(APSInt R, APSInt I)
Creates an integer complex APValue with the given real and imaginary values.
Definition: APValue.h:346
bool isUnion() const
Definition: APValue.h:476
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
Definition: APValue.cpp:964
const CharUnits & getLValueOffset() const
Definition: APValue.h:553
bool allowConstexprUnknown() const
Definition: APValue.h:318
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:957
bool isFixedPoint() const
Definition: APValue.h:469
APValue & operator=(const APValue &RHS)
Definition: APValue.cpp:389
unsigned getLValueCallIndex() const
Definition: APValue.cpp:1010
void setVector(const APValue *E, unsigned N)
Definition: APValue.h:666
@ 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:625
const APSInt & getComplexIntImag() const
Definition: APValue.h:531
bool isStruct() const
Definition: APValue.h:475
bool isNullPointer() const
Definition: APValue.cpp:1020
APSInt & getComplexIntReal()
Definition: APValue.h:519
APFloat & getComplexFloatImag()
Definition: APValue.h:543
APFloat & getComplexFloatReal()
Definition: APValue.h:535
APFloat & getFloat()
Definition: APValue.h:503
APValue & getStructBase(unsigned i)
Definition: APValue.h:612
void dump() const
Definition: ASTDumper.cpp:337
APValue(APFixedPoint FX)
Creates a fixed-point APValue holding the given value.
Definition: APValue.h:335
const AddrLabelExpr * getAddrLabelDiffLHS() const
Definition: APValue.h:645
bool isAddrLabelDiff() const
Definition: APValue.h:478
APValue()
Creates an empty APValue of type None.
Definition: APValue.h:325
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:1224
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...
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26
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