10b57cec5SDimitry Andric //===- BitcodeAnalyzer.cpp - Internal BitcodeAnalyzer implementation ------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeAnalyzer.h" 100b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h" 110b57cec5SDimitry Andric #include "llvm/Bitcode/LLVMBitCodes.h" 120b57cec5SDimitry Andric #include "llvm/Bitstream/BitCodes.h" 130b57cec5SDimitry Andric #include "llvm/Bitstream/BitstreamReader.h" 140b57cec5SDimitry Andric #include "llvm/Support/Format.h" 150b57cec5SDimitry Andric #include "llvm/Support/SHA1.h" 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric using namespace llvm; 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric static Error reportError(StringRef Message) { 200b57cec5SDimitry Andric return createStringError(std::errc::illegal_byte_sequence, Message.data()); 210b57cec5SDimitry Andric } 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric /// Return a symbolic block name if known, otherwise return null. 240b57cec5SDimitry Andric static Optional<const char *> GetBlockName(unsigned BlockID, 250b57cec5SDimitry Andric const BitstreamBlockInfo &BlockInfo, 260b57cec5SDimitry Andric CurStreamTypeType CurStreamType) { 270b57cec5SDimitry Andric // Standard blocks for all bitcode files. 280b57cec5SDimitry Andric if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { 290b57cec5SDimitry Andric if (BlockID == bitc::BLOCKINFO_BLOCK_ID) 300b57cec5SDimitry Andric return "BLOCKINFO_BLOCK"; 310b57cec5SDimitry Andric return None; 320b57cec5SDimitry Andric } 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric // Check to see if we have a blockinfo record for this block, with a name. 350b57cec5SDimitry Andric if (const BitstreamBlockInfo::BlockInfo *Info = 360b57cec5SDimitry Andric BlockInfo.getBlockInfo(BlockID)) { 370b57cec5SDimitry Andric if (!Info->Name.empty()) 380b57cec5SDimitry Andric return Info->Name.c_str(); 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric if (CurStreamType != LLVMIRBitstream) 420b57cec5SDimitry Andric return None; 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric switch (BlockID) { 450b57cec5SDimitry Andric default: 460b57cec5SDimitry Andric return None; 470b57cec5SDimitry Andric case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: 480b57cec5SDimitry Andric return "OPERAND_BUNDLE_TAGS_BLOCK"; 490b57cec5SDimitry Andric case bitc::MODULE_BLOCK_ID: 500b57cec5SDimitry Andric return "MODULE_BLOCK"; 510b57cec5SDimitry Andric case bitc::PARAMATTR_BLOCK_ID: 520b57cec5SDimitry Andric return "PARAMATTR_BLOCK"; 530b57cec5SDimitry Andric case bitc::PARAMATTR_GROUP_BLOCK_ID: 540b57cec5SDimitry Andric return "PARAMATTR_GROUP_BLOCK_ID"; 550b57cec5SDimitry Andric case bitc::TYPE_BLOCK_ID_NEW: 560b57cec5SDimitry Andric return "TYPE_BLOCK_ID"; 570b57cec5SDimitry Andric case bitc::CONSTANTS_BLOCK_ID: 580b57cec5SDimitry Andric return "CONSTANTS_BLOCK"; 590b57cec5SDimitry Andric case bitc::FUNCTION_BLOCK_ID: 600b57cec5SDimitry Andric return "FUNCTION_BLOCK"; 610b57cec5SDimitry Andric case bitc::IDENTIFICATION_BLOCK_ID: 620b57cec5SDimitry Andric return "IDENTIFICATION_BLOCK_ID"; 630b57cec5SDimitry Andric case bitc::VALUE_SYMTAB_BLOCK_ID: 640b57cec5SDimitry Andric return "VALUE_SYMTAB"; 650b57cec5SDimitry Andric case bitc::METADATA_BLOCK_ID: 660b57cec5SDimitry Andric return "METADATA_BLOCK"; 670b57cec5SDimitry Andric case bitc::METADATA_KIND_BLOCK_ID: 680b57cec5SDimitry Andric return "METADATA_KIND_BLOCK"; 690b57cec5SDimitry Andric case bitc::METADATA_ATTACHMENT_ID: 700b57cec5SDimitry Andric return "METADATA_ATTACHMENT_BLOCK"; 710b57cec5SDimitry Andric case bitc::USELIST_BLOCK_ID: 720b57cec5SDimitry Andric return "USELIST_BLOCK_ID"; 730b57cec5SDimitry Andric case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: 740b57cec5SDimitry Andric return "GLOBALVAL_SUMMARY_BLOCK"; 750b57cec5SDimitry Andric case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: 760b57cec5SDimitry Andric return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK"; 770b57cec5SDimitry Andric case bitc::MODULE_STRTAB_BLOCK_ID: 780b57cec5SDimitry Andric return "MODULE_STRTAB_BLOCK"; 790b57cec5SDimitry Andric case bitc::STRTAB_BLOCK_ID: 800b57cec5SDimitry Andric return "STRTAB_BLOCK"; 810b57cec5SDimitry Andric case bitc::SYMTAB_BLOCK_ID: 820b57cec5SDimitry Andric return "SYMTAB_BLOCK"; 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric /// Return a symbolic code name if known, otherwise return null. 870b57cec5SDimitry Andric static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, 880b57cec5SDimitry Andric const BitstreamBlockInfo &BlockInfo, 890b57cec5SDimitry Andric CurStreamTypeType CurStreamType) { 900b57cec5SDimitry Andric // Standard blocks for all bitcode files. 910b57cec5SDimitry Andric if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { 920b57cec5SDimitry Andric if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { 930b57cec5SDimitry Andric switch (CodeID) { 940b57cec5SDimitry Andric default: 950b57cec5SDimitry Andric return None; 960b57cec5SDimitry Andric case bitc::BLOCKINFO_CODE_SETBID: 970b57cec5SDimitry Andric return "SETBID"; 980b57cec5SDimitry Andric case bitc::BLOCKINFO_CODE_BLOCKNAME: 990b57cec5SDimitry Andric return "BLOCKNAME"; 1000b57cec5SDimitry Andric case bitc::BLOCKINFO_CODE_SETRECORDNAME: 1010b57cec5SDimitry Andric return "SETRECORDNAME"; 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric return None; 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric // Check to see if we have a blockinfo record for this record, with a name. 1080b57cec5SDimitry Andric if (const BitstreamBlockInfo::BlockInfo *Info = 1090b57cec5SDimitry Andric BlockInfo.getBlockInfo(BlockID)) { 1100b57cec5SDimitry Andric for (unsigned i = 0, e = Info->RecordNames.size(); i != e; ++i) 1110b57cec5SDimitry Andric if (Info->RecordNames[i].first == CodeID) 1120b57cec5SDimitry Andric return Info->RecordNames[i].second.c_str(); 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric if (CurStreamType != LLVMIRBitstream) 1160b57cec5SDimitry Andric return None; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric #define STRINGIFY_CODE(PREFIX, CODE) \ 1190b57cec5SDimitry Andric case bitc::PREFIX##_##CODE: \ 1200b57cec5SDimitry Andric return #CODE; 1210b57cec5SDimitry Andric switch (BlockID) { 1220b57cec5SDimitry Andric default: 1230b57cec5SDimitry Andric return None; 1240b57cec5SDimitry Andric case bitc::MODULE_BLOCK_ID: 1250b57cec5SDimitry Andric switch (CodeID) { 1260b57cec5SDimitry Andric default: 1270b57cec5SDimitry Andric return None; 1280b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, VERSION) 1290b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, TRIPLE) 1300b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, DATALAYOUT) 1310b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, ASM) 1320b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, SECTIONNAME) 1335ffd83dbSDimitry Andric STRINGIFY_CODE(MODULE_CODE, DEPLIB) // Deprecated, present in old bitcode 1340b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, GLOBALVAR) 1350b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, FUNCTION) 1360b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, ALIAS) 1370b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, GCNAME) 138e8d8bef9SDimitry Andric STRINGIFY_CODE(MODULE_CODE, COMDAT) 1390b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, VSTOFFSET) 1400b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, METADATA_VALUES_UNUSED) 1410b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, SOURCE_FILENAME) 1420b57cec5SDimitry Andric STRINGIFY_CODE(MODULE_CODE, HASH) 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric case bitc::IDENTIFICATION_BLOCK_ID: 1450b57cec5SDimitry Andric switch (CodeID) { 1460b57cec5SDimitry Andric default: 1470b57cec5SDimitry Andric return None; 1480b57cec5SDimitry Andric STRINGIFY_CODE(IDENTIFICATION_CODE, STRING) 1490b57cec5SDimitry Andric STRINGIFY_CODE(IDENTIFICATION_CODE, EPOCH) 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric case bitc::PARAMATTR_BLOCK_ID: 1520b57cec5SDimitry Andric switch (CodeID) { 1530b57cec5SDimitry Andric default: 1540b57cec5SDimitry Andric return None; 1550b57cec5SDimitry Andric // FIXME: Should these be different? 1560b57cec5SDimitry Andric case bitc::PARAMATTR_CODE_ENTRY_OLD: 1570b57cec5SDimitry Andric return "ENTRY"; 1580b57cec5SDimitry Andric case bitc::PARAMATTR_CODE_ENTRY: 1590b57cec5SDimitry Andric return "ENTRY"; 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric case bitc::PARAMATTR_GROUP_BLOCK_ID: 1620b57cec5SDimitry Andric switch (CodeID) { 1630b57cec5SDimitry Andric default: 1640b57cec5SDimitry Andric return None; 1650b57cec5SDimitry Andric case bitc::PARAMATTR_GRP_CODE_ENTRY: 1660b57cec5SDimitry Andric return "ENTRY"; 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric case bitc::TYPE_BLOCK_ID_NEW: 1690b57cec5SDimitry Andric switch (CodeID) { 1700b57cec5SDimitry Andric default: 1710b57cec5SDimitry Andric return None; 1720b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, NUMENTRY) 1730b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, VOID) 1740b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, FLOAT) 1750b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, DOUBLE) 1760b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, LABEL) 1770b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, OPAQUE) 1780b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, INTEGER) 1790b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, POINTER) 180e8d8bef9SDimitry Andric STRINGIFY_CODE(TYPE_CODE, HALF) 1810b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, ARRAY) 1820b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, VECTOR) 1830b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, X86_FP80) 1840b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, FP128) 1850b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, PPC_FP128) 1860b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, METADATA) 187e8d8bef9SDimitry Andric STRINGIFY_CODE(TYPE_CODE, X86_MMX) 1880b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, STRUCT_ANON) 1890b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, STRUCT_NAME) 1900b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, STRUCT_NAMED) 1910b57cec5SDimitry Andric STRINGIFY_CODE(TYPE_CODE, FUNCTION) 192e8d8bef9SDimitry Andric STRINGIFY_CODE(TYPE_CODE, TOKEN) 193e8d8bef9SDimitry Andric STRINGIFY_CODE(TYPE_CODE, BFLOAT) 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric case bitc::CONSTANTS_BLOCK_ID: 1970b57cec5SDimitry Andric switch (CodeID) { 1980b57cec5SDimitry Andric default: 1990b57cec5SDimitry Andric return None; 2000b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, SETTYPE) 2010b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, NULL) 2020b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, UNDEF) 2030b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, INTEGER) 2040b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, WIDE_INTEGER) 2050b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, FLOAT) 2060b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, AGGREGATE) 2070b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, STRING) 2080b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CSTRING) 2090b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_BINOP) 2100b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_CAST) 2110b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_GEP) 2120b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_INBOUNDS_GEP) 2130b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_SELECT) 2140b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_EXTRACTELT) 2150b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_INSERTELT) 2160b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_SHUFFLEVEC) 2170b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_CMP) 2180b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, INLINEASM) 2190b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX) 2200b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, CE_UNOP) 221fe6060f1SDimitry Andric STRINGIFY_CODE(CST_CODE, DSO_LOCAL_EQUIVALENT) 2220b57cec5SDimitry Andric case bitc::CST_CODE_BLOCKADDRESS: 2230b57cec5SDimitry Andric return "CST_CODE_BLOCKADDRESS"; 2240b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, DATA) 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric case bitc::FUNCTION_BLOCK_ID: 2270b57cec5SDimitry Andric switch (CodeID) { 2280b57cec5SDimitry Andric default: 2290b57cec5SDimitry Andric return None; 2300b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, DECLAREBLOCKS) 2310b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_BINOP) 2320b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CAST) 2330b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_GEP_OLD) 2340b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_INBOUNDS_GEP_OLD) 2350b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_SELECT) 2360b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTELT) 2370b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_INSERTELT) 2380b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_SHUFFLEVEC) 2390b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CMP) 2400b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_RET) 2410b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_BR) 2420b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_SWITCH) 2430b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_INVOKE) 2440b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_UNOP) 2450b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE) 2460b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET) 2470b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET) 2480b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CATCHPAD) 2490b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_PHI) 2500b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_ALLOCA) 2510b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_LOAD) 2520b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_VAARG) 2530b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_STORE) 2540b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTVAL) 2550b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_INSERTVAL) 2560b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CMP2) 2570b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_VSELECT) 2580b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC_AGAIN) 2590b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CALL) 2600b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC) 2610b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_GEP) 2620b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, OPERAND_BUNDLE) 2630b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_FENCE) 2640b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_ATOMICRMW) 2650b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_LOADATOMIC) 2660b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_STOREATOMIC) 2670b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CMPXCHG) 2680b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CALLBR) 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric case bitc::VALUE_SYMTAB_BLOCK_ID: 2710b57cec5SDimitry Andric switch (CodeID) { 2720b57cec5SDimitry Andric default: 2730b57cec5SDimitry Andric return None; 2740b57cec5SDimitry Andric STRINGIFY_CODE(VST_CODE, ENTRY) 2750b57cec5SDimitry Andric STRINGIFY_CODE(VST_CODE, BBENTRY) 2760b57cec5SDimitry Andric STRINGIFY_CODE(VST_CODE, FNENTRY) 2770b57cec5SDimitry Andric STRINGIFY_CODE(VST_CODE, COMBINED_ENTRY) 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric case bitc::MODULE_STRTAB_BLOCK_ID: 2800b57cec5SDimitry Andric switch (CodeID) { 2810b57cec5SDimitry Andric default: 2820b57cec5SDimitry Andric return None; 2830b57cec5SDimitry Andric STRINGIFY_CODE(MST_CODE, ENTRY) 2840b57cec5SDimitry Andric STRINGIFY_CODE(MST_CODE, HASH) 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: 2870b57cec5SDimitry Andric case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: 2880b57cec5SDimitry Andric switch (CodeID) { 2890b57cec5SDimitry Andric default: 2900b57cec5SDimitry Andric return None; 2910b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE) 2920b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE_PROFILE) 2930b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE_RELBF) 2940b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE_GLOBALVAR_INIT_REFS) 2950b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE_VTABLE_GLOBALVAR_INIT_REFS) 2960b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED) 2970b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED_PROFILE) 2980b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED_GLOBALVAR_INIT_REFS) 2990b57cec5SDimitry Andric STRINGIFY_CODE(FS, ALIAS) 3000b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED_ALIAS) 3010b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED_ORIGINAL_NAME) 3020b57cec5SDimitry Andric STRINGIFY_CODE(FS, VERSION) 3030b57cec5SDimitry Andric STRINGIFY_CODE(FS, FLAGS) 3040b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_TESTS) 3050b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_VCALLS) 3060b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_VCALLS) 3070b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_CONST_VCALL) 3080b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_CONST_VCALL) 3090b57cec5SDimitry Andric STRINGIFY_CODE(FS, VALUE_GUID) 3100b57cec5SDimitry Andric STRINGIFY_CODE(FS, CFI_FUNCTION_DEFS) 3110b57cec5SDimitry Andric STRINGIFY_CODE(FS, CFI_FUNCTION_DECLS) 3120b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_ID) 3130b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_ID_METADATA) 3145ffd83dbSDimitry Andric STRINGIFY_CODE(FS, BLOCK_COUNT) 3155ffd83dbSDimitry Andric STRINGIFY_CODE(FS, PARAM_ACCESS) 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric case bitc::METADATA_ATTACHMENT_ID: 3180b57cec5SDimitry Andric switch (CodeID) { 3190b57cec5SDimitry Andric default: 3200b57cec5SDimitry Andric return None; 3210b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, ATTACHMENT) 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric case bitc::METADATA_BLOCK_ID: 3240b57cec5SDimitry Andric switch (CodeID) { 3250b57cec5SDimitry Andric default: 3260b57cec5SDimitry Andric return None; 3270b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, STRING_OLD) 3280b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, VALUE) 3290b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, NODE) 3300b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, NAME) 3310b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, DISTINCT_NODE) 3320b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, KIND) // Older bitcode has it in a MODULE_BLOCK 3330b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, LOCATION) 3340b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, OLD_NODE) 3350b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, OLD_FN_NODE) 3360b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, NAMED_NODE) 3370b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, GENERIC_DEBUG) 3380b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, SUBRANGE) 3390b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, ENUMERATOR) 3400b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, BASIC_TYPE) 3410b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, FILE) 3420b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, DERIVED_TYPE) 3430b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, COMPOSITE_TYPE) 3440b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, SUBROUTINE_TYPE) 3450b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, COMPILE_UNIT) 3460b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, SUBPROGRAM) 3470b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, LEXICAL_BLOCK) 3480b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, LEXICAL_BLOCK_FILE) 3490b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, NAMESPACE) 3500b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, TEMPLATE_TYPE) 3510b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, TEMPLATE_VALUE) 3520b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, GLOBAL_VAR) 3530b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, LOCAL_VAR) 3540b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, EXPRESSION) 3550b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, OBJC_PROPERTY) 3560b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, IMPORTED_ENTITY) 3570b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, MODULE) 3580b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, MACRO) 3590b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, MACRO_FILE) 3600b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, STRINGS) 3610b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, GLOBAL_DECL_ATTACHMENT) 3620b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, GLOBAL_VAR_EXPR) 3630b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, INDEX_OFFSET) 3640b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, INDEX) 365fe6060f1SDimitry Andric STRINGIFY_CODE(METADATA, ARG_LIST) 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric case bitc::METADATA_KIND_BLOCK_ID: 3680b57cec5SDimitry Andric switch (CodeID) { 3690b57cec5SDimitry Andric default: 3700b57cec5SDimitry Andric return None; 3710b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, KIND) 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric case bitc::USELIST_BLOCK_ID: 3740b57cec5SDimitry Andric switch (CodeID) { 3750b57cec5SDimitry Andric default: 3760b57cec5SDimitry Andric return None; 3770b57cec5SDimitry Andric case bitc::USELIST_CODE_DEFAULT: 3780b57cec5SDimitry Andric return "USELIST_CODE_DEFAULT"; 3790b57cec5SDimitry Andric case bitc::USELIST_CODE_BB: 3800b57cec5SDimitry Andric return "USELIST_CODE_BB"; 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: 3840b57cec5SDimitry Andric switch (CodeID) { 3850b57cec5SDimitry Andric default: 3860b57cec5SDimitry Andric return None; 3870b57cec5SDimitry Andric case bitc::OPERAND_BUNDLE_TAG: 3880b57cec5SDimitry Andric return "OPERAND_BUNDLE_TAG"; 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric case bitc::STRTAB_BLOCK_ID: 3910b57cec5SDimitry Andric switch (CodeID) { 3920b57cec5SDimitry Andric default: 3930b57cec5SDimitry Andric return None; 3940b57cec5SDimitry Andric case bitc::STRTAB_BLOB: 3950b57cec5SDimitry Andric return "BLOB"; 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric case bitc::SYMTAB_BLOCK_ID: 3980b57cec5SDimitry Andric switch (CodeID) { 3990b57cec5SDimitry Andric default: 4000b57cec5SDimitry Andric return None; 4010b57cec5SDimitry Andric case bitc::SYMTAB_BLOB: 4020b57cec5SDimitry Andric return "BLOB"; 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric #undef STRINGIFY_CODE 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric static void printSize(raw_ostream &OS, double Bits) { 4090b57cec5SDimitry Andric OS << format("%.2f/%.2fB/%luW", Bits, Bits / 8, (unsigned long)(Bits / 32)); 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric static void printSize(raw_ostream &OS, uint64_t Bits) { 4120b57cec5SDimitry Andric OS << format("%lub/%.2fB/%luW", (unsigned long)Bits, (double)Bits / 8, 4130b57cec5SDimitry Andric (unsigned long)(Bits / 32)); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric static Expected<CurStreamTypeType> ReadSignature(BitstreamCursor &Stream) { 4170b57cec5SDimitry Andric auto tryRead = [&Stream](char &Dest, size_t size) -> Error { 4180b57cec5SDimitry Andric if (Expected<SimpleBitstreamCursor::word_t> MaybeWord = Stream.Read(size)) 4190b57cec5SDimitry Andric Dest = MaybeWord.get(); 4200b57cec5SDimitry Andric else 4210b57cec5SDimitry Andric return MaybeWord.takeError(); 4220b57cec5SDimitry Andric return Error::success(); 4230b57cec5SDimitry Andric }; 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric char Signature[6]; 4260b57cec5SDimitry Andric if (Error Err = tryRead(Signature[0], 8)) 4270b57cec5SDimitry Andric return std::move(Err); 4280b57cec5SDimitry Andric if (Error Err = tryRead(Signature[1], 8)) 4290b57cec5SDimitry Andric return std::move(Err); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric // Autodetect the file contents, if it is one we know. 4320b57cec5SDimitry Andric if (Signature[0] == 'C' && Signature[1] == 'P') { 4330b57cec5SDimitry Andric if (Error Err = tryRead(Signature[2], 8)) 4340b57cec5SDimitry Andric return std::move(Err); 4350b57cec5SDimitry Andric if (Error Err = tryRead(Signature[3], 8)) 4360b57cec5SDimitry Andric return std::move(Err); 4370b57cec5SDimitry Andric if (Signature[2] == 'C' && Signature[3] == 'H') 4380b57cec5SDimitry Andric return ClangSerializedASTBitstream; 4390b57cec5SDimitry Andric } else if (Signature[0] == 'D' && Signature[1] == 'I') { 4400b57cec5SDimitry Andric if (Error Err = tryRead(Signature[2], 8)) 4410b57cec5SDimitry Andric return std::move(Err); 4420b57cec5SDimitry Andric if (Error Err = tryRead(Signature[3], 8)) 4430b57cec5SDimitry Andric return std::move(Err); 4440b57cec5SDimitry Andric if (Signature[2] == 'A' && Signature[3] == 'G') 4450b57cec5SDimitry Andric return ClangSerializedDiagnosticsBitstream; 4468bcb0991SDimitry Andric } else if (Signature[0] == 'R' && Signature[1] == 'M') { 4478bcb0991SDimitry Andric if (Error Err = tryRead(Signature[2], 8)) 4488bcb0991SDimitry Andric return std::move(Err); 4498bcb0991SDimitry Andric if (Error Err = tryRead(Signature[3], 8)) 4508bcb0991SDimitry Andric return std::move(Err); 4518bcb0991SDimitry Andric if (Signature[2] == 'R' && Signature[3] == 'K') 4528bcb0991SDimitry Andric return LLVMBitstreamRemarks; 4530b57cec5SDimitry Andric } else { 4540b57cec5SDimitry Andric if (Error Err = tryRead(Signature[2], 4)) 4550b57cec5SDimitry Andric return std::move(Err); 4560b57cec5SDimitry Andric if (Error Err = tryRead(Signature[3], 4)) 4570b57cec5SDimitry Andric return std::move(Err); 4580b57cec5SDimitry Andric if (Error Err = tryRead(Signature[4], 4)) 4590b57cec5SDimitry Andric return std::move(Err); 4600b57cec5SDimitry Andric if (Error Err = tryRead(Signature[5], 4)) 4610b57cec5SDimitry Andric return std::move(Err); 4620b57cec5SDimitry Andric if (Signature[0] == 'B' && Signature[1] == 'C' && Signature[2] == 0x0 && 4630b57cec5SDimitry Andric Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD) 4640b57cec5SDimitry Andric return LLVMIRBitstream; 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric return UnknownBitstream; 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric static Expected<CurStreamTypeType> analyzeHeader(Optional<BCDumpOptions> O, 4700b57cec5SDimitry Andric BitstreamCursor &Stream) { 4710b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes = Stream.getBitcodeBytes(); 4720b57cec5SDimitry Andric const unsigned char *BufPtr = (const unsigned char *)Bytes.data(); 4730b57cec5SDimitry Andric const unsigned char *EndBufPtr = BufPtr + Bytes.size(); 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric // If we have a wrapper header, parse it and ignore the non-bc file 4760b57cec5SDimitry Andric // contents. The magic number is 0x0B17C0DE stored in little endian. 4770b57cec5SDimitry Andric if (isBitcodeWrapper(BufPtr, EndBufPtr)) { 4780b57cec5SDimitry Andric if (Bytes.size() < BWH_HeaderSize) 4790b57cec5SDimitry Andric return reportError("Invalid bitcode wrapper header"); 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric if (O) { 4820b57cec5SDimitry Andric unsigned Magic = support::endian::read32le(&BufPtr[BWH_MagicField]); 4830b57cec5SDimitry Andric unsigned Version = support::endian::read32le(&BufPtr[BWH_VersionField]); 4840b57cec5SDimitry Andric unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]); 4850b57cec5SDimitry Andric unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]); 4860b57cec5SDimitry Andric unsigned CPUType = support::endian::read32le(&BufPtr[BWH_CPUTypeField]); 4870b57cec5SDimitry Andric 4880b57cec5SDimitry Andric O->OS << "<BITCODE_WRAPPER_HEADER" 4890b57cec5SDimitry Andric << " Magic=" << format_hex(Magic, 10) 4900b57cec5SDimitry Andric << " Version=" << format_hex(Version, 10) 4910b57cec5SDimitry Andric << " Offset=" << format_hex(Offset, 10) 4920b57cec5SDimitry Andric << " Size=" << format_hex(Size, 10) 4930b57cec5SDimitry Andric << " CPUType=" << format_hex(CPUType, 10) << "/>\n"; 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) 4970b57cec5SDimitry Andric return reportError("Invalid bitcode wrapper header"); 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric // Use the cursor modified by skipping the wrapper header. 5010b57cec5SDimitry Andric Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, EndBufPtr)); 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric return ReadSignature(Stream); 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric static bool canDecodeBlob(unsigned Code, unsigned BlockID) { 5070b57cec5SDimitry Andric return BlockID == bitc::METADATA_BLOCK_ID && Code == bitc::METADATA_STRINGS; 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric Error BitcodeAnalyzer::decodeMetadataStringsBlob(StringRef Indent, 5110b57cec5SDimitry Andric ArrayRef<uint64_t> Record, 5120b57cec5SDimitry Andric StringRef Blob, 5130b57cec5SDimitry Andric raw_ostream &OS) { 5140b57cec5SDimitry Andric if (Blob.empty()) 5150b57cec5SDimitry Andric return reportError("Cannot decode empty blob."); 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric if (Record.size() != 2) 5180b57cec5SDimitry Andric return reportError( 5190b57cec5SDimitry Andric "Decoding metadata strings blob needs two record entries."); 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric unsigned NumStrings = Record[0]; 5220b57cec5SDimitry Andric unsigned StringsOffset = Record[1]; 5230b57cec5SDimitry Andric OS << " num-strings = " << NumStrings << " {\n"; 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric StringRef Lengths = Blob.slice(0, StringsOffset); 5260b57cec5SDimitry Andric SimpleBitstreamCursor R(Lengths); 5270b57cec5SDimitry Andric StringRef Strings = Blob.drop_front(StringsOffset); 5280b57cec5SDimitry Andric do { 5290b57cec5SDimitry Andric if (R.AtEndOfStream()) 5300b57cec5SDimitry Andric return reportError("bad length"); 5310b57cec5SDimitry Andric 532349cc55cSDimitry Andric uint32_t Size; 533349cc55cSDimitry Andric if (Error E = R.ReadVBR(6).moveInto(Size)) 534349cc55cSDimitry Andric return E; 5350b57cec5SDimitry Andric if (Strings.size() < Size) 5360b57cec5SDimitry Andric return reportError("truncated chars"); 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric OS << Indent << " '"; 5390b57cec5SDimitry Andric OS.write_escaped(Strings.slice(0, Size), /*hex=*/true); 5400b57cec5SDimitry Andric OS << "'\n"; 5410b57cec5SDimitry Andric Strings = Strings.drop_front(Size); 5420b57cec5SDimitry Andric } while (--NumStrings); 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric OS << Indent << " }"; 5450b57cec5SDimitry Andric return Error::success(); 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric BitcodeAnalyzer::BitcodeAnalyzer(StringRef Buffer, 5490b57cec5SDimitry Andric Optional<StringRef> BlockInfoBuffer) 5500b57cec5SDimitry Andric : Stream(Buffer) { 5510b57cec5SDimitry Andric if (BlockInfoBuffer) 5520b57cec5SDimitry Andric BlockInfoStream.emplace(*BlockInfoBuffer); 5530b57cec5SDimitry Andric } 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric Error BitcodeAnalyzer::analyze(Optional<BCDumpOptions> O, 5560b57cec5SDimitry Andric Optional<StringRef> CheckHash) { 557349cc55cSDimitry Andric if (Error E = analyzeHeader(O, Stream).moveInto(CurStreamType)) 558349cc55cSDimitry Andric return E; 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric Stream.setBlockInfo(&BlockInfo); 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric // Read block info from BlockInfoStream, if specified. 5630b57cec5SDimitry Andric // The block info must be a top-level block. 5640b57cec5SDimitry Andric if (BlockInfoStream) { 5650b57cec5SDimitry Andric BitstreamCursor BlockInfoCursor(*BlockInfoStream); 566349cc55cSDimitry Andric if (Error E = analyzeHeader(O, BlockInfoCursor).takeError()) 567349cc55cSDimitry Andric return E; 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric while (!BlockInfoCursor.AtEndOfStream()) { 5700b57cec5SDimitry Andric Expected<unsigned> MaybeCode = BlockInfoCursor.ReadCode(); 5710b57cec5SDimitry Andric if (!MaybeCode) 5720b57cec5SDimitry Andric return MaybeCode.takeError(); 5730b57cec5SDimitry Andric if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) 5740b57cec5SDimitry Andric return reportError("Invalid record at top-level in block info file"); 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andric Expected<unsigned> MaybeBlockID = BlockInfoCursor.ReadSubBlockID(); 5770b57cec5SDimitry Andric if (!MaybeBlockID) 5780b57cec5SDimitry Andric return MaybeBlockID.takeError(); 5790b57cec5SDimitry Andric if (MaybeBlockID.get() == bitc::BLOCKINFO_BLOCK_ID) { 580349cc55cSDimitry Andric Optional<BitstreamBlockInfo> NewBlockInfo; 581349cc55cSDimitry Andric if (Error E = 582349cc55cSDimitry Andric BlockInfoCursor.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true) 583349cc55cSDimitry Andric .moveInto(NewBlockInfo)) 584349cc55cSDimitry Andric return E; 5850b57cec5SDimitry Andric if (!NewBlockInfo) 5860b57cec5SDimitry Andric return reportError("Malformed BlockInfoBlock in block info file"); 5870b57cec5SDimitry Andric BlockInfo = std::move(*NewBlockInfo); 5880b57cec5SDimitry Andric break; 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric if (Error Err = BlockInfoCursor.SkipBlock()) 5920b57cec5SDimitry Andric return Err; 5930b57cec5SDimitry Andric } 5940b57cec5SDimitry Andric } 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric // Parse the top-level structure. We only allow blocks at the top-level. 5970b57cec5SDimitry Andric while (!Stream.AtEndOfStream()) { 5980b57cec5SDimitry Andric Expected<unsigned> MaybeCode = Stream.ReadCode(); 5990b57cec5SDimitry Andric if (!MaybeCode) 6000b57cec5SDimitry Andric return MaybeCode.takeError(); 6010b57cec5SDimitry Andric if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) 6020b57cec5SDimitry Andric return reportError("Invalid record at top-level"); 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric Expected<unsigned> MaybeBlockID = Stream.ReadSubBlockID(); 6050b57cec5SDimitry Andric if (!MaybeBlockID) 6060b57cec5SDimitry Andric return MaybeBlockID.takeError(); 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric if (Error E = parseBlock(MaybeBlockID.get(), 0, O, CheckHash)) 6090b57cec5SDimitry Andric return E; 6100b57cec5SDimitry Andric ++NumTopBlocks; 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric return Error::success(); 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric void BitcodeAnalyzer::printStats(BCDumpOptions O, 6170b57cec5SDimitry Andric Optional<StringRef> Filename) { 6180b57cec5SDimitry Andric uint64_t BufferSizeBits = Stream.getBitcodeBytes().size() * CHAR_BIT; 6190b57cec5SDimitry Andric // Print a summary of the read file. 6200b57cec5SDimitry Andric O.OS << "Summary "; 6210b57cec5SDimitry Andric if (Filename) 6220b57cec5SDimitry Andric O.OS << "of " << Filename->data() << ":\n"; 6230b57cec5SDimitry Andric O.OS << " Total size: "; 6240b57cec5SDimitry Andric printSize(O.OS, BufferSizeBits); 6250b57cec5SDimitry Andric O.OS << "\n"; 6260b57cec5SDimitry Andric O.OS << " Stream type: "; 6270b57cec5SDimitry Andric switch (CurStreamType) { 6280b57cec5SDimitry Andric case UnknownBitstream: 6290b57cec5SDimitry Andric O.OS << "unknown\n"; 6300b57cec5SDimitry Andric break; 6310b57cec5SDimitry Andric case LLVMIRBitstream: 6320b57cec5SDimitry Andric O.OS << "LLVM IR\n"; 6330b57cec5SDimitry Andric break; 6340b57cec5SDimitry Andric case ClangSerializedASTBitstream: 6350b57cec5SDimitry Andric O.OS << "Clang Serialized AST\n"; 6360b57cec5SDimitry Andric break; 6370b57cec5SDimitry Andric case ClangSerializedDiagnosticsBitstream: 6380b57cec5SDimitry Andric O.OS << "Clang Serialized Diagnostics\n"; 6390b57cec5SDimitry Andric break; 6408bcb0991SDimitry Andric case LLVMBitstreamRemarks: 6418bcb0991SDimitry Andric O.OS << "LLVM Remarks\n"; 6428bcb0991SDimitry Andric break; 6430b57cec5SDimitry Andric } 6440b57cec5SDimitry Andric O.OS << " # Toplevel Blocks: " << NumTopBlocks << "\n"; 6450b57cec5SDimitry Andric O.OS << "\n"; 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andric // Emit per-block stats. 6480b57cec5SDimitry Andric O.OS << "Per-block Summary:\n"; 6490b57cec5SDimitry Andric for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(), 6500b57cec5SDimitry Andric E = BlockIDStats.end(); 6510b57cec5SDimitry Andric I != E; ++I) { 6520b57cec5SDimitry Andric O.OS << " Block ID #" << I->first; 6530b57cec5SDimitry Andric if (Optional<const char *> BlockName = 6540b57cec5SDimitry Andric GetBlockName(I->first, BlockInfo, CurStreamType)) 6550b57cec5SDimitry Andric O.OS << " (" << *BlockName << ")"; 6560b57cec5SDimitry Andric O.OS << ":\n"; 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric const PerBlockIDStats &Stats = I->second; 6590b57cec5SDimitry Andric O.OS << " Num Instances: " << Stats.NumInstances << "\n"; 6600b57cec5SDimitry Andric O.OS << " Total Size: "; 6610b57cec5SDimitry Andric printSize(O.OS, Stats.NumBits); 6620b57cec5SDimitry Andric O.OS << "\n"; 6630b57cec5SDimitry Andric double pct = (Stats.NumBits * 100.0) / BufferSizeBits; 6640b57cec5SDimitry Andric O.OS << " Percent of file: " << format("%2.4f%%", pct) << "\n"; 6650b57cec5SDimitry Andric if (Stats.NumInstances > 1) { 6660b57cec5SDimitry Andric O.OS << " Average Size: "; 6670b57cec5SDimitry Andric printSize(O.OS, Stats.NumBits / (double)Stats.NumInstances); 6680b57cec5SDimitry Andric O.OS << "\n"; 6690b57cec5SDimitry Andric O.OS << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/" 6700b57cec5SDimitry Andric << Stats.NumSubBlocks / (double)Stats.NumInstances << "\n"; 6710b57cec5SDimitry Andric O.OS << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/" 6720b57cec5SDimitry Andric << Stats.NumAbbrevs / (double)Stats.NumInstances << "\n"; 6730b57cec5SDimitry Andric O.OS << " Tot/Avg Records: " << Stats.NumRecords << "/" 6740b57cec5SDimitry Andric << Stats.NumRecords / (double)Stats.NumInstances << "\n"; 6750b57cec5SDimitry Andric } else { 6760b57cec5SDimitry Andric O.OS << " Num SubBlocks: " << Stats.NumSubBlocks << "\n"; 6770b57cec5SDimitry Andric O.OS << " Num Abbrevs: " << Stats.NumAbbrevs << "\n"; 6780b57cec5SDimitry Andric O.OS << " Num Records: " << Stats.NumRecords << "\n"; 6790b57cec5SDimitry Andric } 6800b57cec5SDimitry Andric if (Stats.NumRecords) { 6810b57cec5SDimitry Andric double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords; 6820b57cec5SDimitry Andric O.OS << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n"; 6830b57cec5SDimitry Andric } 6840b57cec5SDimitry Andric O.OS << "\n"; 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric // Print a histogram of the codes we see. 6870b57cec5SDimitry Andric if (O.Histogram && !Stats.CodeFreq.empty()) { 6880b57cec5SDimitry Andric std::vector<std::pair<unsigned, unsigned>> FreqPairs; // <freq,code> 6890b57cec5SDimitry Andric for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i) 6900b57cec5SDimitry Andric if (unsigned Freq = Stats.CodeFreq[i].NumInstances) 6910b57cec5SDimitry Andric FreqPairs.push_back(std::make_pair(Freq, i)); 6920b57cec5SDimitry Andric llvm::stable_sort(FreqPairs); 6930b57cec5SDimitry Andric std::reverse(FreqPairs.begin(), FreqPairs.end()); 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric O.OS << "\tRecord Histogram:\n"; 6960b57cec5SDimitry Andric O.OS << "\t\t Count # Bits b/Rec % Abv Record Kind\n"; 6970b57cec5SDimitry Andric for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) { 6980b57cec5SDimitry Andric const PerRecordStats &RecStats = Stats.CodeFreq[FreqPairs[i].second]; 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric O.OS << format("\t\t%7d %9lu", RecStats.NumInstances, 7010b57cec5SDimitry Andric (unsigned long)RecStats.TotalBits); 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric if (RecStats.NumInstances > 1) 7040b57cec5SDimitry Andric O.OS << format(" %9.1f", 7050b57cec5SDimitry Andric (double)RecStats.TotalBits / RecStats.NumInstances); 7060b57cec5SDimitry Andric else 7070b57cec5SDimitry Andric O.OS << " "; 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andric if (RecStats.NumAbbrev) 7100b57cec5SDimitry Andric O.OS << format(" %7.2f", (double)RecStats.NumAbbrev / 7110b57cec5SDimitry Andric RecStats.NumInstances * 100); 7120b57cec5SDimitry Andric else 7130b57cec5SDimitry Andric O.OS << " "; 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric O.OS << " "; 7160b57cec5SDimitry Andric if (Optional<const char *> CodeName = GetCodeName( 7170b57cec5SDimitry Andric FreqPairs[i].second, I->first, BlockInfo, CurStreamType)) 7180b57cec5SDimitry Andric O.OS << *CodeName << "\n"; 7190b57cec5SDimitry Andric else 7200b57cec5SDimitry Andric O.OS << "UnknownCode" << FreqPairs[i].second << "\n"; 7210b57cec5SDimitry Andric } 7220b57cec5SDimitry Andric O.OS << "\n"; 7230b57cec5SDimitry Andric } 7240b57cec5SDimitry Andric } 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel, 7280b57cec5SDimitry Andric Optional<BCDumpOptions> O, 7290b57cec5SDimitry Andric Optional<StringRef> CheckHash) { 7300b57cec5SDimitry Andric std::string Indent(IndentLevel * 2, ' '); 7310b57cec5SDimitry Andric uint64_t BlockBitStart = Stream.GetCurrentBitNo(); 7320b57cec5SDimitry Andric 7330b57cec5SDimitry Andric // Get the statistics for this BlockID. 7340b57cec5SDimitry Andric PerBlockIDStats &BlockStats = BlockIDStats[BlockID]; 7350b57cec5SDimitry Andric 7360b57cec5SDimitry Andric BlockStats.NumInstances++; 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric // BLOCKINFO is a special part of the stream. 7390b57cec5SDimitry Andric bool DumpRecords = O.hasValue(); 7400b57cec5SDimitry Andric if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { 741349cc55cSDimitry Andric if (O && !O->DumpBlockinfo) 7420b57cec5SDimitry Andric O->OS << Indent << "<BLOCKINFO_BLOCK/>\n"; 743349cc55cSDimitry Andric Optional<BitstreamBlockInfo> NewBlockInfo; 744349cc55cSDimitry Andric if (Error E = Stream.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true) 745349cc55cSDimitry Andric .moveInto(NewBlockInfo)) 746349cc55cSDimitry Andric return E; 7470b57cec5SDimitry Andric if (!NewBlockInfo) 7480b57cec5SDimitry Andric return reportError("Malformed BlockInfoBlock"); 7490b57cec5SDimitry Andric BlockInfo = std::move(*NewBlockInfo); 7500b57cec5SDimitry Andric if (Error Err = Stream.JumpToBit(BlockBitStart)) 7510b57cec5SDimitry Andric return Err; 7520b57cec5SDimitry Andric // It's not really interesting to dump the contents of the blockinfo 753349cc55cSDimitry Andric // block, so only do it if the user explicitly requests it. 754349cc55cSDimitry Andric DumpRecords = O && O->DumpBlockinfo; 7550b57cec5SDimitry Andric } 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric unsigned NumWords = 0; 7580b57cec5SDimitry Andric if (Error Err = Stream.EnterSubBlock(BlockID, &NumWords)) 7590b57cec5SDimitry Andric return Err; 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric // Keep it for later, when we see a MODULE_HASH record 7620b57cec5SDimitry Andric uint64_t BlockEntryPos = Stream.getCurrentByteNo(); 7630b57cec5SDimitry Andric 7640b57cec5SDimitry Andric Optional<const char *> BlockName = None; 7650b57cec5SDimitry Andric if (DumpRecords) { 7660b57cec5SDimitry Andric O->OS << Indent << "<"; 7670b57cec5SDimitry Andric if ((BlockName = GetBlockName(BlockID, BlockInfo, CurStreamType))) 7680b57cec5SDimitry Andric O->OS << *BlockName; 7690b57cec5SDimitry Andric else 7700b57cec5SDimitry Andric O->OS << "UnknownBlock" << BlockID; 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric if (!O->Symbolic && BlockName) 7730b57cec5SDimitry Andric O->OS << " BlockID=" << BlockID; 7740b57cec5SDimitry Andric 7750b57cec5SDimitry Andric O->OS << " NumWords=" << NumWords 7760b57cec5SDimitry Andric << " BlockCodeSize=" << Stream.getAbbrevIDWidth() << ">\n"; 7770b57cec5SDimitry Andric } 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric SmallVector<uint64_t, 64> Record; 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric // Keep the offset to the metadata index if seen. 7820b57cec5SDimitry Andric uint64_t MetadataIndexOffset = 0; 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric // Read all the records for this block. 7850b57cec5SDimitry Andric while (1) { 7860b57cec5SDimitry Andric if (Stream.AtEndOfStream()) 7870b57cec5SDimitry Andric return reportError("Premature end of bitstream"); 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andric uint64_t RecordStartBit = Stream.GetCurrentBitNo(); 7900b57cec5SDimitry Andric 791349cc55cSDimitry Andric BitstreamEntry Entry; 792349cc55cSDimitry Andric if (Error E = Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs) 793349cc55cSDimitry Andric .moveInto(Entry)) 794349cc55cSDimitry Andric return E; 7950b57cec5SDimitry Andric 7960b57cec5SDimitry Andric switch (Entry.Kind) { 7970b57cec5SDimitry Andric case BitstreamEntry::Error: 7980b57cec5SDimitry Andric return reportError("malformed bitcode file"); 7990b57cec5SDimitry Andric case BitstreamEntry::EndBlock: { 8000b57cec5SDimitry Andric uint64_t BlockBitEnd = Stream.GetCurrentBitNo(); 8010b57cec5SDimitry Andric BlockStats.NumBits += BlockBitEnd - BlockBitStart; 8020b57cec5SDimitry Andric if (DumpRecords) { 8030b57cec5SDimitry Andric O->OS << Indent << "</"; 8040b57cec5SDimitry Andric if (BlockName) 8050b57cec5SDimitry Andric O->OS << *BlockName << ">\n"; 8060b57cec5SDimitry Andric else 8070b57cec5SDimitry Andric O->OS << "UnknownBlock" << BlockID << ">\n"; 8080b57cec5SDimitry Andric } 8090b57cec5SDimitry Andric return Error::success(); 8100b57cec5SDimitry Andric } 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andric case BitstreamEntry::SubBlock: { 8130b57cec5SDimitry Andric uint64_t SubBlockBitStart = Stream.GetCurrentBitNo(); 8140b57cec5SDimitry Andric if (Error E = parseBlock(Entry.ID, IndentLevel + 1, O, CheckHash)) 8150b57cec5SDimitry Andric return E; 8160b57cec5SDimitry Andric ++BlockStats.NumSubBlocks; 8170b57cec5SDimitry Andric uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo(); 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric // Don't include subblock sizes in the size of this block. 8200b57cec5SDimitry Andric BlockBitStart += SubBlockBitEnd - SubBlockBitStart; 8210b57cec5SDimitry Andric continue; 8220b57cec5SDimitry Andric } 8230b57cec5SDimitry Andric case BitstreamEntry::Record: 8240b57cec5SDimitry Andric // The interesting case. 8250b57cec5SDimitry Andric break; 8260b57cec5SDimitry Andric } 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andric if (Entry.ID == bitc::DEFINE_ABBREV) { 8290b57cec5SDimitry Andric if (Error Err = Stream.ReadAbbrevRecord()) 8300b57cec5SDimitry Andric return Err; 8310b57cec5SDimitry Andric ++BlockStats.NumAbbrevs; 8320b57cec5SDimitry Andric continue; 8330b57cec5SDimitry Andric } 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric Record.clear(); 8360b57cec5SDimitry Andric 8370b57cec5SDimitry Andric ++BlockStats.NumRecords; 8380b57cec5SDimitry Andric 8390b57cec5SDimitry Andric StringRef Blob; 8400b57cec5SDimitry Andric uint64_t CurrentRecordPos = Stream.GetCurrentBitNo(); 841349cc55cSDimitry Andric unsigned Code; 842349cc55cSDimitry Andric if (Error E = Stream.readRecord(Entry.ID, Record, &Blob).moveInto(Code)) 843349cc55cSDimitry Andric return E; 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andric // Increment the # occurrences of this code. 8460b57cec5SDimitry Andric if (BlockStats.CodeFreq.size() <= Code) 8470b57cec5SDimitry Andric BlockStats.CodeFreq.resize(Code + 1); 8480b57cec5SDimitry Andric BlockStats.CodeFreq[Code].NumInstances++; 8490b57cec5SDimitry Andric BlockStats.CodeFreq[Code].TotalBits += 8500b57cec5SDimitry Andric Stream.GetCurrentBitNo() - RecordStartBit; 8510b57cec5SDimitry Andric if (Entry.ID != bitc::UNABBREV_RECORD) { 8520b57cec5SDimitry Andric BlockStats.CodeFreq[Code].NumAbbrev++; 8530b57cec5SDimitry Andric ++BlockStats.NumAbbreviatedRecords; 8540b57cec5SDimitry Andric } 8550b57cec5SDimitry Andric 8560b57cec5SDimitry Andric if (DumpRecords) { 8570b57cec5SDimitry Andric O->OS << Indent << " <"; 8580b57cec5SDimitry Andric Optional<const char *> CodeName = 8590b57cec5SDimitry Andric GetCodeName(Code, BlockID, BlockInfo, CurStreamType); 8600b57cec5SDimitry Andric if (CodeName) 8610b57cec5SDimitry Andric O->OS << *CodeName; 8620b57cec5SDimitry Andric else 8630b57cec5SDimitry Andric O->OS << "UnknownCode" << Code; 8640b57cec5SDimitry Andric if (!O->Symbolic && CodeName) 8650b57cec5SDimitry Andric O->OS << " codeid=" << Code; 8660b57cec5SDimitry Andric const BitCodeAbbrev *Abbv = nullptr; 8670b57cec5SDimitry Andric if (Entry.ID != bitc::UNABBREV_RECORD) { 8680b57cec5SDimitry Andric Abbv = Stream.getAbbrev(Entry.ID); 8690b57cec5SDimitry Andric O->OS << " abbrevid=" << Entry.ID; 8700b57cec5SDimitry Andric } 8710b57cec5SDimitry Andric 8720b57cec5SDimitry Andric for (unsigned i = 0, e = Record.size(); i != e; ++i) 8730b57cec5SDimitry Andric O->OS << " op" << i << "=" << (int64_t)Record[i]; 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric // If we found a metadata index, let's verify that we had an offset 8760b57cec5SDimitry Andric // before and validate its forward reference offset was correct! 8770b57cec5SDimitry Andric if (BlockID == bitc::METADATA_BLOCK_ID) { 8780b57cec5SDimitry Andric if (Code == bitc::METADATA_INDEX_OFFSET) { 8790b57cec5SDimitry Andric if (Record.size() != 2) 8800b57cec5SDimitry Andric O->OS << "(Invalid record)"; 8810b57cec5SDimitry Andric else { 8820b57cec5SDimitry Andric auto Offset = Record[0] + (Record[1] << 32); 8830b57cec5SDimitry Andric MetadataIndexOffset = Stream.GetCurrentBitNo() + Offset; 8840b57cec5SDimitry Andric } 8850b57cec5SDimitry Andric } 8860b57cec5SDimitry Andric if (Code == bitc::METADATA_INDEX) { 8870b57cec5SDimitry Andric O->OS << " (offset "; 8880b57cec5SDimitry Andric if (MetadataIndexOffset == RecordStartBit) 8890b57cec5SDimitry Andric O->OS << "match)"; 8900b57cec5SDimitry Andric else 8910b57cec5SDimitry Andric O->OS << "mismatch: " << MetadataIndexOffset << " vs " 8920b57cec5SDimitry Andric << RecordStartBit << ")"; 8930b57cec5SDimitry Andric } 8940b57cec5SDimitry Andric } 8950b57cec5SDimitry Andric 8960b57cec5SDimitry Andric // If we found a module hash, let's verify that it matches! 8970b57cec5SDimitry Andric if (BlockID == bitc::MODULE_BLOCK_ID && Code == bitc::MODULE_CODE_HASH && 8980b57cec5SDimitry Andric CheckHash.hasValue()) { 8990b57cec5SDimitry Andric if (Record.size() != 5) 9000b57cec5SDimitry Andric O->OS << " (invalid)"; 9010b57cec5SDimitry Andric else { 9020b57cec5SDimitry Andric // Recompute the hash and compare it to the one in the bitcode 9030b57cec5SDimitry Andric SHA1 Hasher; 9040b57cec5SDimitry Andric StringRef Hash; 9050b57cec5SDimitry Andric Hasher.update(*CheckHash); 9060b57cec5SDimitry Andric { 9070b57cec5SDimitry Andric int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos; 9080b57cec5SDimitry Andric auto Ptr = Stream.getPointerToByte(BlockEntryPos, BlockSize); 9090b57cec5SDimitry Andric Hasher.update(ArrayRef<uint8_t>(Ptr, BlockSize)); 9100b57cec5SDimitry Andric Hash = Hasher.result(); 9110b57cec5SDimitry Andric } 9125ffd83dbSDimitry Andric std::array<char, 20> RecordedHash; 9130b57cec5SDimitry Andric int Pos = 0; 9140b57cec5SDimitry Andric for (auto &Val : Record) { 9150b57cec5SDimitry Andric assert(!(Val >> 32) && "Unexpected high bits set"); 9165ffd83dbSDimitry Andric support::endian::write32be(&RecordedHash[Pos], Val); 9175ffd83dbSDimitry Andric Pos += 4; 9180b57cec5SDimitry Andric } 9195ffd83dbSDimitry Andric if (Hash == StringRef(RecordedHash.data(), RecordedHash.size())) 9200b57cec5SDimitry Andric O->OS << " (match)"; 9210b57cec5SDimitry Andric else 9220b57cec5SDimitry Andric O->OS << " (!mismatch!)"; 9230b57cec5SDimitry Andric } 9240b57cec5SDimitry Andric } 9250b57cec5SDimitry Andric 9260b57cec5SDimitry Andric O->OS << "/>"; 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric if (Abbv) { 9290b57cec5SDimitry Andric for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) { 9300b57cec5SDimitry Andric const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); 9310b57cec5SDimitry Andric if (!Op.isEncoding() || Op.getEncoding() != BitCodeAbbrevOp::Array) 9320b57cec5SDimitry Andric continue; 9330b57cec5SDimitry Andric assert(i + 2 == e && "Array op not second to last"); 9340b57cec5SDimitry Andric std::string Str; 9350b57cec5SDimitry Andric bool ArrayIsPrintable = true; 9360b57cec5SDimitry Andric for (unsigned j = i - 1, je = Record.size(); j != je; ++j) { 9370b57cec5SDimitry Andric if (!isPrint(static_cast<unsigned char>(Record[j]))) { 9380b57cec5SDimitry Andric ArrayIsPrintable = false; 9390b57cec5SDimitry Andric break; 9400b57cec5SDimitry Andric } 9410b57cec5SDimitry Andric Str += (char)Record[j]; 9420b57cec5SDimitry Andric } 9430b57cec5SDimitry Andric if (ArrayIsPrintable) 9440b57cec5SDimitry Andric O->OS << " record string = '" << Str << "'"; 9450b57cec5SDimitry Andric break; 9460b57cec5SDimitry Andric } 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric if (Blob.data()) { 9500b57cec5SDimitry Andric if (canDecodeBlob(Code, BlockID)) { 9510b57cec5SDimitry Andric if (Error E = decodeMetadataStringsBlob(Indent, Record, Blob, O->OS)) 9520b57cec5SDimitry Andric return E; 9530b57cec5SDimitry Andric } else { 9540b57cec5SDimitry Andric O->OS << " blob data = "; 9550b57cec5SDimitry Andric if (O->ShowBinaryBlobs) { 9560b57cec5SDimitry Andric O->OS << "'"; 9570b57cec5SDimitry Andric O->OS.write_escaped(Blob, /*hex=*/true) << "'"; 9580b57cec5SDimitry Andric } else { 9590b57cec5SDimitry Andric bool BlobIsPrintable = true; 960*4824e7fdSDimitry Andric for (char C : Blob) 961*4824e7fdSDimitry Andric if (!isPrint(static_cast<unsigned char>(C))) { 9620b57cec5SDimitry Andric BlobIsPrintable = false; 9630b57cec5SDimitry Andric break; 9640b57cec5SDimitry Andric } 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric if (BlobIsPrintable) 9670b57cec5SDimitry Andric O->OS << "'" << Blob << "'"; 9680b57cec5SDimitry Andric else 9690b57cec5SDimitry Andric O->OS << "unprintable, " << Blob.size() << " bytes."; 9700b57cec5SDimitry Andric } 9710b57cec5SDimitry Andric } 9720b57cec5SDimitry Andric } 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andric O->OS << "\n"; 9750b57cec5SDimitry Andric } 9760b57cec5SDimitry Andric 9770b57cec5SDimitry Andric // Make sure that we can skip the current record. 9780b57cec5SDimitry Andric if (Error Err = Stream.JumpToBit(CurrentRecordPos)) 9790b57cec5SDimitry Andric return Err; 9800b57cec5SDimitry Andric if (Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) 9810b57cec5SDimitry Andric ; // Do nothing. 9820b57cec5SDimitry Andric else 9830b57cec5SDimitry Andric return Skipped.takeError(); 9840b57cec5SDimitry Andric } 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric 987