APValue.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. //===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the APValue class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/AST/APValue.h"
  14. #include "clang/AST/ASTContext.h"
  15. #include "clang/AST/CharUnits.h"
  16. #include "clang/AST/DeclCXX.h"
  17. #include "clang/AST/Expr.h"
  18. #include "clang/AST/Type.h"
  19. #include "clang/Basic/Diagnostic.h"
  20. #include "llvm/ADT/SmallString.h"
  21. #include "llvm/Support/ErrorHandling.h"
  22. #include "llvm/Support/raw_ostream.h"
  23. using namespace clang;
  24. namespace {
  25. struct LVBase {
  26. llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
  27. CharUnits Offset;
  28. unsigned PathLength;
  29. unsigned CallIndex;
  30. };
  31. }
  32. struct APValue::LV : LVBase {
  33. static const unsigned InlinePathSpace =
  34. (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
  35. /// Path - The sequence of base classes, fields and array indices to follow to
  36. /// walk from Base to the subobject. When performing GCC-style folding, there
  37. /// may not be such a path.
  38. union {
  39. LValuePathEntry Path[InlinePathSpace];
  40. LValuePathEntry *PathPtr;
  41. };
  42. LV() { PathLength = (unsigned)-1; }
  43. ~LV() { resizePath(0); }
  44. void resizePath(unsigned Length) {
  45. if (Length == PathLength)
  46. return;
  47. if (hasPathPtr())
  48. delete [] PathPtr;
  49. PathLength = Length;
  50. if (hasPathPtr())
  51. PathPtr = new LValuePathEntry[Length];
  52. }
  53. bool hasPath() const { return PathLength != (unsigned)-1; }
  54. bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; }
  55. LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }
  56. const LValuePathEntry *getPath() const {
  57. return hasPathPtr() ? PathPtr : Path;
  58. }
  59. };
  60. namespace {
  61. struct MemberPointerBase {
  62. llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
  63. unsigned PathLength;
  64. };
  65. }
  66. struct APValue::MemberPointerData : MemberPointerBase {
  67. static const unsigned InlinePathSpace =
  68. (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
  69. typedef const CXXRecordDecl *PathElem;
  70. union {
  71. PathElem Path[InlinePathSpace];
  72. PathElem *PathPtr;
  73. };
  74. MemberPointerData() { PathLength = 0; }
  75. ~MemberPointerData() { resizePath(0); }
  76. void resizePath(unsigned Length) {
  77. if (Length == PathLength)
  78. return;
  79. if (hasPathPtr())
  80. delete [] PathPtr;
  81. PathLength = Length;
  82. if (hasPathPtr())
  83. PathPtr = new PathElem[Length];
  84. }
  85. bool hasPathPtr() const { return PathLength > InlinePathSpace; }
  86. PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
  87. const PathElem *getPath() const {
  88. return hasPathPtr() ? PathPtr : Path;
  89. }
  90. };
  91. // FIXME: Reduce the malloc traffic here.
  92. APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
  93. Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
  94. NumElts(NumElts), ArrSize(Size) {}
  95. APValue::Arr::~Arr() { delete [] Elts; }
  96. APValue::StructData::StructData(unsigned NumBases, unsigned NumFields) :
  97. Elts(new APValue[NumBases+NumFields]),
  98. NumBases(NumBases), NumFields(NumFields) {}
  99. APValue::StructData::~StructData() {
  100. delete [] Elts;
  101. }
  102. APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
  103. APValue::UnionData::~UnionData () {
  104. delete Value;
  105. }
  106. APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
  107. switch (RHS.getKind()) {
  108. case Uninitialized:
  109. break;
  110. case Int:
  111. MakeInt();
  112. setInt(RHS.getInt());
  113. break;
  114. case Float:
  115. MakeFloat();
  116. setFloat(RHS.getFloat());
  117. break;
  118. case Vector:
  119. MakeVector();
  120. setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
  121. RHS.getVectorLength());
  122. break;
  123. case ComplexInt:
  124. MakeComplexInt();
  125. setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
  126. break;
  127. case ComplexFloat:
  128. MakeComplexFloat();
  129. setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
  130. break;
  131. case LValue:
  132. MakeLValue();
  133. if (RHS.hasLValuePath())
  134. setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
  135. RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex());
  136. else
  137. setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
  138. RHS.getLValueCallIndex());
  139. break;
  140. case Array:
  141. MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
  142. for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
  143. getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
  144. if (RHS.hasArrayFiller())
  145. getArrayFiller() = RHS.getArrayFiller();
  146. break;
  147. case Struct:
  148. MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
  149. for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
  150. getStructBase(I) = RHS.getStructBase(I);
  151. for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
  152. getStructField(I) = RHS.getStructField(I);
  153. break;
  154. case Union:
  155. MakeUnion();
  156. setUnion(RHS.getUnionField(), RHS.getUnionValue());
  157. break;
  158. case MemberPointer:
  159. MakeMemberPointer(RHS.getMemberPointerDecl(),
  160. RHS.isMemberPointerToDerivedMember(),
  161. RHS.getMemberPointerPath());
  162. break;
  163. case AddrLabelDiff:
  164. MakeAddrLabelDiff();
  165. setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());
  166. break;
  167. }
  168. }
  169. void APValue::DestroyDataAndMakeUninit() {
  170. if (Kind == Int)
  171. ((APSInt*)(char*)Data.buffer)->~APSInt();
  172. else if (Kind == Float)
  173. ((APFloat*)(char*)Data.buffer)->~APFloat();
  174. else if (Kind == Vector)
  175. ((Vec*)(char*)Data.buffer)->~Vec();
  176. else if (Kind == ComplexInt)
  177. ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
  178. else if (Kind == ComplexFloat)
  179. ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
  180. else if (Kind == LValue)
  181. ((LV*)(char*)Data.buffer)->~LV();
  182. else if (Kind == Array)
  183. ((Arr*)(char*)Data.buffer)->~Arr();
  184. else if (Kind == Struct)
  185. ((StructData*)(char*)Data.buffer)->~StructData();
  186. else if (Kind == Union)
  187. ((UnionData*)(char*)Data.buffer)->~UnionData();
  188. else if (Kind == MemberPointer)
  189. ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
  190. else if (Kind == AddrLabelDiff)
  191. ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
  192. Kind = Uninitialized;
  193. }
  194. bool APValue::needsCleanup() const {
  195. switch (getKind()) {
  196. case Uninitialized:
  197. case AddrLabelDiff:
  198. return false;
  199. case Struct:
  200. case Union:
  201. case Array:
  202. case Vector:
  203. return true;
  204. case Int:
  205. return getInt().needsCleanup();
  206. case Float:
  207. return getFloat().needsCleanup();
  208. case ComplexFloat:
  209. assert(getComplexFloatImag().needsCleanup() ==
  210. getComplexFloatReal().needsCleanup() &&
  211. "In _Complex float types, real and imaginary values always have the "
  212. "same size.");
  213. return getComplexFloatReal().needsCleanup();
  214. case ComplexInt:
  215. assert(getComplexIntImag().needsCleanup() ==
  216. getComplexIntReal().needsCleanup() &&
  217. "In _Complex int types, real and imaginary values must have the "
  218. "same size.");
  219. return getComplexIntReal().needsCleanup();
  220. case LValue:
  221. return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
  222. case MemberPointer:
  223. return reinterpret_cast<const MemberPointerData *>(Data.buffer)
  224. ->hasPathPtr();
  225. }
  226. llvm_unreachable("Unknown APValue kind!");
  227. }
  228. void APValue::swap(APValue &RHS) {
  229. std::swap(Kind, RHS.Kind);
  230. char TmpData[DataSize];
  231. memcpy(TmpData, Data.buffer, DataSize);
  232. memcpy(Data.buffer, RHS.Data.buffer, DataSize);
  233. memcpy(RHS.Data.buffer, TmpData, DataSize);
  234. }
  235. void APValue::dump() const {
  236. dump(llvm::errs());
  237. llvm::errs() << '\n';
  238. }
  239. static double GetApproxValue(const llvm::APFloat &F) {
  240. llvm::APFloat V = F;
  241. bool ignored;
  242. V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
  243. &ignored);
  244. return V.convertToDouble();
  245. }
  246. void APValue::dump(raw_ostream &OS) const {
  247. switch (getKind()) {
  248. case Uninitialized:
  249. OS << "Uninitialized";
  250. return;
  251. case Int:
  252. OS << "Int: " << getInt();
  253. return;
  254. case Float:
  255. OS << "Float: " << GetApproxValue(getFloat());
  256. return;
  257. case Vector:
  258. OS << "Vector: ";
  259. getVectorElt(0).dump(OS);
  260. for (unsigned i = 1; i != getVectorLength(); ++i) {
  261. OS << ", ";
  262. getVectorElt(i).dump(OS);
  263. }
  264. return;
  265. case ComplexInt:
  266. OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
  267. return;
  268. case ComplexFloat:
  269. OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
  270. << ", " << GetApproxValue(getComplexFloatImag());
  271. return;
  272. case LValue:
  273. OS << "LValue: <todo>";
  274. return;
  275. case Array:
  276. OS << "Array: ";
  277. for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) {
  278. getArrayInitializedElt(I).dump(OS);
  279. if (I != getArraySize() - 1) OS << ", ";
  280. }
  281. if (hasArrayFiller()) {
  282. OS << getArraySize() - getArrayInitializedElts() << " x ";
  283. getArrayFiller().dump(OS);
  284. }
  285. return;
  286. case Struct:
  287. OS << "Struct ";
  288. if (unsigned N = getStructNumBases()) {
  289. OS << " bases: ";
  290. getStructBase(0).dump(OS);
  291. for (unsigned I = 1; I != N; ++I) {
  292. OS << ", ";
  293. getStructBase(I).dump(OS);
  294. }
  295. }
  296. if (unsigned N = getStructNumFields()) {
  297. OS << " fields: ";
  298. getStructField(0).dump(OS);
  299. for (unsigned I = 1; I != N; ++I) {
  300. OS << ", ";
  301. getStructField(I).dump(OS);
  302. }
  303. }
  304. return;
  305. case Union:
  306. OS << "Union: ";
  307. getUnionValue().dump(OS);
  308. return;
  309. case MemberPointer:
  310. OS << "MemberPointer: <todo>";
  311. return;
  312. case AddrLabelDiff:
  313. OS << "AddrLabelDiff: <todo>";
  314. return;
  315. }
  316. llvm_unreachable("Unknown APValue kind!");
  317. }
  318. void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
  319. switch (getKind()) {
  320. case APValue::Uninitialized:
  321. Out << "<uninitialized>";
  322. return;
  323. case APValue::Int:
  324. if (Ty->isBooleanType())
  325. Out << (getInt().getBoolValue() ? "true" : "false");
  326. else
  327. Out << getInt();
  328. return;
  329. case APValue::Float:
  330. Out << GetApproxValue(getFloat());
  331. return;
  332. case APValue::Vector: {
  333. Out << '{';
  334. QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
  335. getVectorElt(0).printPretty(Out, Ctx, ElemTy);
  336. for (unsigned i = 1; i != getVectorLength(); ++i) {
  337. Out << ", ";
  338. getVectorElt(i).printPretty(Out, Ctx, ElemTy);
  339. }
  340. Out << '}';
  341. return;
  342. }
  343. case APValue::ComplexInt:
  344. Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
  345. return;
  346. case APValue::ComplexFloat:
  347. Out << GetApproxValue(getComplexFloatReal()) << "+"
  348. << GetApproxValue(getComplexFloatImag()) << "i";
  349. return;
  350. case APValue::LValue: {
  351. LValueBase Base = getLValueBase();
  352. if (!Base) {
  353. Out << "0";
  354. return;
  355. }
  356. bool IsReference = Ty->isReferenceType();
  357. QualType InnerTy
  358. = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
  359. if (InnerTy.isNull())
  360. InnerTy = Ty;
  361. if (!hasLValuePath()) {
  362. // No lvalue path: just print the offset.
  363. CharUnits O = getLValueOffset();
  364. CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
  365. if (!O.isZero()) {
  366. if (IsReference)
  367. Out << "*(";
  368. if (O % S) {
  369. Out << "(char*)";
  370. S = CharUnits::One();
  371. }
  372. Out << '&';
  373. } else if (!IsReference)
  374. Out << '&';
  375. if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
  376. Out << *VD;
  377. else {
  378. assert(Base.get<const Expr *>() != nullptr &&
  379. "Expecting non-null Expr");
  380. Base.get<const Expr*>()->printPretty(Out, nullptr,
  381. Ctx.getPrintingPolicy());
  382. }
  383. if (!O.isZero()) {
  384. Out << " + " << (O / S);
  385. if (IsReference)
  386. Out << ')';
  387. }
  388. return;
  389. }
  390. // We have an lvalue path. Print it out nicely.
  391. if (!IsReference)
  392. Out << '&';
  393. else if (isLValueOnePastTheEnd())
  394. Out << "*(&";
  395. QualType ElemTy;
  396. if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
  397. Out << *VD;
  398. ElemTy = VD->getType();
  399. } else {
  400. const Expr *E = Base.get<const Expr*>();
  401. assert(E != nullptr && "Expecting non-null Expr");
  402. E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
  403. ElemTy = E->getType();
  404. }
  405. ArrayRef<LValuePathEntry> Path = getLValuePath();
  406. const CXXRecordDecl *CastToBase = nullptr;
  407. for (unsigned I = 0, N = Path.size(); I != N; ++I) {
  408. if (ElemTy->getAs<RecordType>()) {
  409. // The lvalue refers to a class type, so the next path entry is a base
  410. // or member.
  411. const Decl *BaseOrMember =
  412. BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
  413. if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
  414. CastToBase = RD;
  415. ElemTy = Ctx.getRecordType(RD);
  416. } else {
  417. const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
  418. Out << ".";
  419. if (CastToBase)
  420. Out << *CastToBase << "::";
  421. Out << *VD;
  422. ElemTy = VD->getType();
  423. }
  424. } else {
  425. // The lvalue must refer to an array.
  426. Out << '[' << Path[I].ArrayIndex << ']';
  427. ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
  428. }
  429. }
  430. // Handle formatting of one-past-the-end lvalues.
  431. if (isLValueOnePastTheEnd()) {
  432. // FIXME: If CastToBase is non-0, we should prefix the output with
  433. // "(CastToBase*)".
  434. Out << " + 1";
  435. if (IsReference)
  436. Out << ')';
  437. }
  438. return;
  439. }
  440. case APValue::Array: {
  441. const ArrayType *AT = Ctx.getAsArrayType(Ty);
  442. QualType ElemTy = AT->getElementType();
  443. Out << '{';
  444. if (unsigned N = getArrayInitializedElts()) {
  445. getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy);
  446. for (unsigned I = 1; I != N; ++I) {
  447. Out << ", ";
  448. if (I == 10) {
  449. // Avoid printing out the entire contents of large arrays.
  450. Out << "...";
  451. break;
  452. }
  453. getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy);
  454. }
  455. }
  456. Out << '}';
  457. return;
  458. }
  459. case APValue::Struct: {
  460. Out << '{';
  461. const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
  462. bool First = true;
  463. if (unsigned N = getStructNumBases()) {
  464. const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
  465. CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();
  466. for (unsigned I = 0; I != N; ++I, ++BI) {
  467. assert(BI != CD->bases_end());
  468. if (!First)
  469. Out << ", ";
  470. getStructBase(I).printPretty(Out, Ctx, BI->getType());
  471. First = false;
  472. }
  473. }
  474. for (const auto *FI : RD->fields()) {
  475. if (!First)
  476. Out << ", ";
  477. if (FI->isUnnamedBitfield()) continue;
  478. getStructField(FI->getFieldIndex()).
  479. printPretty(Out, Ctx, FI->getType());
  480. First = false;
  481. }
  482. Out << '}';
  483. return;
  484. }
  485. case APValue::Union:
  486. Out << '{';
  487. if (const FieldDecl *FD = getUnionField()) {
  488. Out << "." << *FD << " = ";
  489. getUnionValue().printPretty(Out, Ctx, FD->getType());
  490. }
  491. Out << '}';
  492. return;
  493. case APValue::MemberPointer:
  494. // FIXME: This is not enough to unambiguously identify the member in a
  495. // multiple-inheritance scenario.
  496. if (const ValueDecl *VD = getMemberPointerDecl()) {
  497. Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
  498. return;
  499. }
  500. Out << "0";
  501. return;
  502. case APValue::AddrLabelDiff:
  503. Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName();
  504. Out << " - ";
  505. Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName();
  506. return;
  507. }
  508. llvm_unreachable("Unknown APValue kind!");
  509. }
  510. std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
  511. std::string Result;
  512. llvm::raw_string_ostream Out(Result);
  513. printPretty(Out, Ctx, Ty);
  514. Out.flush();
  515. return Result;
  516. }
  517. const APValue::LValueBase APValue::getLValueBase() const {
  518. assert(isLValue() && "Invalid accessor");
  519. return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
  520. }
  521. bool APValue::isLValueOnePastTheEnd() const {
  522. assert(isLValue() && "Invalid accessor");
  523. return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
  524. }
  525. CharUnits &APValue::getLValueOffset() {
  526. assert(isLValue() && "Invalid accessor");
  527. return ((LV*)(void*)Data.buffer)->Offset;
  528. }
  529. bool APValue::hasLValuePath() const {
  530. assert(isLValue() && "Invalid accessor");
  531. return ((const LV*)(const char*)Data.buffer)->hasPath();
  532. }
  533. ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
  534. assert(isLValue() && hasLValuePath() && "Invalid accessor");
  535. const LV &LVal = *((const LV*)(const char*)Data.buffer);
  536. return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
  537. }
  538. unsigned APValue::getLValueCallIndex() const {
  539. assert(isLValue() && "Invalid accessor");
  540. return ((const LV*)(const char*)Data.buffer)->CallIndex;
  541. }
  542. void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
  543. unsigned CallIndex) {
  544. assert(isLValue() && "Invalid accessor");
  545. LV &LVal = *((LV*)(char*)Data.buffer);
  546. LVal.BaseAndIsOnePastTheEnd.setPointer(B);
  547. LVal.BaseAndIsOnePastTheEnd.setInt(false);
  548. LVal.Offset = O;
  549. LVal.CallIndex = CallIndex;
  550. LVal.resizePath((unsigned)-1);
  551. }
  552. void APValue::setLValue(LValueBase B, const CharUnits &O,
  553. ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
  554. unsigned CallIndex) {
  555. assert(isLValue() && "Invalid accessor");
  556. LV &LVal = *((LV*)(char*)Data.buffer);
  557. LVal.BaseAndIsOnePastTheEnd.setPointer(B);
  558. LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
  559. LVal.Offset = O;
  560. LVal.CallIndex = CallIndex;
  561. LVal.resizePath(Path.size());
  562. memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
  563. }
  564. const ValueDecl *APValue::getMemberPointerDecl() const {
  565. assert(isMemberPointer() && "Invalid accessor");
  566. const MemberPointerData &MPD =
  567. *((const MemberPointerData *)(const char *)Data.buffer);
  568. return MPD.MemberAndIsDerivedMember.getPointer();
  569. }
  570. bool APValue::isMemberPointerToDerivedMember() const {
  571. assert(isMemberPointer() && "Invalid accessor");
  572. const MemberPointerData &MPD =
  573. *((const MemberPointerData *)(const char *)Data.buffer);
  574. return MPD.MemberAndIsDerivedMember.getInt();
  575. }
  576. ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
  577. assert(isMemberPointer() && "Invalid accessor");
  578. const MemberPointerData &MPD =
  579. *((const MemberPointerData *)(const char *)Data.buffer);
  580. return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
  581. }
  582. void APValue::MakeLValue() {
  583. assert(isUninit() && "Bad state change");
  584. static_assert(sizeof(LV) <= DataSize, "LV too big");
  585. new ((void*)(char*)Data.buffer) LV();
  586. Kind = LValue;
  587. }
  588. void APValue::MakeArray(unsigned InitElts, unsigned Size) {
  589. assert(isUninit() && "Bad state change");
  590. new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
  591. Kind = Array;
  592. }
  593. void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
  594. ArrayRef<const CXXRecordDecl*> Path) {
  595. assert(isUninit() && "Bad state change");
  596. MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
  597. Kind = MemberPointer;
  598. MPD->MemberAndIsDerivedMember.setPointer(Member);
  599. MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
  600. MPD->resizePath(Path.size());
  601. memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
  602. }