| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // DxcPixVariables.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. // |
| // // |
| // Defines DXC's PIX api for exposing llvm::DIVariables. // |
| // // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #include "dxc/Support/WinIncludes.h" |
| |
| #include "dxc/Support/Global.h" |
| #include "dxc/Support/microcom.h" |
| #include "dxc/dxcpix.h" |
| #include "llvm/IR/DebugInfo.h" |
| #include "llvm/IR/DebugInfoMetadata.h" |
| |
| #include "DxcPixBase.h" |
| #include "DxcPixDxilDebugInfo.h" |
| #include "DxcPixDxilStorage.h" |
| #include "DxcPixLiveVariables.h" |
| #include "DxcPixTypes.h" |
| #include "DxilDiaSession.h" |
| |
| #include <set> |
| #include <vector> |
| |
| namespace dxil_debug_info { |
| template <typename T> class DxcPixVariable : public IDxcPixVariable { |
| DXC_MICROCOM_TM_REF_FIELDS() |
| CComPtr<DxcPixDxilDebugInfo> m_pDxilDebugInfo; |
| T *m_pVariable; |
| VariableInfo const *m_pVarInfo; |
| llvm::DIType *m_pType; |
| |
| DxcPixVariable(IMalloc *pMalloc, DxcPixDxilDebugInfo *DxilDebugInfo, |
| T *pVariable, VariableInfo const *pVarInfo) |
| : m_pMalloc(pMalloc), m_pDxilDebugInfo(DxilDebugInfo), |
| m_pVariable(pVariable), m_pVarInfo(pVarInfo) { |
| const llvm::DITypeIdentifierMap EmptyMap; |
| m_pType = m_pVariable->getType().resolve(EmptyMap); |
| } |
| |
| public: |
| DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL() |
| DXC_MICROCOM_TM_ALLOC(DxcPixVariable) |
| |
| HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, |
| void **ppvObject) override { |
| return DoBasicQueryInterface<IDxcPixVariable>(this, iid, ppvObject); |
| } |
| |
| public: |
| STDMETHODIMP GetName(BSTR *Name) override; |
| |
| STDMETHODIMP GetType(IDxcPixType **ppType) override; |
| |
| STDMETHODIMP GetStorage(IDxcPixDxilStorage **ppStorage) override; |
| }; |
| |
| } // namespace dxil_debug_info |
| |
| template <typename T> |
| STDMETHODIMP dxil_debug_info::DxcPixVariable<T>::GetName(BSTR *Name) { |
| *Name = CComBSTR(CA2W(m_pVariable->getName().data())).Detach(); |
| return S_OK; |
| } |
| |
| template <typename T> |
| STDMETHODIMP dxil_debug_info::DxcPixVariable<T>::GetType(IDxcPixType **ppType) { |
| return dxil_debug_info::CreateDxcPixType(m_pDxilDebugInfo, m_pType, ppType); |
| } |
| |
| template <typename T> |
| STDMETHODIMP |
| dxil_debug_info::DxcPixVariable<T>::GetStorage(IDxcPixDxilStorage **ppStorage) { |
| const unsigned InitialOffsetInBits = 0; |
| return CreateDxcPixStorage(m_pDxilDebugInfo, m_pType, m_pVarInfo, |
| InitialOffsetInBits, ppStorage); |
| } |
| |
| namespace dxil_debug_info { |
| class DxcPixDxilLiveVariables : public IDxcPixDxilLiveVariables { |
| private: |
| DXC_MICROCOM_TM_REF_FIELDS(); |
| CComPtr<DxcPixDxilDebugInfo> m_pDxilDebugInfo; |
| std::vector<const VariableInfo *> m_LiveVars; |
| |
| DxcPixDxilLiveVariables(IMalloc *pMalloc, DxcPixDxilDebugInfo *pDxilDebugInfo, |
| std::vector<const VariableInfo *> LiveVars) |
| : m_pMalloc(pMalloc), m_pDxilDebugInfo(pDxilDebugInfo), |
| m_LiveVars(std::move(LiveVars)) { |
| #ifndef NDEBUG |
| for (auto VarAndInfo : m_LiveVars) { |
| assert(llvm::isa<llvm::DIGlobalVariable>(VarAndInfo->m_Variable) || |
| llvm::isa<llvm::DILocalVariable>(VarAndInfo->m_Variable)); |
| } |
| #endif // !NDEBUG |
| } |
| |
| STDMETHODIMP CreateDxcPixVariable(IDxcPixVariable **ppVariable, |
| VariableInfo const *VarInfo) const; |
| |
| public: |
| DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL(); |
| DXC_MICROCOM_TM_ALLOC(DxcPixDxilLiveVariables); |
| |
| HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) final { |
| return DoBasicQueryInterface<IDxcPixDxilLiveVariables>(this, iid, |
| ppvObject); |
| } |
| |
| STDMETHODIMP GetCount(DWORD *dwSize) override; |
| |
| STDMETHODIMP GetVariableByIndex(DWORD Index, |
| IDxcPixVariable **ppVariable) override; |
| |
| STDMETHODIMP GetVariableByName(LPCWSTR Name, |
| IDxcPixVariable **ppVariable) override; |
| }; |
| |
| } // namespace dxil_debug_info |
| STDMETHODIMP dxil_debug_info::DxcPixDxilLiveVariables::GetCount(DWORD *dwSize) { |
| *dwSize = m_LiveVars.size(); |
| return S_OK; |
| } |
| |
| STDMETHODIMP dxil_debug_info::DxcPixDxilLiveVariables::CreateDxcPixVariable( |
| IDxcPixVariable **ppVariable, VariableInfo const *VarInfo) const { |
| auto *Var = VarInfo->m_Variable; |
| if (auto *DILV = llvm::dyn_cast<llvm::DILocalVariable>(Var)) { |
| return NewDxcPixDxilDebugInfoObjectOrThrow< |
| DxcPixVariable<llvm::DILocalVariable>>(ppVariable, m_pMalloc, |
| m_pDxilDebugInfo, DILV, VarInfo); |
| } else if (auto *DIGV = llvm::dyn_cast<llvm::DIGlobalVariable>(Var)) { |
| return NewDxcPixDxilDebugInfoObjectOrThrow< |
| DxcPixVariable<llvm::DIGlobalVariable>>( |
| ppVariable, m_pMalloc, m_pDxilDebugInfo, DIGV, VarInfo); |
| } |
| |
| return E_UNEXPECTED; |
| } |
| |
| STDMETHODIMP dxil_debug_info::DxcPixDxilLiveVariables::GetVariableByIndex( |
| DWORD Index, IDxcPixVariable **ppVariable) { |
| if (Index >= m_LiveVars.size()) { |
| return E_BOUNDS; |
| } |
| |
| auto *VarInfo = m_LiveVars[Index]; |
| return CreateDxcPixVariable(ppVariable, VarInfo); |
| } |
| |
| STDMETHODIMP dxil_debug_info::DxcPixDxilLiveVariables::GetVariableByName( |
| LPCWSTR Name, IDxcPixVariable **ppVariable) { |
| std::string name = std::string(CW2A(Name)); |
| |
| for (auto *VarInfo : m_LiveVars) { |
| auto *Var = VarInfo->m_Variable; |
| if (Var->getName() == name) { |
| return CreateDxcPixVariable(ppVariable, VarInfo); |
| } |
| } |
| |
| return E_BOUNDS; |
| } |
| |
| HRESULT dxil_debug_info::CreateDxilLiveVariables( |
| DxcPixDxilDebugInfo *pDxilDebugInfo, |
| std::vector<const VariableInfo *> &&LiveVariables, |
| IDxcPixDxilLiveVariables **ppResult) { |
| return NewDxcPixDxilDebugInfoObjectOrThrow<DxcPixDxilLiveVariables>( |
| ppResult, pDxilDebugInfo->GetMallocNoRef(), pDxilDebugInfo, |
| std::move(LiveVariables)); |
| } |