1 //===-- BitcodeReader.cpp - ClangDoc Bitcode Reader ------------*- C++ -*-===// 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 #include "BitcodeReader.h" 11 #include "llvm/ADT/IndexedMap.h" 12 #include "llvm/ADT/Optional.h" 13 #include "llvm/Support/raw_ostream.h" 14 15 namespace clang { 16 namespace doc { 17 18 using Record = llvm::SmallVector<uint64_t, 1024>; 19 20 bool decodeRecord(Record R, llvm::SmallVectorImpl<char> &Field, 21 llvm::StringRef Blob) { 22 Field.assign(Blob.begin(), Blob.end()); 23 return true; 24 } 25 26 bool decodeRecord(Record R, SymbolID &Field, llvm::StringRef Blob) { 27 if (R[0] != BitCodeConstants::USRHashSize) 28 return false; 29 30 // First position in the record is the length of the following array, so we 31 // copy the following elements to the field. 32 for (int I = 0, E = R[0]; I < E; ++I) 33 Field[I] = R[I + 1]; 34 return true; 35 } 36 37 bool decodeRecord(Record R, bool &Field, llvm::StringRef Blob) { 38 Field = R[0] != 0; 39 return true; 40 } 41 42 bool decodeRecord(Record R, int &Field, llvm::StringRef Blob) { 43 if (R[0] > INT_MAX) 44 return false; 45 Field = (int)R[0]; 46 return true; 47 } 48 49 bool decodeRecord(Record R, AccessSpecifier &Field, llvm::StringRef Blob) { 50 switch (R[0]) { 51 case AS_public: 52 case AS_private: 53 case AS_protected: 54 case AS_none: 55 Field = (AccessSpecifier)R[0]; 56 return true; 57 default: 58 return false; 59 } 60 } 61 62 bool decodeRecord(Record R, TagTypeKind &Field, llvm::StringRef Blob) { 63 switch (R[0]) { 64 case TTK_Struct: 65 case TTK_Interface: 66 case TTK_Union: 67 case TTK_Class: 68 case TTK_Enum: 69 Field = (TagTypeKind)R[0]; 70 return true; 71 default: 72 return false; 73 } 74 } 75 76 bool decodeRecord(Record R, llvm::Optional<Location> &Field, 77 llvm::StringRef Blob) { 78 if (R[0] > INT_MAX) 79 return false; 80 Field.emplace((int)R[0], Blob); 81 return true; 82 } 83 84 bool decodeRecord(Record R, InfoType &Field, llvm::StringRef Blob) { 85 switch (auto IT = static_cast<InfoType>(R[0])) { 86 case InfoType::IT_namespace: 87 case InfoType::IT_record: 88 case InfoType::IT_function: 89 case InfoType::IT_default: 90 case InfoType::IT_enum: 91 Field = IT; 92 return true; 93 } 94 return false; 95 } 96 97 bool decodeRecord(Record R, FieldId &Field, llvm::StringRef Blob) { 98 switch (auto F = static_cast<FieldId>(R[0])) { 99 case FieldId::F_namespace: 100 case FieldId::F_parent: 101 case FieldId::F_vparent: 102 case FieldId::F_type: 103 case FieldId::F_child_namespace: 104 case FieldId::F_child_record: 105 case FieldId::F_default: 106 Field = F; 107 return true; 108 } 109 return false; 110 } 111 112 bool decodeRecord(Record R, llvm::SmallVectorImpl<llvm::SmallString<16>> &Field, 113 llvm::StringRef Blob) { 114 Field.push_back(Blob); 115 return true; 116 } 117 118 bool decodeRecord(Record R, llvm::SmallVectorImpl<Location> &Field, 119 llvm::StringRef Blob) { 120 if (R[0] > INT_MAX) 121 return false; 122 Field.emplace_back((int)R[0], Blob); 123 return true; 124 } 125 126 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, 127 const unsigned VersionNo) { 128 if (ID == VERSION && R[0] == VersionNo) 129 return true; 130 return false; 131 } 132 133 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, 134 NamespaceInfo *I) { 135 switch (ID) { 136 case NAMESPACE_USR: 137 return decodeRecord(R, I->USR, Blob); 138 case NAMESPACE_NAME: 139 return decodeRecord(R, I->Name, Blob); 140 default: 141 return false; 142 } 143 } 144 145 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, RecordInfo *I) { 146 switch (ID) { 147 case RECORD_USR: 148 return decodeRecord(R, I->USR, Blob); 149 case RECORD_NAME: 150 return decodeRecord(R, I->Name, Blob); 151 case RECORD_DEFLOCATION: 152 return decodeRecord(R, I->DefLoc, Blob); 153 case RECORD_LOCATION: 154 return decodeRecord(R, I->Loc, Blob); 155 case RECORD_TAG_TYPE: 156 return decodeRecord(R, I->TagType, Blob); 157 default: 158 return false; 159 } 160 } 161 162 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, EnumInfo *I) { 163 switch (ID) { 164 case ENUM_USR: 165 return decodeRecord(R, I->USR, Blob); 166 case ENUM_NAME: 167 return decodeRecord(R, I->Name, Blob); 168 case ENUM_DEFLOCATION: 169 return decodeRecord(R, I->DefLoc, Blob); 170 case ENUM_LOCATION: 171 return decodeRecord(R, I->Loc, Blob); 172 case ENUM_MEMBER: 173 return decodeRecord(R, I->Members, Blob); 174 case ENUM_SCOPED: 175 return decodeRecord(R, I->Scoped, Blob); 176 default: 177 return false; 178 } 179 } 180 181 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, FunctionInfo *I) { 182 switch (ID) { 183 case FUNCTION_USR: 184 return decodeRecord(R, I->USR, Blob); 185 case FUNCTION_NAME: 186 return decodeRecord(R, I->Name, Blob); 187 case FUNCTION_DEFLOCATION: 188 return decodeRecord(R, I->DefLoc, Blob); 189 case FUNCTION_LOCATION: 190 return decodeRecord(R, I->Loc, Blob); 191 case FUNCTION_ACCESS: 192 return decodeRecord(R, I->Access, Blob); 193 case FUNCTION_IS_METHOD: 194 return decodeRecord(R, I->IsMethod, Blob); 195 default: 196 return false; 197 } 198 } 199 200 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, TypeInfo *I) { 201 return true; 202 } 203 204 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, 205 FieldTypeInfo *I) { 206 switch (ID) { 207 case FIELD_TYPE_NAME: 208 return decodeRecord(R, I->Name, Blob); 209 default: 210 return false; 211 } 212 } 213 214 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, 215 MemberTypeInfo *I) { 216 switch (ID) { 217 case MEMBER_TYPE_NAME: 218 return decodeRecord(R, I->Name, Blob); 219 case MEMBER_TYPE_ACCESS: 220 return decodeRecord(R, I->Access, Blob); 221 default: 222 return false; 223 } 224 } 225 226 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { 227 switch (ID) { 228 case COMMENT_KIND: 229 return decodeRecord(R, I->Kind, Blob); 230 case COMMENT_TEXT: 231 return decodeRecord(R, I->Text, Blob); 232 case COMMENT_NAME: 233 return decodeRecord(R, I->Name, Blob); 234 case COMMENT_DIRECTION: 235 return decodeRecord(R, I->Direction, Blob); 236 case COMMENT_PARAMNAME: 237 return decodeRecord(R, I->ParamName, Blob); 238 case COMMENT_CLOSENAME: 239 return decodeRecord(R, I->CloseName, Blob); 240 case COMMENT_ATTRKEY: 241 return decodeRecord(R, I->AttrKeys, Blob); 242 case COMMENT_ATTRVAL: 243 return decodeRecord(R, I->AttrValues, Blob); 244 case COMMENT_ARG: 245 return decodeRecord(R, I->Args, Blob); 246 case COMMENT_SELFCLOSING: 247 return decodeRecord(R, I->SelfClosing, Blob); 248 case COMMENT_EXPLICIT: 249 return decodeRecord(R, I->Explicit, Blob); 250 default: 251 return false; 252 } 253 } 254 255 bool parseRecord(Record R, unsigned ID, llvm::StringRef Blob, Reference *I, 256 FieldId &F) { 257 switch (ID) { 258 case REFERENCE_USR: 259 return decodeRecord(R, I->USR, Blob); 260 case REFERENCE_NAME: 261 return decodeRecord(R, I->Name, Blob); 262 case REFERENCE_TYPE: 263 return decodeRecord(R, I->RefType, Blob); 264 case REFERENCE_FIELD: 265 return decodeRecord(R, F, Blob); 266 default: 267 return false; 268 } 269 } 270 271 template <typename T> CommentInfo *getCommentInfo(T I) { 272 llvm::errs() << "Cannot have comment subblock.\n"; 273 exit(1); 274 } 275 276 template <> CommentInfo *getCommentInfo(FunctionInfo *I) { 277 I->Description.emplace_back(); 278 return &I->Description.back(); 279 } 280 281 template <> CommentInfo *getCommentInfo(NamespaceInfo *I) { 282 I->Description.emplace_back(); 283 return &I->Description.back(); 284 } 285 286 template <> CommentInfo *getCommentInfo(RecordInfo *I) { 287 I->Description.emplace_back(); 288 return &I->Description.back(); 289 } 290 291 template <> CommentInfo *getCommentInfo(EnumInfo *I) { 292 I->Description.emplace_back(); 293 return &I->Description.back(); 294 } 295 296 template <> CommentInfo *getCommentInfo(CommentInfo *I) { 297 I->Children.emplace_back(llvm::make_unique<CommentInfo>()); 298 return I->Children.back().get(); 299 } 300 301 template <> CommentInfo *getCommentInfo(std::unique_ptr<CommentInfo> &I) { 302 return getCommentInfo(I.get()); 303 } 304 305 template <typename T, typename TTypeInfo> 306 void addTypeInfo(T I, TTypeInfo &&TI) { 307 llvm::errs() << "Invalid type for info.\n"; 308 exit(1); 309 } 310 311 template <> void addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) { 312 I->Members.emplace_back(std::move(T)); 313 } 314 315 template <> void addTypeInfo(FunctionInfo *I, TypeInfo &&T) { 316 I->ReturnType = std::move(T); 317 } 318 319 template <> void addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) { 320 I->Params.emplace_back(std::move(T)); 321 } 322 323 template <typename T> void addReference(T I, Reference &&R, FieldId F) { 324 llvm::errs() << "Invalid field type for info.\n"; 325 exit(1); 326 } 327 328 template <> void addReference(TypeInfo *I, Reference &&R, FieldId F) { 329 switch (F) { 330 case FieldId::F_type: 331 I->Type = std::move(R); 332 break; 333 default: 334 llvm::errs() << "Invalid field type for info.\n"; 335 exit(1); 336 } 337 } 338 339 template <> void addReference(FieldTypeInfo *I, Reference &&R, FieldId F) { 340 switch (F) { 341 case FieldId::F_type: 342 I->Type = std::move(R); 343 break; 344 default: 345 llvm::errs() << "Invalid field type for info.\n"; 346 exit(1); 347 } 348 } 349 350 template <> void addReference(MemberTypeInfo *I, Reference &&R, FieldId F) { 351 switch (F) { 352 case FieldId::F_type: 353 I->Type = std::move(R); 354 break; 355 default: 356 llvm::errs() << "Invalid field type for info.\n"; 357 exit(1); 358 } 359 } 360 361 template <> void addReference(EnumInfo *I, Reference &&R, FieldId F) { 362 switch (F) { 363 case FieldId::F_namespace: 364 I->Namespace.emplace_back(std::move(R)); 365 break; 366 default: 367 llvm::errs() << "Invalid field type for info.\n"; 368 exit(1); 369 } 370 } 371 372 template <> void addReference(NamespaceInfo *I, Reference &&R, FieldId F) { 373 switch (F) { 374 case FieldId::F_namespace: 375 I->Namespace.emplace_back(std::move(R)); 376 break; 377 case FieldId::F_child_namespace: 378 I->ChildNamespaces.emplace_back(std::move(R)); 379 break; 380 case FieldId::F_child_record: 381 I->ChildRecords.emplace_back(std::move(R)); 382 break; 383 default: 384 llvm::errs() << "Invalid field type for info.\n"; 385 exit(1); 386 } 387 } 388 389 template <> void addReference(FunctionInfo *I, Reference &&R, FieldId F) { 390 switch (F) { 391 case FieldId::F_namespace: 392 I->Namespace.emplace_back(std::move(R)); 393 break; 394 case FieldId::F_parent: 395 I->Parent = std::move(R); 396 break; 397 default: 398 llvm::errs() << "Invalid field type for info.\n"; 399 exit(1); 400 } 401 } 402 403 template <> void addReference(RecordInfo *I, Reference &&R, FieldId F) { 404 switch (F) { 405 case FieldId::F_namespace: 406 I->Namespace.emplace_back(std::move(R)); 407 break; 408 case FieldId::F_parent: 409 I->Parents.emplace_back(std::move(R)); 410 break; 411 case FieldId::F_vparent: 412 I->VirtualParents.emplace_back(std::move(R)); 413 break; 414 case FieldId::F_child_record: 415 I->ChildRecords.emplace_back(std::move(R)); 416 break; 417 default: 418 llvm::errs() << "Invalid field type for info.\n"; 419 exit(1); 420 } 421 } 422 423 template <typename T, typename ChildInfoType> 424 void addChild(T I, ChildInfoType &&R) { 425 llvm::errs() << "Invalid child type for info.\n"; 426 exit(1); 427 } 428 429 template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) { 430 I->ChildFunctions.emplace_back(std::move(R)); 431 } 432 433 template <> void addChild(NamespaceInfo *I, EnumInfo &&R) { 434 I->ChildEnums.emplace_back(std::move(R)); 435 } 436 437 template <> void addChild(RecordInfo *I, FunctionInfo &&R) { 438 I->ChildFunctions.emplace_back(std::move(R)); 439 } 440 441 template <> void addChild(RecordInfo *I, EnumInfo &&R) { 442 I->ChildEnums.emplace_back(std::move(R)); 443 } 444 445 // Read records from bitcode into a given info. 446 template <typename T> bool ClangDocBitcodeReader::readRecord(unsigned ID, T I) { 447 Record R; 448 llvm::StringRef Blob; 449 unsigned RecID = Stream.readRecord(ID, R, &Blob); 450 return parseRecord(R, RecID, Blob, I); 451 } 452 453 template <> bool ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) { 454 Record R; 455 llvm::StringRef Blob; 456 unsigned RecID = Stream.readRecord(ID, R, &Blob); 457 return parseRecord(R, RecID, Blob, I, CurrentReferenceField); 458 } 459 460 // Read a block of records into a single info. 461 template <typename T> bool ClangDocBitcodeReader::readBlock(unsigned ID, T I) { 462 if (Stream.EnterSubBlock(ID)) 463 return false; 464 465 while (true) { 466 unsigned BlockOrCode = 0; 467 Cursor Res = skipUntilRecordOrBlock(BlockOrCode); 468 469 switch (Res) { 470 case Cursor::BadBlock: 471 return false; 472 case Cursor::BlockEnd: 473 return true; 474 case Cursor::BlockBegin: 475 if (readSubBlock(BlockOrCode, I)) 476 continue; 477 if (!Stream.SkipBlock()) 478 return false; 479 continue; 480 case Cursor::Record: 481 break; 482 } 483 if (!readRecord(BlockOrCode, I)) 484 return false; 485 } 486 } 487 488 template <typename T> 489 bool ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { 490 switch (ID) { 491 // Blocks can only have Comment, Reference, TypeInfo, FunctionInfo, or 492 // EnumInfo subblocks 493 case BI_COMMENT_BLOCK_ID: 494 if (readBlock(ID, getCommentInfo(I))) 495 return true; 496 return false; 497 case BI_TYPE_BLOCK_ID: { 498 TypeInfo TI; 499 if (readBlock(ID, &TI)) { 500 addTypeInfo(I, std::move(TI)); 501 return true; 502 } 503 return false; 504 } 505 case BI_FIELD_TYPE_BLOCK_ID: { 506 FieldTypeInfo TI; 507 if (readBlock(ID, &TI)) { 508 addTypeInfo(I, std::move(TI)); 509 return true; 510 } 511 return false; 512 } 513 case BI_MEMBER_TYPE_BLOCK_ID: { 514 MemberTypeInfo TI; 515 if (readBlock(ID, &TI)) { 516 addTypeInfo(I, std::move(TI)); 517 return true; 518 } 519 return false; 520 } 521 case BI_REFERENCE_BLOCK_ID: { 522 Reference R; 523 if (readBlock(ID, &R)) { 524 addReference(I, std::move(R), CurrentReferenceField); 525 return true; 526 } 527 return false; 528 } 529 case BI_FUNCTION_BLOCK_ID: { 530 FunctionInfo F; 531 if (readBlock(ID, &F)) { 532 addChild(I, std::move(F)); 533 return true; 534 } 535 return false; 536 } 537 case BI_ENUM_BLOCK_ID: { 538 EnumInfo E; 539 if (readBlock(ID, &E)) { 540 addChild(I, std::move(E)); 541 return true; 542 } 543 return false; 544 } 545 default: 546 llvm::errs() << "Invalid subblock type.\n"; 547 return false; 548 } 549 } 550 551 ClangDocBitcodeReader::Cursor 552 ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) { 553 BlockOrRecordID = 0; 554 555 while (!Stream.AtEndOfStream()) { 556 unsigned Code = Stream.ReadCode(); 557 558 switch ((llvm::bitc::FixedAbbrevIDs)Code) { 559 case llvm::bitc::ENTER_SUBBLOCK: 560 BlockOrRecordID = Stream.ReadSubBlockID(); 561 return Cursor::BlockBegin; 562 case llvm::bitc::END_BLOCK: 563 if (Stream.ReadBlockEnd()) 564 return Cursor::BadBlock; 565 return Cursor::BlockEnd; 566 case llvm::bitc::DEFINE_ABBREV: 567 Stream.ReadAbbrevRecord(); 568 continue; 569 case llvm::bitc::UNABBREV_RECORD: 570 return Cursor::BadBlock; 571 default: 572 BlockOrRecordID = Code; 573 return Cursor::Record; 574 } 575 } 576 llvm_unreachable("Premature stream end."); 577 } 578 579 bool ClangDocBitcodeReader::validateStream() { 580 if (Stream.AtEndOfStream()) 581 return false; 582 583 // Sniff for the signature. 584 if (Stream.Read(8) != BitCodeConstants::Signature[0] || 585 Stream.Read(8) != BitCodeConstants::Signature[1] || 586 Stream.Read(8) != BitCodeConstants::Signature[2] || 587 Stream.Read(8) != BitCodeConstants::Signature[3]) 588 return false; 589 return true; 590 } 591 592 bool ClangDocBitcodeReader::readBlockInfoBlock() { 593 BlockInfo = Stream.ReadBlockInfoBlock(); 594 if (!BlockInfo) 595 return false; 596 Stream.setBlockInfo(&*BlockInfo); 597 return true; 598 } 599 600 template <typename T> 601 std::unique_ptr<Info> ClangDocBitcodeReader::createInfo(unsigned ID) { 602 std::unique_ptr<Info> I = llvm::make_unique<T>(); 603 if (readBlock(ID, static_cast<T *>(I.get()))) 604 return I; 605 llvm::errs() << "Error reading from block.\n"; 606 return nullptr; 607 } 608 609 std::unique_ptr<Info> ClangDocBitcodeReader::readBlockToInfo(unsigned ID) { 610 switch (ID) { 611 case BI_NAMESPACE_BLOCK_ID: 612 return createInfo<NamespaceInfo>(ID); 613 case BI_RECORD_BLOCK_ID: 614 return createInfo<RecordInfo>(ID); 615 case BI_ENUM_BLOCK_ID: 616 return createInfo<EnumInfo>(ID); 617 case BI_FUNCTION_BLOCK_ID: 618 return createInfo<FunctionInfo>(ID); 619 default: 620 llvm::errs() << "Error reading from block.\n"; 621 return nullptr; 622 } 623 } 624 625 // Entry point 626 llvm::Expected<std::vector<std::unique_ptr<Info>>> 627 ClangDocBitcodeReader::readBitcode() { 628 std::vector<std::unique_ptr<Info>> Infos; 629 if (!validateStream()) 630 return llvm::make_error<llvm::StringError>("Invalid bitcode stream.\n", 631 llvm::inconvertibleErrorCode()); 632 ; 633 634 // Read the top level blocks. 635 while (!Stream.AtEndOfStream()) { 636 unsigned Code = Stream.ReadCode(); 637 if (Code != llvm::bitc::ENTER_SUBBLOCK) 638 return llvm::make_error<llvm::StringError>( 639 "Missing subblock in bitcode.\n", llvm::inconvertibleErrorCode()); 640 ; 641 642 unsigned ID = Stream.ReadSubBlockID(); 643 switch (ID) { 644 // NamedType and Comment blocks should not appear at the top level 645 case BI_TYPE_BLOCK_ID: 646 case BI_FIELD_TYPE_BLOCK_ID: 647 case BI_MEMBER_TYPE_BLOCK_ID: 648 case BI_COMMENT_BLOCK_ID: 649 case BI_REFERENCE_BLOCK_ID: 650 return llvm::make_error<llvm::StringError>( 651 "Invalid top level block in bitcode.\n", 652 llvm::inconvertibleErrorCode()); 653 ; 654 case BI_NAMESPACE_BLOCK_ID: 655 case BI_RECORD_BLOCK_ID: 656 case BI_ENUM_BLOCK_ID: 657 case BI_FUNCTION_BLOCK_ID: 658 if (std::unique_ptr<Info> I = readBlockToInfo(ID)) 659 Infos.emplace_back(std::move(I)); 660 continue; 661 case BI_VERSION_BLOCK_ID: 662 if (readBlock(ID, VersionNumber)) 663 continue; 664 return llvm::make_error<llvm::StringError>( 665 "Invalid bitcode version in bitcode.\n", 666 llvm::inconvertibleErrorCode()); 667 ; 668 case llvm::bitc::BLOCKINFO_BLOCK_ID: 669 if (readBlockInfoBlock()) 670 continue; 671 return llvm::make_error<llvm::StringError>( 672 "Invalid BlockInfo in bitcode.\n", llvm::inconvertibleErrorCode()); 673 ; 674 default: 675 if (!Stream.SkipBlock()) 676 continue; 677 } 678 } 679 return std::move(Infos); 680 } 681 682 } // namespace doc 683 } // namespace clang 684