1ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman//===-- ModuleDebugInfoPrinter.cpp - Prints module debug info metadata ----===// 2ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// 3ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// The LLVM Compiler Infrastructure 4ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// 5ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// This file is distributed under the University of Illinois Open Source 6ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// License. See LICENSE.TXT for details. 7ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// 8ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman//===----------------------------------------------------------------------===// 9ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// 10ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// This pass decodes the debug info metadata in a module and prints in a 11ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// (sufficiently-prepared-) human-readable form. 12ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// 13ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// For example, run this pass from opt along with the -analyze option, and 14ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// it'll print to standard output. 15ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman// 16ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman//===----------------------------------------------------------------------===// 17ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 18ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman#include "llvm/Analysis/Passes.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugInfo.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 220bcbd1df7a204e1e512f1a27066d725309de1b13Bill Wendling#include "llvm/Pass.h" 23ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman#include "llvm/Support/ErrorHandling.h" 24ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman#include "llvm/Support/raw_ostream.h" 25ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohmanusing namespace llvm; 26ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 27ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohmannamespace { 28ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman class ModuleDebugInfoPrinter : public ModulePass { 29ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman DebugInfoFinder Finder; 30ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman public: 31ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman static char ID; // Pass identification, replacement for typeid 32081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson ModuleDebugInfoPrinter() : ModulePass(ID) { 33081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson initializeModuleDebugInfoPrinterPass(*PassRegistry::getPassRegistry()); 34081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson } 35ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 37ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 39ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman AU.setPreservesAll(); 40ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman } 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void print(raw_ostream &O, const Module *M) const override; 42ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman }; 43ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman} 44ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 45ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohmanchar ModuleDebugInfoPrinter::ID = 0; 46d13db2c59cc94162d6cf0a04187d408bfef6d4a7Owen AndersonINITIALIZE_PASS(ModuleDebugInfoPrinter, "module-debuginfo", 47ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson "Decodes module-level debug info", false, true) 48ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 49ef0b14593bb8dd5651606925584adb1ac1096ba5Dan GohmanModulePass *llvm::createModuleDebugInfoPrinterPass() { 50ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman return new ModuleDebugInfoPrinter(); 51ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman} 52ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 53ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohmanbool ModuleDebugInfoPrinter::runOnModule(Module &M) { 54ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman Finder.processModule(M); 55ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman return false; 56ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman} 57ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic void printFile(raw_ostream &O, StringRef Filename, StringRef Directory, 594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Line = 0) { 604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Filename.empty()) 614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << " from "; 644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!Directory.empty()) 654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << Directory << "/"; 664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << Filename; 674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Line) 684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << ":" << Line; 694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 71ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohmanvoid ModuleDebugInfoPrinter::print(raw_ostream &O, const Module *M) const { 724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Printing the nodes directly isn't particularly helpful (since they 734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // reference other nodes that won't be printed, particularly for the 744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // filenames), so just print a few useful things. 756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (DICompileUnit *CU : Finder.compile_units()) { 764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << "Compile unit: "; 770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (const char *Lang = dwarf::LanguageString(CU->getSourceLanguage())) 784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << Lang; 794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar O << "unknown-language(" << CU->getSourceLanguage() << ")"; 810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar printFile(O, CU->getFilename(), CU->getDirectory()); 82ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman O << '\n'; 83ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman } 84ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (DISubprogram *S : Finder.subprograms()) { 860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar O << "Subprogram: " << S->getName(); 870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar printFile(O, S->getFilename(), S->getDirectory(), S->getLine()); 880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (!S->getLinkageName().empty()) 890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar O << " ('" << S->getLinkageName() << "')"; 90ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman O << '\n'; 91ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman } 92ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const DIGlobalVariable *GV : Finder.global_variables()) { 940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar O << "Global variable: " << GV->getName(); 950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar printFile(O, GV->getFilename(), GV->getDirectory(), GV->getLine()); 960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (!GV->getLinkageName().empty()) 970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar O << " ('" << GV->getLinkageName() << "')"; 98ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman O << '\n'; 99ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman } 100ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman 1016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const DIType *T : Finder.types()) { 1024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << "Type:"; 1030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (!T->getName().empty()) 1040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar O << ' ' << T->getName(); 1050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar printFile(O, T->getFilename(), T->getDirectory(), T->getLine()); 1066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (auto *BT = dyn_cast<DIBasicType>(T)) { 1074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << " "; 1084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (const char *Encoding = 1090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar dwarf::AttributeEncodingString(BT->getEncoding())) 1104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << Encoding; 1114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 1120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar O << "unknown-encoding(" << BT->getEncoding() << ')'; 1134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else { 1144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << ' '; 1150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (const char *Tag = dwarf::TagString(T->getTag())) 1164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << Tag; 1174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 1180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar O << "unknown-tag(" << T->getTag() << ")"; 1194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (auto *CT = dyn_cast<DICompositeType>(T)) { 1210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (auto *S = CT->getRawIdentifier()) 1224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar O << " (identifier: '" << S->getString() << "')"; 1234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 124ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman O << '\n'; 125ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman } 126ef0b14593bb8dd5651606925584adb1ac1096ba5Dan Gohman} 127