clang 24.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:
48 TypeInfoLValue() : T() {}
49 explicit TypeInfoLValue(const Type *T);
50
51 const Type *getType() const { return T; }
52 explicit operator bool() const { return T; }
53
54 const void *getOpaqueValue() const { return 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
75 const void *getOpaqueValue() const {
76 return reinterpret_cast<const 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 }
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 }
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]).
145 };
146
147 class alignas(uint64_t) LValueBase {
148 typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
150 PtrTy;
151
152 public:
154 LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
155 LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
156 static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
157 static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
158
159 void Profile(llvm::FoldingSetNodeID &ID) const;
160
161 template <class T> bool is() const { return isa<T>(Ptr); }
162
163 template <class T> T get() const { return cast<T>(Ptr); }
164
165 template <class T> T dyn_cast() const {
166 return dyn_cast_if_present<T>(Ptr);
167 }
168
169 void *getOpaqueValue() const;
170
171 bool isNull() const;
172
173 explicit operator bool() const;
174
175 unsigned getCallIndex() const;
176 unsigned getVersion() const;
177 QualType getTypeInfoType() const;
178 QualType getDynamicAllocType() const;
179
180 QualType getType() const;
181
182 friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
183 friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
184 return !(LHS == RHS);
185 }
186 friend llvm::hash_code hash_value(const LValueBase &Base);
187 friend struct llvm::DenseMapInfo<LValueBase>;
188
189 private:
190 PtrTy Ptr;
191 struct LocalState {
192 unsigned CallIndex, Version;
193 };
194 union {
195 LocalState Local;
196 /// The type std::type_info, if this is a TypeInfoLValue.
198 /// The QualType, if this is a DynamicAllocLValue.
200 };
201 };
202
203 /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
204 /// mean a virtual or non-virtual base class subobject.
205 typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
206
207 /// A non-discriminated union of a base, field, or array index.
209 static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
210 "pointer doesn't fit in 64 bits?");
211 uint64_t Value;
212
213 public:
214 LValuePathEntry() : Value() {}
215 LValuePathEntry(BaseOrMemberType BaseOrMember);
216 static LValuePathEntry ArrayIndex(uint64_t Index) {
218 Result.Value = Index;
219 return Result;
220 }
221
223 return BaseOrMemberType::getFromOpaqueValue(
224 reinterpret_cast<void *>(Value));
225 }
226 uint64_t getAsArrayIndex() const { return Value; }
227
228 void Profile(llvm::FoldingSetNodeID &ID) const;
229
231 return A.Value == B.Value;
232 }
234 return A.Value != B.Value;
235 }
236 friend llvm::hash_code hash_value(LValuePathEntry A) {
237 return llvm::hash_value(A.Value);
238 }
239 };
249 struct NoLValuePath {};
250 struct UninitArray {};
251 struct UninitStruct {};
253
254 template <typename Impl> friend class clang::serialization::BasicReaderBase;
255 friend class ASTImporter;
256 friend class ASTNodeImporter;
257
258private:
259 ValueKind Kind;
260 bool AllowConstexprUnknown : 1;
261
262 struct ComplexAPSInt {
263 APSInt Real, Imag;
264 ComplexAPSInt() : Real(1), Imag(1) {}
265 };
266 struct ComplexAPFloat {
267 APFloat Real, Imag;
268 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
269 };
270 struct LV;
271 struct Vec {
272 APValue *Elts = nullptr;
273 unsigned NumElts = 0;
274 Vec() = default;
275 Vec(const Vec &) = delete;
276 Vec &operator=(const Vec &) = delete;
277 ~Vec() { delete[] Elts; }
278 };
279 struct Mat {
280 APValue *Elts = nullptr;
281 unsigned NumRows = 0;
282 unsigned NumCols = 0;
283 Mat() = default;
284 Mat(const Mat &) = delete;
285 Mat &operator=(const Mat &) = delete;
286 ~Mat() { delete[] Elts; }
287 };
288 struct Arr {
289 APValue *Elts;
290 unsigned NumElts, ArrSize;
291 Arr(unsigned NumElts, unsigned ArrSize);
292 Arr(const Arr &) = delete;
293 Arr &operator=(const Arr &) = delete;
294 ~Arr();
295 };
296 struct StructData {
297 APValue *Elts;
298 unsigned NumBases;
299 unsigned NumFields;
300 unsigned NumVirtualBases;
301 StructData(unsigned NumBases, unsigned NumFields, unsigned NumVirtualBases);
302 StructData(const StructData &) = delete;
303 StructData &operator=(const StructData &) = delete;
304 ~StructData();
305 };
306 struct UnionData {
307 const FieldDecl *Field;
308 APValue *Value;
309 UnionData();
310 UnionData(const UnionData &) = delete;
311 UnionData &operator=(const UnionData &) = delete;
312 ~UnionData();
313 };
314 struct AddrLabelDiffData {
315 const AddrLabelExpr* LHSExpr;
316 const AddrLabelExpr* RHSExpr;
317 };
318 struct MemberPointerData;
319
320 // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
321 typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
322 ComplexAPFloat, Vec, Mat, Arr, StructData,
323 UnionData, AddrLabelDiffData>
324 DataType;
325 static const size_t DataSize = sizeof(DataType);
326
327 DataType Data;
328
329public:
330 bool allowConstexprUnknown() const { return AllowConstexprUnknown; }
331
332 void setConstexprUnknown(bool IsConstexprUnknown = true) {
333 AllowConstexprUnknown = IsConstexprUnknown;
334 }
335
336 /// Creates an empty APValue of type None.
337 APValue() : Kind(None), AllowConstexprUnknown(false) {}
338 /// Creates an integer APValue holding the given value.
339 explicit APValue(APSInt I) : Kind(None), AllowConstexprUnknown(false) {
340 MakeInt(); setInt(std::move(I));
341 }
342 /// Creates a float APValue holding the given value.
343 explicit APValue(APFloat F) : Kind(None), AllowConstexprUnknown(false) {
344 MakeFloat(); setFloat(std::move(F));
345 }
346 /// Creates a fixed-point APValue holding the given value.
347 explicit APValue(APFixedPoint FX) : Kind(None), AllowConstexprUnknown(false) {
348 MakeFixedPoint(std::move(FX));
349 }
350 /// Creates a vector APValue with \p N elements. The elements
351 /// are read from \p E.
352 explicit APValue(const APValue *E, unsigned N)
353 : Kind(None), AllowConstexprUnknown(false) {
354 MakeVector(); setVector(E, N);
355 }
356 /// Creates a matrix APValue with given dimensions. The elements
357 /// are read from \p E and assumed to be in row-major order.
358 explicit APValue(const APValue *E, unsigned NumRows, unsigned NumCols)
359 : Kind(None), AllowConstexprUnknown(false) {
360 MakeMatrix();
361 setMatrix(E, NumRows, NumCols);
362 }
363 /// Creates an integer complex APValue with the given real and imaginary
364 /// values.
365 APValue(APSInt R, APSInt I) : Kind(None), AllowConstexprUnknown(false) {
366 MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
367 }
368 /// Creates a float complex APValue with the given real and imaginary values.
369 APValue(APFloat R, APFloat I) : Kind(None), AllowConstexprUnknown(false) {
370 MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
371 }
372 APValue(const APValue &RHS);
373 APValue(APValue &&RHS);
374 /// Creates an lvalue APValue without an lvalue path.
375 /// \param Base The base of the lvalue.
376 /// \param Offset The offset of the lvalue.
377 /// \param IsNullPtr Whether this lvalue is a null pointer.
379 bool IsNullPtr = false)
380 : Kind(None), AllowConstexprUnknown(false) {
381 MakeLValue();
382 setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
383 }
384 /// Creates an lvalue APValue with an lvalue path.
385 /// \param Base The base of the lvalue.
386 /// \param Offset The offset of the lvalue.
387 /// \param Path The lvalue path.
388 /// \param OnePastTheEnd Whether this lvalue is one-past-the-end of the
389 /// subobject it points to.
390 /// \param IsNullPtr Whether this lvalue is a null pointer.
392 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
393 bool IsNullPtr = false)
394 : Kind(None), AllowConstexprUnknown(false) {
395 MakeLValue();
396 setLValue(Base, Offset, Path, OnePastTheEnd, IsNullPtr);
397 }
398 /// Creates a constexpr unknown lvalue APValue.
399 /// \param Base The base of the lvalue.
400 /// \param Offset The offset of the lvalue.
401 /// \param IsNullPtr Whether this lvalue is a null pointer.
403 bool IsNullPtr = false)
404 : Kind(None), AllowConstexprUnknown(true) {
405 MakeLValue();
406 setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
407 }
408
409 /// Creates a new array APValue.
410 /// \param UninitArray Marker. Pass an empty UninitArray.
411 /// \param InitElts Number of elements you're going to initialize in the
412 /// array.
413 /// \param Size Full size of the array.
414 APValue(UninitArray, unsigned InitElts, unsigned Size)
415 : Kind(None), AllowConstexprUnknown(false) {
416 MakeArray(InitElts, Size);
417 }
418 /// Creates a new struct APValue.
419 /// \param UninitStruct Marker. Pass an empty UninitStruct.
420 /// \param NumBases Number of bases.
421 /// \param NumMembers Number of members.
422 /// \param NumVirtualBases Number of virtual bases.
423 APValue(UninitStruct, unsigned NumBases, unsigned NumMembers,
424 unsigned NumVirtualBases = 0)
425 : Kind(None), AllowConstexprUnknown(false) {
426 MakeStruct(NumBases, NumMembers, NumVirtualBases);
427 }
428 /// Creates a new union APValue.
429 /// \param ActiveDecl The FieldDecl of the active union member.
430 /// \param ActiveValue The value of the active union member.
431 explicit APValue(const FieldDecl *ActiveDecl,
432 const APValue &ActiveValue = APValue())
433 : Kind(None), AllowConstexprUnknown(false) {
434 MakeUnion();
435 setUnion(ActiveDecl, ActiveValue);
436 }
437 /// Creates a new member pointer APValue.
438 /// \param Member Declaration of the member
439 /// \param IsDerivedMember Whether member is a derived one.
440 /// \param Path The path of the member.
441 APValue(const ValueDecl *Member, bool IsDerivedMember,
443 : Kind(None), AllowConstexprUnknown(false) {
444 MakeMemberPointer(Member, IsDerivedMember, Path);
445 }
446 /// Creates a new address label diff APValue.
447 /// \param LHSExpr The left-hand side of the difference.
448 /// \param RHSExpr The right-hand side of the difference.
449 APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
450 : Kind(None), AllowConstexprUnknown(false) {
451 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
452 }
455 Result.Kind = Indeterminate;
456 return Result;
457 }
458
459 APValue &operator=(const APValue &RHS);
460 APValue &operator=(APValue &&RHS);
461
463 if (Kind != None && Kind != Indeterminate)
464 DestroyDataAndMakeUninit();
465 }
466
467 /// Returns whether the object performed allocations.
468 ///
469 /// If APValues are constructed via placement new, \c needsCleanup()
470 /// indicates whether the destructor must be called in order to correctly
471 /// free all allocated memory.
472 bool needsCleanup() const;
473
474 /// Swaps the contents of this and the given APValue.
475 void swap(APValue &RHS);
476
477 /// profile this value. There is no guarantee that values of different
478 /// types will not produce the same profiled value, so the type should
479 /// typically also be profiled if it's not implied by the context.
480 void Profile(llvm::FoldingSetNodeID &ID) const;
481
482 ValueKind getKind() const { return Kind; }
483
484 bool isAbsent() const { return Kind == None; }
485 bool isIndeterminate() const { return Kind == Indeterminate; }
486 bool hasValue() const { return Kind != None && Kind != Indeterminate; }
487
488 bool isInt() const { return Kind == Int; }
489 bool isFloat() const { return Kind == Float; }
490 bool isFixedPoint() const { return Kind == FixedPoint; }
491 bool isComplexInt() const { return Kind == ComplexInt; }
492 bool isComplexFloat() const { return Kind == ComplexFloat; }
493 bool isLValue() const { return Kind == LValue; }
494 bool isVector() const { return Kind == Vector; }
495 bool isMatrix() const { return Kind == Matrix; }
496 bool isArray() const { return Kind == Array; }
497 bool isStruct() const { return Kind == Struct; }
498 bool isUnion() const { return Kind == Union; }
499 bool isMemberPointer() const { return Kind == MemberPointer; }
500 bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
501
502 void dump() const;
503 void dump(raw_ostream &OS, const ASTContext &Context) const;
504
505 void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
506 void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
507 const ASTContext *Ctx = nullptr) const;
508
509 std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
510
511 APSInt &getInt() {
512 assert(isInt() && "Invalid accessor");
513 return *(APSInt *)(char *)&Data;
514 }
515 const APSInt &getInt() const {
516 return const_cast<APValue*>(this)->getInt();
517 }
518
519 /// Try to convert this value to an integral constant. This works if it's an
520 /// integer, null pointer, or offset from a null pointer. Returns true on
521 /// success.
522 bool toIntegralConstant(APSInt &Result, QualType SrcTy,
523 const ASTContext &Ctx) const;
524
525 APFloat &getFloat() {
526 assert(isFloat() && "Invalid accessor");
527 return *(APFloat *)(char *)&Data;
528 }
529 const APFloat &getFloat() const {
530 return const_cast<APValue*>(this)->getFloat();
531 }
532
533 APFixedPoint &getFixedPoint() {
534 assert(isFixedPoint() && "Invalid accessor");
535 return *(APFixedPoint *)(char *)&Data;
536 }
537 const APFixedPoint &getFixedPoint() const {
538 return const_cast<APValue *>(this)->getFixedPoint();
539 }
540
542 assert(isComplexInt() && "Invalid accessor");
543 return ((ComplexAPSInt *)(char *)&Data)->Real;
544 }
545 const APSInt &getComplexIntReal() const {
546 return const_cast<APValue*>(this)->getComplexIntReal();
547 }
548
550 assert(isComplexInt() && "Invalid accessor");
551 return ((ComplexAPSInt *)(char *)&Data)->Imag;
552 }
553 const APSInt &getComplexIntImag() const {
554 return const_cast<APValue*>(this)->getComplexIntImag();
555 }
556
558 assert(isComplexFloat() && "Invalid accessor");
559 return ((ComplexAPFloat *)(char *)&Data)->Real;
560 }
561 const APFloat &getComplexFloatReal() const {
562 return const_cast<APValue*>(this)->getComplexFloatReal();
563 }
564
566 assert(isComplexFloat() && "Invalid accessor");
567 return ((ComplexAPFloat *)(char *)&Data)->Imag;
568 }
569 const APFloat &getComplexFloatImag() const {
570 return const_cast<APValue*>(this)->getComplexFloatImag();
571 }
572
573 const LValueBase getLValueBase() const;
574 CharUnits &getLValueOffset();
575 const CharUnits &getLValueOffset() const {
576 return const_cast<APValue*>(this)->getLValueOffset();
577 }
578 bool isLValueOnePastTheEnd() const;
579 bool hasLValuePath() const;
580 ArrayRef<LValuePathEntry> getLValuePath() const;
581 unsigned getLValueCallIndex() const;
582 unsigned getLValueVersion() const;
583 bool isNullPointer() const;
584
585 APValue &getVectorElt(unsigned I) {
586 assert(isVector() && "Invalid accessor");
587 assert(I < getVectorLength() && "Index out of range");
588 return ((Vec *)(char *)&Data)->Elts[I];
589 }
590 const APValue &getVectorElt(unsigned I) const {
591 return const_cast<APValue*>(this)->getVectorElt(I);
592 }
593 unsigned getVectorLength() const {
594 assert(isVector() && "Invalid accessor");
595 return ((const Vec *)(const void *)&Data)->NumElts;
596 }
597
598 unsigned getMatrixNumRows() const {
599 assert(isMatrix() && "Invalid accessor");
600 return ((const Mat *)(const void *)&Data)->NumRows;
601 }
602 unsigned getMatrixNumColumns() const {
603 assert(isMatrix() && "Invalid accessor");
604 return ((const Mat *)(const void *)&Data)->NumCols;
605 }
606 unsigned getMatrixNumElements() const {
608 }
609 APValue &getMatrixElt(unsigned Idx) {
610 assert(isMatrix() && "Invalid accessor");
611 assert(Idx < getMatrixNumElements() && "Index out of range");
612 return ((Mat *)(char *)&Data)->Elts[Idx];
613 }
614 const APValue &getMatrixElt(unsigned Idx) const {
615 return const_cast<APValue *>(this)->getMatrixElt(Idx);
616 }
617 APValue &getMatrixElt(unsigned Row, unsigned Col) {
618 assert(isMatrix() && "Invalid accessor");
619 assert(Row < getMatrixNumRows() && "Row index out of range");
620 assert(Col < getMatrixNumColumns() && "Column index out of range");
621 // Matrix elements are stored in row-major order.
622 unsigned I = Row * getMatrixNumColumns() + Col;
623 return getMatrixElt(I);
624 }
625 const APValue &getMatrixElt(unsigned Row, unsigned Col) const {
626 return const_cast<APValue *>(this)->getMatrixElt(Row, Col);
627 }
628
630 assert(isArray() && "Invalid accessor");
631 assert(I < getArrayInitializedElts() && "Index out of range");
632 return ((Arr *)(char *)&Data)->Elts[I];
633 }
634 const APValue &getArrayInitializedElt(unsigned I) const {
635 return const_cast<APValue*>(this)->getArrayInitializedElt(I);
636 }
637 bool hasArrayFiller() const {
639 }
641 assert(isArray() && "Invalid accessor");
642 assert(hasArrayFiller() && "No array filler");
643 return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
644 }
645 const APValue &getArrayFiller() const {
646 return const_cast<APValue*>(this)->getArrayFiller();
647 }
648 unsigned getArrayInitializedElts() const {
649 assert(isArray() && "Invalid accessor");
650 return ((const Arr *)(const void *)&Data)->NumElts;
651 }
652 unsigned getArraySize() const {
653 assert(isArray() && "Invalid accessor");
654 return ((const Arr *)(const void *)&Data)->ArrSize;
655 }
656
657 unsigned getStructNumBases() const {
658 assert(isStruct() && "Invalid accessor");
659 return ((const StructData *)(const char *)&Data)->NumBases;
660 }
661 unsigned getStructNumFields() const {
662 assert(isStruct() && "Invalid accessor");
663 return ((const StructData *)(const char *)&Data)->NumFields;
664 }
665 unsigned getStructNumVirtualBases() const {
666 assert(isStruct() && "Invalid accessor");
667 return ((const StructData *)(const char *)&Data)->NumVirtualBases;
668 }
669 APValue &getStructBase(unsigned i) {
670 assert(isStruct() && "Invalid accessor");
671 assert(i < getStructNumBases() && "base class index OOB");
672 return ((StructData *)(char *)&Data)->Elts[i];
673 }
674 APValue &getStructField(unsigned i) {
675 assert(isStruct() && "Invalid accessor");
676 assert(i < getStructNumFields() && "field index OOB");
677 return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
678 }
680 assert(isStruct() && "Invalid accessor");
681 assert(i < getStructNumVirtualBases() && "virtual base class index OOB");
682 return ((StructData *)(char *)&Data)
683 ->Elts[getStructNumBases() + getStructNumFields() + i];
684 }
685 const APValue &getStructBase(unsigned i) const {
686 return const_cast<APValue*>(this)->getStructBase(i);
687 }
688 const APValue &getStructField(unsigned i) const {
689 return const_cast<APValue*>(this)->getStructField(i);
690 }
691 const APValue &getStructVirtualBase(unsigned i) const {
692 return const_cast<APValue *>(this)->getStructVirtualBase(i);
693 }
694
695 const FieldDecl *getUnionField() const {
696 assert(isUnion() && "Invalid accessor");
697 return ((const UnionData *)(const char *)&Data)->Field;
698 }
700 assert(isUnion() && "Invalid accessor");
701 return *((UnionData *)(char *)&Data)->Value;
702 }
703 const APValue &getUnionValue() const {
704 return const_cast<APValue*>(this)->getUnionValue();
705 }
706
707 const ValueDecl *getMemberPointerDecl() const;
708 bool isMemberPointerToDerivedMember() const;
709 ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
710
712 assert(isAddrLabelDiff() && "Invalid accessor");
713 return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
714 }
716 assert(isAddrLabelDiff() && "Invalid accessor");
717 return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
718 }
719
720 void setInt(APSInt I) {
721 assert(isInt() && "Invalid accessor");
722 *(APSInt *)(char *)&Data = std::move(I);
723 }
724 void setFloat(APFloat F) {
725 assert(isFloat() && "Invalid accessor");
726 *(APFloat *)(char *)&Data = std::move(F);
727 }
728 void setFixedPoint(APFixedPoint FX) {
729 assert(isFixedPoint() && "Invalid accessor");
730 *(APFixedPoint *)(char *)&Data = std::move(FX);
731 }
732 void setVector(const APValue *E, unsigned N) {
733 MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
734 for (unsigned i = 0; i != N; ++i)
735 InternalElts[i] = E[i];
736 }
737 void setMatrix(const APValue *E, unsigned NumRows, unsigned NumCols) {
738 MutableArrayRef<APValue> InternalElts = setMatrixUninit(NumRows, NumCols);
739 for (unsigned i = 0; i != NumRows * NumCols; ++i)
740 InternalElts[i] = E[i];
741 }
742 void setComplexInt(APSInt R, APSInt I) {
743 assert(R.getBitWidth() == I.getBitWidth() &&
744 "Invalid complex int (type mismatch).");
745 assert(isComplexInt() && "Invalid accessor");
746 ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
747 ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
748 }
749 void setComplexFloat(APFloat R, APFloat I) {
750 assert(&R.getSemantics() == &I.getSemantics() &&
751 "Invalid complex float (type mismatch).");
752 assert(isComplexFloat() && "Invalid accessor");
753 ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
754 ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
755 }
756 void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
757 bool IsNullPtr);
758 void setLValue(LValueBase B, const CharUnits &O,
759 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
760 bool IsNullPtr);
761 void setUnion(const FieldDecl *Field, const APValue &Value);
762 void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
763 const AddrLabelExpr* RHSExpr) {
764 ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
765 ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
766 }
767
768private:
769 void DestroyDataAndMakeUninit();
770 void MakeInt() {
771 assert(isAbsent() && "Bad state change");
772 new ((void *)&Data) APSInt(1);
773 Kind = Int;
774 }
775 void MakeFloat() {
776 assert(isAbsent() && "Bad state change");
777 new ((void *)(char *)&Data) APFloat(0.0);
778 Kind = Float;
779 }
780 void MakeFixedPoint(APFixedPoint &&FX) {
781 assert(isAbsent() && "Bad state change");
782 new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
783 Kind = FixedPoint;
784 }
785 void MakeVector() {
786 assert(isAbsent() && "Bad state change");
787 new ((void *)(char *)&Data) Vec();
788 Kind = Vector;
789 }
790 void MakeMatrix() {
791 assert(isAbsent() && "Bad state change");
792 new ((void *)(char *)&Data) Mat();
793 Kind = Matrix;
794 }
795 void MakeComplexInt() {
796 assert(isAbsent() && "Bad state change");
797 new ((void *)(char *)&Data) ComplexAPSInt();
798 Kind = ComplexInt;
799 }
800 void MakeComplexFloat() {
801 assert(isAbsent() && "Bad state change");
802 new ((void *)(char *)&Data) ComplexAPFloat();
803 Kind = ComplexFloat;
804 }
805 void MakeLValue();
806 void MakeArray(unsigned InitElts, unsigned Size);
807 void MakeStruct(unsigned B, unsigned M, unsigned V) {
808 assert(isAbsent() && "Bad state change");
809 new ((void *)(char *)&Data) StructData(B, M, V);
810 Kind = Struct;
811 }
812 void MakeUnion() {
813 assert(isAbsent() && "Bad state change");
814 new ((void *)(char *)&Data) UnionData();
815 Kind = Union;
816 }
817 void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
818 ArrayRef<const CXXRecordDecl*> Path);
819 void MakeAddrLabelDiff() {
820 assert(isAbsent() && "Bad state change");
821 new ((void *)(char *)&Data) AddrLabelDiffData();
823 }
824
825private:
826 /// The following functions are used as part of initialization, during
827 /// deserialization and importing. Reserve the space so that it can be
828 /// filled in by those steps.
829 MutableArrayRef<APValue> setVectorUninit(unsigned N) {
830 assert(isVector() && "Invalid accessor");
831 Vec *V = ((Vec *)(char *)&Data);
832 V->Elts = new APValue[N];
833 V->NumElts = N;
834 return {V->Elts, V->NumElts};
835 }
836 MutableArrayRef<APValue> setMatrixUninit(unsigned NumRows, unsigned NumCols) {
837 assert(isMatrix() && "Invalid accessor");
838 Mat *M = ((Mat *)(char *)&Data);
839 unsigned NumElts = NumRows * NumCols;
840 M->Elts = new APValue[NumElts];
841 M->NumRows = NumRows;
842 M->NumCols = NumCols;
843 return {M->Elts, NumElts};
844 }
845 MutableArrayRef<LValuePathEntry>
846 setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
847 bool OnePastTheEnd, bool IsNullPtr);
848 MutableArrayRef<const CXXRecordDecl *>
849 setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
850 unsigned Size);
851};
852
853} // end namespace clang.
854
855namespace llvm {
856template<> struct DenseMapInfo<clang::APValue::LValueBase> {
857 static unsigned getHashValue(const clang::APValue::LValueBase &Base);
858 static bool isEqual(const clang::APValue::LValueBase &LHS,
859 const clang::APValue::LValueBase &RHS);
860};
861}
862
863#endif
#define V(N, I)
llvm::APSInt APSInt
Definition Compiler.cpp:25
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
TokenType getType() const
Returns the token's type, e.g.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static bool isVector(QualType QT, QualType ElementType)
This helper function returns true if QT is a vector type that has element type ElementType.
friend llvm::hash_code hash_value(const LValueBase &Base)
Definition APValue.cpp:188
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS)
Definition APValue.h:183
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
Definition APValue.h:199
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
Definition APValue.h:197
A non-discriminated union of a base, field, or array index.
Definition APValue.h:208
BaseOrMemberType getAsBaseOrMember() const
Definition APValue.h:222
uint64_t getAsArrayIndex() const
Definition APValue.h:226
friend llvm::hash_code hash_value(LValuePathEntry A)
Definition APValue.h:236
friend bool operator!=(LValuePathEntry A, LValuePathEntry B)
Definition APValue.h:233
static LValuePathEntry ArrayIndex(uint64_t Index)
Definition APValue.h:216
friend bool operator==(LValuePathEntry A, LValuePathEntry B)
Definition APValue.h:230
ArrayRef< LValuePathEntry > Path
Definition APValue.h:244
LValuePathSerializationHelper(ArrayRef< LValuePathEntry >, QualType)
Definition APValue.cpp:157
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
const APSInt & getComplexIntReal() const
Definition APValue.h:545
bool hasArrayFiller() const
Definition APValue.h:637
APValue(LValueBase Base, const CharUnits &Offset, NoLValuePath, bool IsNullPtr=false)
Creates an lvalue APValue without an lvalue path.
Definition APValue.h:378
APValue(APFloat F)
Creates a float APValue holding the given value.
Definition APValue.h:343
const APValue & getMatrixElt(unsigned Idx) const
Definition APValue.h:614
void setFloat(APFloat F)
Definition APValue.h:724
APValue & getArrayInitializedElt(unsigned I)
Definition APValue.h:629
APSInt & getInt()
Definition APValue.h:511
APValue & getStructField(unsigned i)
Definition APValue.h:674
APValue(const APValue *E, unsigned NumRows, unsigned NumCols)
Creates a matrix APValue with given dimensions.
Definition APValue.h:358
void setInt(APSInt I)
Definition APValue.h:720
unsigned getMatrixNumColumns() const
Definition APValue.h:602
APValue(APSInt I)
Creates an integer APValue holding the given value.
Definition APValue.h:339
const FieldDecl * getUnionField() const
Definition APValue.h:695
const APFloat & getFloat() const
Definition APValue.h:529
bool isVector() const
Definition APValue.h:494
APSInt & getComplexIntImag()
Definition APValue.h:549
unsigned getStructNumFields() const
Definition APValue.h:661
const APValue & getArrayInitializedElt(unsigned I) const
Definition APValue.h:634
APValue(APFloat R, APFloat I)
Creates a float complex APValue with the given real and imaginary values.
Definition APValue.h:369
void setConstexprUnknown(bool IsConstexprUnknown=true)
Definition APValue.h:332
bool isAbsent() const
Definition APValue.h:484
APValue(const FieldDecl *ActiveDecl, const APValue &ActiveValue=APValue())
Creates a new union APValue.
Definition APValue.h:431
bool isComplexInt() const
Definition APValue.h:491
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:205
ValueKind getKind() const
Definition APValue.h:482
APValue & getStructVirtualBase(unsigned i)
Definition APValue.h:679
const APValue & getMatrixElt(unsigned Row, unsigned Col) const
Definition APValue.h:625
bool isArray() const
Definition APValue.h:496
APValue(const APValue *E, unsigned N)
Creates a vector APValue with N elements.
Definition APValue.h:352
void setFixedPoint(APFixedPoint FX)
Definition APValue.h:728
unsigned getArrayInitializedElts() const
Definition APValue.h:648
static APValue IndeterminateValue()
Definition APValue.h:453
bool isFloat() const
Definition APValue.h:489
void setComplexInt(APSInt R, APSInt I)
Definition APValue.h:742
const APFixedPoint & getFixedPoint() const
Definition APValue.h:537
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
Definition APValue.cpp:489
unsigned getStructNumBases() const
Definition APValue.h:657
APFixedPoint & getFixedPoint()
Definition APValue.h:533
APValue(const ValueDecl *Member, bool IsDerivedMember, ArrayRef< const CXXRecordDecl * > Path)
Creates a new member pointer APValue.
Definition APValue.h:441
const APValue & getStructBase(unsigned i) const
Definition APValue.h:685
bool hasValue() const
Definition APValue.h:486
friend class ASTNodeImporter
Definition APValue.h:256
unsigned getStructNumVirtualBases() const
Definition APValue.h:665
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:391
APValue & getUnionValue()
Definition APValue.h:699
void setMatrix(const APValue *E, unsigned NumRows, unsigned NumCols)
Definition APValue.h:737
const AddrLabelExpr * getAddrLabelDiffRHS() const
Definition APValue.h:715
CharUnits & getLValueOffset()
Definition APValue.cpp:1030
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Definition APValue.h:762
void setComplexFloat(APFloat R, APFloat I)
Definition APValue.h:749
bool isComplexFloat() const
Definition APValue.h:492
APValue & getVectorElt(unsigned I)
Definition APValue.h:585
APValue & getArrayFiller()
Definition APValue.h:640
APValue(LValueBase Base, const CharUnits &Offset, ConstexprUnknown, bool IsNullPtr=false)
Creates a constexpr unknown lvalue APValue.
Definition APValue.h:402
const APValue & getArrayFiller() const
Definition APValue.h:645
const APFloat & getComplexFloatImag() const
Definition APValue.h:569
unsigned getVectorLength() const
Definition APValue.h:593
const APValue & getUnionValue() const
Definition APValue.h:703
const APValue & getVectorElt(unsigned I) const
Definition APValue.h:590
APValue(UninitArray, unsigned InitElts, unsigned Size)
Creates a new array APValue.
Definition APValue.h:414
bool isLValue() const
Definition APValue.h:493
void setUnion(const FieldDecl *Field, const APValue &Value)
Definition APValue.cpp:1096
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Creates a new address label diff APValue.
Definition APValue.h:449
bool isIndeterminate() const
Definition APValue.h:485
unsigned getMatrixNumRows() const
Definition APValue.h:598
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
Definition APValue.cpp:1061
bool isMemberPointer() const
Definition APValue.h:499
const APSInt & getInt() const
Definition APValue.h:515
friend class ASTImporter
Definition APValue.h:255
APValue & getMatrixElt(unsigned Row, unsigned Col)
Definition APValue.h:617
const APFloat & getComplexFloatReal() const
Definition APValue.h:561
bool isInt() const
Definition APValue.h:488
unsigned getArraySize() const
Definition APValue.h:652
APValue(APSInt R, APSInt I)
Creates an integer complex APValue with the given real and imaginary values.
Definition APValue.h:365
APValue(UninitStruct, unsigned NumBases, unsigned NumMembers, unsigned NumVirtualBases=0)
Creates a new struct APValue.
Definition APValue.h:423
bool isUnion() const
Definition APValue.h:498
const CharUnits & getLValueOffset() const
Definition APValue.h:575
bool allowConstexprUnknown() const
Definition APValue.h:330
bool isFixedPoint() const
Definition APValue.h:490
void setVector(const APValue *E, unsigned N)
Definition APValue.h:732
APValue & getMatrixElt(unsigned Idx)
Definition APValue.h:609
@ 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 & getStructVirtualBase(unsigned i) const
Definition APValue.h:691
const APValue & getStructField(unsigned i) const
Definition APValue.h:688
const APSInt & getComplexIntImag() const
Definition APValue.h:553
bool isStruct() const
Definition APValue.h:497
APSInt & getComplexIntReal()
Definition APValue.h:541
APFloat & getComplexFloatImag()
Definition APValue.h:565
APFloat & getComplexFloatReal()
Definition APValue.h:557
APFloat & getFloat()
Definition APValue.h:525
APValue & getStructBase(unsigned i)
Definition APValue.h:669
bool isMatrix() const
Definition APValue.h:495
APValue(APFixedPoint FX)
Creates a fixed-point APValue holding the given value.
Definition APValue.h:347
const AddrLabelExpr * getAddrLabelDiffLHS() const
Definition APValue.h:711
unsigned getMatrixNumElements() const
Definition APValue.h:606
bool isAddrLabelDiff() const
Definition APValue.h:500
APValue()
Creates an empty APValue of type None.
Definition APValue.h:337
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition Expr.h:4556
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.
Symbolic representation of a dynamic allocation.
Definition APValue.h:65
static unsigned getMaxIndex()
Definition APValue.h:85
const void * getOpaqueValue() const
Definition APValue.h:75
static constexpr int NumLowBitsAvailable
Definition APValue.h:89
DynamicAllocLValue(unsigned Index)
Definition APValue.h:70
static DynamicAllocLValue getFromOpaqueValue(const void *Value)
Definition APValue.h:79
This represents one expression.
Definition Expr.h:112
Represents a member of a struct/union/class.
Definition Decl.h:3204
A (possibly-)qualified type.
Definition TypeBase.h:937
Symbolic representation of typeid(T) for some type T.
Definition APValue.h:44
const Type * getType() const
Definition APValue.h:51
static TypeInfoLValue getFromOpaqueValue(const void *Value)
Definition APValue.h:55
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
Definition APValue.cpp:30
const void * getOpaqueValue() const
Definition APValue.h:54
The base class of the type hierarchy.
Definition TypeBase.h:1875
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
llvm::APFloat APFloat
Definition Floating.h:27
@ AddrLabelDiff
Difference between two AddrLabelExpr.
Definition Primitives.h:36
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
Definition CallGraph.h:218
@ Result
The result type of a method or function.
Definition TypeBase.h:905
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:62
U cast(CodeGen::Address addr)
Definition Address.h:327
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
hash_code hash_value(const clang::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 false
Definition stdbool.h:26
#define true
Definition stdbool.h:25
Describes how types, statements, expressions, and declarations should be printed.
static bool isEqual(const clang::APValue::LValueBase &LHS, const clang::APValue::LValueBase &RHS)
Definition APValue.cpp:201
static unsigned getHashValue(const clang::APValue::LValueBase &Base)
Definition APValue.cpp:196
static const void * getAsVoidPointer(clang::DynamicAllocLValue V)
Definition APValue.h:107
static clang::DynamicAllocLValue getFromVoidPointer(const void *P)
Definition APValue.h:110
static clang::TypeInfoLValue getFromVoidPointer(const void *P)
Definition APValue.h:98
static const void * getAsVoidPointer(clang::TypeInfoLValue V)
Definition APValue.h:95