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" 22249423Sdim#include "llvm/Support/ErrorHandling.h" 23193326Sed#include "llvm/Support/raw_ostream.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 215263508Sdimbool APValue::needsCleanup() const { 216263508Sdim switch (getKind()) { 217263508Sdim case Uninitialized: 218263508Sdim case AddrLabelDiff: 219263508Sdim return false; 220263508Sdim case Struct: 221263508Sdim case Union: 222263508Sdim case Array: 223263508Sdim case Vector: 224263508Sdim return true; 225263508Sdim case Int: 226263508Sdim return getInt().needsCleanup(); 227263508Sdim case Float: 228263508Sdim return getFloat().needsCleanup(); 229263508Sdim case ComplexFloat: 230263508Sdim assert(getComplexFloatImag().needsCleanup() == 231263508Sdim getComplexFloatReal().needsCleanup() && 232263508Sdim "In _Complex float types, real and imaginary values always have the " 233263508Sdim "same size."); 234263508Sdim return getComplexFloatReal().needsCleanup(); 235263508Sdim case ComplexInt: 236263508Sdim assert(getComplexIntImag().needsCleanup() == 237263508Sdim getComplexIntReal().needsCleanup() && 238263508Sdim "In _Complex int types, real and imaginary values must have the " 239263508Sdim "same size."); 240263508Sdim return getComplexIntReal().needsCleanup(); 241263508Sdim case LValue: 242263508Sdim return reinterpret_cast<const LV *>(Data)->hasPathPtr(); 243263508Sdim case MemberPointer: 244263508Sdim return reinterpret_cast<const MemberPointerData *>(Data)->hasPathPtr(); 245263508Sdim } 246263508Sdim llvm_unreachable("Unknown APValue kind!"); 247263508Sdim} 248263508Sdim 249234353Sdimvoid APValue::swap(APValue &RHS) { 250234353Sdim std::swap(Kind, RHS.Kind); 251234353Sdim char TmpData[MaxSize]; 252234353Sdim memcpy(TmpData, Data, MaxSize); 253234353Sdim memcpy(Data, RHS.Data, MaxSize); 254234353Sdim memcpy(RHS.Data, TmpData, MaxSize); 255234353Sdim} 256234353Sdim 257193326Sedvoid APValue::dump() const { 258234353Sdim dump(llvm::errs()); 259193326Sed llvm::errs() << '\n'; 260193326Sed} 261193326Sed 262193326Sedstatic double GetApproxValue(const llvm::APFloat &F) { 263193326Sed llvm::APFloat V = F; 264193326Sed bool ignored; 265193326Sed V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven, 266193326Sed &ignored); 267193326Sed return V.convertToDouble(); 268193326Sed} 269193326Sed 270234353Sdimvoid APValue::dump(raw_ostream &OS) const { 271193326Sed switch (getKind()) { 272193326Sed case Uninitialized: 273193326Sed OS << "Uninitialized"; 274193326Sed return; 275193326Sed case Int: 276193326Sed OS << "Int: " << getInt(); 277193326Sed return; 278193326Sed case Float: 279193326Sed OS << "Float: " << GetApproxValue(getFloat()); 280193326Sed return; 281193326Sed case Vector: 282234353Sdim OS << "Vector: "; 283234353Sdim getVectorElt(0).dump(OS); 284234353Sdim for (unsigned i = 1; i != getVectorLength(); ++i) { 285234353Sdim OS << ", "; 286234353Sdim getVectorElt(i).dump(OS); 287234353Sdim } 288193326Sed return; 289193326Sed case ComplexInt: 290193326Sed OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); 291193326Sed return; 292193326Sed case ComplexFloat: 293193326Sed OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) 294193326Sed << ", " << GetApproxValue(getComplexFloatImag()); 295234353Sdim return; 296193326Sed case LValue: 297193326Sed OS << "LValue: <todo>"; 298193326Sed return; 299234353Sdim case Array: 300234353Sdim OS << "Array: "; 301234353Sdim for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) { 302234353Sdim getArrayInitializedElt(I).dump(OS); 303234353Sdim if (I != getArraySize() - 1) OS << ", "; 304234353Sdim } 305234353Sdim if (hasArrayFiller()) { 306234353Sdim OS << getArraySize() - getArrayInitializedElts() << " x "; 307234353Sdim getArrayFiller().dump(OS); 308234353Sdim } 309234353Sdim return; 310234353Sdim case Struct: 311234353Sdim OS << "Struct "; 312234353Sdim if (unsigned N = getStructNumBases()) { 313234353Sdim OS << " bases: "; 314234353Sdim getStructBase(0).dump(OS); 315234353Sdim for (unsigned I = 1; I != N; ++I) { 316234353Sdim OS << ", "; 317234353Sdim getStructBase(I).dump(OS); 318234353Sdim } 319234353Sdim } 320234353Sdim if (unsigned N = getStructNumFields()) { 321234353Sdim OS << " fields: "; 322234353Sdim getStructField(0).dump(OS); 323234353Sdim for (unsigned I = 1; I != N; ++I) { 324234353Sdim OS << ", "; 325234353Sdim getStructField(I).dump(OS); 326234353Sdim } 327234353Sdim } 328234353Sdim return; 329234353Sdim case Union: 330234353Sdim OS << "Union: "; 331234353Sdim getUnionValue().dump(OS); 332234353Sdim return; 333234353Sdim case MemberPointer: 334234353Sdim OS << "MemberPointer: <todo>"; 335234353Sdim return; 336234353Sdim case AddrLabelDiff: 337234353Sdim OS << "AddrLabelDiff: <todo>"; 338234353Sdim return; 339193326Sed } 340234353Sdim llvm_unreachable("Unknown APValue kind!"); 341193326Sed} 342193326Sed 343234353Sdimvoid APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{ 344234353Sdim switch (getKind()) { 345226633Sdim case APValue::Uninitialized: 346234353Sdim Out << "<uninitialized>"; 347234353Sdim return; 348226633Sdim case APValue::Int: 349234353Sdim if (Ty->isBooleanType()) 350234353Sdim Out << (getInt().getBoolValue() ? "true" : "false"); 351234353Sdim else 352234353Sdim Out << getInt(); 353234353Sdim return; 354226633Sdim case APValue::Float: 355234353Sdim Out << GetApproxValue(getFloat()); 356234353Sdim return; 357234353Sdim case APValue::Vector: { 358234353Sdim Out << '{'; 359234353Sdim QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); 360234353Sdim getVectorElt(0).printPretty(Out, Ctx, ElemTy); 361234353Sdim for (unsigned i = 1; i != getVectorLength(); ++i) { 362226633Sdim Out << ", "; 363234353Sdim getVectorElt(i).printPretty(Out, Ctx, ElemTy); 364226633Sdim } 365234353Sdim Out << '}'; 366234353Sdim return; 367234353Sdim } 368226633Sdim case APValue::ComplexInt: 369234353Sdim Out << getComplexIntReal() << "+" << getComplexIntImag() << "i"; 370234353Sdim return; 371226633Sdim case APValue::ComplexFloat: 372234353Sdim Out << GetApproxValue(getComplexFloatReal()) << "+" 373234353Sdim << GetApproxValue(getComplexFloatImag()) << "i"; 374234353Sdim return; 375234353Sdim case APValue::LValue: { 376234353Sdim LValueBase Base = getLValueBase(); 377234353Sdim if (!Base) { 378234353Sdim Out << "0"; 379234353Sdim return; 380234353Sdim } 381234353Sdim 382234353Sdim bool IsReference = Ty->isReferenceType(); 383234353Sdim QualType InnerTy 384234353Sdim = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType(); 385249423Sdim if (InnerTy.isNull()) 386249423Sdim InnerTy = Ty; 387234353Sdim 388234353Sdim if (!hasLValuePath()) { 389234353Sdim // No lvalue path: just print the offset. 390234353Sdim CharUnits O = getLValueOffset(); 391234353Sdim CharUnits S = Ctx.getTypeSizeInChars(InnerTy); 392234353Sdim if (!O.isZero()) { 393234353Sdim if (IsReference) 394234353Sdim Out << "*("; 395234353Sdim if (O % S) { 396234353Sdim Out << "(char*)"; 397234353Sdim S = CharUnits::One(); 398234353Sdim } 399234353Sdim Out << '&'; 400234353Sdim } else if (!IsReference) 401234353Sdim Out << '&'; 402234353Sdim 403234353Sdim if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) 404234353Sdim Out << *VD; 405234353Sdim else 406239462Sdim Base.get<const Expr*>()->printPretty(Out, 0, Ctx.getPrintingPolicy()); 407234353Sdim if (!O.isZero()) { 408234353Sdim Out << " + " << (O / S); 409234353Sdim if (IsReference) 410234353Sdim Out << ')'; 411234353Sdim } 412234353Sdim return; 413234353Sdim } 414234353Sdim 415234353Sdim // We have an lvalue path. Print it out nicely. 416234353Sdim if (!IsReference) 417234353Sdim Out << '&'; 418234353Sdim else if (isLValueOnePastTheEnd()) 419234353Sdim Out << "*(&"; 420234353Sdim 421234353Sdim QualType ElemTy; 422234353Sdim if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) { 423234353Sdim Out << *VD; 424234353Sdim ElemTy = VD->getType(); 425234353Sdim } else { 426234353Sdim const Expr *E = Base.get<const Expr*>(); 427239462Sdim E->printPretty(Out, 0, Ctx.getPrintingPolicy()); 428234353Sdim ElemTy = E->getType(); 429234353Sdim } 430234353Sdim 431234353Sdim ArrayRef<LValuePathEntry> Path = getLValuePath(); 432234353Sdim const CXXRecordDecl *CastToBase = 0; 433234353Sdim for (unsigned I = 0, N = Path.size(); I != N; ++I) { 434234353Sdim if (ElemTy->getAs<RecordType>()) { 435234353Sdim // The lvalue refers to a class type, so the next path entry is a base 436234353Sdim // or member. 437234353Sdim const Decl *BaseOrMember = 438234353Sdim BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer(); 439234353Sdim if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) { 440234353Sdim CastToBase = RD; 441234353Sdim ElemTy = Ctx.getRecordType(RD); 442234353Sdim } else { 443234353Sdim const ValueDecl *VD = cast<ValueDecl>(BaseOrMember); 444234353Sdim Out << "."; 445234353Sdim if (CastToBase) 446234353Sdim Out << *CastToBase << "::"; 447234353Sdim Out << *VD; 448234353Sdim ElemTy = VD->getType(); 449234353Sdim } 450234353Sdim } else { 451234353Sdim // The lvalue must refer to an array. 452234353Sdim Out << '[' << Path[I].ArrayIndex << ']'; 453234353Sdim ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType(); 454234353Sdim } 455234353Sdim } 456234353Sdim 457234353Sdim // Handle formatting of one-past-the-end lvalues. 458234353Sdim if (isLValueOnePastTheEnd()) { 459234353Sdim // FIXME: If CastToBase is non-0, we should prefix the output with 460234353Sdim // "(CastToBase*)". 461234353Sdim Out << " + 1"; 462234353Sdim if (IsReference) 463234353Sdim Out << ')'; 464234353Sdim } 465234353Sdim return; 466226633Sdim } 467234353Sdim case APValue::Array: { 468234353Sdim const ArrayType *AT = Ctx.getAsArrayType(Ty); 469234353Sdim QualType ElemTy = AT->getElementType(); 470234353Sdim Out << '{'; 471234353Sdim if (unsigned N = getArrayInitializedElts()) { 472234353Sdim getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy); 473234353Sdim for (unsigned I = 1; I != N; ++I) { 474234353Sdim Out << ", "; 475234353Sdim if (I == 10) { 476234353Sdim // Avoid printing out the entire contents of large arrays. 477234353Sdim Out << "..."; 478234353Sdim break; 479234353Sdim } 480234353Sdim getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy); 481234353Sdim } 482234353Sdim } 483234353Sdim Out << '}'; 484234353Sdim return; 485234353Sdim } 486234353Sdim case APValue::Struct: { 487234353Sdim Out << '{'; 488234353Sdim const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl(); 489234353Sdim bool First = true; 490234353Sdim if (unsigned N = getStructNumBases()) { 491234353Sdim const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD); 492234353Sdim CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin(); 493234353Sdim for (unsigned I = 0; I != N; ++I, ++BI) { 494234353Sdim assert(BI != CD->bases_end()); 495234353Sdim if (!First) 496234353Sdim Out << ", "; 497234353Sdim getStructBase(I).printPretty(Out, Ctx, BI->getType()); 498234353Sdim First = false; 499234353Sdim } 500234353Sdim } 501234353Sdim for (RecordDecl::field_iterator FI = RD->field_begin(); 502234353Sdim FI != RD->field_end(); ++FI) { 503234353Sdim if (!First) 504234353Sdim Out << ", "; 505239462Sdim if (FI->isUnnamedBitfield()) continue; 506239462Sdim getStructField(FI->getFieldIndex()). 507239462Sdim printPretty(Out, Ctx, FI->getType()); 508234353Sdim First = false; 509234353Sdim } 510234353Sdim Out << '}'; 511234353Sdim return; 512234353Sdim } 513234353Sdim case APValue::Union: 514234353Sdim Out << '{'; 515234353Sdim if (const FieldDecl *FD = getUnionField()) { 516234353Sdim Out << "." << *FD << " = "; 517234353Sdim getUnionValue().printPretty(Out, Ctx, FD->getType()); 518234353Sdim } 519234353Sdim Out << '}'; 520234353Sdim return; 521234353Sdim case APValue::MemberPointer: 522234353Sdim // FIXME: This is not enough to unambiguously identify the member in a 523234353Sdim // multiple-inheritance scenario. 524234353Sdim if (const ValueDecl *VD = getMemberPointerDecl()) { 525234353Sdim Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD; 526234353Sdim return; 527234353Sdim } 528234353Sdim Out << "0"; 529234353Sdim return; 530234353Sdim case APValue::AddrLabelDiff: 531234353Sdim Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName(); 532234353Sdim Out << " - "; 533234353Sdim Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName(); 534234353Sdim return; 535234353Sdim } 536234353Sdim llvm_unreachable("Unknown APValue kind!"); 537226633Sdim} 538226633Sdim 539234353Sdimstd::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const { 540234353Sdim std::string Result; 541234353Sdim llvm::raw_string_ostream Out(Result); 542234353Sdim printPretty(Out, Ctx, Ty); 543234353Sdim Out.flush(); 544234353Sdim return Result; 545226633Sdim} 546226633Sdim 547234353Sdimconst APValue::LValueBase APValue::getLValueBase() const { 548202379Srdivacky assert(isLValue() && "Invalid accessor"); 549234353Sdim return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getPointer(); 550202379Srdivacky} 551202379Srdivacky 552234353Sdimbool APValue::isLValueOnePastTheEnd() const { 553234353Sdim assert(isLValue() && "Invalid accessor"); 554234353Sdim return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getInt(); 555202379Srdivacky} 556202379Srdivacky 557234353SdimCharUnits &APValue::getLValueOffset() { 558202379Srdivacky assert(isLValue() && "Invalid accessor"); 559234353Sdim return ((LV*)(void*)Data)->Offset; 560202379Srdivacky} 561202379Srdivacky 562234353Sdimbool APValue::hasLValuePath() const { 563234353Sdim assert(isLValue() && "Invalid accessor"); 564234353Sdim return ((const LV*)(const char*)Data)->hasPath(); 565234353Sdim} 566234353Sdim 567234353SdimArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const { 568234353Sdim assert(isLValue() && hasLValuePath() && "Invalid accessor"); 569234353Sdim const LV &LVal = *((const LV*)(const char*)Data); 570234353Sdim return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength); 571234353Sdim} 572234353Sdim 573234353Sdimunsigned APValue::getLValueCallIndex() const { 574234353Sdim assert(isLValue() && "Invalid accessor"); 575234353Sdim return ((const LV*)(const char*)Data)->CallIndex; 576234353Sdim} 577234353Sdim 578234353Sdimvoid APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath, 579234353Sdim unsigned CallIndex) { 580234353Sdim assert(isLValue() && "Invalid accessor"); 581234353Sdim LV &LVal = *((LV*)(char*)Data); 582234353Sdim LVal.BaseAndIsOnePastTheEnd.setPointer(B); 583234353Sdim LVal.BaseAndIsOnePastTheEnd.setInt(false); 584234353Sdim LVal.Offset = O; 585234353Sdim LVal.CallIndex = CallIndex; 586234353Sdim LVal.resizePath((unsigned)-1); 587234353Sdim} 588234353Sdim 589234353Sdimvoid APValue::setLValue(LValueBase B, const CharUnits &O, 590234353Sdim ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd, 591234353Sdim unsigned CallIndex) { 592234353Sdim assert(isLValue() && "Invalid accessor"); 593234353Sdim LV &LVal = *((LV*)(char*)Data); 594234353Sdim LVal.BaseAndIsOnePastTheEnd.setPointer(B); 595234353Sdim LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd); 596234353Sdim LVal.Offset = O; 597234353Sdim LVal.CallIndex = CallIndex; 598234353Sdim LVal.resizePath(Path.size()); 599234353Sdim memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry)); 600234353Sdim} 601234353Sdim 602234353Sdimconst ValueDecl *APValue::getMemberPointerDecl() const { 603234353Sdim assert(isMemberPointer() && "Invalid accessor"); 604234353Sdim const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data); 605234353Sdim return MPD.MemberAndIsDerivedMember.getPointer(); 606234353Sdim} 607234353Sdim 608234353Sdimbool APValue::isMemberPointerToDerivedMember() const { 609234353Sdim assert(isMemberPointer() && "Invalid accessor"); 610234353Sdim const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data); 611234353Sdim return MPD.MemberAndIsDerivedMember.getInt(); 612234353Sdim} 613234353Sdim 614234353SdimArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const { 615234353Sdim assert(isMemberPointer() && "Invalid accessor"); 616234353Sdim const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data); 617234353Sdim return ArrayRef<const CXXRecordDecl*>(MPD.getPath(), MPD.PathLength); 618234353Sdim} 619234353Sdim 620202379Srdivackyvoid APValue::MakeLValue() { 621202379Srdivacky assert(isUninit() && "Bad state change"); 622234353Sdim assert(sizeof(LV) <= MaxSize && "LV too big"); 623202379Srdivacky new ((void*)(char*)Data) LV(); 624202379Srdivacky Kind = LValue; 625202379Srdivacky} 626202379Srdivacky 627234353Sdimvoid APValue::MakeArray(unsigned InitElts, unsigned Size) { 628234353Sdim assert(isUninit() && "Bad state change"); 629234353Sdim new ((void*)(char*)Data) Arr(InitElts, Size); 630234353Sdim Kind = Array; 631234353Sdim} 632234353Sdim 633234353Sdimvoid APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 634234353Sdim ArrayRef<const CXXRecordDecl*> Path) { 635234353Sdim assert(isUninit() && "Bad state change"); 636234353Sdim MemberPointerData *MPD = new ((void*)(char*)Data) MemberPointerData; 637234353Sdim Kind = MemberPointer; 638234353Sdim MPD->MemberAndIsDerivedMember.setPointer(Member); 639234353Sdim MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember); 640234353Sdim MPD->resizePath(Path.size()); 641234353Sdim memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*)); 642234353Sdim} 643