APValue.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the APValue class.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_CLANG_AST_APVALUE_H
  18. #define LLVM_CLANG_AST_APVALUE_H
  19. #include "clang/Basic/LLVM.h"
  20. #include "llvm/ADT/APFixedPoint.h"
  21. #include "llvm/ADT/APFloat.h"
  22. #include "llvm/ADT/APSInt.h"
  23. #include "llvm/ADT/FoldingSet.h"
  24. #include "llvm/ADT/PointerIntPair.h"
  25. #include "llvm/ADT/PointerUnion.h"
  26. #include "llvm/Support/AlignOf.h"
  27. namespace clang {
  28. namespace serialization {
  29. template <typename T> class BasicReaderBase;
  30. } // end namespace serialization
  31. class AddrLabelExpr;
  32. class ASTContext;
  33. class CharUnits;
  34. class CXXRecordDecl;
  35. class Decl;
  36. class DiagnosticBuilder;
  37. class Expr;
  38. class FieldDecl;
  39. struct PrintingPolicy;
  40. class Type;
  41. class ValueDecl;
  42. class QualType;
  43. /// Symbolic representation of typeid(T) for some type T.
  44. class TypeInfoLValue {
  45. const Type *T;
  46. public:
  47. TypeInfoLValue() : T() {}
  48. explicit TypeInfoLValue(const Type *T);
  49. const Type *getType() const { return T; }
  50. explicit operator bool() const { return T; }
  51. void *getOpaqueValue() { return const_cast<Type*>(T); }
  52. static TypeInfoLValue getFromOpaqueValue(void *Value) {
  53. TypeInfoLValue V;
  54. V.T = reinterpret_cast<const Type*>(Value);
  55. return V;
  56. }
  57. void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
  58. };
  59. /// Symbolic representation of a dynamic allocation.
  60. class DynamicAllocLValue {
  61. unsigned Index;
  62. public:
  63. DynamicAllocLValue() : Index(0) {}
  64. explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
  65. unsigned getIndex() { return Index - 1; }
  66. explicit operator bool() const { return Index != 0; }
  67. void *getOpaqueValue() {
  68. return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
  69. << NumLowBitsAvailable);
  70. }
  71. static DynamicAllocLValue getFromOpaqueValue(void *Value) {
  72. DynamicAllocLValue V;
  73. V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
  74. return V;
  75. }
  76. static unsigned getMaxIndex() {
  77. return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
  78. }
  79. static constexpr int NumLowBitsAvailable = 3;
  80. };
  81. }
  82. namespace llvm {
  83. template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
  84. static void *getAsVoidPointer(clang::TypeInfoLValue V) {
  85. return V.getOpaqueValue();
  86. }
  87. static clang::TypeInfoLValue getFromVoidPointer(void *P) {
  88. return clang::TypeInfoLValue::getFromOpaqueValue(P);
  89. }
  90. // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
  91. // to include Type.h.
  92. static constexpr int NumLowBitsAvailable = 3;
  93. };
  94. template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
  95. static void *getAsVoidPointer(clang::DynamicAllocLValue V) {
  96. return V.getOpaqueValue();
  97. }
  98. static clang::DynamicAllocLValue getFromVoidPointer(void *P) {
  99. return clang::DynamicAllocLValue::getFromOpaqueValue(P);
  100. }
  101. static constexpr int NumLowBitsAvailable =
  102. clang::DynamicAllocLValue::NumLowBitsAvailable;
  103. };
  104. }
  105. namespace clang {
  106. /// APValue - This class implements a discriminated union of [uninitialized]
  107. /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
  108. /// [Vector: N * APValue], [Array: N * APValue]
  109. class APValue {
  110. typedef llvm::APFixedPoint APFixedPoint;
  111. typedef llvm::APSInt APSInt;
  112. typedef llvm::APFloat APFloat;
  113. public:
  114. enum ValueKind {
  115. /// There is no such object (it's outside its lifetime).
  116. None,
  117. /// This object has an indeterminate value (C++ [basic.indet]).
  118. Indeterminate,
  119. Int,
  120. Float,
  121. FixedPoint,
  122. ComplexInt,
  123. ComplexFloat,
  124. LValue,
  125. Vector,
  126. Array,
  127. Struct,
  128. Union,
  129. MemberPointer,
  130. AddrLabelDiff
  131. };
  132. class LValueBase {
  133. typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
  134. DynamicAllocLValue>
  135. PtrTy;
  136. public:
  137. LValueBase() : Local{} {}
  138. LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
  139. LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
  140. static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
  141. static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
  142. void Profile(llvm::FoldingSetNodeID &ID) const;
  143. template <class T>
  144. bool is() const { return Ptr.is<T>(); }
  145. template <class T>
  146. T get() const { return Ptr.get<T>(); }
  147. template <class T>
  148. T dyn_cast() const { return Ptr.dyn_cast<T>(); }
  149. void *getOpaqueValue() const;
  150. bool isNull() const;
  151. explicit operator bool() const;
  152. unsigned getCallIndex() const;
  153. unsigned getVersion() const;
  154. QualType getTypeInfoType() const;
  155. QualType getDynamicAllocType() const;
  156. QualType getType() const;
  157. friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
  158. friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
  159. return !(LHS == RHS);
  160. }
  161. friend llvm::hash_code hash_value(const LValueBase &Base);
  162. friend struct llvm::DenseMapInfo<LValueBase>;
  163. private:
  164. PtrTy Ptr;
  165. struct LocalState {
  166. unsigned CallIndex, Version;
  167. };
  168. union {
  169. LocalState Local;
  170. /// The type std::type_info, if this is a TypeInfoLValue.
  171. void *TypeInfoType;
  172. /// The QualType, if this is a DynamicAllocLValue.
  173. void *DynamicAllocType;
  174. };
  175. };
  176. /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
  177. /// mean a virtual or non-virtual base class subobject.
  178. typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
  179. /// A non-discriminated union of a base, field, or array index.
  180. class LValuePathEntry {
  181. static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
  182. "pointer doesn't fit in 64 bits?");
  183. uint64_t Value;
  184. public:
  185. LValuePathEntry() : Value() {}
  186. LValuePathEntry(BaseOrMemberType BaseOrMember);
  187. static LValuePathEntry ArrayIndex(uint64_t Index) {
  188. LValuePathEntry Result;
  189. Result.Value = Index;
  190. return Result;
  191. }
  192. BaseOrMemberType getAsBaseOrMember() const {
  193. return BaseOrMemberType::getFromOpaqueValue(
  194. reinterpret_cast<void *>(Value));
  195. }
  196. uint64_t getAsArrayIndex() const { return Value; }
  197. void Profile(llvm::FoldingSetNodeID &ID) const;
  198. friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
  199. return A.Value == B.Value;
  200. }
  201. friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
  202. return A.Value != B.Value;
  203. }
  204. friend llvm::hash_code hash_value(LValuePathEntry A) {
  205. return llvm::hash_value(A.Value);
  206. }
  207. };
  208. class LValuePathSerializationHelper {
  209. const void *ElemTy;
  210. public:
  211. ArrayRef<LValuePathEntry> Path;
  212. LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
  213. QualType getType();
  214. };
  215. struct NoLValuePath {};
  216. struct UninitArray {};
  217. struct UninitStruct {};
  218. template <typename Impl> friend class clang::serialization::BasicReaderBase;
  219. friend class ASTImporter;
  220. friend class ASTNodeImporter;
  221. private:
  222. ValueKind Kind;
  223. struct ComplexAPSInt {
  224. APSInt Real, Imag;
  225. ComplexAPSInt() : Real(1), Imag(1) {}
  226. };
  227. struct ComplexAPFloat {
  228. APFloat Real, Imag;
  229. ComplexAPFloat() : Real(0.0), Imag(0.0) {}
  230. };
  231. struct LV;
  232. struct Vec {
  233. APValue *Elts;
  234. unsigned NumElts;
  235. Vec() : Elts(nullptr), NumElts(0) {}
  236. ~Vec() { delete[] Elts; }
  237. };
  238. struct Arr {
  239. APValue *Elts;
  240. unsigned NumElts, ArrSize;
  241. Arr(unsigned NumElts, unsigned ArrSize);
  242. ~Arr();
  243. };
  244. struct StructData {
  245. APValue *Elts;
  246. unsigned NumBases;
  247. unsigned NumFields;
  248. StructData(unsigned NumBases, unsigned NumFields);
  249. ~StructData();
  250. };
  251. struct UnionData {
  252. const FieldDecl *Field;
  253. APValue *Value;
  254. UnionData();
  255. ~UnionData();
  256. };
  257. struct AddrLabelDiffData {
  258. const AddrLabelExpr* LHSExpr;
  259. const AddrLabelExpr* RHSExpr;
  260. };
  261. struct MemberPointerData;
  262. // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
  263. typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
  264. ComplexAPFloat, Vec, Arr, StructData,
  265. UnionData, AddrLabelDiffData> DataType;
  266. static const size_t DataSize = sizeof(DataType);
  267. DataType Data;
  268. public:
  269. APValue() : Kind(None) {}
  270. explicit APValue(APSInt I) : Kind(None) {
  271. MakeInt(); setInt(std::move(I));
  272. }
  273. explicit APValue(APFloat F) : Kind(None) {
  274. MakeFloat(); setFloat(std::move(F));
  275. }
  276. explicit APValue(APFixedPoint FX) : Kind(None) {
  277. MakeFixedPoint(std::move(FX));
  278. }
  279. explicit APValue(const APValue *E, unsigned N) : Kind(None) {
  280. MakeVector(); setVector(E, N);
  281. }
  282. APValue(APSInt R, APSInt I) : Kind(None) {
  283. MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
  284. }
  285. APValue(APFloat R, APFloat I) : Kind(None) {
  286. MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
  287. }
  288. APValue(const APValue &RHS);
  289. APValue(APValue &&RHS);
  290. APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
  291. bool IsNullPtr = false)
  292. : Kind(None) {
  293. MakeLValue(); setLValue(B, O, N, IsNullPtr);
  294. }
  295. APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
  296. bool OnePastTheEnd, bool IsNullPtr = false)
  297. : Kind(None) {
  298. MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
  299. }
  300. APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
  301. MakeArray(InitElts, Size);
  302. }
  303. APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
  304. MakeStruct(B, M);
  305. }
  306. explicit APValue(const FieldDecl *D, const APValue &V = APValue())
  307. : Kind(None) {
  308. MakeUnion(); setUnion(D, V);
  309. }
  310. APValue(const ValueDecl *Member, bool IsDerivedMember,
  311. ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
  312. MakeMemberPointer(Member, IsDerivedMember, Path);
  313. }
  314. APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
  315. : Kind(None) {
  316. MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
  317. }
  318. static APValue IndeterminateValue() {
  319. APValue Result;
  320. Result.Kind = Indeterminate;
  321. return Result;
  322. }
  323. APValue &operator=(const APValue &RHS);
  324. APValue &operator=(APValue &&RHS);
  325. ~APValue() {
  326. if (Kind != None && Kind != Indeterminate)
  327. DestroyDataAndMakeUninit();
  328. }
  329. /// Returns whether the object performed allocations.
  330. ///
  331. /// If APValues are constructed via placement new, \c needsCleanup()
  332. /// indicates whether the destructor must be called in order to correctly
  333. /// free all allocated memory.
  334. bool needsCleanup() const;
  335. /// Swaps the contents of this and the given APValue.
  336. void swap(APValue &RHS);
  337. /// profile this value. There is no guarantee that values of different
  338. /// types will not produce the same profiled value, so the type should
  339. /// typically also be profiled if it's not implied by the context.
  340. void Profile(llvm::FoldingSetNodeID &ID) const;
  341. ValueKind getKind() const { return Kind; }
  342. bool isAbsent() const { return Kind == None; }
  343. bool isIndeterminate() const { return Kind == Indeterminate; }
  344. bool hasValue() const { return Kind != None && Kind != Indeterminate; }
  345. bool isInt() const { return Kind == Int; }
  346. bool isFloat() const { return Kind == Float; }
  347. bool isFixedPoint() const { return Kind == FixedPoint; }
  348. bool isComplexInt() const { return Kind == ComplexInt; }
  349. bool isComplexFloat() const { return Kind == ComplexFloat; }
  350. bool isLValue() const { return Kind == LValue; }
  351. bool isVector() const { return Kind == Vector; }
  352. bool isArray() const { return Kind == Array; }
  353. bool isStruct() const { return Kind == Struct; }
  354. bool isUnion() const { return Kind == Union; }
  355. bool isMemberPointer() const { return Kind == MemberPointer; }
  356. bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
  357. void dump() const;
  358. void dump(raw_ostream &OS, const ASTContext &Context) const;
  359. void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
  360. void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
  361. const ASTContext *Ctx = nullptr) const;
  362. std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
  363. APSInt &getInt() {
  364. assert(isInt() && "Invalid accessor");
  365. return *(APSInt *)(char *)&Data;
  366. }
  367. const APSInt &getInt() const {
  368. return const_cast<APValue*>(this)->getInt();
  369. }
  370. /// Try to convert this value to an integral constant. This works if it's an
  371. /// integer, null pointer, or offset from a null pointer. Returns true on
  372. /// success.
  373. bool toIntegralConstant(APSInt &Result, QualType SrcTy,
  374. const ASTContext &Ctx) const;
  375. APFloat &getFloat() {
  376. assert(isFloat() && "Invalid accessor");
  377. return *(APFloat *)(char *)&Data;
  378. }
  379. const APFloat &getFloat() const {
  380. return const_cast<APValue*>(this)->getFloat();
  381. }
  382. APFixedPoint &getFixedPoint() {
  383. assert(isFixedPoint() && "Invalid accessor");
  384. return *(APFixedPoint *)(char *)&Data;
  385. }
  386. const APFixedPoint &getFixedPoint() const {
  387. return const_cast<APValue *>(this)->getFixedPoint();
  388. }
  389. APSInt &getComplexIntReal() {
  390. assert(isComplexInt() && "Invalid accessor");
  391. return ((ComplexAPSInt *)(char *)&Data)->Real;
  392. }
  393. const APSInt &getComplexIntReal() const {
  394. return const_cast<APValue*>(this)->getComplexIntReal();
  395. }
  396. APSInt &getComplexIntImag() {
  397. assert(isComplexInt() && "Invalid accessor");
  398. return ((ComplexAPSInt *)(char *)&Data)->Imag;
  399. }
  400. const APSInt &getComplexIntImag() const {
  401. return const_cast<APValue*>(this)->getComplexIntImag();
  402. }
  403. APFloat &getComplexFloatReal() {
  404. assert(isComplexFloat() && "Invalid accessor");
  405. return ((ComplexAPFloat *)(char *)&Data)->Real;
  406. }
  407. const APFloat &getComplexFloatReal() const {
  408. return const_cast<APValue*>(this)->getComplexFloatReal();
  409. }
  410. APFloat &getComplexFloatImag() {
  411. assert(isComplexFloat() && "Invalid accessor");
  412. return ((ComplexAPFloat *)(char *)&Data)->Imag;
  413. }
  414. const APFloat &getComplexFloatImag() const {
  415. return const_cast<APValue*>(this)->getComplexFloatImag();
  416. }
  417. const LValueBase getLValueBase() const;
  418. CharUnits &getLValueOffset();
  419. const CharUnits &getLValueOffset() const {
  420. return const_cast<APValue*>(this)->getLValueOffset();
  421. }
  422. bool isLValueOnePastTheEnd() const;
  423. bool hasLValuePath() const;
  424. ArrayRef<LValuePathEntry> getLValuePath() const;
  425. unsigned getLValueCallIndex() const;
  426. unsigned getLValueVersion() const;
  427. bool isNullPointer() const;
  428. APValue &getVectorElt(unsigned I) {
  429. assert(isVector() && "Invalid accessor");
  430. assert(I < getVectorLength() && "Index out of range");
  431. return ((Vec *)(char *)&Data)->Elts[I];
  432. }
  433. const APValue &getVectorElt(unsigned I) const {
  434. return const_cast<APValue*>(this)->getVectorElt(I);
  435. }
  436. unsigned getVectorLength() const {
  437. assert(isVector() && "Invalid accessor");
  438. return ((const Vec *)(const void *)&Data)->NumElts;
  439. }
  440. APValue &getArrayInitializedElt(unsigned I) {
  441. assert(isArray() && "Invalid accessor");
  442. assert(I < getArrayInitializedElts() && "Index out of range");
  443. return ((Arr *)(char *)&Data)->Elts[I];
  444. }
  445. const APValue &getArrayInitializedElt(unsigned I) const {
  446. return const_cast<APValue*>(this)->getArrayInitializedElt(I);
  447. }
  448. bool hasArrayFiller() const {
  449. return getArrayInitializedElts() != getArraySize();
  450. }
  451. APValue &getArrayFiller() {
  452. assert(isArray() && "Invalid accessor");
  453. assert(hasArrayFiller() && "No array filler");
  454. return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
  455. }
  456. const APValue &getArrayFiller() const {
  457. return const_cast<APValue*>(this)->getArrayFiller();
  458. }
  459. unsigned getArrayInitializedElts() const {
  460. assert(isArray() && "Invalid accessor");
  461. return ((const Arr *)(const void *)&Data)->NumElts;
  462. }
  463. unsigned getArraySize() const {
  464. assert(isArray() && "Invalid accessor");
  465. return ((const Arr *)(const void *)&Data)->ArrSize;
  466. }
  467. unsigned getStructNumBases() const {
  468. assert(isStruct() && "Invalid accessor");
  469. return ((const StructData *)(const char *)&Data)->NumBases;
  470. }
  471. unsigned getStructNumFields() const {
  472. assert(isStruct() && "Invalid accessor");
  473. return ((const StructData *)(const char *)&Data)->NumFields;
  474. }
  475. APValue &getStructBase(unsigned i) {
  476. assert(isStruct() && "Invalid accessor");
  477. assert(i < getStructNumBases() && "base class index OOB");
  478. return ((StructData *)(char *)&Data)->Elts[i];
  479. }
  480. APValue &getStructField(unsigned i) {
  481. assert(isStruct() && "Invalid accessor");
  482. assert(i < getStructNumFields() && "field index OOB");
  483. return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
  484. }
  485. const APValue &getStructBase(unsigned i) const {
  486. return const_cast<APValue*>(this)->getStructBase(i);
  487. }
  488. const APValue &getStructField(unsigned i) const {
  489. return const_cast<APValue*>(this)->getStructField(i);
  490. }
  491. const FieldDecl *getUnionField() const {
  492. assert(isUnion() && "Invalid accessor");
  493. return ((const UnionData *)(const char *)&Data)->Field;
  494. }
  495. APValue &getUnionValue() {
  496. assert(isUnion() && "Invalid accessor");
  497. return *((UnionData *)(char *)&Data)->Value;
  498. }
  499. const APValue &getUnionValue() const {
  500. return const_cast<APValue*>(this)->getUnionValue();
  501. }
  502. const ValueDecl *getMemberPointerDecl() const;
  503. bool isMemberPointerToDerivedMember() const;
  504. ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
  505. const AddrLabelExpr* getAddrLabelDiffLHS() const {
  506. assert(isAddrLabelDiff() && "Invalid accessor");
  507. return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
  508. }
  509. const AddrLabelExpr* getAddrLabelDiffRHS() const {
  510. assert(isAddrLabelDiff() && "Invalid accessor");
  511. return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
  512. }
  513. void setInt(APSInt I) {
  514. assert(isInt() && "Invalid accessor");
  515. *(APSInt *)(char *)&Data = std::move(I);
  516. }
  517. void setFloat(APFloat F) {
  518. assert(isFloat() && "Invalid accessor");
  519. *(APFloat *)(char *)&Data = std::move(F);
  520. }
  521. void setFixedPoint(APFixedPoint FX) {
  522. assert(isFixedPoint() && "Invalid accessor");
  523. *(APFixedPoint *)(char *)&Data = std::move(FX);
  524. }
  525. void setVector(const APValue *E, unsigned N) {
  526. MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
  527. for (unsigned i = 0; i != N; ++i)
  528. InternalElts[i] = E[i];
  529. }
  530. void setComplexInt(APSInt R, APSInt I) {
  531. assert(R.getBitWidth() == I.getBitWidth() &&
  532. "Invalid complex int (type mismatch).");
  533. assert(isComplexInt() && "Invalid accessor");
  534. ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
  535. ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
  536. }
  537. void setComplexFloat(APFloat R, APFloat I) {
  538. assert(&R.getSemantics() == &I.getSemantics() &&
  539. "Invalid complex float (type mismatch).");
  540. assert(isComplexFloat() && "Invalid accessor");
  541. ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
  542. ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
  543. }
  544. void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
  545. bool IsNullPtr);
  546. void setLValue(LValueBase B, const CharUnits &O,
  547. ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
  548. bool IsNullPtr);
  549. void setUnion(const FieldDecl *Field, const APValue &Value);
  550. void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
  551. const AddrLabelExpr* RHSExpr) {
  552. ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
  553. ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
  554. }
  555. private:
  556. void DestroyDataAndMakeUninit();
  557. void MakeInt() {
  558. assert(isAbsent() && "Bad state change");
  559. new ((void *)&Data) APSInt(1);
  560. Kind = Int;
  561. }
  562. void MakeFloat() {
  563. assert(isAbsent() && "Bad state change");
  564. new ((void *)(char *)&Data) APFloat(0.0);
  565. Kind = Float;
  566. }
  567. void MakeFixedPoint(APFixedPoint &&FX) {
  568. assert(isAbsent() && "Bad state change");
  569. new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
  570. Kind = FixedPoint;
  571. }
  572. void MakeVector() {
  573. assert(isAbsent() && "Bad state change");
  574. new ((void *)(char *)&Data) Vec();
  575. Kind = Vector;
  576. }
  577. void MakeComplexInt() {
  578. assert(isAbsent() && "Bad state change");
  579. new ((void *)(char *)&Data) ComplexAPSInt();
  580. Kind = ComplexInt;
  581. }
  582. void MakeComplexFloat() {
  583. assert(isAbsent() && "Bad state change");
  584. new ((void *)(char *)&Data) ComplexAPFloat();
  585. Kind = ComplexFloat;
  586. }
  587. void MakeLValue();
  588. void MakeArray(unsigned InitElts, unsigned Size);
  589. void MakeStruct(unsigned B, unsigned M) {
  590. assert(isAbsent() && "Bad state change");
  591. new ((void *)(char *)&Data) StructData(B, M);
  592. Kind = Struct;
  593. }
  594. void MakeUnion() {
  595. assert(isAbsent() && "Bad state change");
  596. new ((void *)(char *)&Data) UnionData();
  597. Kind = Union;
  598. }
  599. void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
  600. ArrayRef<const CXXRecordDecl*> Path);
  601. void MakeAddrLabelDiff() {
  602. assert(isAbsent() && "Bad state change");
  603. new ((void *)(char *)&Data) AddrLabelDiffData();
  604. Kind = AddrLabelDiff;
  605. }
  606. private:
  607. /// The following functions are used as part of initialization, during
  608. /// deserialization and importing. Reserve the space so that it can be
  609. /// filled in by those steps.
  610. MutableArrayRef<APValue> setVectorUninit(unsigned N) {
  611. assert(isVector() && "Invalid accessor");
  612. Vec *V = ((Vec *)(char *)&Data);
  613. V->Elts = new APValue[N];
  614. V->NumElts = N;
  615. return {V->Elts, V->NumElts};
  616. }
  617. MutableArrayRef<LValuePathEntry>
  618. setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
  619. bool OnePastTheEnd, bool IsNullPtr);
  620. MutableArrayRef<const CXXRecordDecl *>
  621. setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
  622. unsigned Size);
  623. };
  624. } // end namespace clang.
  625. namespace llvm {
  626. template<> struct DenseMapInfo<clang::APValue::LValueBase> {
  627. static clang::APValue::LValueBase getEmptyKey();
  628. static clang::APValue::LValueBase getTombstoneKey();
  629. static unsigned getHashValue(const clang::APValue::LValueBase &Base);
  630. static bool isEqual(const clang::APValue::LValueBase &LHS,
  631. const clang::APValue::LValueBase &RHS);
  632. };
  633. }
  634. #endif
  635. #ifdef __GNUC__
  636. #pragma GCC diagnostic pop
  637. #endif