/////////////////////////////////////////////////////////////////////////////// // // // DxilDiaTableLineNumbers.cpp // // Copyright (C) Microsoft Corporation. All rights reserved. // // This file is distributed under the University of Illinois Open Source // // License. See LICENSE.TXT for details. // // // // DIA API implementation for DXIL modules. // // // /////////////////////////////////////////////////////////////////////////////// #include "DxilDiaTableLineNumbers.h" #include #include "llvm/IR/DebugInfoMetadata.h" #include "DxilDiaSession.h" dxil_dia::LineNumber::LineNumber( /* [in] */ IMalloc *pMalloc, /* [in] */ Session *pSession, /* [in] */ const llvm::Instruction * inst) : m_pMalloc(pMalloc), m_pSession(pSession), m_inst(inst) { } const llvm::DebugLoc &dxil_dia::LineNumber::DL() const { DXASSERT(bool(m_inst->getDebugLoc()), "Trying to read line info from invalid debug location"); return m_inst->getDebugLoc(); } STDMETHODIMP dxil_dia::LineNumber::get_sourceFile( /* [retval][out] */ IDiaSourceFile **pRetVal) { DWORD id; HRESULT hr = get_sourceFileId(&id); if (hr != S_OK) return hr; return m_pSession->findFileById(id, pRetVal); } STDMETHODIMP dxil_dia::LineNumber::get_lineNumber( /* [retval][out] */ DWORD *pRetVal) { *pRetVal = DL().getLine(); return S_OK; } STDMETHODIMP dxil_dia::LineNumber::get_lineNumberEnd( /* [retval][out] */ DWORD *pRetVal) { *pRetVal = DL().getLine(); return S_OK; } STDMETHODIMP dxil_dia::LineNumber::get_columnNumber( /* [retval][out] */ DWORD *pRetVal) { *pRetVal = DL().getCol(); return S_OK; } STDMETHODIMP dxil_dia::LineNumber::get_columnNumberEnd( /* [retval][out] */ DWORD *pRetVal) { *pRetVal = DL().getCol(); return S_OK; } STDMETHODIMP dxil_dia::LineNumber::get_addressOffset( /* [retval][out] */ DWORD *pRetVal) { return get_relativeVirtualAddress(pRetVal); } STDMETHODIMP dxil_dia::LineNumber::get_relativeVirtualAddress( /* [retval][out] */ DWORD *pRetVal) { if (pRetVal == nullptr) { return E_INVALIDARG; } *pRetVal = 0; const auto &rvaMap = m_pSession->RvaMapRef(); auto it = rvaMap.find(m_inst); if (it == rvaMap.end()) { return E_FAIL; } *pRetVal = it->second; return S_OK; } STDMETHODIMP dxil_dia::LineNumber::get_length( /* [retval][out] */ DWORD *pRetVal) { if (pRetVal == nullptr) { return E_INVALIDARG; } *pRetVal = 1; if (llvm::DebugLoc DL = m_inst->getDebugLoc()) { const auto &LineToColumn = m_pSession->LineToColumnStartMapRef(); auto it = LineToColumn.find(DL.getLine()); if (it != LineToColumn.end()) { *pRetVal = it->second.Last - it->second.First; } } return S_OK; } STDMETHODIMP dxil_dia::LineNumber::get_statement( /* [retval][out] */ BOOL *pRetVal) { if (pRetVal == nullptr) { return E_INVALIDARG; } *pRetVal = FALSE; if (llvm::DebugLoc DL = m_inst->getDebugLoc()) { const auto &LineToColumn = m_pSession->LineToColumnStartMapRef(); auto it = LineToColumn.find(DL.getLine()); if (it != LineToColumn.end()) { *pRetVal = it->second.StartCol == DL.getCol(); } } return S_OK; } STDMETHODIMP dxil_dia::LineNumber::get_sourceFileId( /* [retval][out] */ DWORD *pRetVal) { llvm::MDNode *pScope = DL().getScope(); auto *pBlock = llvm::dyn_cast_or_null(pScope); if (pBlock != nullptr) { return m_pSession->getSourceFileIdByName(pBlock->getFile()->getFilename(), pRetVal); } auto *pSubProgram = llvm::dyn_cast_or_null(pScope); if (pSubProgram != nullptr) { return m_pSession->getSourceFileIdByName(pSubProgram->getFile()->getFilename(), pRetVal); } *pRetVal = 0; return S_FALSE; } STDMETHODIMP dxil_dia::LineNumber::get_compilandId( /* [retval][out] */ DWORD *pRetVal) { // Single compiland for now, so pretty simple. *pRetVal = HlslCompilandId; return S_OK; } dxil_dia::LineNumbersTable::LineNumbersTable(IMalloc *pMalloc, Session *pSession) : impl::TableBase(pMalloc, pSession, Table::Kind::LineNumbers) , m_instructions(pSession->InstructionLinesRef()) { m_count = m_instructions.size(); } dxil_dia::LineNumbersTable::LineNumbersTable(IMalloc *pMalloc, Session *pSession, std::vector &&instructions) : impl::TableBase(pMalloc, pSession, Table::Kind::LineNumbers) , m_instructions(m_instructionsStorage) , m_instructionsStorage(std::move(instructions)) { m_count = m_instructions.size(); } HRESULT dxil_dia::LineNumbersTable::GetItem(DWORD index, IDiaLineNumber **ppItem) { if (index >= m_instructions.size()) return E_INVALIDARG; *ppItem = CreateOnMalloc(m_pMalloc, m_pSession, m_instructions[index]); if (*ppItem == nullptr) return E_OUTOFMEMORY; (*ppItem)->AddRef(); return S_OK; }