DxilDiaTableLineNumbers.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilDiaTableLineNumbers.cpp //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // DIA API implementation for DXIL modules. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include "DxilDiaTableLineNumbers.h"
  12. #include <utility>
  13. #include "llvm/IR/DebugInfoMetadata.h"
  14. #include "DxilDiaSession.h"
  15. dxil_dia::LineNumber::LineNumber(
  16. /* [in] */ IMalloc *pMalloc,
  17. /* [in] */ Session *pSession,
  18. /* [in] */ const llvm::Instruction * inst)
  19. : m_pMalloc(pMalloc),
  20. m_pSession(pSession),
  21. m_inst(inst) {
  22. }
  23. const llvm::DebugLoc &dxil_dia::LineNumber::DL() const {
  24. DXASSERT(bool(m_inst->getDebugLoc()), "Trying to read line info from invalid debug location");
  25. return m_inst->getDebugLoc();
  26. }
  27. STDMETHODIMP dxil_dia::LineNumber::get_sourceFile(
  28. /* [retval][out] */ IDiaSourceFile **pRetVal) {
  29. DWORD id;
  30. HRESULT hr = get_sourceFileId(&id);
  31. if (hr != S_OK)
  32. return hr;
  33. return m_pSession->findFileById(id, pRetVal);
  34. }
  35. STDMETHODIMP dxil_dia::LineNumber::get_lineNumber(
  36. /* [retval][out] */ DWORD *pRetVal) {
  37. *pRetVal = DL().getLine();
  38. return S_OK;
  39. }
  40. STDMETHODIMP dxil_dia::LineNumber::get_lineNumberEnd(
  41. /* [retval][out] */ DWORD *pRetVal) {
  42. *pRetVal = DL().getLine();
  43. return S_OK;
  44. }
  45. STDMETHODIMP dxil_dia::LineNumber::get_columnNumber(
  46. /* [retval][out] */ DWORD *pRetVal) {
  47. *pRetVal = DL().getCol();
  48. return S_OK;
  49. }
  50. STDMETHODIMP dxil_dia::LineNumber::get_columnNumberEnd(
  51. /* [retval][out] */ DWORD *pRetVal) {
  52. *pRetVal = DL().getCol();
  53. return S_OK;
  54. }
  55. STDMETHODIMP dxil_dia::LineNumber::get_addressOffset(
  56. /* [retval][out] */ DWORD *pRetVal) {
  57. return get_relativeVirtualAddress(pRetVal);
  58. }
  59. STDMETHODIMP dxil_dia::LineNumber::get_relativeVirtualAddress(
  60. /* [retval][out] */ DWORD *pRetVal) {
  61. if (pRetVal == nullptr) {
  62. return E_INVALIDARG;
  63. }
  64. *pRetVal = 0;
  65. const auto &rvaMap = m_pSession->RvaMapRef();
  66. auto it = rvaMap.find(m_inst);
  67. if (it == rvaMap.end()) {
  68. return E_FAIL;
  69. }
  70. *pRetVal = it->second;
  71. return S_OK;
  72. }
  73. STDMETHODIMP dxil_dia::LineNumber::get_length(
  74. /* [retval][out] */ DWORD *pRetVal) {
  75. if (pRetVal == nullptr) {
  76. return E_INVALIDARG;
  77. }
  78. *pRetVal = 1;
  79. if (llvm::DebugLoc DL = m_inst->getDebugLoc()) {
  80. const auto &LineToColumn = m_pSession->LineToColumnStartMapRef();
  81. auto it = LineToColumn.find(DL.getLine());
  82. if (it != LineToColumn.end()) {
  83. *pRetVal = it->second.Last - it->second.First;
  84. }
  85. }
  86. return S_OK;
  87. }
  88. STDMETHODIMP dxil_dia::LineNumber::get_statement(
  89. /* [retval][out] */ BOOL *pRetVal) {
  90. if (pRetVal == nullptr) {
  91. return E_INVALIDARG;
  92. }
  93. *pRetVal = FALSE;
  94. if (llvm::DebugLoc DL = m_inst->getDebugLoc()) {
  95. const auto &LineToColumn = m_pSession->LineToColumnStartMapRef();
  96. auto it = LineToColumn.find(DL.getLine());
  97. if (it != LineToColumn.end()) {
  98. *pRetVal = it->second.StartCol == DL.getCol();
  99. }
  100. }
  101. return S_OK;
  102. }
  103. STDMETHODIMP dxil_dia::LineNumber::get_sourceFileId(
  104. /* [retval][out] */ DWORD *pRetVal) {
  105. llvm::MDNode *pScope = DL().getScope();
  106. auto *pBlock = llvm::dyn_cast_or_null<llvm::DILexicalBlock>(pScope);
  107. if (pBlock != nullptr) {
  108. return m_pSession->getSourceFileIdByName(pBlock->getFile()->getFilename(), pRetVal);
  109. }
  110. auto *pSubProgram = llvm::dyn_cast_or_null<llvm::DISubprogram>(pScope);
  111. if (pSubProgram != nullptr) {
  112. return m_pSession->getSourceFileIdByName(pSubProgram->getFile()->getFilename(), pRetVal);
  113. }
  114. *pRetVal = 0;
  115. return S_FALSE;
  116. }
  117. STDMETHODIMP dxil_dia::LineNumber::get_compilandId(
  118. /* [retval][out] */ DWORD *pRetVal) {
  119. // Single compiland for now, so pretty simple.
  120. *pRetVal = HlslCompilandId;
  121. return S_OK;
  122. }
  123. dxil_dia::LineNumbersTable::LineNumbersTable(IMalloc *pMalloc, Session *pSession)
  124. : impl::TableBase<IDiaEnumLineNumbers, IDiaLineNumber>(pMalloc, pSession, Table::Kind::LineNumbers)
  125. , m_instructions(pSession->InstructionLinesRef())
  126. {
  127. m_count = m_instructions.size();
  128. }
  129. dxil_dia::LineNumbersTable::LineNumbersTable(IMalloc *pMalloc, Session *pSession, std::vector<const llvm::Instruction*> &&instructions)
  130. : impl::TableBase<IDiaEnumLineNumbers, IDiaLineNumber>(pMalloc, pSession, Table::Kind::LineNumbers)
  131. , m_instructions(m_instructionsStorage)
  132. , m_instructionsStorage(std::move(instructions))
  133. {
  134. m_count = m_instructions.size();
  135. }
  136. HRESULT dxil_dia::LineNumbersTable::GetItem(DWORD index, IDiaLineNumber **ppItem) {
  137. if (index >= m_instructions.size())
  138. return E_INVALIDARG;
  139. *ppItem = CreateOnMalloc<LineNumber>(m_pMalloc, m_pSession, m_instructions[index]);
  140. if (*ppItem == nullptr)
  141. return E_OUTOFMEMORY;
  142. (*ppItem)->AddRef();
  143. return S_OK;
  144. }