DebugLoc.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. //===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
  2. //
  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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/IR/DebugLoc.h"
  9. #include "LLVMContextImpl.h"
  10. #include "llvm/Config/llvm-config.h"
  11. #include "llvm/IR/DebugInfo.h"
  12. using namespace llvm;
  13. //===----------------------------------------------------------------------===//
  14. // DebugLoc Implementation
  15. //===----------------------------------------------------------------------===//
  16. DebugLoc::DebugLoc(const DILocation *L) : Loc(const_cast<DILocation *>(L)) {}
  17. DebugLoc::DebugLoc(const MDNode *L) : Loc(const_cast<MDNode *>(L)) {}
  18. DILocation *DebugLoc::get() const {
  19. return cast_or_null<DILocation>(Loc.get());
  20. }
  21. unsigned DebugLoc::getLine() const {
  22. assert(get() && "Expected valid DebugLoc");
  23. return get()->getLine();
  24. }
  25. unsigned DebugLoc::getCol() const {
  26. assert(get() && "Expected valid DebugLoc");
  27. return get()->getColumn();
  28. }
  29. MDNode *DebugLoc::getScope() const {
  30. assert(get() && "Expected valid DebugLoc");
  31. return get()->getScope();
  32. }
  33. DILocation *DebugLoc::getInlinedAt() const {
  34. assert(get() && "Expected valid DebugLoc");
  35. return get()->getInlinedAt();
  36. }
  37. MDNode *DebugLoc::getInlinedAtScope() const {
  38. return cast<DILocation>(Loc)->getInlinedAtScope();
  39. }
  40. DebugLoc DebugLoc::getFnDebugLoc() const {
  41. // FIXME: Add a method on \a DILocation that does this work.
  42. const MDNode *Scope = getInlinedAtScope();
  43. if (auto *SP = getDISubprogram(Scope))
  44. return DebugLoc::get(SP->getScopeLine(), 0, SP);
  45. return DebugLoc();
  46. }
  47. bool DebugLoc::isImplicitCode() const {
  48. if (DILocation *Loc = get()) {
  49. return Loc->isImplicitCode();
  50. }
  51. return true;
  52. }
  53. void DebugLoc::setImplicitCode(bool ImplicitCode) {
  54. if (DILocation *Loc = get()) {
  55. Loc->setImplicitCode(ImplicitCode);
  56. }
  57. }
  58. DebugLoc DebugLoc::get(unsigned Line, unsigned Col, const MDNode *Scope,
  59. const MDNode *InlinedAt, bool ImplicitCode) {
  60. // If no scope is available, this is an unknown location.
  61. if (!Scope)
  62. return DebugLoc();
  63. return DILocation::get(Scope->getContext(), Line, Col,
  64. const_cast<MDNode *>(Scope),
  65. const_cast<MDNode *>(InlinedAt), ImplicitCode);
  66. }
  67. DebugLoc DebugLoc::appendInlinedAt(DebugLoc DL, DILocation *InlinedAt,
  68. LLVMContext &Ctx,
  69. DenseMap<const MDNode *, MDNode *> &Cache,
  70. bool ReplaceLast) {
  71. SmallVector<DILocation *, 3> InlinedAtLocations;
  72. DILocation *Last = InlinedAt;
  73. DILocation *CurInlinedAt = DL;
  74. // Gather all the inlined-at nodes.
  75. while (DILocation *IA = CurInlinedAt->getInlinedAt()) {
  76. // Skip any we've already built nodes for.
  77. if (auto *Found = Cache[IA]) {
  78. Last = cast<DILocation>(Found);
  79. break;
  80. }
  81. if (ReplaceLast && !IA->getInlinedAt())
  82. break;
  83. InlinedAtLocations.push_back(IA);
  84. CurInlinedAt = IA;
  85. }
  86. // Starting from the top, rebuild the nodes to point to the new inlined-at
  87. // location (then rebuilding the rest of the chain behind it) and update the
  88. // map of already-constructed inlined-at nodes.
  89. for (const DILocation *MD : reverse(InlinedAtLocations))
  90. Cache[MD] = Last = DILocation::getDistinct(
  91. Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);
  92. return Last;
  93. }
  94. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  95. LLVM_DUMP_METHOD void DebugLoc::dump() const { print(dbgs()); }
  96. #endif
  97. void DebugLoc::print(raw_ostream &OS) const {
  98. if (!Loc)
  99. return;
  100. // Print source line info.
  101. auto *Scope = cast<DIScope>(getScope());
  102. OS << Scope->getFilename();
  103. OS << ':' << getLine();
  104. if (getCol() != 0)
  105. OS << ':' << getCol();
  106. if (DebugLoc InlinedAtDL = getInlinedAt()) {
  107. OS << " @[ ";
  108. InlinedAtDL.print(OS);
  109. OS << " ]";
  110. }
  111. }