/////////////////////////////////////////////////////////////////////////////// // // // 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/dxcpix.h" #include "dxc/Support/microcom.h" #include "dxc/Support/Global.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 #include namespace dxil_debug_info { template class DxcPixVariable : public IDxcPixVariable { DXC_MICROCOM_TM_REF_FIELDS() CComPtr 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) { return DoBasicQueryInterface(this, iid, ppvObject); } public: STDMETHODIMP GetName( _Outptr_result_z_ BSTR *Name) override; STDMETHODIMP GetType( _Outptr_result_z_ IDxcPixType** ppType) override; STDMETHODIMP GetStorage( _COM_Outptr_ IDxcPixDxilStorage** ppStorage) override; }; } // namespace dxil_debug_info template STDMETHODIMP dxil_debug_info::DxcPixVariable::GetName( _Outptr_result_z_ BSTR* Name) { *Name = CComBSTR(CA2W(m_pVariable->getName().data())).Detach(); return S_OK; } template STDMETHODIMP dxil_debug_info::DxcPixVariable::GetType( _Outptr_result_z_ IDxcPixType **ppType ) { return dxil_debug_info::CreateDxcPixType( m_pDxilDebugInfo, m_pType, ppType); } template STDMETHODIMP dxil_debug_info::DxcPixVariable::GetStorage( _COM_Outptr_ 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 m_pDxilDebugInfo; std::vector m_LiveVars; DxcPixDxilLiveVariables( IMalloc *pMalloc, DxcPixDxilDebugInfo *pDxilDebugInfo, std::vector LiveVars ) : m_pMalloc(pMalloc) , m_pDxilDebugInfo(pDxilDebugInfo) , m_LiveVars(std::move(LiveVars)) { #ifndef NDEBUG for (auto VarAndInfo : m_LiveVars) { assert(llvm::isa(VarAndInfo->m_Variable) || llvm::isa(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(this, iid, ppvObject); } STDMETHODIMP GetCount( _Outptr_ DWORD *dwSize) override; STDMETHODIMP GetVariableByIndex( _In_ DWORD Index, _Outptr_result_z_ IDxcPixVariable** ppVariable) override; STDMETHODIMP GetVariableByName( _In_ LPCWSTR Name, _Outptr_result_z_ IDxcPixVariable** ppVariable) override; }; } // namespace dxil_debug_info STDMETHODIMP dxil_debug_info::DxcPixDxilLiveVariables::GetCount( _Outptr_ 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(Var)) { return NewDxcPixDxilDebugInfoObjectOrThrow>( ppVariable, m_pMalloc, m_pDxilDebugInfo, DILV, VarInfo); } else if (auto *DIGV = llvm::dyn_cast(Var)) { return NewDxcPixDxilDebugInfoObjectOrThrow>( ppVariable, m_pMalloc, m_pDxilDebugInfo, DIGV, VarInfo); } return E_UNEXPECTED; } STDMETHODIMP dxil_debug_info::DxcPixDxilLiveVariables::GetVariableByIndex( _In_ DWORD Index, _Outptr_result_z_ 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( _In_ LPCWSTR Name, _Outptr_result_z_ IDxcPixVariable **ppVariable) { std::string name = 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 &&LiveVariables, IDxcPixDxilLiveVariables **ppResult) { return NewDxcPixDxilDebugInfoObjectOrThrow( ppResult, pDxilDebugInfo->GetMallocNoRef(), pDxilDebugInfo, std::move(LiveVariables)); }