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