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