1ef860a24SChandler Carruth //===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
2ef860a24SChandler Carruth //
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
6ef860a24SChandler Carruth //
7ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
8ef860a24SChandler Carruth
992051407SChandler Carruth #include "llvm/IR/DebugLoc.h"
10432a3883SNico Weber #include "llvm/Config/llvm-config.h"
119a4c9e59SChandler Carruth #include "llvm/IR/DebugInfo.h"
12ef860a24SChandler Carruth using namespace llvm;
13ef860a24SChandler Carruth
14ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
15ef860a24SChandler Carruth // DebugLoc Implementation
16ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
DebugLoc(const DILocation * L)17a9308c49SDuncan P. N. Exon Smith DebugLoc::DebugLoc(const DILocation *L) : Loc(const_cast<DILocation *>(L)) {}
DebugLoc(const MDNode * L)185c8f1dc2SDuncan P. N. Exon Smith DebugLoc::DebugLoc(const MDNode *L) : Loc(const_cast<MDNode *>(L)) {}
19ef860a24SChandler Carruth
get() const20a9308c49SDuncan P. N. Exon Smith DILocation *DebugLoc::get() const {
21a9308c49SDuncan P. N. Exon Smith return cast_or_null<DILocation>(Loc.get());
22ef860a24SChandler Carruth }
23ef860a24SChandler Carruth
getLine() const2486b0db42SDuncan P. N. Exon Smith unsigned DebugLoc::getLine() const {
2586b0db42SDuncan P. N. Exon Smith assert(get() && "Expected valid DebugLoc");
2686b0db42SDuncan P. N. Exon Smith return get()->getLine();
27ef860a24SChandler Carruth }
28ef860a24SChandler Carruth
getCol() const2986b0db42SDuncan P. N. Exon Smith unsigned DebugLoc::getCol() const {
3086b0db42SDuncan P. N. Exon Smith assert(get() && "Expected valid DebugLoc");
3186b0db42SDuncan P. N. Exon Smith return get()->getColumn();
3286b0db42SDuncan P. N. Exon Smith }
3386b0db42SDuncan P. N. Exon Smith
getScope() const3486b0db42SDuncan P. N. Exon Smith MDNode *DebugLoc::getScope() const {
3586b0db42SDuncan P. N. Exon Smith assert(get() && "Expected valid DebugLoc");
3686b0db42SDuncan P. N. Exon Smith return get()->getScope();
3786b0db42SDuncan P. N. Exon Smith }
3886b0db42SDuncan P. N. Exon Smith
getInlinedAt() const39a9308c49SDuncan P. N. Exon Smith DILocation *DebugLoc::getInlinedAt() const {
4086b0db42SDuncan P. N. Exon Smith assert(get() && "Expected valid DebugLoc");
4186b0db42SDuncan P. N. Exon Smith return get()->getInlinedAt();
4286b0db42SDuncan P. N. Exon Smith }
4386b0db42SDuncan P. N. Exon Smith
getInlinedAtScope() const4486b0db42SDuncan P. N. Exon Smith MDNode *DebugLoc::getInlinedAtScope() const {
45a9308c49SDuncan P. N. Exon Smith return cast<DILocation>(Loc)->getInlinedAtScope();
46ef860a24SChandler Carruth }
47ef860a24SChandler Carruth
getFnDebugLoc() const485bf8fef5SDuncan P. N. Exon Smith DebugLoc DebugLoc::getFnDebugLoc() const {
49a9308c49SDuncan P. N. Exon Smith // FIXME: Add a method on \a DILocation that does this work.
5086b0db42SDuncan P. N. Exon Smith const MDNode *Scope = getInlinedAtScope();
512fbe1354SDuncan P. N. Exon Smith if (auto *SP = getDISubprogram(Scope))
52b5ad32efSFangrui Song return DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
53f166f6c8STimur Iskhodzhanov
54f166f6c8STimur Iskhodzhanov return DebugLoc();
55f166f6c8STimur Iskhodzhanov }
56ef860a24SChandler Carruth
isImplicitCode() const57eb7f6020SCalixte Denizet bool DebugLoc::isImplicitCode() const {
58eb7f6020SCalixte Denizet if (DILocation *Loc = get()) {
59eb7f6020SCalixte Denizet return Loc->isImplicitCode();
60eb7f6020SCalixte Denizet }
61eb7f6020SCalixte Denizet return true;
62eb7f6020SCalixte Denizet }
63eb7f6020SCalixte Denizet
setImplicitCode(bool ImplicitCode)64eb7f6020SCalixte Denizet void DebugLoc::setImplicitCode(bool ImplicitCode) {
65eb7f6020SCalixte Denizet if (DILocation *Loc = get()) {
66eb7f6020SCalixte Denizet Loc->setImplicitCode(ImplicitCode);
67eb7f6020SCalixte Denizet }
68eb7f6020SCalixte Denizet }
69eb7f6020SCalixte Denizet
appendInlinedAt(const DebugLoc & DL,DILocation * InlinedAt,LLVMContext & Ctx,DenseMap<const MDNode *,MDNode * > & Cache)700ae989a1SSimon Pilgrim DebugLoc DebugLoc::appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt,
71c10d0e5cSAdrian Prantl LLVMContext &Ctx,
72*d466e10aSFangrui Song DenseMap<const MDNode *, MDNode *> &Cache) {
73c10d0e5cSAdrian Prantl SmallVector<DILocation *, 3> InlinedAtLocations;
74c10d0e5cSAdrian Prantl DILocation *Last = InlinedAt;
75c10d0e5cSAdrian Prantl DILocation *CurInlinedAt = DL;
76c10d0e5cSAdrian Prantl
77c10d0e5cSAdrian Prantl // Gather all the inlined-at nodes.
78c10d0e5cSAdrian Prantl while (DILocation *IA = CurInlinedAt->getInlinedAt()) {
79c10d0e5cSAdrian Prantl // Skip any we've already built nodes for.
80c10d0e5cSAdrian Prantl if (auto *Found = Cache[IA]) {
81c10d0e5cSAdrian Prantl Last = cast<DILocation>(Found);
82c10d0e5cSAdrian Prantl break;
83c10d0e5cSAdrian Prantl }
84c10d0e5cSAdrian Prantl
85c10d0e5cSAdrian Prantl InlinedAtLocations.push_back(IA);
86c10d0e5cSAdrian Prantl CurInlinedAt = IA;
87c10d0e5cSAdrian Prantl }
88c10d0e5cSAdrian Prantl
89c10d0e5cSAdrian Prantl // Starting from the top, rebuild the nodes to point to the new inlined-at
90c10d0e5cSAdrian Prantl // location (then rebuilding the rest of the chain behind it) and update the
91c10d0e5cSAdrian Prantl // map of already-constructed inlined-at nodes.
92c10d0e5cSAdrian Prantl for (const DILocation *MD : reverse(InlinedAtLocations))
93c10d0e5cSAdrian Prantl Cache[MD] = Last = DILocation::getDistinct(
94c10d0e5cSAdrian Prantl Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);
95c10d0e5cSAdrian Prantl
96c10d0e5cSAdrian Prantl return Last;
97c10d0e5cSAdrian Prantl }
98c10d0e5cSAdrian Prantl
99615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const100673f4b57SSean Silva LLVM_DUMP_METHOD void DebugLoc::dump() const { print(dbgs()); }
1018c209aa8SMatthias Braun #endif
102ef860a24SChandler Carruth
print(raw_ostream & OS) const1035bf8fef5SDuncan P. N. Exon Smith void DebugLoc::print(raw_ostream &OS) const {
10486b0db42SDuncan P. N. Exon Smith if (!Loc)
10586b0db42SDuncan P. N. Exon Smith return;
10686b0db42SDuncan P. N. Exon Smith
107da925c0dSZinovy Nis // Print source line info.
108a9308c49SDuncan P. N. Exon Smith auto *Scope = cast<DIScope>(getScope());
109b273d06bSDuncan P. N. Exon Smith OS << Scope->getFilename();
110da925c0dSZinovy Nis OS << ':' << getLine();
111da925c0dSZinovy Nis if (getCol() != 0)
112da925c0dSZinovy Nis OS << ':' << getCol();
11386b0db42SDuncan P. N. Exon Smith
11486b0db42SDuncan P. N. Exon Smith if (DebugLoc InlinedAtDL = getInlinedAt()) {
115da925c0dSZinovy Nis OS << " @[ ";
1165bf8fef5SDuncan P. N. Exon Smith InlinedAtDL.print(OS);
117da925c0dSZinovy Nis OS << " ]";
118da925c0dSZinovy Nis }
119da925c0dSZinovy Nis }
120