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)) { 1100eae32dcSDimitry Andric for (const std::pair<unsigned, std::string> &RN : Info->RecordNames) 1110eae32dcSDimitry Andric if (RN.first == CodeID) 1120eae32dcSDimitry Andric return RN.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) 2220eae32dcSDimitry Andric STRINGIFY_CODE(CST_CODE, NO_CFI_VALUE) 2230b57cec5SDimitry Andric case bitc::CST_CODE_BLOCKADDRESS: 2240b57cec5SDimitry Andric return "CST_CODE_BLOCKADDRESS"; 2250b57cec5SDimitry Andric STRINGIFY_CODE(CST_CODE, DATA) 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric case bitc::FUNCTION_BLOCK_ID: 2280b57cec5SDimitry Andric switch (CodeID) { 2290b57cec5SDimitry Andric default: 2300b57cec5SDimitry Andric return None; 2310b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, DECLAREBLOCKS) 2320b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_BINOP) 2330b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CAST) 2340b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_GEP_OLD) 2350b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_INBOUNDS_GEP_OLD) 2360b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_SELECT) 2370b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTELT) 2380b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_INSERTELT) 2390b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_SHUFFLEVEC) 2400b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CMP) 2410b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_RET) 2420b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_BR) 2430b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_SWITCH) 2440b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_INVOKE) 2450b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_UNOP) 2460b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE) 2470b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET) 2480b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET) 2490b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CATCHPAD) 2500b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_PHI) 2510b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_ALLOCA) 2520b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_LOAD) 2530b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_VAARG) 2540b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_STORE) 2550b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTVAL) 2560b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_INSERTVAL) 2570b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CMP2) 2580b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_VSELECT) 2590b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC_AGAIN) 2600b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CALL) 2610b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC) 2620b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_GEP) 2630b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, OPERAND_BUNDLE) 2640b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_FENCE) 2650b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_ATOMICRMW) 2660b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_LOADATOMIC) 2670b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_STOREATOMIC) 2680b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CMPXCHG) 2690b57cec5SDimitry Andric STRINGIFY_CODE(FUNC_CODE, INST_CALLBR) 270*81ad6265SDimitry Andric STRINGIFY_CODE(FUNC_CODE, BLOCKADDR_USERS) 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric case bitc::VALUE_SYMTAB_BLOCK_ID: 2730b57cec5SDimitry Andric switch (CodeID) { 2740b57cec5SDimitry Andric default: 2750b57cec5SDimitry Andric return None; 2760b57cec5SDimitry Andric STRINGIFY_CODE(VST_CODE, ENTRY) 2770b57cec5SDimitry Andric STRINGIFY_CODE(VST_CODE, BBENTRY) 2780b57cec5SDimitry Andric STRINGIFY_CODE(VST_CODE, FNENTRY) 2790b57cec5SDimitry Andric STRINGIFY_CODE(VST_CODE, COMBINED_ENTRY) 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric case bitc::MODULE_STRTAB_BLOCK_ID: 2820b57cec5SDimitry Andric switch (CodeID) { 2830b57cec5SDimitry Andric default: 2840b57cec5SDimitry Andric return None; 2850b57cec5SDimitry Andric STRINGIFY_CODE(MST_CODE, ENTRY) 2860b57cec5SDimitry Andric STRINGIFY_CODE(MST_CODE, HASH) 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: 2890b57cec5SDimitry Andric case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: 2900b57cec5SDimitry Andric switch (CodeID) { 2910b57cec5SDimitry Andric default: 2920b57cec5SDimitry Andric return None; 2930b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE) 2940b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE_PROFILE) 2950b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE_RELBF) 2960b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE_GLOBALVAR_INIT_REFS) 2970b57cec5SDimitry Andric STRINGIFY_CODE(FS, PERMODULE_VTABLE_GLOBALVAR_INIT_REFS) 2980b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED) 2990b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED_PROFILE) 3000b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED_GLOBALVAR_INIT_REFS) 3010b57cec5SDimitry Andric STRINGIFY_CODE(FS, ALIAS) 3020b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED_ALIAS) 3030b57cec5SDimitry Andric STRINGIFY_CODE(FS, COMBINED_ORIGINAL_NAME) 3040b57cec5SDimitry Andric STRINGIFY_CODE(FS, VERSION) 3050b57cec5SDimitry Andric STRINGIFY_CODE(FS, FLAGS) 3060b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_TESTS) 3070b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_VCALLS) 3080b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_VCALLS) 3090b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_CONST_VCALL) 3100b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_CONST_VCALL) 3110b57cec5SDimitry Andric STRINGIFY_CODE(FS, VALUE_GUID) 3120b57cec5SDimitry Andric STRINGIFY_CODE(FS, CFI_FUNCTION_DEFS) 3130b57cec5SDimitry Andric STRINGIFY_CODE(FS, CFI_FUNCTION_DECLS) 3140b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_ID) 3150b57cec5SDimitry Andric STRINGIFY_CODE(FS, TYPE_ID_METADATA) 3165ffd83dbSDimitry Andric STRINGIFY_CODE(FS, BLOCK_COUNT) 3175ffd83dbSDimitry Andric STRINGIFY_CODE(FS, PARAM_ACCESS) 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric case bitc::METADATA_ATTACHMENT_ID: 3200b57cec5SDimitry Andric switch (CodeID) { 3210b57cec5SDimitry Andric default: 3220b57cec5SDimitry Andric return None; 3230b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, ATTACHMENT) 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric case bitc::METADATA_BLOCK_ID: 3260b57cec5SDimitry Andric switch (CodeID) { 3270b57cec5SDimitry Andric default: 3280b57cec5SDimitry Andric return None; 3290b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, STRING_OLD) 3300b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, VALUE) 3310b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, NODE) 3320b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, NAME) 3330b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, DISTINCT_NODE) 3340b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, KIND) // Older bitcode has it in a MODULE_BLOCK 3350b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, LOCATION) 3360b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, OLD_NODE) 3370b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, OLD_FN_NODE) 3380b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, NAMED_NODE) 3390b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, GENERIC_DEBUG) 3400b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, SUBRANGE) 3410b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, ENUMERATOR) 3420b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, BASIC_TYPE) 3430b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, FILE) 3440b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, DERIVED_TYPE) 3450b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, COMPOSITE_TYPE) 3460b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, SUBROUTINE_TYPE) 3470b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, COMPILE_UNIT) 3480b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, SUBPROGRAM) 3490b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, LEXICAL_BLOCK) 3500b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, LEXICAL_BLOCK_FILE) 3510b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, NAMESPACE) 3520b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, TEMPLATE_TYPE) 3530b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, TEMPLATE_VALUE) 3540b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, GLOBAL_VAR) 3550b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, LOCAL_VAR) 3560b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, EXPRESSION) 3570b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, OBJC_PROPERTY) 3580b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, IMPORTED_ENTITY) 3590b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, MODULE) 3600b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, MACRO) 3610b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, MACRO_FILE) 3620b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, STRINGS) 3630b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, GLOBAL_DECL_ATTACHMENT) 3640b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, GLOBAL_VAR_EXPR) 3650b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, INDEX_OFFSET) 3660b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, INDEX) 367fe6060f1SDimitry Andric STRINGIFY_CODE(METADATA, ARG_LIST) 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric case bitc::METADATA_KIND_BLOCK_ID: 3700b57cec5SDimitry Andric switch (CodeID) { 3710b57cec5SDimitry Andric default: 3720b57cec5SDimitry Andric return None; 3730b57cec5SDimitry Andric STRINGIFY_CODE(METADATA, KIND) 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric case bitc::USELIST_BLOCK_ID: 3760b57cec5SDimitry Andric switch (CodeID) { 3770b57cec5SDimitry Andric default: 3780b57cec5SDimitry Andric return None; 3790b57cec5SDimitry Andric case bitc::USELIST_CODE_DEFAULT: 3800b57cec5SDimitry Andric return "USELIST_CODE_DEFAULT"; 3810b57cec5SDimitry Andric case bitc::USELIST_CODE_BB: 3820b57cec5SDimitry Andric return "USELIST_CODE_BB"; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: 3860b57cec5SDimitry Andric switch (CodeID) { 3870b57cec5SDimitry Andric default: 3880b57cec5SDimitry Andric return None; 3890b57cec5SDimitry Andric case bitc::OPERAND_BUNDLE_TAG: 3900b57cec5SDimitry Andric return "OPERAND_BUNDLE_TAG"; 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric case bitc::STRTAB_BLOCK_ID: 3930b57cec5SDimitry Andric switch (CodeID) { 3940b57cec5SDimitry Andric default: 3950b57cec5SDimitry Andric return None; 3960b57cec5SDimitry Andric case bitc::STRTAB_BLOB: 3970b57cec5SDimitry Andric return "BLOB"; 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric case bitc::SYMTAB_BLOCK_ID: 4000b57cec5SDimitry Andric switch (CodeID) { 4010b57cec5SDimitry Andric default: 4020b57cec5SDimitry Andric return None; 4030b57cec5SDimitry Andric case bitc::SYMTAB_BLOB: 4040b57cec5SDimitry Andric return "BLOB"; 4050b57cec5SDimitry Andric } 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric #undef STRINGIFY_CODE 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric static void printSize(raw_ostream &OS, double Bits) { 4110b57cec5SDimitry Andric OS << format("%.2f/%.2fB/%luW", Bits, Bits / 8, (unsigned long)(Bits / 32)); 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric static void printSize(raw_ostream &OS, uint64_t Bits) { 4140b57cec5SDimitry Andric OS << format("%lub/%.2fB/%luW", (unsigned long)Bits, (double)Bits / 8, 4150b57cec5SDimitry Andric (unsigned long)(Bits / 32)); 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric static Expected<CurStreamTypeType> ReadSignature(BitstreamCursor &Stream) { 4190b57cec5SDimitry Andric auto tryRead = [&Stream](char &Dest, size_t size) -> Error { 4200b57cec5SDimitry Andric if (Expected<SimpleBitstreamCursor::word_t> MaybeWord = Stream.Read(size)) 4210b57cec5SDimitry Andric Dest = MaybeWord.get(); 4220b57cec5SDimitry Andric else 4230b57cec5SDimitry Andric return MaybeWord.takeError(); 4240b57cec5SDimitry Andric return Error::success(); 4250b57cec5SDimitry Andric }; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric char Signature[6]; 4280b57cec5SDimitry Andric if (Error Err = tryRead(Signature[0], 8)) 4290b57cec5SDimitry Andric return std::move(Err); 4300b57cec5SDimitry Andric if (Error Err = tryRead(Signature[1], 8)) 4310b57cec5SDimitry Andric return std::move(Err); 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric // Autodetect the file contents, if it is one we know. 4340b57cec5SDimitry Andric if (Signature[0] == 'C' && Signature[1] == 'P') { 4350b57cec5SDimitry Andric if (Error Err = tryRead(Signature[2], 8)) 4360b57cec5SDimitry Andric return std::move(Err); 4370b57cec5SDimitry Andric if (Error Err = tryRead(Signature[3], 8)) 4380b57cec5SDimitry Andric return std::move(Err); 4390b57cec5SDimitry Andric if (Signature[2] == 'C' && Signature[3] == 'H') 4400b57cec5SDimitry Andric return ClangSerializedASTBitstream; 4410b57cec5SDimitry Andric } else if (Signature[0] == 'D' && Signature[1] == 'I') { 4420b57cec5SDimitry Andric if (Error Err = tryRead(Signature[2], 8)) 4430b57cec5SDimitry Andric return std::move(Err); 4440b57cec5SDimitry Andric if (Error Err = tryRead(Signature[3], 8)) 4450b57cec5SDimitry Andric return std::move(Err); 4460b57cec5SDimitry Andric if (Signature[2] == 'A' && Signature[3] == 'G') 4470b57cec5SDimitry Andric return ClangSerializedDiagnosticsBitstream; 4488bcb0991SDimitry Andric } else if (Signature[0] == 'R' && Signature[1] == 'M') { 4498bcb0991SDimitry Andric if (Error Err = tryRead(Signature[2], 8)) 4508bcb0991SDimitry Andric return std::move(Err); 4518bcb0991SDimitry Andric if (Error Err = tryRead(Signature[3], 8)) 4528bcb0991SDimitry Andric return std::move(Err); 4538bcb0991SDimitry Andric if (Signature[2] == 'R' && Signature[3] == 'K') 4548bcb0991SDimitry Andric return LLVMBitstreamRemarks; 4550b57cec5SDimitry Andric } else { 4560b57cec5SDimitry Andric if (Error Err = tryRead(Signature[2], 4)) 4570b57cec5SDimitry Andric return std::move(Err); 4580b57cec5SDimitry Andric if (Error Err = tryRead(Signature[3], 4)) 4590b57cec5SDimitry Andric return std::move(Err); 4600b57cec5SDimitry Andric if (Error Err = tryRead(Signature[4], 4)) 4610b57cec5SDimitry Andric return std::move(Err); 4620b57cec5SDimitry Andric if (Error Err = tryRead(Signature[5], 4)) 4630b57cec5SDimitry Andric return std::move(Err); 4640b57cec5SDimitry Andric if (Signature[0] == 'B' && Signature[1] == 'C' && Signature[2] == 0x0 && 4650b57cec5SDimitry Andric Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD) 4660b57cec5SDimitry Andric return LLVMIRBitstream; 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric return UnknownBitstream; 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric static Expected<CurStreamTypeType> analyzeHeader(Optional<BCDumpOptions> O, 4720b57cec5SDimitry Andric BitstreamCursor &Stream) { 4730b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes = Stream.getBitcodeBytes(); 4740b57cec5SDimitry Andric const unsigned char *BufPtr = (const unsigned char *)Bytes.data(); 4750b57cec5SDimitry Andric const unsigned char *EndBufPtr = BufPtr + Bytes.size(); 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric // If we have a wrapper header, parse it and ignore the non-bc file 4780b57cec5SDimitry Andric // contents. The magic number is 0x0B17C0DE stored in little endian. 4790b57cec5SDimitry Andric if (isBitcodeWrapper(BufPtr, EndBufPtr)) { 4800b57cec5SDimitry Andric if (Bytes.size() < BWH_HeaderSize) 4810b57cec5SDimitry Andric return reportError("Invalid bitcode wrapper header"); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric if (O) { 4840b57cec5SDimitry Andric unsigned Magic = support::endian::read32le(&BufPtr[BWH_MagicField]); 4850b57cec5SDimitry Andric unsigned Version = support::endian::read32le(&BufPtr[BWH_VersionField]); 4860b57cec5SDimitry Andric unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]); 4870b57cec5SDimitry Andric unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]); 4880b57cec5SDimitry Andric unsigned CPUType = support::endian::read32le(&BufPtr[BWH_CPUTypeField]); 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric O->OS << "<BITCODE_WRAPPER_HEADER" 4910b57cec5SDimitry Andric << " Magic=" << format_hex(Magic, 10) 4920b57cec5SDimitry Andric << " Version=" << format_hex(Version, 10) 4930b57cec5SDimitry Andric << " Offset=" << format_hex(Offset, 10) 4940b57cec5SDimitry Andric << " Size=" << format_hex(Size, 10) 4950b57cec5SDimitry Andric << " CPUType=" << format_hex(CPUType, 10) << "/>\n"; 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) 4990b57cec5SDimitry Andric return reportError("Invalid bitcode wrapper header"); 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric // Use the cursor modified by skipping the wrapper header. 5030b57cec5SDimitry Andric Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, EndBufPtr)); 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric return ReadSignature(Stream); 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric static bool canDecodeBlob(unsigned Code, unsigned BlockID) { 5090b57cec5SDimitry Andric return BlockID == bitc::METADATA_BLOCK_ID && Code == bitc::METADATA_STRINGS; 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric Error BitcodeAnalyzer::decodeMetadataStringsBlob(StringRef Indent, 5130b57cec5SDimitry Andric ArrayRef<uint64_t> Record, 5140b57cec5SDimitry Andric StringRef Blob, 5150b57cec5SDimitry Andric raw_ostream &OS) { 5160b57cec5SDimitry Andric if (Blob.empty()) 5170b57cec5SDimitry Andric return reportError("Cannot decode empty blob."); 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric if (Record.size() != 2) 5200b57cec5SDimitry Andric return reportError( 5210b57cec5SDimitry Andric "Decoding metadata strings blob needs two record entries."); 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric unsigned NumStrings = Record[0]; 5240b57cec5SDimitry Andric unsigned StringsOffset = Record[1]; 5250b57cec5SDimitry Andric OS << " num-strings = " << NumStrings << " {\n"; 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric StringRef Lengths = Blob.slice(0, StringsOffset); 5280b57cec5SDimitry Andric SimpleBitstreamCursor R(Lengths); 5290b57cec5SDimitry Andric StringRef Strings = Blob.drop_front(StringsOffset); 5300b57cec5SDimitry Andric do { 5310b57cec5SDimitry Andric if (R.AtEndOfStream()) 5320b57cec5SDimitry Andric return reportError("bad length"); 5330b57cec5SDimitry Andric 534349cc55cSDimitry Andric uint32_t Size; 535349cc55cSDimitry Andric if (Error E = R.ReadVBR(6).moveInto(Size)) 536349cc55cSDimitry Andric return E; 5370b57cec5SDimitry Andric if (Strings.size() < Size) 5380b57cec5SDimitry Andric return reportError("truncated chars"); 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric OS << Indent << " '"; 5410b57cec5SDimitry Andric OS.write_escaped(Strings.slice(0, Size), /*hex=*/true); 5420b57cec5SDimitry Andric OS << "'\n"; 5430b57cec5SDimitry Andric Strings = Strings.drop_front(Size); 5440b57cec5SDimitry Andric } while (--NumStrings); 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric OS << Indent << " }"; 5470b57cec5SDimitry Andric return Error::success(); 5480b57cec5SDimitry Andric } 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric BitcodeAnalyzer::BitcodeAnalyzer(StringRef Buffer, 5510b57cec5SDimitry Andric Optional<StringRef> BlockInfoBuffer) 5520b57cec5SDimitry Andric : Stream(Buffer) { 5530b57cec5SDimitry Andric if (BlockInfoBuffer) 5540b57cec5SDimitry Andric BlockInfoStream.emplace(*BlockInfoBuffer); 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric Error BitcodeAnalyzer::analyze(Optional<BCDumpOptions> O, 5580b57cec5SDimitry Andric Optional<StringRef> CheckHash) { 559349cc55cSDimitry Andric if (Error E = analyzeHeader(O, Stream).moveInto(CurStreamType)) 560349cc55cSDimitry Andric return E; 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric Stream.setBlockInfo(&BlockInfo); 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric // Read block info from BlockInfoStream, if specified. 5650b57cec5SDimitry Andric // The block info must be a top-level block. 5660b57cec5SDimitry Andric if (BlockInfoStream) { 5670b57cec5SDimitry Andric BitstreamCursor BlockInfoCursor(*BlockInfoStream); 568349cc55cSDimitry Andric if (Error E = analyzeHeader(O, BlockInfoCursor).takeError()) 569349cc55cSDimitry Andric return E; 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric while (!BlockInfoCursor.AtEndOfStream()) { 5720b57cec5SDimitry Andric Expected<unsigned> MaybeCode = BlockInfoCursor.ReadCode(); 5730b57cec5SDimitry Andric if (!MaybeCode) 5740b57cec5SDimitry Andric return MaybeCode.takeError(); 5750b57cec5SDimitry Andric if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) 5760b57cec5SDimitry Andric return reportError("Invalid record at top-level in block info file"); 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric Expected<unsigned> MaybeBlockID = BlockInfoCursor.ReadSubBlockID(); 5790b57cec5SDimitry Andric if (!MaybeBlockID) 5800b57cec5SDimitry Andric return MaybeBlockID.takeError(); 5810b57cec5SDimitry Andric if (MaybeBlockID.get() == bitc::BLOCKINFO_BLOCK_ID) { 582349cc55cSDimitry Andric Optional<BitstreamBlockInfo> NewBlockInfo; 583349cc55cSDimitry Andric if (Error E = 584349cc55cSDimitry Andric BlockInfoCursor.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true) 585349cc55cSDimitry Andric .moveInto(NewBlockInfo)) 586349cc55cSDimitry Andric return E; 5870b57cec5SDimitry Andric if (!NewBlockInfo) 5880b57cec5SDimitry Andric return reportError("Malformed BlockInfoBlock in block info file"); 5890b57cec5SDimitry Andric BlockInfo = std::move(*NewBlockInfo); 5900b57cec5SDimitry Andric break; 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric if (Error Err = BlockInfoCursor.SkipBlock()) 5940b57cec5SDimitry Andric return Err; 5950b57cec5SDimitry Andric } 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric // Parse the top-level structure. We only allow blocks at the top-level. 5990b57cec5SDimitry Andric while (!Stream.AtEndOfStream()) { 6000b57cec5SDimitry Andric Expected<unsigned> MaybeCode = Stream.ReadCode(); 6010b57cec5SDimitry Andric if (!MaybeCode) 6020b57cec5SDimitry Andric return MaybeCode.takeError(); 6030b57cec5SDimitry Andric if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) 6040b57cec5SDimitry Andric return reportError("Invalid record at top-level"); 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric Expected<unsigned> MaybeBlockID = Stream.ReadSubBlockID(); 6070b57cec5SDimitry Andric if (!MaybeBlockID) 6080b57cec5SDimitry Andric return MaybeBlockID.takeError(); 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric if (Error E = parseBlock(MaybeBlockID.get(), 0, O, CheckHash)) 6110b57cec5SDimitry Andric return E; 6120b57cec5SDimitry Andric ++NumTopBlocks; 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric return Error::success(); 6160b57cec5SDimitry Andric } 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric void BitcodeAnalyzer::printStats(BCDumpOptions O, 6190b57cec5SDimitry Andric Optional<StringRef> Filename) { 6200b57cec5SDimitry Andric uint64_t BufferSizeBits = Stream.getBitcodeBytes().size() * CHAR_BIT; 6210b57cec5SDimitry Andric // Print a summary of the read file. 6220b57cec5SDimitry Andric O.OS << "Summary "; 6230b57cec5SDimitry Andric if (Filename) 6240b57cec5SDimitry Andric O.OS << "of " << Filename->data() << ":\n"; 6250b57cec5SDimitry Andric O.OS << " Total size: "; 6260b57cec5SDimitry Andric printSize(O.OS, BufferSizeBits); 6270b57cec5SDimitry Andric O.OS << "\n"; 6280b57cec5SDimitry Andric O.OS << " Stream type: "; 6290b57cec5SDimitry Andric switch (CurStreamType) { 6300b57cec5SDimitry Andric case UnknownBitstream: 6310b57cec5SDimitry Andric O.OS << "unknown\n"; 6320b57cec5SDimitry Andric break; 6330b57cec5SDimitry Andric case LLVMIRBitstream: 6340b57cec5SDimitry Andric O.OS << "LLVM IR\n"; 6350b57cec5SDimitry Andric break; 6360b57cec5SDimitry Andric case ClangSerializedASTBitstream: 6370b57cec5SDimitry Andric O.OS << "Clang Serialized AST\n"; 6380b57cec5SDimitry Andric break; 6390b57cec5SDimitry Andric case ClangSerializedDiagnosticsBitstream: 6400b57cec5SDimitry Andric O.OS << "Clang Serialized Diagnostics\n"; 6410b57cec5SDimitry Andric break; 6428bcb0991SDimitry Andric case LLVMBitstreamRemarks: 6438bcb0991SDimitry Andric O.OS << "LLVM Remarks\n"; 6448bcb0991SDimitry Andric break; 6450b57cec5SDimitry Andric } 6460b57cec5SDimitry Andric O.OS << " # Toplevel Blocks: " << NumTopBlocks << "\n"; 6470b57cec5SDimitry Andric O.OS << "\n"; 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric // Emit per-block stats. 6500b57cec5SDimitry Andric O.OS << "Per-block Summary:\n"; 6510eae32dcSDimitry Andric for (const auto &Stat : BlockIDStats) { 6520eae32dcSDimitry Andric O.OS << " Block ID #" << Stat.first; 6530b57cec5SDimitry Andric if (Optional<const char *> BlockName = 6540eae32dcSDimitry Andric GetBlockName(Stat.first, BlockInfo, CurStreamType)) 6550b57cec5SDimitry Andric O.OS << " (" << *BlockName << ")"; 6560b57cec5SDimitry Andric O.OS << ":\n"; 6570b57cec5SDimitry Andric 6580eae32dcSDimitry Andric const PerBlockIDStats &Stats = Stat.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"; 6970eae32dcSDimitry Andric for (const auto &FreqPair : FreqPairs) { 6980eae32dcSDimitry Andric const PerRecordStats &RecStats = Stats.CodeFreq[FreqPair.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( 7170eae32dcSDimitry Andric FreqPair.second, Stat.first, BlockInfo, CurStreamType)) 7180b57cec5SDimitry Andric O.OS << *CodeName << "\n"; 7190b57cec5SDimitry Andric else 7200eae32dcSDimitry Andric O.OS << "UnknownCode" << FreqPair.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. 739*81ad6265SDimitry Andric bool DumpRecords = O.has_value(); 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. 78504eeddc0SDimitry Andric while (true) { 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) { 868*81ad6265SDimitry Andric Expected<const BitCodeAbbrev *> MaybeAbbv = Stream.getAbbrev(Entry.ID); 869*81ad6265SDimitry Andric if (!MaybeAbbv) 870*81ad6265SDimitry Andric return MaybeAbbv.takeError(); 871*81ad6265SDimitry Andric Abbv = MaybeAbbv.get(); 8720b57cec5SDimitry Andric O->OS << " abbrevid=" << Entry.ID; 8730b57cec5SDimitry Andric } 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric for (unsigned i = 0, e = Record.size(); i != e; ++i) 8760b57cec5SDimitry Andric O->OS << " op" << i << "=" << (int64_t)Record[i]; 8770b57cec5SDimitry Andric 8780b57cec5SDimitry Andric // If we found a metadata index, let's verify that we had an offset 8790b57cec5SDimitry Andric // before and validate its forward reference offset was correct! 8800b57cec5SDimitry Andric if (BlockID == bitc::METADATA_BLOCK_ID) { 8810b57cec5SDimitry Andric if (Code == bitc::METADATA_INDEX_OFFSET) { 8820b57cec5SDimitry Andric if (Record.size() != 2) 8830b57cec5SDimitry Andric O->OS << "(Invalid record)"; 8840b57cec5SDimitry Andric else { 8850b57cec5SDimitry Andric auto Offset = Record[0] + (Record[1] << 32); 8860b57cec5SDimitry Andric MetadataIndexOffset = Stream.GetCurrentBitNo() + Offset; 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric if (Code == bitc::METADATA_INDEX) { 8900b57cec5SDimitry Andric O->OS << " (offset "; 8910b57cec5SDimitry Andric if (MetadataIndexOffset == RecordStartBit) 8920b57cec5SDimitry Andric O->OS << "match)"; 8930b57cec5SDimitry Andric else 8940b57cec5SDimitry Andric O->OS << "mismatch: " << MetadataIndexOffset << " vs " 8950b57cec5SDimitry Andric << RecordStartBit << ")"; 8960b57cec5SDimitry Andric } 8970b57cec5SDimitry Andric } 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric // If we found a module hash, let's verify that it matches! 9000b57cec5SDimitry Andric if (BlockID == bitc::MODULE_BLOCK_ID && Code == bitc::MODULE_CODE_HASH && 901*81ad6265SDimitry Andric CheckHash) { 9020b57cec5SDimitry Andric if (Record.size() != 5) 9030b57cec5SDimitry Andric O->OS << " (invalid)"; 9040b57cec5SDimitry Andric else { 9050b57cec5SDimitry Andric // Recompute the hash and compare it to the one in the bitcode 9060b57cec5SDimitry Andric SHA1 Hasher; 907*81ad6265SDimitry Andric std::array<uint8_t, 20> Hash; 9080b57cec5SDimitry Andric Hasher.update(*CheckHash); 9090b57cec5SDimitry Andric { 9100b57cec5SDimitry Andric int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos; 9110b57cec5SDimitry Andric auto Ptr = Stream.getPointerToByte(BlockEntryPos, BlockSize); 9120b57cec5SDimitry Andric Hasher.update(ArrayRef<uint8_t>(Ptr, BlockSize)); 9130b57cec5SDimitry Andric Hash = Hasher.result(); 9140b57cec5SDimitry Andric } 915*81ad6265SDimitry Andric std::array<uint8_t, 20> RecordedHash; 9160b57cec5SDimitry Andric int Pos = 0; 9170b57cec5SDimitry Andric for (auto &Val : Record) { 9180b57cec5SDimitry Andric assert(!(Val >> 32) && "Unexpected high bits set"); 9195ffd83dbSDimitry Andric support::endian::write32be(&RecordedHash[Pos], Val); 9205ffd83dbSDimitry Andric Pos += 4; 9210b57cec5SDimitry Andric } 922*81ad6265SDimitry Andric if (Hash == RecordedHash) 9230b57cec5SDimitry Andric O->OS << " (match)"; 9240b57cec5SDimitry Andric else 9250b57cec5SDimitry Andric O->OS << " (!mismatch!)"; 9260b57cec5SDimitry Andric } 9270b57cec5SDimitry Andric } 9280b57cec5SDimitry Andric 9290b57cec5SDimitry Andric O->OS << "/>"; 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric if (Abbv) { 9320b57cec5SDimitry Andric for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) { 9330b57cec5SDimitry Andric const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); 9340b57cec5SDimitry Andric if (!Op.isEncoding() || Op.getEncoding() != BitCodeAbbrevOp::Array) 9350b57cec5SDimitry Andric continue; 9360b57cec5SDimitry Andric assert(i + 2 == e && "Array op not second to last"); 9370b57cec5SDimitry Andric std::string Str; 9380b57cec5SDimitry Andric bool ArrayIsPrintable = true; 9390b57cec5SDimitry Andric for (unsigned j = i - 1, je = Record.size(); j != je; ++j) { 9400b57cec5SDimitry Andric if (!isPrint(static_cast<unsigned char>(Record[j]))) { 9410b57cec5SDimitry Andric ArrayIsPrintable = false; 9420b57cec5SDimitry Andric break; 9430b57cec5SDimitry Andric } 9440b57cec5SDimitry Andric Str += (char)Record[j]; 9450b57cec5SDimitry Andric } 9460b57cec5SDimitry Andric if (ArrayIsPrintable) 9470b57cec5SDimitry Andric O->OS << " record string = '" << Str << "'"; 9480b57cec5SDimitry Andric break; 9490b57cec5SDimitry Andric } 9500b57cec5SDimitry Andric } 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andric if (Blob.data()) { 9530b57cec5SDimitry Andric if (canDecodeBlob(Code, BlockID)) { 9540b57cec5SDimitry Andric if (Error E = decodeMetadataStringsBlob(Indent, Record, Blob, O->OS)) 9550b57cec5SDimitry Andric return E; 9560b57cec5SDimitry Andric } else { 9570b57cec5SDimitry Andric O->OS << " blob data = "; 9580b57cec5SDimitry Andric if (O->ShowBinaryBlobs) { 9590b57cec5SDimitry Andric O->OS << "'"; 9600b57cec5SDimitry Andric O->OS.write_escaped(Blob, /*hex=*/true) << "'"; 9610b57cec5SDimitry Andric } else { 9620b57cec5SDimitry Andric bool BlobIsPrintable = true; 9634824e7fdSDimitry Andric for (char C : Blob) 9644824e7fdSDimitry Andric if (!isPrint(static_cast<unsigned char>(C))) { 9650b57cec5SDimitry Andric BlobIsPrintable = false; 9660b57cec5SDimitry Andric break; 9670b57cec5SDimitry Andric } 9680b57cec5SDimitry Andric 9690b57cec5SDimitry Andric if (BlobIsPrintable) 9700b57cec5SDimitry Andric O->OS << "'" << Blob << "'"; 9710b57cec5SDimitry Andric else 9720b57cec5SDimitry Andric O->OS << "unprintable, " << Blob.size() << " bytes."; 9730b57cec5SDimitry Andric } 9740b57cec5SDimitry Andric } 9750b57cec5SDimitry Andric } 9760b57cec5SDimitry Andric 9770b57cec5SDimitry Andric O->OS << "\n"; 9780b57cec5SDimitry Andric } 9790b57cec5SDimitry Andric 9800b57cec5SDimitry Andric // Make sure that we can skip the current record. 9810b57cec5SDimitry Andric if (Error Err = Stream.JumpToBit(CurrentRecordPos)) 9820b57cec5SDimitry Andric return Err; 9830b57cec5SDimitry Andric if (Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) 9840b57cec5SDimitry Andric ; // Do nothing. 9850b57cec5SDimitry Andric else 9860b57cec5SDimitry Andric return Skipped.takeError(); 9870b57cec5SDimitry Andric } 9880b57cec5SDimitry Andric } 9890b57cec5SDimitry Andric 990