1 //===- BreakpointPrinter.cpp - Breakpoint location printer ----------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// Breakpoint location printer.
12 //===----------------------------------------------------------------------===//
13 #include "BreakpointPrinter.h"
14 #include "llvm/ADT/StringSet.h"
15 #include "llvm/IR/DebugInfo.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/Pass.h"
18 #include "llvm/Support/raw_ostream.h"
24 struct BreakpointPrinter
: public ModulePass
{
28 BreakpointPrinter(raw_ostream
&out
) : ModulePass(ID
), Out(out
) {}
30 void getContextName(const DIScope
*Context
, std::string
&N
) {
31 if (auto *NS
= dyn_cast
<DINamespace
>(Context
)) {
32 if (!NS
->getName().empty()) {
33 getContextName(NS
->getScope(), N
);
34 N
= N
+ NS
->getName().str() + "::";
36 } else if (auto *TY
= dyn_cast
<DIType
>(Context
)) {
37 if (!TY
->getName().empty()) {
38 getContextName(TY
->getScope(), N
);
39 N
= N
+ TY
->getName().str() + "::";
44 bool runOnModule(Module
&M
) override
{
45 StringSet
<> Processed
;
46 if (NamedMDNode
*NMD
= M
.getNamedMetadata("llvm.dbg.sp"))
47 for (unsigned i
= 0, e
= NMD
->getNumOperands(); i
!= e
; ++i
) {
49 auto *SP
= cast_or_null
<DISubprogram
>(NMD
->getOperand(i
));
52 getContextName(SP
->getScope(), Name
);
53 Name
= Name
+ SP
->getName().str();
54 if (!Name
.empty() && Processed
.insert(Name
).second
) {
61 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
66 char BreakpointPrinter::ID
= 0;
69 ModulePass
*llvm::createBreakpointPrinter(raw_ostream
&out
) {
70 return new BreakpointPrinter(out
);