154dc2839SEli Bendersky //===- BreakpointPrinter.cpp - Breakpoint location printer ----------------===//
254dc2839SEli Bendersky //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
654dc2839SEli Bendersky //
754dc2839SEli Bendersky //===----------------------------------------------------------------------===//
854dc2839SEli Bendersky ///
954dc2839SEli Bendersky /// \file
105f8f34e4SAdrian Prantl /// Breakpoint location printer.
1154dc2839SEli Bendersky ///
1254dc2839SEli Bendersky //===----------------------------------------------------------------------===//
1354dc2839SEli Bendersky #include "BreakpointPrinter.h"
1454dc2839SEli Bendersky #include "llvm/ADT/StringSet.h"
159a4c9e59SChandler Carruth #include "llvm/IR/DebugInfo.h"
1654dc2839SEli Bendersky #include "llvm/IR/Module.h"
1754dc2839SEli Bendersky #include "llvm/Pass.h"
1854dc2839SEli Bendersky #include "llvm/Support/raw_ostream.h"
1954dc2839SEli Bendersky 
2054dc2839SEli Bendersky using namespace llvm;
2154dc2839SEli Bendersky 
2254dc2839SEli Bendersky namespace {
2354dc2839SEli Bendersky 
2454dc2839SEli Bendersky struct BreakpointPrinter : public ModulePass {
2554dc2839SEli Bendersky   raw_ostream &Out;
2654dc2839SEli Bendersky   static char ID;
2754dc2839SEli Bendersky 
BreakpointPrinter__anon7cefdbef0111::BreakpointPrinter2854dc2839SEli Bendersky   BreakpointPrinter(raw_ostream &out) : ModulePass(ID), Out(out) {}
2954dc2839SEli Bendersky 
getContextName__anon7cefdbef0111::BreakpointPrinter30a9308c49SDuncan P. N. Exon Smith   void getContextName(const DIScope *Context, std::string &N) {
31a9308c49SDuncan P. N. Exon Smith     if (auto *NS = dyn_cast<DINamespace>(Context)) {
3220caafbfSDuncan P. N. Exon Smith       if (!NS->getName().empty()) {
3320caafbfSDuncan P. N. Exon Smith         getContextName(NS->getScope(), N);
3420caafbfSDuncan P. N. Exon Smith         N = N + NS->getName().str() + "::";
3554dc2839SEli Bendersky       }
36a9308c49SDuncan P. N. Exon Smith     } else if (auto *TY = dyn_cast<DIType>(Context)) {
37b1055640SDuncan P. N. Exon Smith       if (!TY->getName().empty()) {
38*da82ce99SFangrui Song         getContextName(TY->getScope(), N);
39b1055640SDuncan P. N. Exon Smith         N = N + TY->getName().str() + "::";
4054dc2839SEli Bendersky       }
4154dc2839SEli Bendersky     }
4254dc2839SEli Bendersky   }
4354dc2839SEli Bendersky 
runOnModule__anon7cefdbef0111::BreakpointPrinter44e56917c0SCraig Topper   bool runOnModule(Module &M) override {
4554dc2839SEli Bendersky     StringSet<> Processed;
4654dc2839SEli Bendersky     if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp"))
4754dc2839SEli Bendersky       for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
4854dc2839SEli Bendersky         std::string Name;
49a9308c49SDuncan P. N. Exon Smith         auto *SP = cast_or_null<DISubprogram>(NMD->getOperand(i));
5054dc2839SEli Bendersky         if (!SP)
5154dc2839SEli Bendersky           continue;
52*da82ce99SFangrui Song         getContextName(SP->getScope(), Name);
539d2f019fSAdrian Prantl         Name = Name + SP->getName().str();
540356975cSDavid Blaikie         if (!Name.empty() && Processed.insert(Name).second) {
5554dc2839SEli Bendersky           Out << Name << "\n";
5654dc2839SEli Bendersky         }
5754dc2839SEli Bendersky       }
5854dc2839SEli Bendersky     return false;
5954dc2839SEli Bendersky   }
6054dc2839SEli Bendersky 
getAnalysisUsage__anon7cefdbef0111::BreakpointPrinter61e56917c0SCraig Topper   void getAnalysisUsage(AnalysisUsage &AU) const override {
6254dc2839SEli Bendersky     AU.setPreservesAll();
6354dc2839SEli Bendersky   }
6454dc2839SEli Bendersky };
6554dc2839SEli Bendersky 
6654dc2839SEli Bendersky char BreakpointPrinter::ID = 0;
6754dc2839SEli Bendersky }
6854dc2839SEli Bendersky 
createBreakpointPrinter(raw_ostream & out)6954dc2839SEli Bendersky ModulePass *llvm::createBreakpointPrinter(raw_ostream &out) {
7054dc2839SEli Bendersky   return new BreakpointPrinter(out);
7154dc2839SEli Bendersky }
72