APValue.cpp revision 234353
1193326Sed//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the APValue class. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/AST/APValue.h" 15234353Sdim#include "clang/AST/ASTContext.h" 16202379Srdivacky#include "clang/AST/CharUnits.h" 17234353Sdim#include "clang/AST/DeclCXX.h" 18234353Sdim#include "clang/AST/Expr.h" 19234353Sdim#include "clang/AST/Type.h" 20226633Sdim#include "clang/Basic/Diagnostic.h" 21226633Sdim#include "llvm/ADT/SmallString.h" 22193326Sed#include "llvm/Support/raw_ostream.h" 23226633Sdim#include "llvm/Support/ErrorHandling.h" 24193326Sedusing namespace clang; 25193326Sed 26202379Srdivackynamespace { 27234353Sdim struct LVBase { 28234353Sdim llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd; 29202379Srdivacky CharUnits Offset; 30234353Sdim unsigned PathLength; 31234353Sdim unsigned CallIndex; 32202379Srdivacky }; 33202379Srdivacky} 34193326Sed 35234353Sdimstruct APValue::LV : LVBase { 36234353Sdim static const unsigned InlinePathSpace = 37234353Sdim (MaxSize - sizeof(LVBase)) / sizeof(LValuePathEntry); 38234353Sdim 39234353Sdim /// Path - The sequence of base classes, fields and array indices to follow to 40234353Sdim /// walk from Base to the subobject. When performing GCC-style folding, there 41234353Sdim /// may not be such a path. 42234353Sdim union { 43234353Sdim LValuePathEntry Path[InlinePathSpace]; 44234353Sdim LValuePathEntry *PathPtr; 45234353Sdim }; 46234353Sdim 47234353Sdim LV() { PathLength = (unsigned)-1; } 48234353Sdim ~LV() { resizePath(0); } 49234353Sdim 50234353Sdim void resizePath(unsigned Length) { 51234353Sdim if (Length == PathLength) 52234353Sdim return; 53234353Sdim if (hasPathPtr()) 54234353Sdim delete [] PathPtr; 55234353Sdim PathLength = Length; 56234353Sdim if (hasPathPtr()) 57234353Sdim PathPtr = new LValuePathEntry[Length]; 58234353Sdim } 59234353Sdim 60234353Sdim bool hasPath() const { return PathLength != (unsigned)-1; } 61234353Sdim bool hasPathPtr() const { return hasPath() && PathLength > InlinePathSpace; } 62234353Sdim 63234353Sdim LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; } 64234353Sdim const LValuePathEntry *getPath() const { 65234353Sdim return hasPathPtr() ? PathPtr : Path; 66234353Sdim } 67234353Sdim}; 68234353Sdim 69234353Sdimnamespace { 70234353Sdim struct MemberPointerBase { 71234353Sdim llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember; 72234353Sdim unsigned PathLength; 73234353Sdim }; 74202379Srdivacky} 75202379Srdivacky 76234353Sdimstruct APValue::MemberPointerData : MemberPointerBase { 77234353Sdim static const unsigned InlinePathSpace = 78234353Sdim (MaxSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*); 79234353Sdim typedef const CXXRecordDecl *PathElem; 80234353Sdim union { 81234353Sdim PathElem Path[InlinePathSpace]; 82234353Sdim PathElem *PathPtr; 83234353Sdim }; 84234353Sdim 85234353Sdim MemberPointerData() { PathLength = 0; } 86234353Sdim ~MemberPointerData() { resizePath(0); } 87234353Sdim 88234353Sdim void resizePath(unsigned Length) { 89234353Sdim if (Length == PathLength) 90234353Sdim return; 91234353Sdim if (hasPathPtr()) 92234353Sdim delete [] PathPtr; 93234353Sdim PathLength = Length; 94234353Sdim if (hasPathPtr()) 95234353Sdim PathPtr = new PathElem[Length]; 96193326Sed } 97234353Sdim 98234353Sdim bool hasPathPtr() const { return PathLength > InlinePathSpace; } 99234353Sdim 100234353Sdim PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; } 101234353Sdim const PathElem *getPath() const { 102234353Sdim return hasPathPtr() ? PathPtr : Path; 103234353Sdim } 104234353Sdim}; 105234353Sdim 106234353Sdim// FIXME: Reduce the malloc traffic here. 107234353Sdim 108234353SdimAPValue::Arr::Arr(unsigned NumElts, unsigned Size) : 109234353Sdim Elts(new APValue[NumElts + (NumElts != Size ? 1 : 0)]), 110234353Sdim NumElts(NumElts), ArrSize(Size) {} 111234353SdimAPValue::Arr::~Arr() { delete [] Elts; } 112234353Sdim 113234353SdimAPValue::StructData::StructData(unsigned NumBases, unsigned NumFields) : 114234353Sdim Elts(new APValue[NumBases+NumFields]), 115234353Sdim NumBases(NumBases), NumFields(NumFields) {} 116234353SdimAPValue::StructData::~StructData() { 117234353Sdim delete [] Elts; 118234353Sdim} 119234353Sdim 120234353SdimAPValue::UnionData::UnionData() : Field(0), Value(new APValue) {} 121234353SdimAPValue::UnionData::~UnionData () { 122234353Sdim delete Value; 123234353Sdim} 124234353Sdim 125234353SdimAPValue::APValue(const APValue &RHS) : Kind(Uninitialized) { 126234353Sdim switch (RHS.getKind()) { 127234353Sdim case Uninitialized: 128234353Sdim break; 129234353Sdim case Int: 130234353Sdim MakeInt(); 131193326Sed setInt(RHS.getInt()); 132234353Sdim break; 133234353Sdim case Float: 134234353Sdim MakeFloat(); 135193326Sed setFloat(RHS.getFloat()); 136234353Sdim break; 137234353Sdim case Vector: 138234353Sdim MakeVector(); 139207619Srdivacky setVector(((const Vec *)(const char *)RHS.Data)->Elts, 140207619Srdivacky RHS.getVectorLength()); 141234353Sdim break; 142234353Sdim case ComplexInt: 143234353Sdim MakeComplexInt(); 144193326Sed setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag()); 145234353Sdim break; 146234353Sdim case ComplexFloat: 147234353Sdim MakeComplexFloat(); 148193326Sed setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag()); 149234353Sdim break; 150234353Sdim case LValue: 151234353Sdim MakeLValue(); 152234353Sdim if (RHS.hasLValuePath()) 153234353Sdim setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(), 154234353Sdim RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex()); 155234353Sdim else 156234353Sdim setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(), 157234353Sdim RHS.getLValueCallIndex()); 158234353Sdim break; 159234353Sdim case Array: 160234353Sdim MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize()); 161234353Sdim for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I) 162234353Sdim getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I); 163234353Sdim if (RHS.hasArrayFiller()) 164234353Sdim getArrayFiller() = RHS.getArrayFiller(); 165234353Sdim break; 166234353Sdim case Struct: 167234353Sdim MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields()); 168234353Sdim for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I) 169234353Sdim getStructBase(I) = RHS.getStructBase(I); 170234353Sdim for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I) 171234353Sdim getStructField(I) = RHS.getStructField(I); 172234353Sdim break; 173234353Sdim case Union: 174234353Sdim MakeUnion(); 175234353Sdim setUnion(RHS.getUnionField(), RHS.getUnionValue()); 176234353Sdim break; 177234353Sdim case MemberPointer: 178234353Sdim MakeMemberPointer(RHS.getMemberPointerDecl(), 179234353Sdim RHS.isMemberPointerToDerivedMember(), 180234353Sdim RHS.getMemberPointerPath()); 181234353Sdim break; 182234353Sdim case AddrLabelDiff: 183234353Sdim MakeAddrLabelDiff(); 184234353Sdim setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS()); 185234353Sdim break; 186234353Sdim } 187193326Sed} 188193326Sed 189234353Sdimvoid APValue::DestroyDataAndMakeUninit() { 190193326Sed if (Kind == Int) 191198092Srdivacky ((APSInt*)(char*)Data)->~APSInt(); 192193326Sed else if (Kind == Float) 193198092Srdivacky ((APFloat*)(char*)Data)->~APFloat(); 194193326Sed else if (Kind == Vector) 195198092Srdivacky ((Vec*)(char*)Data)->~Vec(); 196193326Sed else if (Kind == ComplexInt) 197198092Srdivacky ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt(); 198193326Sed else if (Kind == ComplexFloat) 199198092Srdivacky ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat(); 200234353Sdim else if (Kind == LValue) 201198092Srdivacky ((LV*)(char*)Data)->~LV(); 202234353Sdim else if (Kind == Array) 203234353Sdim ((Arr*)(char*)Data)->~Arr(); 204234353Sdim else if (Kind == Struct) 205234353Sdim ((StructData*)(char*)Data)->~StructData(); 206234353Sdim else if (Kind == Union) 207234353Sdim ((UnionData*)(char*)Data)->~UnionData(); 208234353Sdim else if (Kind == MemberPointer) 209234353Sdim ((MemberPointerData*)(char*)Data)->~MemberPointerData(); 210234353Sdim else if (Kind == AddrLabelDiff) 211234353Sdim ((AddrLabelDiffData*)(char*)Data)->~AddrLabelDiffData(); 212193326Sed Kind = Uninitialized; 213193326Sed} 214193326Sed 215234353Sdimvoid APValue::swap(APValue &RHS) { 216234353Sdim std::swap(Kind, RHS.Kind); 217234353Sdim char TmpData[MaxSize]; 218234353Sdim memcpy(TmpData, Data, MaxSize); 219234353Sdim memcpy(Data, RHS.Data, MaxSize); 220234353Sdim memcpy(RHS.Data, TmpData, MaxSize); 221234353Sdim} 222234353Sdim 223193326Sedvoid APValue::dump() const { 224234353Sdim dump(llvm::errs()); 225193326Sed llvm::errs() << '\n'; 226193326Sed} 227193326Sed 228193326Sedstatic double GetApproxValue(const llvm::APFloat &F) { 229193326Sed llvm::APFloat V = F; 230193326Sed bool ignored; 231193326Sed V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven, 232193326Sed &ignored); 233193326Sed return V.convertToDouble(); 234193326Sed} 235193326Sed 236234353Sdimvoid APValue::dump(raw_ostream &OS) const { 237193326Sed switch (getKind()) { 238193326Sed case Uninitialized: 239193326Sed OS << "Uninitialized"; 240193326Sed return; 241193326Sed case Int: 242193326Sed OS << "Int: " << getInt(); 243193326Sed return; 244193326Sed case Float: 245193326Sed OS << "Float: " << GetApproxValue(getFloat()); 246193326Sed return; 247193326Sed case Vector: 248234353Sdim OS << "Vector: "; 249234353Sdim getVectorElt(0).dump(OS); 250234353Sdim for (unsigned i = 1; i != getVectorLength(); ++i) { 251234353Sdim OS << ", "; 252234353Sdim getVectorElt(i).dump(OS); 253234353Sdim } 254193326Sed return; 255193326Sed case ComplexInt: 256193326Sed OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); 257193326Sed return; 258193326Sed case ComplexFloat: 259193326Sed OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) 260193326Sed << ", " << GetApproxValue(getComplexFloatImag()); 261234353Sdim return; 262193326Sed case LValue: 263193326Sed OS << "LValue: <todo>"; 264193326Sed return; 265234353Sdim case Array: 266234353Sdim OS << "Array: "; 267234353Sdim for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) { 268234353Sdim getArrayInitializedElt(I).dump(OS); 269234353Sdim if (I != getArraySize() - 1) OS << ", "; 270234353Sdim } 271234353Sdim if (hasArrayFiller()) { 272234353Sdim OS << getArraySize() - getArrayInitializedElts() << " x "; 273234353Sdim getArrayFiller().dump(OS); 274234353Sdim } 275234353Sdim return; 276234353Sdim case Struct: 277234353Sdim OS << "Struct "; 278234353Sdim if (unsigned N = getStructNumBases()) { 279234353Sdim OS << " bases: "; 280234353Sdim getStructBase(0).dump(OS); 281234353Sdim for (unsigned I = 1; I != N; ++I) { 282234353Sdim OS << ", "; 283234353Sdim getStructBase(I).dump(OS); 284234353Sdim } 285234353Sdim } 286234353Sdim if (unsigned N = getStructNumFields()) { 287234353Sdim OS << " fields: "; 288234353Sdim getStructField(0).dump(OS); 289234353Sdim for (unsigned I = 1; I != N; ++I) { 290234353Sdim OS << ", "; 291234353Sdim getStructField(I).dump(OS); 292234353Sdim } 293234353Sdim } 294234353Sdim return; 295234353Sdim case Union: 296234353Sdim OS << "Union: "; 297234353Sdim getUnionValue().dump(OS); 298234353Sdim return; 299234353Sdim case MemberPointer: 300234353Sdim OS << "MemberPointer: <todo>"; 301234353Sdim return; 302234353Sdim case AddrLabelDiff: 303234353Sdim OS << "AddrLabelDiff: <todo>"; 304234353Sdim return; 305193326Sed } 306234353Sdim llvm_unreachable("Unknown APValue kind!"); 307193326Sed} 308193326Sed 309234353Sdimvoid APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{ 310234353Sdim switch (getKind()) { 311226633Sdim case APValue::Uninitialized: 312234353Sdim Out << "<uninitialized>"; 313234353Sdim return; 314226633Sdim case APValue::Int: 315234353Sdim if (Ty->isBooleanType()) 316234353Sdim Out << (getInt().getBoolValue() ? "true" : "false"); 317234353Sdim else 318234353Sdim Out << getInt(); 319234353Sdim return; 320226633Sdim case APValue::Float: 321234353Sdim Out << GetApproxValue(getFloat()); 322234353Sdim return; 323234353Sdim case APValue::Vector: { 324234353Sdim Out << '{'; 325234353Sdim QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); 326234353Sdim getVectorElt(0).printPretty(Out, Ctx, ElemTy); 327234353Sdim for (unsigned i = 1; i != getVectorLength(); ++i) { 328226633Sdim Out << ", "; 329234353Sdim getVectorElt(i).printPretty(Out, Ctx, ElemTy); 330226633Sdim } 331234353Sdim Out << '}'; 332234353Sdim return; 333234353Sdim } 334226633Sdim case APValue::ComplexInt: 335234353Sdim Out << getComplexIntReal() << "+" << getComplexIntImag() << "i"; 336234353Sdim return; 337226633Sdim case APValue::ComplexFloat: 338234353Sdim Out << GetApproxValue(getComplexFloatReal()) << "+" 339234353Sdim << GetApproxValue(getComplexFloatImag()) << "i"; 340234353Sdim return; 341234353Sdim case APValue::LValue: { 342234353Sdim LValueBase Base = getLValueBase(); 343234353Sdim if (!Base) { 344234353Sdim Out << "0"; 345234353Sdim return; 346234353Sdim } 347234353Sdim 348234353Sdim bool IsReference = Ty->isReferenceType(); 349234353Sdim QualType InnerTy 350234353Sdim = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType(); 351234353Sdim 352234353Sdim if (!hasLValuePath()) { 353234353Sdim // No lvalue path: just print the offset. 354234353Sdim CharUnits O = getLValueOffset(); 355234353Sdim CharUnits S = Ctx.getTypeSizeInChars(InnerTy); 356234353Sdim if (!O.isZero()) { 357234353Sdim if (IsReference) 358234353Sdim Out << "*("; 359234353Sdim if (O % S) { 360234353Sdim Out << "(char*)"; 361234353Sdim S = CharUnits::One(); 362234353Sdim } 363234353Sdim Out << '&'; 364234353Sdim } else if (!IsReference) 365234353Sdim Out << '&'; 366234353Sdim 367234353Sdim if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) 368234353Sdim Out << *VD; 369234353Sdim else 370234353Sdim Base.get<const Expr*>()->printPretty(Out, Ctx, 0, 371234353Sdim Ctx.getPrintingPolicy()); 372234353Sdim if (!O.isZero()) { 373234353Sdim Out << " + " << (O / S); 374234353Sdim if (IsReference) 375234353Sdim Out << ')'; 376234353Sdim } 377234353Sdim return; 378234353Sdim } 379234353Sdim 380234353Sdim // We have an lvalue path. Print it out nicely. 381234353Sdim if (!IsReference) 382234353Sdim Out << '&'; 383234353Sdim else if (isLValueOnePastTheEnd()) 384234353Sdim Out << "*(&"; 385234353Sdim 386234353Sdim QualType ElemTy; 387234353Sdim if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) { 388234353Sdim Out << *VD; 389234353Sdim ElemTy = VD->getType(); 390234353Sdim } else { 391234353Sdim const Expr *E = Base.get<const Expr*>(); 392234353Sdim E->printPretty(Out, Ctx, 0,Ctx.getPrintingPolicy()); 393234353Sdim ElemTy = E->getType(); 394234353Sdim } 395234353Sdim 396234353Sdim ArrayRef<LValuePathEntry> Path = getLValuePath(); 397234353Sdim const CXXRecordDecl *CastToBase = 0; 398234353Sdim for (unsigned I = 0, N = Path.size(); I != N; ++I) { 399234353Sdim if (ElemTy->getAs<RecordType>()) { 400234353Sdim // The lvalue refers to a class type, so the next path entry is a base 401234353Sdim // or member. 402234353Sdim const Decl *BaseOrMember = 403234353Sdim BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer(); 404234353Sdim if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) { 405234353Sdim CastToBase = RD; 406234353Sdim ElemTy = Ctx.getRecordType(RD); 407234353Sdim } else { 408234353Sdim const ValueDecl *VD = cast<ValueDecl>(BaseOrMember); 409234353Sdim Out << "."; 410234353Sdim if (CastToBase) 411234353Sdim Out << *CastToBase << "::"; 412234353Sdim Out << *VD; 413234353Sdim ElemTy = VD->getType(); 414234353Sdim } 415234353Sdim } else { 416234353Sdim // The lvalue must refer to an array. 417234353Sdim Out << '[' << Path[I].ArrayIndex << ']'; 418234353Sdim ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType(); 419234353Sdim } 420234353Sdim } 421234353Sdim 422234353Sdim // Handle formatting of one-past-the-end lvalues. 423234353Sdim if (isLValueOnePastTheEnd()) { 424234353Sdim // FIXME: If CastToBase is non-0, we should prefix the output with 425234353Sdim // "(CastToBase*)". 426234353Sdim Out << " + 1"; 427234353Sdim if (IsReference) 428234353Sdim Out << ')'; 429234353Sdim } 430234353Sdim return; 431226633Sdim } 432234353Sdim case APValue::Array: { 433234353Sdim const ArrayType *AT = Ctx.getAsArrayType(Ty); 434234353Sdim QualType ElemTy = AT->getElementType(); 435234353Sdim Out << '{'; 436234353Sdim if (unsigned N = getArrayInitializedElts()) { 437234353Sdim getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy); 438234353Sdim for (unsigned I = 1; I != N; ++I) { 439234353Sdim Out << ", "; 440234353Sdim if (I == 10) { 441234353Sdim // Avoid printing out the entire contents of large arrays. 442234353Sdim Out << "..."; 443234353Sdim break; 444234353Sdim } 445234353Sdim getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy); 446234353Sdim } 447234353Sdim } 448234353Sdim Out << '}'; 449234353Sdim return; 450234353Sdim } 451234353Sdim case APValue::Struct: { 452234353Sdim Out << '{'; 453234353Sdim const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl(); 454234353Sdim bool First = true; 455234353Sdim if (unsigned N = getStructNumBases()) { 456234353Sdim const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD); 457234353Sdim CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin(); 458234353Sdim for (unsigned I = 0; I != N; ++I, ++BI) { 459234353Sdim assert(BI != CD->bases_end()); 460234353Sdim if (!First) 461234353Sdim Out << ", "; 462234353Sdim getStructBase(I).printPretty(Out, Ctx, BI->getType()); 463234353Sdim First = false; 464234353Sdim } 465234353Sdim } 466234353Sdim for (RecordDecl::field_iterator FI = RD->field_begin(); 467234353Sdim FI != RD->field_end(); ++FI) { 468234353Sdim if (!First) 469234353Sdim Out << ", "; 470234353Sdim if ((*FI)->isUnnamedBitfield()) continue; 471234353Sdim getStructField((*FI)->getFieldIndex()). 472234353Sdim printPretty(Out, Ctx, (*FI)->getType()); 473234353Sdim First = false; 474234353Sdim } 475234353Sdim Out << '}'; 476234353Sdim return; 477234353Sdim } 478234353Sdim case APValue::Union: 479234353Sdim Out << '{'; 480234353Sdim if (const FieldDecl *FD = getUnionField()) { 481234353Sdim Out << "." << *FD << " = "; 482234353Sdim getUnionValue().printPretty(Out, Ctx, FD->getType()); 483234353Sdim } 484234353Sdim Out << '}'; 485234353Sdim return; 486234353Sdim case APValue::MemberPointer: 487234353Sdim // FIXME: This is not enough to unambiguously identify the member in a 488234353Sdim // multiple-inheritance scenario. 489234353Sdim if (const ValueDecl *VD = getMemberPointerDecl()) { 490234353Sdim Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD; 491234353Sdim return; 492234353Sdim } 493234353Sdim Out << "0"; 494234353Sdim return; 495234353Sdim case APValue::AddrLabelDiff: 496234353Sdim Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName(); 497234353Sdim Out << " - "; 498234353Sdim Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName(); 499234353Sdim return; 500234353Sdim } 501234353Sdim llvm_unreachable("Unknown APValue kind!"); 502226633Sdim} 503226633Sdim 504234353Sdimstd::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const { 505234353Sdim std::string Result; 506234353Sdim llvm::raw_string_ostream Out(Result); 507234353Sdim printPretty(Out, Ctx, Ty); 508234353Sdim Out.flush(); 509234353Sdim return Result; 510226633Sdim} 511226633Sdim 512234353Sdimconst APValue::LValueBase APValue::getLValueBase() const { 513202379Srdivacky assert(isLValue() && "Invalid accessor"); 514234353Sdim return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getPointer(); 515202379Srdivacky} 516202379Srdivacky 517234353Sdimbool APValue::isLValueOnePastTheEnd() const { 518234353Sdim assert(isLValue() && "Invalid accessor"); 519234353Sdim return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getInt(); 520202379Srdivacky} 521202379Srdivacky 522234353SdimCharUnits &APValue::getLValueOffset() { 523202379Srdivacky assert(isLValue() && "Invalid accessor"); 524234353Sdim return ((LV*)(void*)Data)->Offset; 525202379Srdivacky} 526202379Srdivacky 527234353Sdimbool APValue::hasLValuePath() const { 528234353Sdim assert(isLValue() && "Invalid accessor"); 529234353Sdim return ((const LV*)(const char*)Data)->hasPath(); 530234353Sdim} 531234353Sdim 532234353SdimArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const { 533234353Sdim assert(isLValue() && hasLValuePath() && "Invalid accessor"); 534234353Sdim const LV &LVal = *((const LV*)(const char*)Data); 535234353Sdim return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength); 536234353Sdim} 537234353Sdim 538234353Sdimunsigned APValue::getLValueCallIndex() const { 539234353Sdim assert(isLValue() && "Invalid accessor"); 540234353Sdim return ((const LV*)(const char*)Data)->CallIndex; 541234353Sdim} 542234353Sdim 543234353Sdimvoid APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath, 544234353Sdim unsigned CallIndex) { 545234353Sdim assert(isLValue() && "Invalid accessor"); 546234353Sdim LV &LVal = *((LV*)(char*)Data); 547234353Sdim LVal.BaseAndIsOnePastTheEnd.setPointer(B); 548234353Sdim LVal.BaseAndIsOnePastTheEnd.setInt(false); 549234353Sdim LVal.Offset = O; 550234353Sdim LVal.CallIndex = CallIndex; 551234353Sdim LVal.resizePath((unsigned)-1); 552234353Sdim} 553234353Sdim 554234353Sdimvoid APValue::setLValue(LValueBase B, const CharUnits &O, 555234353Sdim ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd, 556234353Sdim unsigned CallIndex) { 557234353Sdim assert(isLValue() && "Invalid accessor"); 558234353Sdim LV &LVal = *((LV*)(char*)Data); 559234353Sdim LVal.BaseAndIsOnePastTheEnd.setPointer(B); 560234353Sdim LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd); 561234353Sdim LVal.Offset = O; 562234353Sdim LVal.CallIndex = CallIndex; 563234353Sdim LVal.resizePath(Path.size()); 564234353Sdim memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry)); 565234353Sdim} 566234353Sdim 567234353Sdimconst ValueDecl *APValue::getMemberPointerDecl() const { 568234353Sdim assert(isMemberPointer() && "Invalid accessor"); 569234353Sdim const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data); 570234353Sdim return MPD.MemberAndIsDerivedMember.getPointer(); 571234353Sdim} 572234353Sdim 573234353Sdimbool APValue::isMemberPointerToDerivedMember() const { 574234353Sdim assert(isMemberPointer() && "Invalid accessor"); 575234353Sdim const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data); 576234353Sdim return MPD.MemberAndIsDerivedMember.getInt(); 577234353Sdim} 578234353Sdim 579234353SdimArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const { 580234353Sdim assert(isMemberPointer() && "Invalid accessor"); 581234353Sdim const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data); 582234353Sdim return ArrayRef<const CXXRecordDecl*>(MPD.getPath(), MPD.PathLength); 583234353Sdim} 584234353Sdim 585202379Srdivackyvoid APValue::MakeLValue() { 586202379Srdivacky assert(isUninit() && "Bad state change"); 587234353Sdim assert(sizeof(LV) <= MaxSize && "LV too big"); 588202379Srdivacky new ((void*)(char*)Data) LV(); 589202379Srdivacky Kind = LValue; 590202379Srdivacky} 591202379Srdivacky 592234353Sdimvoid APValue::MakeArray(unsigned InitElts, unsigned Size) { 593234353Sdim assert(isUninit() && "Bad state change"); 594234353Sdim new ((void*)(char*)Data) Arr(InitElts, Size); 595234353Sdim Kind = Array; 596234353Sdim} 597234353Sdim 598234353Sdimvoid APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 599234353Sdim ArrayRef<const CXXRecordDecl*> Path) { 600234353Sdim assert(isUninit() && "Bad state change"); 601234353Sdim MemberPointerData *MPD = new ((void*)(char*)Data) MemberPointerData; 602234353Sdim Kind = MemberPointer; 603234353Sdim MPD->MemberAndIsDerivedMember.setPointer(Member); 604234353Sdim MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember); 605234353Sdim MPD->resizePath(Path.size()); 606234353Sdim memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*)); 607234353Sdim} 608