13#ifndef LLVM_CLANG_AST_APVALUE_H
14#define LLVM_CLANG_AST_APVALUE_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"
26namespace serialization {
52 explicit operator bool()
const {
return T; }
73 explicit operator bool()
const {
return Index != 0; }
76 return reinterpret_cast<void *
>(
static_cast<uintptr_t>(Index)
96 return V.getOpaqueValue();
103 static constexpr int NumLowBitsAvailable = 3;
108 return V.getOpaqueValue();
113 static constexpr int NumLowBitsAvailable =
123 typedef llvm::APFixedPoint APFixedPoint;
124 typedef llvm::APSInt APSInt;
125 typedef llvm::APFloat APFloat;
158 void Profile(llvm::FoldingSetNodeID &
ID)
const;
160 template <
class T>
bool is()
const {
return isa<T>(Ptr); }
162 template <
class T>
T get()
const {
return cast<T>(Ptr); }
165 return dyn_cast_if_present<T>(Ptr);
168 void *getOpaqueValue()
const;
172 explicit operator bool()
const;
174 unsigned getCallIndex()
const;
175 unsigned getVersion()
const;
177 QualType getDynamicAllocType()
const;
183 return !(LHS == RHS);
191 unsigned CallIndex, Version;
208 static_assert(
sizeof(
uintptr_t) <=
sizeof(uint64_t),
209 "pointer doesn't fit in 64 bits?");
217 Result.Value = Index;
222 return BaseOrMemberType::getFromOpaqueValue(
223 reinterpret_cast<void *
>(
Value));
227 void Profile(llvm::FoldingSetNodeID &
ID)
const;
230 return A.Value == B.Value;
233 return A.Value != B.Value;
259 bool AllowConstexprUnknown : 1;
261 struct ComplexAPSInt {
263 ComplexAPSInt() : Real(1), Imag(1) {}
265 struct ComplexAPFloat {
267 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
272 unsigned NumElts = 0;
274 Vec(
const Vec &) =
delete;
275 Vec &operator=(
const Vec &) =
delete;
276 ~Vec() {
delete[] Elts; }
280 unsigned NumElts, ArrSize;
281 Arr(
unsigned NumElts,
unsigned ArrSize);
282 Arr(
const Arr &) =
delete;
283 Arr &operator=(
const Arr &) =
delete;
290 StructData(
unsigned NumBases,
unsigned NumFields);
291 StructData(
const StructData &) =
delete;
292 StructData &operator=(
const StructData &) =
delete;
296 const FieldDecl *
Field;
299 UnionData(
const UnionData &) =
delete;
300 UnionData &operator=(
const UnionData &) =
delete;
303 struct AddrLabelDiffData {
304 const AddrLabelExpr* LHSExpr;
305 const AddrLabelExpr* RHSExpr;
307 struct MemberPointerData;
310 typedef llvm::AlignedCharArrayUnion<
void *,
APSInt,
APFloat, ComplexAPSInt,
311 ComplexAPFloat, Vec, Arr, StructData,
312 UnionData, AddrLabelDiffData> DataType;
313 static const size_t DataSize =
sizeof(DataType);
321 AllowConstexprUnknown = IsConstexprUnknown;
328 MakeInt(); setInt(std::move(I));
332 MakeFloat(); setFloat(std::move(F));
336 MakeFixedPoint(std::move(FX));
342 MakeVector(); setVector(
E, N);
347 MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
351 MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
360 bool IsNullPtr =
false)
374 bool IsNullPtr =
false)
377 setLValue(
Base, Offset,
Path, OnePastTheEnd, IsNullPtr);
384 bool IsNullPtr =
false)
397 MakeArray(InitElts, Size);
405 MakeStruct(NumBases, NumMembers);
414 setUnion(ActiveDecl, ActiveValue);
423 MakeMemberPointer(
Member, IsDerivedMember,
Path);
430 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
434 Result.Kind = Indeterminate;
443 DestroyDataAndMakeUninit();
451 bool needsCleanup()
const;
459 void Profile(llvm::FoldingSetNodeID &
ID)
const;
490 assert(isInt() &&
"Invalid accessor");
491 return *(APSInt *)(
char *)&
Data;
494 return const_cast<APValue*
>(
this)->getInt();
504 assert(isFloat() &&
"Invalid accessor");
505 return *(APFloat *)(
char *)&
Data;
508 return const_cast<APValue*
>(
this)->getFloat();
512 assert(isFixedPoint() &&
"Invalid accessor");
513 return *(APFixedPoint *)(
char *)&
Data;
516 return const_cast<APValue *
>(
this)->getFixedPoint();
520 assert(isComplexInt() &&
"Invalid accessor");
521 return ((ComplexAPSInt *)(
char *)&
Data)->Real;
524 return const_cast<APValue*
>(
this)->getComplexIntReal();
528 assert(isComplexInt() &&
"Invalid accessor");
529 return ((ComplexAPSInt *)(
char *)&
Data)->Imag;
532 return const_cast<APValue*
>(
this)->getComplexIntImag();
536 assert(isComplexFloat() &&
"Invalid accessor");
537 return ((ComplexAPFloat *)(
char *)&
Data)->Real;
540 return const_cast<APValue*
>(
this)->getComplexFloatReal();
544 assert(isComplexFloat() &&
"Invalid accessor");
545 return ((ComplexAPFloat *)(
char *)&
Data)->Imag;
548 return const_cast<APValue*
>(
this)->getComplexFloatImag();
551 const LValueBase getLValueBase()
const;
554 return const_cast<APValue*
>(
this)->getLValueOffset();
556 bool isLValueOnePastTheEnd()
const;
557 bool hasLValuePath()
const;
559 unsigned getLValueCallIndex()
const;
560 unsigned getLValueVersion()
const;
561 bool isNullPointer()
const;
564 assert(
isVector() &&
"Invalid accessor");
565 assert(I < getVectorLength() &&
"Index out of range");
566 return ((Vec *)(
char *)&
Data)->Elts[I];
569 return const_cast<APValue*
>(
this)->getVectorElt(I);
572 assert(
isVector() &&
"Invalid accessor");
573 return ((
const Vec *)(
const void *)&
Data)->NumElts;
577 assert(isArray() &&
"Invalid accessor");
578 assert(I < getArrayInitializedElts() &&
"Index out of range");
579 return ((Arr *)(
char *)&
Data)->Elts[I];
582 return const_cast<APValue*
>(
this)->getArrayInitializedElt(I);
585 return getArrayInitializedElts() != getArraySize();
588 assert(isArray() &&
"Invalid accessor");
589 assert(hasArrayFiller() &&
"No array filler");
590 return ((Arr *)(
char *)&
Data)->Elts[getArrayInitializedElts()];
593 return const_cast<APValue*
>(
this)->getArrayFiller();
596 assert(isArray() &&
"Invalid accessor");
597 return ((
const Arr *)(
const void *)&
Data)->NumElts;
600 assert(isArray() &&
"Invalid accessor");
601 return ((
const Arr *)(
const void *)&
Data)->ArrSize;
605 assert(isStruct() &&
"Invalid accessor");
606 return ((
const StructData *)(
const char *)&
Data)->NumBases;
609 assert(isStruct() &&
"Invalid accessor");
610 return ((
const StructData *)(
const char *)&
Data)->NumFields;
613 assert(isStruct() &&
"Invalid accessor");
614 assert(i < getStructNumBases() &&
"base class index OOB");
615 return ((StructData *)(
char *)&
Data)->Elts[i];
618 assert(isStruct() &&
"Invalid accessor");
619 assert(i < getStructNumFields() &&
"field index OOB");
620 return ((StructData *)(
char *)&
Data)->Elts[getStructNumBases() + i];
623 return const_cast<APValue*
>(
this)->getStructBase(i);
626 return const_cast<APValue*
>(
this)->getStructField(i);
630 assert(isUnion() &&
"Invalid accessor");
631 return ((
const UnionData *)(
const char *)&
Data)->Field;
634 assert(isUnion() &&
"Invalid accessor");
635 return *((UnionData *)(
char *)&
Data)->
Value;
638 return const_cast<APValue*
>(
this)->getUnionValue();
641 const ValueDecl *getMemberPointerDecl()
const;
642 bool isMemberPointerToDerivedMember()
const;
646 assert(isAddrLabelDiff() &&
"Invalid accessor");
647 return ((
const AddrLabelDiffData *)(
const char *)&
Data)->LHSExpr;
650 assert(isAddrLabelDiff() &&
"Invalid accessor");
651 return ((
const AddrLabelDiffData *)(
const char *)&
Data)->RHSExpr;
655 assert(isInt() &&
"Invalid accessor");
656 *(APSInt *)(
char *)&
Data = std::move(I);
659 assert(isFloat() &&
"Invalid accessor");
660 *(APFloat *)(
char *)&
Data = std::move(F);
663 assert(isFixedPoint() &&
"Invalid accessor");
664 *(APFixedPoint *)(
char *)&
Data = std::move(FX);
668 for (
unsigned i = 0; i != N; ++i)
669 InternalElts[i] =
E[i];
672 assert(R.getBitWidth() == I.getBitWidth() &&
673 "Invalid complex int (type mismatch).");
674 assert(isComplexInt() &&
"Invalid accessor");
675 ((ComplexAPSInt *)(
char *)&
Data)->Real = std::move(R);
676 ((ComplexAPSInt *)(
char *)&
Data)->Imag = std::move(I);
679 assert(&R.getSemantics() == &I.getSemantics() &&
680 "Invalid complex float (type mismatch).");
681 assert(isComplexFloat() &&
"Invalid accessor");
682 ((ComplexAPFloat *)(
char *)&
Data)->Real = std::move(R);
683 ((ComplexAPFloat *)(
char *)&
Data)->Imag = std::move(I);
685 void setLValue(LValueBase B,
const CharUnits &O, NoLValuePath,
687 void setLValue(LValueBase B,
const CharUnits &O,
693 ((AddrLabelDiffData *)(
char *)&
Data)->LHSExpr = LHSExpr;
694 ((AddrLabelDiffData *)(
char *)&
Data)->RHSExpr = RHSExpr;
698 void DestroyDataAndMakeUninit();
700 assert(isAbsent() &&
"Bad state change");
705 assert(isAbsent() &&
"Bad state change");
706 new ((
void *)(
char *)&
Data) APFloat(0.0);
709 void MakeFixedPoint(APFixedPoint &&FX) {
710 assert(isAbsent() &&
"Bad state change");
711 new ((
void *)(
char *)&
Data) APFixedPoint(std::move(FX));
715 assert(isAbsent() &&
"Bad state change");
716 new ((
void *)(
char *)&
Data) Vec();
719 void MakeComplexInt() {
720 assert(isAbsent() &&
"Bad state change");
721 new ((
void *)(
char *)&
Data) ComplexAPSInt();
724 void MakeComplexFloat() {
725 assert(isAbsent() &&
"Bad state change");
726 new ((
void *)(
char *)&
Data) ComplexAPFloat();
730 void MakeArray(
unsigned InitElts,
unsigned Size);
731 void MakeStruct(
unsigned B,
unsigned M) {
732 assert(isAbsent() &&
"Bad state change");
733 new ((
void *)(
char *)&
Data) StructData(B, M);
737 assert(isAbsent() &&
"Bad state change");
738 new ((
void *)(
char *)&
Data) UnionData();
741 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
742 ArrayRef<const CXXRecordDecl*>
Path);
743 void MakeAddrLabelDiff() {
744 assert(isAbsent() &&
"Bad state change");
745 new ((
void *)(
char *)&
Data) AddrLabelDiffData();
746 Kind = AddrLabelDiff;
753 MutableArrayRef<APValue> setVectorUninit(
unsigned N) {
754 assert(
isVector() &&
"Invalid accessor");
755 Vec *
V = ((Vec *)(
char *)&
Data);
758 return {
V->Elts,
V->NumElts};
760 MutableArrayRef<LValuePathEntry>
761 setLValueUninit(LValueBase B,
const CharUnits &O,
unsigned Size,
762 bool OnePastTheEnd,
bool IsNullPtr);
763 MutableArrayRef<const CXXRecordDecl *>
764 setMemberPointerUninit(
const ValueDecl *Member,
bool IsDerivedMember,
771template<>
struct DenseMapInfo<
clang::APValue::LValueBase> {
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
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 bool operator!=(const LValueBase &LHS, const LValueBase &RHS)
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
uint64_t getAsArrayIndex() const
friend llvm::hash_code hash_value(LValuePathEntry A)
friend bool operator!=(LValuePathEntry A, LValuePathEntry B)
static LValuePathEntry ArrayIndex(uint64_t Index)
friend bool operator==(LValuePathEntry A, LValuePathEntry B)
ArrayRef< LValuePathEntry > Path
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const APSInt & getComplexIntReal() const
bool hasArrayFiller() const
APValue(LValueBase Base, const CharUnits &Offset, NoLValuePath, bool IsNullPtr=false)
Creates an lvalue APValue without an lvalue path.
APValue(APFloat F)
Creates a float APValue holding the given value.
APValue & getArrayInitializedElt(unsigned I)
APValue & getStructField(unsigned i)
APValue(APSInt I)
Creates an integer APValue holding the given value.
const FieldDecl * getUnionField() const
const APFloat & getFloat() const
APSInt & getComplexIntImag()
unsigned getStructNumFields() const
const APValue & getArrayInitializedElt(unsigned I) const
APValue(APFloat R, APFloat I)
Creates a float complex APValue with the given real and imaginary values.
void setConstexprUnknown(bool IsConstexprUnknown=true)
APValue(const FieldDecl *ActiveDecl, const APValue &ActiveValue=APValue())
Creates a new union APValue.
bool isComplexInt() const
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...
ValueKind getKind() const
APValue(const APValue *E, unsigned N)
Creates a vector APValue with N elements.
void setFixedPoint(APFixedPoint FX)
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
void setComplexInt(APSInt R, APSInt I)
const APFixedPoint & getFixedPoint() const
unsigned getStructNumBases() const
APFixedPoint & getFixedPoint()
APValue(const ValueDecl *Member, bool IsDerivedMember, ArrayRef< const CXXRecordDecl * > Path)
Creates a new member pointer APValue.
const APValue & getStructBase(unsigned i) const
APValue(LValueBase Base, const CharUnits &Offset, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, bool IsNullPtr=false)
Creates an lvalue APValue with an lvalue path.
APValue & getUnionValue()
const AddrLabelExpr * getAddrLabelDiffRHS() const
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
void setComplexFloat(APFloat R, APFloat I)
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
APValue(LValueBase Base, const CharUnits &Offset, ConstexprUnknown, bool IsNullPtr=false)
Creates a constexpr unknown lvalue APValue.
const APValue & getArrayFiller() const
const APFloat & getComplexFloatImag() const
unsigned getVectorLength() const
const APValue & getUnionValue() const
const APValue & getVectorElt(unsigned I) const
APValue(UninitArray, unsigned InitElts, unsigned Size)
Creates a new array APValue.
APValue(UninitStruct, unsigned NumBases, unsigned NumMembers)
Creates a new struct APValue.
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Creates a new address label diff APValue.
bool isIndeterminate() const
bool isMemberPointer() const
const APSInt & getInt() const
const APFloat & getComplexFloatReal() const
unsigned getArraySize() const
APValue(APSInt R, APSInt I)
Creates an integer complex APValue with the given real and imaginary values.
const CharUnits & getLValueOffset() const
bool allowConstexprUnknown() const
bool isFixedPoint() const
void setVector(const APValue *E, unsigned N)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
const APValue & getStructField(unsigned i) const
const APSInt & getComplexIntImag() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
APValue(APFixedPoint FX)
Creates a fixed-point APValue holding the given value.
const AddrLabelExpr * getAddrLabelDiffLHS() const
bool isAddrLabelDiff() const
APValue()
Creates an empty APValue of type None.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Imports selected nodes from one AST context into another context, merging AST nodes where appropriate...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents a C++ struct/union/class.
CharUnits - This is an opaque type for sizes expressed in character units.
Decl - This represents one declaration (or definition), e.g.
A little helper class used to produce diagnostics.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
static constexpr int NumLowBitsAvailable
DynamicAllocLValue(unsigned Index)
static DynamicAllocLValue getFromOpaqueValue(void *Value)
This represents one expression.
Represents a member of a struct/union/class.
A (possibly-)qualified type.
Symbolic representation of typeid(T) for some type T.
const Type * getType() const
static TypeInfoLValue getFromOpaqueValue(void *Value)
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
The base class of the type hierarchy.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
The JSON file list parser is used to communicate input to InstallAPI.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
const FunctionProtoType * T
llvm::StringRef getAsString(SyncScope S)
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Describes how types, statements, expressions, and declarations should be printed.
static void * getAsVoidPointer(clang::DynamicAllocLValue V)
static clang::DynamicAllocLValue getFromVoidPointer(void *P)
static void * getAsVoidPointer(clang::TypeInfoLValue V)
static clang::TypeInfoLValue getFromVoidPointer(void *P)