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