DxilDiaSymbolManager.cpp 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilDiaSymbolsManager.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 "DxilDiaSymbolManager.h"
  12. #include <cctype>
  13. #include <functional>
  14. #include <type_traits>
  15. #include <comdef.h>
  16. #include "dxc/DxilPIXPasses/DxilPIXVirtualRegisters.h"
  17. #include "dxc/Support/Unicode.h"
  18. #include "llvm/ADT/DenseMap.h"
  19. #include "llvm/ADT/STLExtras.h"
  20. #include "llvm/IR/Constants.h"
  21. #include "llvm/IR/DebugInfo.h"
  22. #include "llvm/IR/DebugInfoMetadata.h"
  23. #include "llvm/IR/Function.h"
  24. #include "llvm/IR/Instructions.h"
  25. #include "llvm/IR/Intrinsics.h"
  26. #include "llvm/IR/Module.h"
  27. #include "llvm/Support/raw_ostream.h"
  28. #include "DxilDiaSession.h"
  29. #include "DxilDiaTableSymbols.h"
  30. static constexpr std::uint32_t kNullSymbolID = 0;
  31. namespace dxil_dia {
  32. namespace hlsl_symbols {
  33. // HLSL Symbol Hierarchy
  34. // ---- ------ ---------
  35. //
  36. // +---------------+
  37. // | Program (EXE) | Global Scope
  38. // +------+--------+
  39. // |
  40. // +--------^-----------+
  41. // | Compiland (Shader) | Compilation Unit
  42. // +--------+-----------+
  43. // |
  44. // +------------+------------+--------+-------+------------+--------------+
  45. // | | | | | | |
  46. // +----^----+ +---^---+ +----^---+ | +---^---+ +----^----+ +-----^-----+
  47. // | Details | | Flags | | Target | | | Entry | | Defines | | Arguments | Synthetic Symbols
  48. // +---------+ +-------+ +--------+ | +-------+ +---------+ +-----------+
  49. // |
  50. // |
  51. // +---------------+------------+----+-----+-------------+-----------+
  52. // | | | | | |
  53. // +-----^-----+ +-----^-----+ +--^--+ +---^--+ +---^--+ +--^--+
  54. // | Function0 | | Function1 | | ... | | UDT0 | | UDT1 | | ... | Source Symbols
  55. // +-----+-----+ +-----+-----+ +-----+ +---+--+ +---+--+ +-----+
  56. // | | | |
  57. // +----^----+ +----^----+ +----^----+ +----^----+
  58. // | Locals0 | | Locals1 | | Fields0 | | Fields1 |
  59. // +---------+ +---------+ +---------+ +---------+
  60. static const std::string & DxilEntryName(Session *pSession);
  61. template <typename S, typename... C, typename = typename std::enable_if<!std::is_same<Symbol, S>::value>::type>
  62. HRESULT AllocAndInit(
  63. IMalloc *pMalloc,
  64. Session *pSession,
  65. DWORD dwIndex,
  66. DWORD dwSymTag,
  67. S **ppSymbol,
  68. C... ctorArgs) {
  69. *ppSymbol = S::Alloc(pMalloc, ctorArgs...);
  70. if (*ppSymbol == nullptr) {
  71. return E_OUTOFMEMORY;
  72. }
  73. (*ppSymbol)->AddRef();
  74. (*ppSymbol)->Init(pSession, dwIndex, dwSymTag);
  75. return S_OK;
  76. }
  77. template <typename T, typename R>
  78. T *dyn_cast_to_ditype(R ref) {
  79. return llvm::dyn_cast<T>((llvm::Metadata *) ref);
  80. }
  81. template <typename T, typename R>
  82. T *dyn_cast_to_ditype_or_null(R ref) {
  83. return llvm::dyn_cast_or_null<T>((llvm::Metadata *) ref);
  84. }
  85. template <typename N>
  86. struct DISymbol : public Symbol {
  87. DISymbol(IMalloc *M, N Node) : Symbol(M), m_pNode(Node) {}
  88. N m_pNode;
  89. };
  90. template <typename N>
  91. struct TypedSymbol : public DISymbol<N> {
  92. TypedSymbol(IMalloc *M, N Node, DWORD dwTypeID, llvm::DIType *Type) : DISymbol(M, Node), m_dwTypeID(dwTypeID), m_pType(Type) {}
  93. STDMETHODIMP get_type(
  94. /* [retval][out] */ IDiaSymbol **ppRetVal) override {
  95. if (ppRetVal == nullptr) {
  96. return E_INVALIDARG;
  97. }
  98. *ppRetVal = false;
  99. if (m_pType == nullptr) {
  100. return S_FALSE;
  101. }
  102. Symbol *ret;
  103. IFR(m_pSession->SymMgr().GetSymbolByID(m_dwTypeID, &ret));
  104. *ppRetVal = ret;
  105. return S_OK;
  106. }
  107. const DWORD m_dwTypeID;
  108. llvm::DIType *m_pType;
  109. };
  110. struct GlobalScopeSymbol : public Symbol {
  111. DXC_MICROCOM_TM_ALLOC(GlobalScopeSymbol)
  112. explicit GlobalScopeSymbol(IMalloc *M) : Symbol(M) {}
  113. static HRESULT Create(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
  114. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  115. };
  116. namespace symbol_factory {
  117. class GlobalScope final : public SymbolManager::SymbolFactory {
  118. public:
  119. GlobalScope(DWORD ID, DWORD ParentID)
  120. : SymbolManager::SymbolFactory(ID, ParentID) {}
  121. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  122. IMalloc *pMalloc = pSession->GetMallocNoRef();
  123. return hlsl_symbols::GlobalScopeSymbol::Create(pMalloc, pSession, ppRet);
  124. }
  125. };
  126. } // namespace symbol_factory
  127. struct CompilandSymbol : public DISymbol<llvm::DICompileUnit *> {
  128. DXC_MICROCOM_TM_ALLOC(CompilandSymbol)
  129. explicit CompilandSymbol(IMalloc *M, llvm::DICompileUnit *CU) : DISymbol<llvm::DICompileUnit *>(M, CU) {}
  130. static HRESULT Create(IMalloc *pMalloc, Session *pSession, llvm::DICompileUnit *CU, Symbol **ppSym);
  131. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  132. };
  133. namespace symbol_factory {
  134. class Compiland final : public SymbolManager::SymbolFactory {
  135. public:
  136. Compiland(DWORD ID, DWORD ParentID, llvm::DICompileUnit *CU)
  137. : SymbolManager::SymbolFactory(ID, ParentID), m_CU(CU) {}
  138. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  139. IMalloc *pMalloc = pSession->GetMallocNoRef();
  140. IFR(hlsl_symbols::CompilandSymbol::Create(pMalloc, pSession, m_CU, ppRet));
  141. (*ppRet)->SetLexicalParent(m_ParentID);
  142. return S_OK;
  143. }
  144. private:
  145. llvm::DICompileUnit *m_CU;
  146. };
  147. } // namespace symbol_factory
  148. struct CompilandDetailsSymbol : public Symbol {
  149. DXC_MICROCOM_TM_ALLOC(CompilandDetailsSymbol)
  150. explicit CompilandDetailsSymbol(IMalloc *M) : Symbol(M) {}
  151. static HRESULT Create(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
  152. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  153. #pragma region IDiaSymbol implementation
  154. // DEFINE_SIMPLE_GETTER is used to generate the boilerplate needed for the
  155. // property getters needed by this symbol. name is the property name (as
  156. // defined in IDiaSymbol::get_<name>. There should be a static (non-const OK)
  157. // function defined in this class as
  158. //
  159. // <RetTy> <name>(CompilandDetailsSymbol * <this>)
  160. //
  161. // <RetTy> **must** match the property type in IDiaSymbol::get_<name>'s
  162. // parameter; <this> is literally the this pointer. The function needs to
  163. // be static (thus requiring the explicit <this> parameter) so that
  164. // DEFINE_SIMPLE_GETTER can use decltype(name(nullptr)) in order to
  165. // define the property parameter type.
  166. #define DEFINE_SIMPLE_GETTER(name) \
  167. STDMETHODIMP get_ ## name(decltype(name(nullptr)) *pValue) override { \
  168. if (pValue == nullptr) { \
  169. return E_INVALIDARG; \
  170. } \
  171. *pValue = name(this); \
  172. return S_OK; \
  173. }
  174. static constexpr DWORD platform(CompilandDetailsSymbol *) { return 256; }
  175. static constexpr DWORD language(CompilandDetailsSymbol *) { return 16; }
  176. static constexpr BOOL hasDebugInfo(CompilandDetailsSymbol *) { return true; }
  177. static BSTR compilerName(CompilandDetailsSymbol *) {
  178. CComBSTR retval;
  179. retval.Append("dxcompiler");
  180. return retval.Detach();
  181. }
  182. static DWORD frontEndMajor(CompilandDetailsSymbol *self) {
  183. return self->m_pSession->DxilModuleRef().GetShaderModel()->GetMajor();
  184. }
  185. static DWORD frontEndMinor(CompilandDetailsSymbol *self) {
  186. return self->m_pSession->DxilModuleRef().GetShaderModel()->GetMinor();
  187. }
  188. DEFINE_SIMPLE_GETTER(platform);
  189. DEFINE_SIMPLE_GETTER(language);
  190. DEFINE_SIMPLE_GETTER(frontEndMajor);
  191. DEFINE_SIMPLE_GETTER(frontEndMinor);
  192. DEFINE_SIMPLE_GETTER(hasDebugInfo);
  193. DEFINE_SIMPLE_GETTER(compilerName);
  194. #undef DEFINE_SIMPLE_GETTER
  195. #pragma endregion
  196. };
  197. namespace symbol_factory {
  198. class CompilandDetails final : public SymbolManager::SymbolFactory {
  199. public:
  200. CompilandDetails(DWORD ID, DWORD ParentID)
  201. : SymbolManager::SymbolFactory(ID, ParentID) {}
  202. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  203. IMalloc *pMalloc = pSession->GetMallocNoRef();
  204. IFR(hlsl_symbols::CompilandDetailsSymbol::Create(pMalloc, pSession, ppRet));
  205. (*ppRet)->SetLexicalParent(m_ParentID);
  206. return S_OK;
  207. }
  208. };
  209. } // namespace symbol_factory
  210. struct CompilandEnvSymbol : public Symbol {
  211. DXC_MICROCOM_TM_ALLOC(CompilandEnvSymbol)
  212. explicit CompilandEnvSymbol(IMalloc *M) : Symbol(M) {}
  213. static HRESULT CreateFlags(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
  214. static HRESULT CreateTarget(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
  215. static HRESULT CreateEntry(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
  216. static HRESULT CreateDefines(IMalloc *pMalloc, Session *pSession, Symbol **pSym);
  217. static HRESULT CreateArguments(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
  218. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  219. };
  220. namespace symbol_factory {
  221. using CompilandEnvCreateFn = HRESULT(IMalloc *, Session *, Symbol **);
  222. template<CompilandEnvCreateFn C>
  223. class CompilandEnv final : public SymbolManager::SymbolFactory {
  224. public:
  225. CompilandEnv(DWORD ID, DWORD ParentID)
  226. : SymbolManager::SymbolFactory(ID, ParentID) {}
  227. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  228. IMalloc *pMalloc = pSession->GetMallocNoRef();
  229. IFR(C(pMalloc, pSession, ppRet));
  230. (*ppRet)->SetLexicalParent(m_ParentID);
  231. return S_OK;
  232. }
  233. };
  234. } // namespace symbol_factory
  235. struct FunctionSymbol : public TypedSymbol<llvm::DISubprogram *> {
  236. DXC_MICROCOM_TM_ALLOC(FunctionSymbol)
  237. FunctionSymbol(IMalloc *M, llvm::DISubprogram *Node, DWORD dwTypeID, llvm::DIType *Type) : TypedSymbol<llvm::DISubprogram *>(M, Node, dwTypeID, Type) {}
  238. static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DISubprogram *Node, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym);
  239. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  240. };
  241. namespace symbol_factory {
  242. class Function final : public SymbolManager::SymbolFactory {
  243. public:
  244. Function(DWORD ID, DWORD ParentID, llvm::DISubprogram *Node, DWORD TypeID)
  245. : SymbolManager::SymbolFactory(ID, ParentID),
  246. m_Node(Node), m_TypeID(TypeID) {}
  247. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  248. IMalloc *pMalloc = pSession->GetMallocNoRef();
  249. IFR(FunctionSymbol::Create(pMalloc, pSession, m_ID, m_Node, m_TypeID, m_Node->getType(), ppRet));
  250. (*ppRet)->SetLexicalParent(m_ParentID);
  251. (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
  252. return S_OK;
  253. }
  254. private:
  255. llvm::DISubprogram *m_Node;
  256. DWORD m_TypeID;
  257. };
  258. } // namespace symbol_factory
  259. struct FunctionBlockSymbol : public Symbol {
  260. DXC_MICROCOM_TM_ALLOC(FunctionBlockSymbol)
  261. explicit FunctionBlockSymbol(IMalloc *M) : Symbol(M) {}
  262. static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, Symbol **ppSym);
  263. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  264. };
  265. namespace symbol_factory {
  266. class FunctionBlock final : public SymbolManager::SymbolFactory {
  267. public:
  268. FunctionBlock(DWORD ID, DWORD ParentID)
  269. : SymbolManager::SymbolFactory(ID, ParentID) {}
  270. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  271. IMalloc *pMalloc = pSession->GetMallocNoRef();
  272. IFR(FunctionBlockSymbol::Create(pMalloc, pSession, m_ID, ppRet));
  273. (*ppRet)->SetLexicalParent(m_ParentID);
  274. return S_OK;
  275. }
  276. };
  277. } // namespace symbol_factory
  278. struct TypeSymbol : public DISymbol<llvm::DIType *> {
  279. using LazySymbolName = std::function<HRESULT(Session *, std::string *)>;
  280. DXC_MICROCOM_TM_ALLOC(TypeSymbol)
  281. TypeSymbol(IMalloc *M, llvm::DIType *Node, LazySymbolName LazySymbolName) : DISymbol<llvm::DIType *>(M, Node), m_lazySymbolName(LazySymbolName) {}
  282. static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, DWORD st, llvm::DIType *Node, LazySymbolName LazySymbolName, Symbol **ppSym);
  283. STDMETHODIMP get_name(
  284. /* [retval][out] */ BSTR *pRetVal) override;
  285. STDMETHODIMP get_baseType(
  286. /* [retval][out] */ DWORD *pRetVal) override;
  287. STDMETHODIMP get_length(
  288. /* [retval][out] */ ULONGLONG *pRetVal) override;
  289. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  290. LazySymbolName m_lazySymbolName;
  291. };
  292. namespace symbol_factory {
  293. class Type final : public SymbolManager::SymbolFactory {
  294. public:
  295. Type(DWORD ID, DWORD ParentID, DWORD st, llvm::DIType *Node, TypeSymbol::LazySymbolName LazySymbolName)
  296. : SymbolManager::SymbolFactory(ID, ParentID),
  297. m_st(st), m_Node(Node), m_LazySymbolName(LazySymbolName) {}
  298. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  299. IMalloc *pMalloc = pSession->GetMallocNoRef();
  300. IFR(TypeSymbol::Create(pMalloc, pSession, m_ParentID, m_ID, m_st, m_Node, m_LazySymbolName, ppRet));
  301. (*ppRet)->SetLexicalParent(m_ParentID);
  302. return S_OK;
  303. }
  304. private:
  305. DWORD m_st;
  306. llvm::DIType *m_Node;
  307. TypeSymbol::LazySymbolName m_LazySymbolName;
  308. };
  309. } // namespace symbol_factory
  310. struct TypedefTypeSymbol : public TypeSymbol {
  311. DXC_MICROCOM_TM_ALLOC(TypedefTypeSymbol)
  312. TypedefTypeSymbol(IMalloc *M, llvm::DIType *Node, DWORD dwBaseTypeID) : TypeSymbol(M, Node, nullptr), m_dwBaseTypeID(dwBaseTypeID) {}
  313. static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DIType *Node, DWORD dwBaseTypeID, Symbol **ppSym);
  314. STDMETHODIMP get_type(
  315. /* [retval][out] */ IDiaSymbol **ppRetVal) override;
  316. const DWORD m_dwBaseTypeID;
  317. };
  318. namespace symbol_factory {
  319. class TypedefType final : public SymbolManager::SymbolFactory {
  320. public:
  321. TypedefType(DWORD ID, DWORD ParentID, llvm::DIType *Node, DWORD BaseTypeID)
  322. : SymbolManager::SymbolFactory(ID, ParentID),
  323. m_Node(Node), m_BaseTypeID(BaseTypeID) {}
  324. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  325. IMalloc *pMalloc = pSession->GetMallocNoRef();
  326. IFR(TypedefTypeSymbol::Create(pMalloc, pSession, m_ParentID, m_ID, m_Node, m_BaseTypeID, ppRet));
  327. (*ppRet)->SetLexicalParent(m_ParentID);
  328. (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
  329. return S_OK;
  330. }
  331. private:
  332. llvm::DIType *m_Node;
  333. DWORD m_BaseTypeID;
  334. };
  335. } // namespace symbol_factory
  336. struct VectorTypeSymbol : public TypeSymbol {
  337. DXC_MICROCOM_TM_ALLOC(VectorTypeSymbol)
  338. VectorTypeSymbol(IMalloc *M, llvm::DIType *Node, DWORD dwElemTyID, std::uint32_t NumElts) : TypeSymbol(M, Node, nullptr), m_ElemTyID(dwElemTyID), m_NumElts(NumElts) {}
  339. static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DIType *Node, DWORD dwElemTyID, std::uint32_t NumElts, Symbol **ppSym);
  340. STDMETHODIMP get_count(
  341. /* [retval][out] */ DWORD *pRetVal) override;
  342. STDMETHODIMP get_type(
  343. /* [retval][out] */ IDiaSymbol **ppRetVal) override;
  344. std::uint32_t m_ElemTyID;
  345. std::uint32_t m_NumElts;
  346. };
  347. namespace symbol_factory {
  348. class VectorType final : public SymbolManager::SymbolFactory {
  349. public:
  350. VectorType(DWORD ID, DWORD ParentID, llvm::DIType *Node, DWORD ElemTyID, std::uint32_t NumElts)
  351. : SymbolManager::SymbolFactory(ID, ParentID),
  352. m_Node(Node), m_ElemTyID(ElemTyID), m_NumElts(NumElts) {}
  353. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  354. IMalloc *pMalloc = pSession->GetMallocNoRef();
  355. IFR(VectorTypeSymbol::Create(pMalloc, pSession, m_ParentID, m_ID, m_Node, m_ElemTyID, m_NumElts, ppRet));
  356. (*ppRet)->SetLexicalParent(m_ParentID);
  357. (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
  358. return S_OK;
  359. }
  360. private:
  361. llvm::DIType *m_Node;
  362. DWORD m_ElemTyID;
  363. std::uint32_t m_NumElts;
  364. };
  365. } // namespace symbol_factory
  366. struct UDTSymbol : public TypeSymbol {
  367. DXC_MICROCOM_TM_ALLOC(UDTSymbol)
  368. UDTSymbol(IMalloc *M, llvm::DICompositeType *Node, LazySymbolName LazyName) : TypeSymbol(M, Node, LazyName) {}
  369. static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DICompositeType *Node, LazySymbolName LazySymbolName, Symbol **ppSym);
  370. };
  371. namespace symbol_factory {
  372. class UDT final : public SymbolManager::SymbolFactory {
  373. public:
  374. UDT(DWORD ID, DWORD ParentID, llvm::DICompositeType *Node, TypeSymbol::LazySymbolName LazySymbolName)
  375. : SymbolManager::SymbolFactory(ID, ParentID),
  376. m_Node(Node), m_LazySymbolName(LazySymbolName) {}
  377. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  378. IMalloc *pMalloc = pSession->GetMallocNoRef();
  379. IFR(UDTSymbol::Create(pMalloc, pSession, m_ParentID, m_ID, m_Node, m_LazySymbolName, ppRet));
  380. (*ppRet)->SetLexicalParent(m_ParentID);
  381. return S_OK;
  382. }
  383. private:
  384. llvm::DICompositeType *m_Node;
  385. TypeSymbol::LazySymbolName m_LazySymbolName;
  386. };
  387. } // namespace symbol_factory
  388. struct GlobalVariableSymbol : public TypedSymbol<llvm::DIGlobalVariable *> {
  389. DXC_MICROCOM_TM_ALLOC(GlobalVariableSymbol)
  390. GlobalVariableSymbol(IMalloc *M, llvm::DIGlobalVariable *GV, DWORD dwTypeID, llvm::DIType *Type) : TypedSymbol<llvm::DIGlobalVariable *>(M, GV, dwTypeID, Type) {}
  391. static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIGlobalVariable *GV, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym);
  392. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  393. };
  394. namespace symbol_factory {
  395. class GlobalVariable final : public SymbolManager::SymbolFactory {
  396. public:
  397. GlobalVariable(DWORD ID, DWORD ParentID, llvm::DIGlobalVariable *GV, DWORD TypeID, llvm::DIType *Type)
  398. : SymbolManager::SymbolFactory(ID, ParentID),
  399. m_GV(GV), m_TypeID(TypeID), m_Type(Type) {}
  400. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  401. IMalloc *pMalloc = pSession->GetMallocNoRef();
  402. IFR(GlobalVariableSymbol::Create(pMalloc, pSession, m_ID, m_GV, m_TypeID, m_Type, ppRet));
  403. (*ppRet)->SetLexicalParent(m_ParentID);
  404. (*ppRet)->SetName(CA2W(m_GV->getName().str().c_str(), CP_UTF8));
  405. (*ppRet)->SetIsHLSLData(true);
  406. return S_OK;
  407. }
  408. private:
  409. llvm::DIGlobalVariable *m_GV;
  410. DWORD m_TypeID;
  411. llvm::DIType *m_Type;
  412. };
  413. } // namespace symbol_factory
  414. struct LocalVariableSymbol : public TypedSymbol<llvm::DIVariable *> {
  415. DXC_MICROCOM_TM_ALLOC(LocalVariableSymbol)
  416. LocalVariableSymbol(IMalloc *M, llvm::DIVariable *Node, DWORD dwTypeID, llvm::DIType *Type, DWORD dwOffsetInUDT, DWORD dwDxilRegNum) : TypedSymbol<llvm::DIVariable *>(M, Node, dwTypeID, Type), m_dwOffsetInUDT(dwOffsetInUDT), m_dwDxilRegNum(dwDxilRegNum) {}
  417. static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIVariable *Node, DWORD dwTypeID, llvm::DIType *Type, DWORD dwOffsetInUDT, DWORD m_dwDxilRegNum, Symbol **ppSym);
  418. STDMETHODIMP get_locationType(
  419. /* [retval][out] */ DWORD *pRetVal) override;
  420. STDMETHODIMP get_isAggregated(
  421. /* [retval][out] */ BOOL *pRetVal) override;
  422. STDMETHODIMP get_registerType(
  423. /* [retval][out] */ DWORD *pRetVal) override;
  424. STDMETHODIMP get_offsetInUdt(
  425. /* [retval][out] */ DWORD *pRetVal) override;
  426. STDMETHODIMP get_sizeInUdt(
  427. /* [retval][out] */ DWORD *pRetVal) override;
  428. STDMETHODIMP get_numberOfRegisterIndices(
  429. /* [retval][out] */ DWORD *pRetVal) override;
  430. STDMETHODIMP get_numericProperties(
  431. /* [in] */ DWORD cnt,
  432. /* [out] */ DWORD *pcnt,
  433. /* [size_is][out] */ DWORD *pProperties) override;
  434. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  435. const DWORD m_dwOffsetInUDT;
  436. const DWORD m_dwDxilRegNum;
  437. };
  438. namespace symbol_factory {
  439. class LocalVarInfo {
  440. public:
  441. LocalVarInfo() = default;
  442. LocalVarInfo(const LocalVarInfo &) = delete;
  443. LocalVarInfo(LocalVarInfo &&) = default;
  444. DWORD GetVarID() const { return m_dwVarID; }
  445. DWORD GetOffsetInUDT() const { return m_dwOffsetInUDT; }
  446. DWORD GetDxilRegister() const { return m_dwDxilRegister; }
  447. void SetVarID(DWORD dwVarID) { m_dwVarID = dwVarID; }
  448. void SetOffsetInUDT(DWORD dwOffsetInUDT) { m_dwOffsetInUDT = dwOffsetInUDT; }
  449. void SetDxilRegister(DWORD dwDxilReg) { m_dwDxilRegister = dwDxilReg; }
  450. private:
  451. DWORD m_dwVarID = 0;
  452. DWORD m_dwOffsetInUDT = 0;
  453. DWORD m_dwDxilRegister = 0;
  454. };
  455. class LocalVariable final : public SymbolManager::SymbolFactory {
  456. public:
  457. LocalVariable(DWORD ID, DWORD ParentID, llvm::DIVariable *Node, DWORD TypeID, llvm::DIType *Type, std::shared_ptr<LocalVarInfo> VI)
  458. : SymbolManager::SymbolFactory(ID, ParentID),
  459. m_Node(Node), m_TypeID(TypeID), m_Type(Type), m_VI(VI) {}
  460. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  461. IMalloc *pMalloc = pSession->GetMallocNoRef();
  462. IFR(LocalVariableSymbol::Create(pMalloc, pSession, m_ID, m_Node, m_TypeID, m_Type, m_VI->GetOffsetInUDT(), m_VI->GetDxilRegister(), ppRet));
  463. (*ppRet)->SetLexicalParent(m_ParentID);
  464. (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
  465. (*ppRet)->SetDataKind(m_Node->getTag() == llvm::dwarf::DW_TAG_arg_variable ? DataIsParam : DataIsLocal);
  466. return S_OK;
  467. }
  468. private:
  469. llvm::DIVariable *m_Node;
  470. DWORD m_TypeID;
  471. llvm::DIType *m_Type;
  472. std::shared_ptr<LocalVarInfo> m_VI;
  473. };
  474. } // namespace symbol_factory
  475. struct UDTFieldSymbol : public TypedSymbol<llvm::DIDerivedType *> {
  476. DXC_MICROCOM_TM_ALLOC(UDTFieldSymbol)
  477. UDTFieldSymbol(IMalloc *M, llvm::DIDerivedType *Node, DWORD dwTypeID, llvm::DIType *Type) : TypedSymbol<llvm::DIDerivedType *>(M, Node, dwTypeID, Type) {}
  478. static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIDerivedType *Node, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym);
  479. STDMETHODIMP get_offset(
  480. /* [retval][out] */ LONG *pRetVal) override;
  481. HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
  482. };
  483. namespace symbol_factory {
  484. class UDTField final : public SymbolManager::SymbolFactory {
  485. public:
  486. UDTField(DWORD ID, DWORD ParentID, llvm::DIDerivedType *Node, DWORD TypeID, llvm::DIType *Type)
  487. : SymbolManager::SymbolFactory(ID, ParentID),
  488. m_Node(Node), m_TypeID(TypeID), m_Type(Type) {}
  489. virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
  490. IMalloc *pMalloc = pSession->GetMallocNoRef();
  491. IFR(UDTFieldSymbol::Create(pMalloc, pSession, m_ID, m_Node, m_TypeID, m_Type, ppRet));
  492. (*ppRet)->SetLexicalParent(m_ParentID);
  493. (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
  494. (*ppRet)->SetDataKind(m_Node->isStaticMember() ? DataIsStaticLocal : DataIsMember);
  495. return S_OK;
  496. }
  497. private:
  498. llvm::DIDerivedType *m_Node;
  499. DWORD m_TypeID;
  500. llvm::DIType *m_Type;
  501. };
  502. } // namespace symbol_factory
  503. class SymbolManagerInit {
  504. public:
  505. using SymbolCtor = std::function<HRESULT(Session *pSession, DWORD ID, Symbol **ppSym)>;
  506. using LazySymbolName = TypeSymbol::LazySymbolName;
  507. class TypeInfo {
  508. public:
  509. TypeInfo() = delete;
  510. TypeInfo(const TypeInfo &) = delete;
  511. TypeInfo(TypeInfo &&) = default;
  512. explicit TypeInfo(DWORD dwTypeID) : m_dwTypeID(dwTypeID) {}
  513. DWORD GetTypeID() const { return m_dwTypeID; }
  514. DWORD GetCurrentSizeInBytes() const { return m_dwCurrentSizeInBytes; }
  515. const std::vector<llvm::DIType *> &GetLayout() const { return m_Layout; }
  516. void Embed(const TypeInfo &TI);
  517. void AddBasicType(llvm::DIBasicType *BT);
  518. private:
  519. DWORD m_dwTypeID;
  520. std::vector<llvm::DIType *> m_Layout;
  521. DWORD m_dwCurrentSizeInBytes = 0;
  522. };
  523. using TypeToInfoMap = llvm::DenseMap<llvm::DIType *, std::unique_ptr<TypeInfo> >;
  524. // Because of the way the VarToID map is constructed, the
  525. // vector<LocalVarInfo> may need to grow. The Symbol Constructor for local
  526. // variable captures the LocalVarInfo for the local variable it creates, and
  527. // it needs access to the information on this map (thus a by-value capture is
  528. // not enough). We heap-allocate the VarInfos, and the local variables symbol
  529. // constructors capture the pointer - meaning everything should be fine
  530. // even if the vector is moved around.
  531. using LocalVarToIDMap = llvm::DenseMap<
  532. llvm::DILocalVariable *,
  533. std::vector<std::shared_ptr<symbol_factory::LocalVarInfo>>>;
  534. using UDTFieldToIDMap = llvm::DenseMap<llvm::DIDerivedType *, DWORD>;
  535. SymbolManagerInit(
  536. Session *pSession,
  537. std::vector<std::unique_ptr<SymbolManager::SymbolFactory>> *pSymCtors,
  538. SymbolManager::ScopeToIDMap *pScopeToSym,
  539. SymbolManager::IDToLiveRangeMap *pSymToLR);
  540. template <typename Factory, typename... Args>
  541. HRESULT AddSymbol(DWORD dwParentID, DWORD *pNewSymID, Args&&... args) {
  542. if (dwParentID > m_SymCtors.size()) {
  543. return E_FAIL;
  544. }
  545. const DWORD dwNewSymID = m_SymCtors.size() + 1;
  546. m_SymCtors.emplace_back(std::unique_ptr<Factory>(new Factory(dwNewSymID, dwParentID, std::forward<Args>(args)...)));
  547. *pNewSymID = dwNewSymID;
  548. IFR(AddParent(dwParentID));
  549. return S_OK;
  550. }
  551. HRESULT CreateFunctionsForAllCUs();
  552. HRESULT CreateGlobalVariablesForAllCUs();
  553. HRESULT CreateLocalVariables();
  554. HRESULT CreateLiveRanges();
  555. HRESULT IsDbgDeclareCall(llvm::Module *M, const llvm::Instruction *I,
  556. DWORD *pReg, DWORD *pRegSize,
  557. llvm::DILocalVariable **LV, uint64_t *pStartOffset,
  558. uint64_t *pEndOffset,
  559. dxil_dia::Session::RVA *pLowestUserRVA,
  560. dxil_dia::Session::RVA *pHighestUserRVA);
  561. HRESULT GetDxilAllocaRegister(llvm::Instruction *I, DWORD *pRegNum, DWORD *pRegSize);
  562. HRESULT PopulateParentToChildrenIDMap(SymbolManager::ParentToChildrenMap *pParentToChildren);
  563. private:
  564. HRESULT GetTypeInfo(llvm::DIType *T, TypeInfo **TI);
  565. template<typename Factory, typename... Args>
  566. HRESULT AddType(DWORD dwParentID, llvm::DIType *T, DWORD *pNewSymID, Args&&... args) {
  567. IFR(AddSymbol<Factory>(dwParentID, pNewSymID, std::forward<Args>(args)...));
  568. if (!m_TypeToInfo.insert(std::make_pair(T, llvm::make_unique<TypeInfo>(*pNewSymID))).second) {
  569. return E_FAIL;
  570. }
  571. return S_OK;
  572. }
  573. HRESULT AddParent(DWORD dwParentIndex);
  574. HRESULT CreateFunctionBlockForLocalScope(llvm::DILocalScope *LS, DWORD *pNewSymID);
  575. HRESULT CreateFunctionBlockForInstruction(llvm::Instruction *I);
  576. HRESULT CreateFunctionBlocksForFunction(llvm::Function *F);
  577. HRESULT CreateFunctionsForCU(llvm::DICompileUnit *CU);
  578. HRESULT CreateGlobalVariablesForCU(llvm::DICompileUnit *CU);
  579. HRESULT GetScopeID(llvm::DIScope *S, DWORD *pScopeID);
  580. HRESULT CreateType(llvm::DIType *T, DWORD *pNewTypeID);
  581. HRESULT CreateSubroutineType(DWORD dwParentID, llvm::DISubroutineType *ST, DWORD *pNewTypeID);
  582. HRESULT CreateBasicType(DWORD dwParentID, llvm::DIBasicType *VT, DWORD *pNewTypeID);
  583. HRESULT CreateCompositeType(DWORD dwParentID, llvm::DICompositeType *CT, DWORD *pNewTypeID);
  584. HRESULT CreateHLSLType(llvm::DICompositeType *T, DWORD *pNewTypeID);
  585. HRESULT IsHLSLVectorType(llvm::DICompositeType *T, DWORD *pEltTyID, std::uint32_t *pElemCnt);
  586. HRESULT CreateHLSLVectorType(llvm::DICompositeType *T, DWORD pEltTyID, std::uint32_t pElemCnt, DWORD *pNewTypeID);
  587. HRESULT HandleDerivedType(DWORD dwParentID, llvm::DIDerivedType *DT, DWORD *pNewTypeID);
  588. HRESULT CreateLocalVariable(DWORD dwParentID, llvm::DILocalVariable *LV);
  589. HRESULT GetTypeLayout(llvm::DIType *Ty, std::vector<DWORD> *pRet);
  590. HRESULT CreateUDTField(DWORD dwParentID, llvm::DIDerivedType *Field);
  591. Session &m_Session;
  592. std::vector<std::unique_ptr<SymbolManager::SymbolFactory>> &m_SymCtors;
  593. SymbolManager::ScopeToIDMap &m_ScopeToSym;
  594. SymbolManager::IDToLiveRangeMap &m_SymToLR;
  595. // vector of parents, i.e., for each i in parents[i], parents[i] is the
  596. // parent of m_symbol[i].
  597. std::vector<std::uint32_t> m_Parent;
  598. LocalVarToIDMap m_VarToID;
  599. UDTFieldToIDMap m_FieldToID;
  600. TypeToInfoMap m_TypeToInfo;
  601. TypeInfo &CurrentUDTInfo() { return *m_pCurUDT; }
  602. TypeInfo *m_pCurUDT = nullptr;
  603. struct UDTScope {
  604. UDTScope() = delete;
  605. UDTScope(const UDTScope &) = delete;
  606. UDTScope(UDTScope &&) = default;
  607. UDTScope(TypeInfo **pCur, TypeInfo *pNext) : m_pCur(pCur), m_pPrev(*pCur) {
  608. *pCur = pNext;
  609. }
  610. ~UDTScope() { *m_pCur = m_pPrev; }
  611. TypeInfo **m_pCur;
  612. TypeInfo *m_pPrev;
  613. };
  614. UDTScope BeginUDTScope(TypeInfo *pNext) {
  615. return UDTScope(&m_pCurUDT, pNext);
  616. }
  617. };
  618. } // namespace hlsl_symbols
  619. } // namespace dxil_dia
  620. STDMETHODIMP dxil_dia::hlsl_symbols::TypeSymbol::get_baseType(
  621. /* [retval][out] */ DWORD *pRetVal) {
  622. if (pRetVal == nullptr) {
  623. return E_INVALIDARG;
  624. }
  625. *pRetVal = btNoType;
  626. if (auto *BT = llvm::dyn_cast<llvm::DIBasicType>(m_pNode)) {
  627. const DWORD SizeInBits = BT->getSizeInBits();
  628. switch (BT->getEncoding()) {
  629. case llvm::dwarf::DW_ATE_boolean:
  630. *pRetVal = btBool; break;
  631. case llvm::dwarf::DW_ATE_unsigned:
  632. *pRetVal = btUInt; break;
  633. case llvm::dwarf::DW_ATE_signed:
  634. *pRetVal = btInt; break;
  635. case llvm::dwarf::DW_ATE_float:
  636. *pRetVal = btFloat; break;
  637. }
  638. }
  639. return S_OK;
  640. }
  641. STDMETHODIMP dxil_dia::hlsl_symbols::TypeSymbol::get_length(
  642. /* [retval][out] */ ULONGLONG *pRetVal) {
  643. if (pRetVal == nullptr) {
  644. return E_INVALIDARG;
  645. }
  646. *pRetVal = 0;
  647. if (auto *BT = llvm::dyn_cast<llvm::DIBasicType>(m_pNode)) {
  648. static constexpr DWORD kNumBitsPerByte = 8;
  649. const DWORD SizeInBits = BT->getSizeInBits();
  650. *pRetVal = SizeInBits / kNumBitsPerByte;
  651. }
  652. return S_OK;
  653. }
  654. static const std::string &dxil_dia::hlsl_symbols::DxilEntryName(Session *pSession) {
  655. return pSession->DxilModuleRef().GetEntryFunctionName();
  656. }
  657. HRESULT dxil_dia::hlsl_symbols::GlobalScopeSymbol::Create(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
  658. IFR(AllocAndInit(pMalloc, pSession, HlslProgramId, SymTagExe, (GlobalScopeSymbol**)ppSym));
  659. (*ppSym)->SetName(L"HLSL");
  660. return S_OK;
  661. }
  662. HRESULT dxil_dia::hlsl_symbols::GlobalScopeSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  663. return m_pSession->SymMgr().ChildrenOf(this, children);
  664. }
  665. HRESULT dxil_dia::hlsl_symbols::CompilandSymbol::Create(IMalloc *pMalloc, Session *pSession, llvm::DICompileUnit *CU, Symbol **ppSym) {
  666. IFR(AllocAndInit(pMalloc, pSession, HlslCompilandId, SymTagCompiland, (CompilandSymbol**)ppSym, CU));
  667. (*ppSym)->SetName(L"main");
  668. if (pSession->MainFileName()) {
  669. llvm::StringRef strRef = llvm::dyn_cast<llvm::MDString>(pSession->MainFileName()->getOperand(0)->getOperand(0))->getString();
  670. std::string str(strRef.begin(), strRef.size()); // To make sure str is null terminated
  671. (*ppSym)->SetSourceFileName(_bstr_t(Unicode::UTF8ToUTF16StringOrThrow(str.data()).c_str()));
  672. }
  673. return S_OK;
  674. }
  675. HRESULT dxil_dia::hlsl_symbols::CompilandSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  676. return m_pSession->SymMgr().ChildrenOf(this, children);
  677. }
  678. HRESULT dxil_dia::hlsl_symbols::CompilandDetailsSymbol::Create(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
  679. IFR(AllocAndInit(pMalloc, pSession, HlslCompilandDetailsId, SymTagCompilandDetails, (CompilandDetailsSymbol**)ppSym));
  680. return S_OK;
  681. }
  682. HRESULT dxil_dia::hlsl_symbols::CompilandDetailsSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  683. children->clear();
  684. return S_OK;
  685. }
  686. HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateFlags(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
  687. IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvFlagsId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
  688. (*ppSym)->SetName(L"hlslFlags");
  689. const char *specialCases[] = { "/T", "-T", "-D", "/D", "-E", "/E", };
  690. llvm::MDNode *argsNode = pSession->Arguments()->getOperand(0);
  691. // Construct a double null terminated string for defines with L"\0" as a delimiter
  692. CComBSTR pBSTR;
  693. for (llvm::MDNode::op_iterator it = argsNode->op_begin(); it != argsNode->op_end(); ++it) {
  694. llvm::StringRef strRef = llvm::dyn_cast<llvm::MDString>(*it)->getString();
  695. bool skip = false;
  696. bool skipTwice = false;
  697. for (unsigned i = 0; i < _countof(specialCases); i++) {
  698. if (strRef == specialCases[i]) {
  699. skipTwice = true;
  700. skip = true;
  701. break;
  702. }
  703. else if (strRef.startswith(specialCases[i])) {
  704. skip = true;
  705. break;
  706. }
  707. }
  708. if (skip) {
  709. if (skipTwice)
  710. ++it;
  711. continue;
  712. }
  713. std::string str(strRef.begin(), strRef.size());
  714. CA2W cv(str.c_str(), CP_UTF8);
  715. pBSTR.Append(cv);
  716. pBSTR.Append(L"\0", 1);
  717. }
  718. pBSTR.Append(L"\0", 1);
  719. VARIANT Variant;
  720. Variant.bstrVal = pBSTR;
  721. Variant.vt = VARENUM::VT_BSTR;
  722. (*ppSym)->SetValue(&Variant);
  723. return S_OK;
  724. }
  725. HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateTarget(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
  726. IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvTargetId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
  727. (*ppSym)->SetName(L"hlslTarget");
  728. (*ppSym)->SetValue(pSession->DxilModuleRef().GetShaderModel()->GetName());
  729. return S_OK;
  730. }
  731. HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateEntry(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
  732. IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvEntryId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
  733. (*ppSym)->SetName(L"hlslEntry");
  734. (*ppSym)->SetValue(DxilEntryName(pSession).c_str());
  735. return S_OK;
  736. }
  737. HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateDefines(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
  738. IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvDefinesId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
  739. (*ppSym)->SetName(L"hlslDefines");
  740. llvm::MDNode *definesNode = pSession->Defines()->getOperand(0);
  741. // Construct a double null terminated string for defines with L"\0" as a delimiter
  742. CComBSTR pBSTR;
  743. for (llvm::MDNode::op_iterator it = definesNode->op_begin(); it != definesNode->op_end(); ++it) {
  744. llvm::StringRef strRef = llvm::dyn_cast<llvm::MDString>(*it)->getString();
  745. std::string str(strRef.begin(), strRef.size());
  746. CA2W cv(str.c_str(), CP_UTF8);
  747. pBSTR.Append(cv);
  748. pBSTR.Append(L"\0", 1);
  749. }
  750. pBSTR.Append(L"\0", 1);
  751. VARIANT Variant;
  752. Variant.bstrVal = pBSTR;
  753. Variant.vt = VARENUM::VT_BSTR;
  754. (*ppSym)->SetValue(&Variant);
  755. return S_OK;
  756. }
  757. HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateArguments(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
  758. IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvArgumentsId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
  759. (*ppSym)->SetName(L"hlslArguments");
  760. auto Arguments = pSession->Arguments()->getOperand(0);
  761. auto NumArguments = Arguments->getNumOperands();
  762. std::string args;
  763. for (unsigned i = 0; i < NumArguments; ++i) {
  764. llvm::StringRef strRef = llvm::dyn_cast<llvm::MDString>(Arguments->getOperand(i))->getString();
  765. if (!args.empty())
  766. args.push_back(' ');
  767. args = args + strRef.str();
  768. }
  769. (*ppSym)->SetValue(args.c_str());
  770. return S_OK;
  771. }
  772. HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  773. children->clear();
  774. return S_OK;
  775. }
  776. HRESULT dxil_dia::hlsl_symbols::FunctionSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DISubprogram *Node, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym) {
  777. IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagFunction, (FunctionSymbol**)ppSym, Node, dwTypeID, Type));
  778. return S_OK;
  779. }
  780. HRESULT dxil_dia::hlsl_symbols::FunctionSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  781. return m_pSession->SymMgr().ChildrenOf(this, children);
  782. }
  783. HRESULT dxil_dia::hlsl_symbols::FunctionBlockSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, Symbol **ppSym) {
  784. IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagBlock, (FunctionBlockSymbol**)ppSym));
  785. return S_OK;
  786. }
  787. HRESULT dxil_dia::hlsl_symbols::FunctionBlockSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  788. return m_pSession->SymMgr().ChildrenOf(this, children);
  789. }
  790. HRESULT dxil_dia::hlsl_symbols::TypeSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, DWORD st, llvm::DIType *Node, LazySymbolName LazySymbolName, Symbol **ppSym) {
  791. IFR(AllocAndInit(pMalloc, pSession, dwID, st, (TypeSymbol**)ppSym, Node, LazySymbolName));
  792. return S_OK;
  793. }
  794. STDMETHODIMP dxil_dia::hlsl_symbols::TypeSymbol::get_name(
  795. /* [retval][out] */ BSTR *pRetVal) {
  796. DxcThreadMalloc TM(m_pSession->GetMallocNoRef());
  797. if (m_lazySymbolName != nullptr) {
  798. DXASSERT(!this->HasName(), "Setting type name multiple times.");
  799. std::string Name;
  800. IFR(m_lazySymbolName(m_pSession, &Name));
  801. this->SetName(CA2W(Name.c_str(), CP_UTF8));
  802. m_lazySymbolName = nullptr;
  803. }
  804. return Symbol::get_name(pRetVal);
  805. }
  806. HRESULT dxil_dia::hlsl_symbols::TypeSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  807. return m_pSession->SymMgr().ChildrenOf(this, children);
  808. }
  809. HRESULT dxil_dia::hlsl_symbols::VectorTypeSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DIType *Node, DWORD dwElemTyID, std::uint32_t NumElts, Symbol **ppSym) {
  810. IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagVectorType, (VectorTypeSymbol**)ppSym, Node, dwElemTyID, NumElts));
  811. return S_OK;
  812. }
  813. STDMETHODIMP dxil_dia::hlsl_symbols::VectorTypeSymbol::get_count(
  814. /* [retval][out] */ DWORD *pRetVal) {
  815. if (pRetVal == nullptr) {
  816. return E_INVALIDARG;
  817. }
  818. *pRetVal = m_NumElts;
  819. return S_OK;
  820. }
  821. STDMETHODIMP dxil_dia::hlsl_symbols::VectorTypeSymbol::get_type(
  822. /* [retval][out] */ IDiaSymbol **ppRetVal) {
  823. if (ppRetVal == nullptr) {
  824. return E_INVALIDARG;
  825. }
  826. *ppRetVal = false;
  827. Symbol *ret;
  828. IFR(m_pSession->SymMgr().GetSymbolByID(m_ElemTyID, &ret));
  829. *ppRetVal = ret;
  830. return S_OK;
  831. }
  832. HRESULT dxil_dia::hlsl_symbols::UDTSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DICompositeType *Node, LazySymbolName LazySymbolName, Symbol **ppSym) {
  833. IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagUDT, (UDTSymbol**)ppSym, Node, LazySymbolName));
  834. return S_OK;
  835. }
  836. HRESULT dxil_dia::hlsl_symbols::TypedefTypeSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DIType *Node, DWORD dwBaseTypeID, Symbol **ppSym) {
  837. IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagTypedef, (TypedefTypeSymbol**)ppSym, Node, dwBaseTypeID));
  838. return S_OK;
  839. }
  840. STDMETHODIMP dxil_dia::hlsl_symbols::TypedefTypeSymbol::get_type(
  841. /* [retval][out] */ IDiaSymbol **ppRetVal) {
  842. if (ppRetVal == nullptr) {
  843. return E_INVALIDARG;
  844. }
  845. *ppRetVal = nullptr;
  846. Symbol *ret = nullptr;
  847. IFR(m_pSession->SymMgr().GetSymbolByID(m_dwBaseTypeID, &ret));
  848. *ppRetVal = ret;
  849. return S_FALSE;
  850. }
  851. HRESULT dxil_dia::hlsl_symbols::GlobalVariableSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIGlobalVariable *GV, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym) {
  852. IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagData, (GlobalVariableSymbol**)ppSym, GV, dwTypeID, Type));
  853. return S_OK;
  854. }
  855. HRESULT dxil_dia::hlsl_symbols::GlobalVariableSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  856. children->clear();
  857. return S_OK;
  858. }
  859. HRESULT dxil_dia::hlsl_symbols::LocalVariableSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIVariable *Node, DWORD dwTypeID, llvm::DIType *Type, DWORD dwOffsetInUDT, DWORD dwDxilRegNum, Symbol **ppSym) {
  860. IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagData, (LocalVariableSymbol**)ppSym, Node, dwTypeID, Type, dwOffsetInUDT, dwDxilRegNum));
  861. return S_OK;
  862. }
  863. STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_locationType(
  864. /* [retval][out] */ DWORD *pRetVal) {
  865. if (pRetVal == nullptr) {
  866. return E_INVALIDARG;
  867. }
  868. *pRetVal = LocIsEnregistered;
  869. return S_OK;
  870. }
  871. STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_isAggregated(
  872. /* [retval][out] */ BOOL *pRetVal) {
  873. if (pRetVal == nullptr) {
  874. return E_INVALIDARG;
  875. }
  876. *pRetVal = m_pType->getTag() == llvm::dwarf::DW_TAG_member;
  877. return S_OK;
  878. }
  879. STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_registerType(
  880. /* [retval][out] */ DWORD *pRetVal) {
  881. if (pRetVal == nullptr) {
  882. return E_INVALIDARG;
  883. }
  884. static constexpr DWORD kPixTraceVirtualRegister = 0xfe;
  885. *pRetVal = kPixTraceVirtualRegister;
  886. return S_OK;
  887. }
  888. STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_offsetInUdt(
  889. /* [retval][out] */ DWORD *pRetVal) {
  890. if (pRetVal == nullptr) {
  891. return E_INVALIDARG;
  892. }
  893. *pRetVal = m_dwOffsetInUDT;
  894. return S_OK;
  895. }
  896. STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_sizeInUdt(
  897. /* [retval][out] */ DWORD *pRetVal) {
  898. if (pRetVal == nullptr) {
  899. return E_INVALIDARG;
  900. }
  901. static constexpr DWORD kBitsPerByte = 8;
  902. //auto *DT = llvm::cast<llvm::DIDerivedType>(m_pType);
  903. *pRetVal = 4; //DT->getSizeInBits() / kBitsPerByte;
  904. return S_OK;
  905. }
  906. STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_numberOfRegisterIndices(
  907. /* [retval][out] */ DWORD *pRetVal) {
  908. if (pRetVal == nullptr) {
  909. return E_INVALIDARG;
  910. }
  911. *pRetVal = 1;
  912. return S_OK;
  913. }
  914. STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_numericProperties(
  915. /* [in] */ DWORD cnt,
  916. /* [out] */ DWORD *pcnt,
  917. /* [size_is][out] */ DWORD *pProperties) {
  918. if (pcnt == nullptr || pProperties == nullptr || cnt != 1) {
  919. return E_INVALIDARG;
  920. }
  921. pProperties[0] = m_dwDxilRegNum;
  922. *pcnt = 1;
  923. return S_OK;
  924. }
  925. HRESULT dxil_dia::hlsl_symbols::LocalVariableSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  926. children->clear();
  927. return S_OK;
  928. }
  929. HRESULT dxil_dia::hlsl_symbols::UDTFieldSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIDerivedType *Node, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym) {
  930. IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagData, (UDTFieldSymbol**)ppSym, Node, dwTypeID, Type));
  931. return S_OK;
  932. }
  933. STDMETHODIMP dxil_dia::hlsl_symbols::UDTFieldSymbol::get_offset(
  934. /* [retval][out] */ LONG *pRetVal) {
  935. if (pRetVal == nullptr) {
  936. return E_INVALIDARG;
  937. }
  938. static constexpr DWORD kBitsPerByte = 8;
  939. *pRetVal = m_pNode->getOffsetInBits() / kBitsPerByte;
  940. return S_OK;
  941. }
  942. HRESULT dxil_dia::hlsl_symbols::UDTFieldSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
  943. children->clear();
  944. return S_OK;
  945. }
  946. dxil_dia::hlsl_symbols::SymbolManagerInit::SymbolManagerInit(
  947. Session *pSession,
  948. std::vector<std::unique_ptr<SymbolManager::SymbolFactory>> *pSymCtors,
  949. SymbolManager::ScopeToIDMap *pScopeToSym,
  950. SymbolManager::IDToLiveRangeMap *pSymToLR)
  951. : m_Session(*pSession),
  952. m_SymCtors(*pSymCtors),
  953. m_ScopeToSym(*pScopeToSym),
  954. m_SymToLR(*pSymToLR) {
  955. DXASSERT_ARGS(m_Parent.size() == m_SymCtors.size(),
  956. "parent and symbol array size mismatch: %d vs %d",
  957. m_Parent.size(),
  958. m_SymCtors.size());
  959. }
  960. void dxil_dia::hlsl_symbols::SymbolManagerInit::TypeInfo::Embed(const TypeInfo &TI) {
  961. for (const auto &E : TI.GetLayout()) {
  962. m_Layout.emplace_back(E);
  963. }
  964. m_dwCurrentSizeInBytes += TI.m_dwCurrentSizeInBytes;
  965. }
  966. void dxil_dia::hlsl_symbols::SymbolManagerInit::TypeInfo::AddBasicType(llvm::DIBasicType *BT) {
  967. m_Layout.emplace_back(BT);
  968. static constexpr DWORD kNumBitsPerByte = 8;
  969. m_dwCurrentSizeInBytes += BT->getSizeInBits() / kNumBitsPerByte;
  970. }
  971. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::GetTypeInfo(llvm::DIType *T, TypeInfo **TI) {
  972. auto tyInfoIt = m_TypeToInfo.find(T);
  973. if (tyInfoIt == m_TypeToInfo.end()) {
  974. return E_FAIL;
  975. }
  976. *TI = tyInfoIt->second.get();
  977. return S_OK;
  978. }
  979. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::AddParent(DWORD dwParentIndex) {
  980. m_Parent.emplace_back(dwParentIndex);
  981. return S_OK;
  982. }
  983. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionBlockForLocalScope(llvm::DILocalScope *LS, DWORD *pNewSymID) {
  984. if (LS == nullptr) {
  985. return E_FAIL;
  986. }
  987. auto lsIT = m_ScopeToSym.find(LS);
  988. if (lsIT != m_ScopeToSym.end()) {
  989. *pNewSymID = lsIT->second;
  990. return S_OK;
  991. }
  992. llvm::DILocalScope *ParentLS = nullptr;
  993. if (auto *Location = llvm::dyn_cast<llvm::DILocation>(LS)) {
  994. ParentLS = Location->getInlinedAtScope();
  995. if (ParentLS == nullptr) {
  996. ParentLS = Location->getScope();
  997. }
  998. } else if (auto *Block = llvm::dyn_cast<llvm::DILexicalBlock>(LS)) {
  999. ParentLS = Block->getScope();
  1000. } else if (auto *BlockFile = llvm::dyn_cast<llvm::DILexicalBlockFile>(LS)) {
  1001. ParentLS = BlockFile->getScope();
  1002. }
  1003. if (ParentLS == nullptr) {
  1004. return E_FAIL;
  1005. }
  1006. DWORD dwParentID;
  1007. IFR(CreateFunctionBlockForLocalScope(ParentLS, &dwParentID));
  1008. IFR(AddSymbol<symbol_factory::FunctionBlock>(dwParentID, pNewSymID));
  1009. m_ScopeToSym.insert(std::make_pair(LS, *pNewSymID));
  1010. return S_OK;
  1011. }
  1012. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionBlockForInstruction(llvm::Instruction *I) {
  1013. const llvm::DebugLoc &DL = I->getDebugLoc();
  1014. if (!DL) {
  1015. return S_OK;
  1016. }
  1017. llvm::MDNode *LocalScope = DL.getInlinedAtScope();
  1018. if (LocalScope == nullptr) {
  1019. LocalScope = DL.getScope();
  1020. }
  1021. if (LocalScope == nullptr) {
  1022. return S_OK;
  1023. }
  1024. auto *LS = llvm::dyn_cast<llvm::DILocalScope>(LocalScope);
  1025. if (LS == nullptr) {
  1026. return E_FAIL;
  1027. }
  1028. auto localScopeIt = m_ScopeToSym.find(LS);
  1029. if (localScopeIt == m_ScopeToSym.end()) {
  1030. DWORD dwUnusedNewSymID;
  1031. IFR(CreateFunctionBlockForLocalScope(LS, &dwUnusedNewSymID));
  1032. }
  1033. return S_OK;
  1034. }
  1035. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionBlocksForFunction(llvm::Function *F) {
  1036. for (llvm::BasicBlock &BB : *F) {
  1037. for (llvm::Instruction &I : BB) {
  1038. IFR(CreateFunctionBlockForInstruction(&I));
  1039. }
  1040. }
  1041. return S_OK;
  1042. }
  1043. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionsForCU(llvm::DICompileUnit *CU) {
  1044. bool FoundFunctions = false;
  1045. for (llvm::DISubprogram *SubProgram : CU->getSubprograms()) {
  1046. DWORD dwNewFunID;
  1047. const DWORD dwParentID = SubProgram->isLocalToUnit() ? HlslCompilandId : HlslProgramId;
  1048. DWORD dwSubprogramTypeID;
  1049. IFR(CreateType(SubProgram->getType(), &dwSubprogramTypeID));
  1050. IFR(AddSymbol<symbol_factory::Function>(dwParentID, &dwNewFunID, SubProgram, dwSubprogramTypeID));
  1051. m_ScopeToSym.insert(std::make_pair(SubProgram, dwNewFunID));
  1052. }
  1053. for (llvm::DISubprogram* SubProgram : CU->getSubprograms()) {
  1054. if (llvm::Function *F = SubProgram->getFunction()) {
  1055. IFR(CreateFunctionBlocksForFunction(F));
  1056. FoundFunctions = true;
  1057. }
  1058. }
  1059. if (!FoundFunctions) {
  1060. // This works around an old bug in dxcompiler whose effects are still
  1061. // sometimes present in PIX users' traces. (The bug was that the subprogram(s)
  1062. // weren't pointing to their contained function.)
  1063. llvm::Module *M = &m_Session.ModuleRef();
  1064. auto &DM = M->GetDxilModule();
  1065. llvm::Function *EntryPoint = DM.GetEntryFunction();
  1066. IFR(CreateFunctionBlocksForFunction(EntryPoint));
  1067. }
  1068. return S_OK;
  1069. }
  1070. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionsForAllCUs() {
  1071. for (llvm::DICompileUnit *pCU : m_Session.InfoRef().compile_units()) {
  1072. IFR(CreateFunctionsForCU(pCU));
  1073. }
  1074. return S_OK;
  1075. }
  1076. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateGlobalVariablesForCU(llvm::DICompileUnit *CU) {
  1077. for (llvm::DIGlobalVariable *GlobalVariable : CU->getGlobalVariables()) {
  1078. DWORD dwUnusedNewGVID;
  1079. const DWORD dwParentID = GlobalVariable->isLocalToUnit() ? HlslCompilandId : HlslProgramId;
  1080. auto *GVType = dyn_cast_to_ditype<llvm::DIType>(GlobalVariable->getType());
  1081. DWORD dwGVTypeID;
  1082. IFR(CreateType(GVType, &dwGVTypeID));
  1083. IFR(AddSymbol<symbol_factory::GlobalVariable>(dwParentID, &dwUnusedNewGVID, GlobalVariable, dwGVTypeID, GVType));
  1084. }
  1085. return S_OK;
  1086. }
  1087. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateGlobalVariablesForAllCUs() {
  1088. for (llvm::DICompileUnit *pCU : m_Session.InfoRef().compile_units()) {
  1089. IFR(CreateGlobalVariablesForCU(pCU));
  1090. }
  1091. return S_OK;
  1092. }
  1093. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::GetScopeID(llvm::DIScope *S, DWORD *pScopeID) {
  1094. auto ParentScopeIt = m_ScopeToSym.find(S);
  1095. if (ParentScopeIt != m_ScopeToSym.end()) {
  1096. *pScopeID = ParentScopeIt->second;
  1097. } else {
  1098. auto *ParentScopeTy = llvm::dyn_cast<llvm::DIType>(S);
  1099. if (!ParentScopeTy) {
  1100. // Any non-existing scope must be a type.
  1101. return E_FAIL;
  1102. }
  1103. IFR(CreateType(ParentScopeTy, pScopeID));
  1104. }
  1105. return S_OK;
  1106. }
  1107. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateType(llvm::DIType *Type, DWORD *pNewTypeID) {
  1108. if (Type == nullptr) {
  1109. return E_FAIL;
  1110. }
  1111. auto lsIT = m_TypeToInfo.find(Type);
  1112. if (lsIT != m_TypeToInfo.end()) {
  1113. *pNewTypeID = lsIT->second->GetTypeID();
  1114. return S_OK;
  1115. }
  1116. if (auto *ST = llvm::dyn_cast<llvm::DISubroutineType>(Type)) {
  1117. IFR(CreateSubroutineType(HlslProgramId, ST, pNewTypeID));
  1118. return S_OK;
  1119. } else if (auto *BT = llvm::dyn_cast<llvm::DIBasicType>(Type)) {
  1120. IFR(CreateBasicType(HlslProgramId, BT, pNewTypeID));
  1121. return S_OK;
  1122. } else if (auto *CT = llvm::dyn_cast<llvm::DICompositeType>(Type)) {
  1123. DWORD dwParentID = HlslProgramId;
  1124. if (auto *ParentScope = dyn_cast_to_ditype_or_null<llvm::DIScope>(CT->getScope())) {
  1125. IFR(GetScopeID(ParentScope, &dwParentID));
  1126. }
  1127. IFR(CreateCompositeType(dwParentID, CT, pNewTypeID));
  1128. return S_OK;
  1129. } else if (auto *DT = llvm::dyn_cast<llvm::DIDerivedType>(Type)) {
  1130. DWORD dwParentID = HlslProgramId;
  1131. if (auto *ParentScope = dyn_cast_to_ditype_or_null<llvm::DIScope>(DT->getScope())) {
  1132. IFR(GetScopeID(ParentScope, &dwParentID));
  1133. }
  1134. IFR(HandleDerivedType(dwParentID, DT, pNewTypeID));
  1135. return S_OK;
  1136. }
  1137. return E_FAIL;
  1138. }
  1139. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateSubroutineType(DWORD dwParentID, llvm::DISubroutineType *ST, DWORD *pNewTypeID) {
  1140. LazySymbolName LazyName;
  1141. llvm::DITypeRefArray Types = ST->getTypeArray();
  1142. if (Types.size() > 0) {
  1143. std::vector<DWORD> TypeIDs;
  1144. TypeIDs.reserve(Types.size());
  1145. for (llvm::Metadata *M : Types) {
  1146. auto *Ty = dyn_cast_to_ditype_or_null<llvm::DIType>(M);
  1147. if (Ty == nullptr) {
  1148. TypeIDs.emplace_back(kNullSymbolID);
  1149. } else {
  1150. DWORD dwTyID;
  1151. IFR(CreateType(Ty, &dwTyID));
  1152. TypeIDs.emplace_back(dwTyID);
  1153. }
  1154. }
  1155. LazyName = [TypeIDs](Session *pSession, std::string *Name) -> HRESULT {
  1156. Name->clear();
  1157. llvm::raw_string_ostream OS(*Name);
  1158. OS.SetUnbuffered();
  1159. bool first = true;
  1160. bool firstArg = true;
  1161. auto &SM = pSession->SymMgr();
  1162. for (DWORD ID : TypeIDs) {
  1163. if (!first && !firstArg) {
  1164. OS << ", ";
  1165. }
  1166. if (ID == kNullSymbolID) {
  1167. OS << "void";
  1168. } else {
  1169. CComPtr<Symbol> SymTy;
  1170. IFR(SM.GetSymbolByID(ID, &SymTy));
  1171. CComBSTR name;
  1172. IFR(SymTy->get_name(&name));
  1173. if (!name) {
  1174. OS << "???";
  1175. } else {
  1176. OS << CW2A((BSTR)name, CP_UTF8);
  1177. }
  1178. }
  1179. if (first) {
  1180. OS << "(";
  1181. }
  1182. firstArg = first;
  1183. first = false;
  1184. }
  1185. OS << ")";
  1186. return S_OK;
  1187. };
  1188. }
  1189. IFR(AddType<symbol_factory::Type>(dwParentID, ST, pNewTypeID, SymTagFunctionType, ST, LazyName));
  1190. return S_OK;
  1191. }
  1192. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateBasicType(DWORD dwParentID, llvm::DIBasicType *BT, DWORD *pNewTypeID) {
  1193. DXASSERT_ARGS(dwParentID == HlslProgramId,
  1194. "%d vs %d",
  1195. dwParentID,
  1196. HlslProgramId);
  1197. LazySymbolName LazyName = [BT](Session *pSession, std::string *Name) -> HRESULT {
  1198. *Name = BT->getName();
  1199. return S_OK;
  1200. };
  1201. IFR(AddType<symbol_factory::Type>(dwParentID, BT, pNewTypeID, SymTagBaseType, BT, LazyName));
  1202. TypeInfo *TI;
  1203. IFR(GetTypeInfo(BT, &TI));
  1204. TI->AddBasicType(BT);
  1205. return S_OK;
  1206. }
  1207. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateCompositeType(DWORD dwParentID, llvm::DICompositeType *CT, DWORD *pNewTypeID) {
  1208. switch (CT->getTag()) {
  1209. case llvm::dwarf::DW_TAG_array_type: {
  1210. auto *BaseType = dyn_cast_to_ditype_or_null<llvm::DIType>(CT->getBaseType());
  1211. if (BaseType == nullptr) {
  1212. return E_FAIL;
  1213. }
  1214. DWORD dwBaseTypeID = kNullSymbolID;
  1215. IFR(CreateType(BaseType, &dwBaseTypeID));
  1216. auto LazyName = [CT, dwBaseTypeID](Session *pSession, std::string *Name) -> HRESULT {
  1217. auto &SM = pSession->SymMgr();
  1218. Name->clear();
  1219. llvm::raw_string_ostream OS(*Name);
  1220. OS.SetUnbuffered();
  1221. auto *BaseTy = llvm::dyn_cast<llvm::DIType>(CT->getBaseType());
  1222. if (BaseTy == nullptr) {
  1223. return E_FAIL;
  1224. }
  1225. CComPtr<Symbol> SymTy;
  1226. IFR(SM.GetSymbolByID(dwBaseTypeID, &SymTy));
  1227. CComBSTR name;
  1228. IFR(SymTy->get_name(&name));
  1229. if (!name) {
  1230. OS << "???";
  1231. } else {
  1232. OS << CW2A((BSTR)name, CP_UTF8);
  1233. }
  1234. OS << "[";
  1235. bool first = true;
  1236. for (llvm::DINode *N : CT->getElements()) {
  1237. if (!first) {
  1238. OS << "][";
  1239. }
  1240. first = false;
  1241. if (N != nullptr) {
  1242. if (auto *SubRange = llvm::dyn_cast<llvm::DISubrange>(N)) {
  1243. OS << SubRange->getCount();
  1244. } else {
  1245. OS << "???";
  1246. }
  1247. }
  1248. }
  1249. OS << "]";
  1250. return S_OK;
  1251. };
  1252. IFR(AddType<symbol_factory::Type>(dwParentID, CT, pNewTypeID, SymTagArrayType, CT, LazyName));
  1253. TypeInfo *ctTI;
  1254. IFR(GetTypeInfo(CT, &ctTI));
  1255. TypeInfo *baseTI;
  1256. IFR(GetTypeInfo(BaseType, &baseTI));
  1257. int64_t embedCount = 1;
  1258. for (llvm::DINode *N : CT->getElements()) {
  1259. if (N != nullptr) {
  1260. if (auto *SubRange = llvm::dyn_cast<llvm::DISubrange>(N)) {
  1261. embedCount *= SubRange->getCount();
  1262. } else {
  1263. return E_FAIL;
  1264. }
  1265. }
  1266. }
  1267. for (int64_t i = 0; i < embedCount; ++i) {
  1268. ctTI->Embed(*baseTI);
  1269. }
  1270. return S_OK;
  1271. }
  1272. case llvm::dwarf::DW_TAG_class_type: {
  1273. HRESULT hr;
  1274. IFR(hr = CreateHLSLType(CT, pNewTypeID));
  1275. if (hr == S_OK) {
  1276. return S_OK;
  1277. }
  1278. break;
  1279. }
  1280. }
  1281. auto LazyName = [CT](Session *pSession, std::string *Name) -> HRESULT {
  1282. *Name = CT->getName();
  1283. return S_OK;
  1284. };
  1285. IFR(AddType<symbol_factory::UDT>(dwParentID, CT, pNewTypeID, CT, LazyName));
  1286. TypeInfo *udtTI;
  1287. IFR(GetTypeInfo(CT, &udtTI));
  1288. auto udtScope = BeginUDTScope(udtTI);
  1289. for (llvm::DINode *N : CT->getElements()) {
  1290. if (auto *Field = llvm::dyn_cast<llvm::DIType>(N)) {
  1291. DWORD dwUnusedFieldID;
  1292. IFR(CreateType(Field, &dwUnusedFieldID));
  1293. }
  1294. }
  1295. return S_OK;
  1296. }
  1297. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateHLSLType(llvm::DICompositeType *T, DWORD *pNewTypeID) {
  1298. DWORD dwEltTyID;
  1299. std::uint32_t ElemCnt;
  1300. HRESULT hr;
  1301. IFR(hr = IsHLSLVectorType(T, &dwEltTyID, &ElemCnt));
  1302. if (hr == S_OK) {
  1303. // e.g. float4, int2 etc
  1304. return CreateHLSLVectorType(T, dwEltTyID, ElemCnt, pNewTypeID);
  1305. }
  1306. return S_FALSE;
  1307. }
  1308. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::IsHLSLVectorType(llvm::DICompositeType *T, DWORD *pEltTyID, std::uint32_t *pElemCnt) {
  1309. llvm::StringRef Name = T->getName();
  1310. if (!Name.startswith("vector<")) {
  1311. return S_FALSE;
  1312. }
  1313. llvm::DITemplateParameterArray Args = T->getTemplateParams();
  1314. if (Args.size() != 2) {
  1315. return E_FAIL;
  1316. }
  1317. auto *ElemTyParam = llvm::dyn_cast<llvm::DITemplateTypeParameter>(Args[0]);
  1318. if (ElemTyParam == nullptr) {
  1319. return E_FAIL;
  1320. }
  1321. auto *ElemTy = dyn_cast_to_ditype<llvm::DIType>(ElemTyParam->getType());
  1322. if (ElemTy == nullptr) {
  1323. return E_FAIL;
  1324. }
  1325. DWORD dwEltTyID;
  1326. IFR(CreateType(ElemTy, &dwEltTyID));
  1327. auto *ElemCntParam = llvm::dyn_cast<llvm::DITemplateValueParameter>(Args[1]);
  1328. if (ElemCntParam == nullptr) {
  1329. return E_FAIL;
  1330. }
  1331. auto *ElemCntMD = llvm::dyn_cast<llvm::ConstantAsMetadata>(ElemCntParam->getValue());
  1332. auto *ElemCnt = llvm::dyn_cast_or_null<llvm::ConstantInt>(ElemCntMD->getValue());
  1333. if (ElemCnt == nullptr) {
  1334. return E_FAIL;
  1335. }
  1336. if (ElemCnt->getLimitedValue() > 4) {
  1337. return E_FAIL;
  1338. }
  1339. *pEltTyID = dwEltTyID;
  1340. *pElemCnt = ElemCnt->getLimitedValue();
  1341. return S_OK;
  1342. }
  1343. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateHLSLVectorType(llvm::DICompositeType *T, DWORD pEltTyID, std::uint32_t pElemCnt, DWORD *pNewTypeID) {
  1344. llvm::DITemplateParameterArray Args = T->getTemplateParams();
  1345. if (Args.size() != 2) {
  1346. return E_FAIL;
  1347. }
  1348. auto *ElemTyParam = llvm::dyn_cast<llvm::DITemplateTypeParameter>(Args[0]);
  1349. if (ElemTyParam == nullptr) {
  1350. return E_FAIL;
  1351. }
  1352. auto *ElemTy = dyn_cast_to_ditype<llvm::DIType>(ElemTyParam->getType());
  1353. if (ElemTy == nullptr) {
  1354. return E_FAIL;
  1355. }
  1356. DWORD dwElemTyID;
  1357. IFT(CreateType(ElemTy, &dwElemTyID));
  1358. auto *ElemCntParam = llvm::dyn_cast<llvm::DITemplateValueParameter>(Args[1]);
  1359. if (ElemCntParam == nullptr) {
  1360. return E_FAIL;
  1361. }
  1362. auto *ElemCntMD = llvm::dyn_cast<llvm::ConstantAsMetadata>(ElemCntParam->getValue());
  1363. auto *ElemCnt = llvm::dyn_cast_or_null<llvm::ConstantInt>(ElemCntMD->getValue());
  1364. if (ElemCnt == nullptr) {
  1365. return E_FAIL;
  1366. }
  1367. if (ElemCnt->getLimitedValue() > 4) {
  1368. return E_FAIL;
  1369. }
  1370. const DWORD dwParentID = HlslProgramId;
  1371. IFR(AddType<symbol_factory::VectorType>(dwParentID, T, pNewTypeID, T, dwElemTyID, ElemCnt->getLimitedValue()));
  1372. TypeInfo *vecTI;
  1373. IFR(GetTypeInfo(T, &vecTI));
  1374. TypeInfo *elemTI;
  1375. IFR(GetTypeInfo(ElemTy, &elemTI));
  1376. for (std::uint64_t i = 0; i < ElemCnt->getLimitedValue(); ++i) {
  1377. vecTI->Embed(*elemTI);
  1378. }
  1379. return S_OK;
  1380. }
  1381. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::HandleDerivedType(DWORD dwParentID, llvm::DIDerivedType *DT, DWORD *pNewTypeID) {
  1382. DWORD st;
  1383. LazySymbolName LazyName;
  1384. DWORD dwBaseTypeID = kNullSymbolID;
  1385. auto *BaseTy = llvm::dyn_cast_or_null<llvm::DIType>(DT->getBaseType());
  1386. if (BaseTy != nullptr) {
  1387. IFR(CreateType(BaseTy, &dwBaseTypeID));
  1388. }
  1389. auto LazyNameWithQualifier = [dwBaseTypeID, DT](Session *pSession, std::string *Name, const char *Qualifier) -> HRESULT {
  1390. auto &SM = pSession->SymMgr();
  1391. Name->clear();
  1392. llvm::raw_string_ostream OS(*Name);
  1393. OS.SetUnbuffered();
  1394. auto *BaseTy = llvm::dyn_cast<llvm::DIType>(DT->getBaseType());
  1395. if (BaseTy == nullptr) {
  1396. return E_FAIL;
  1397. }
  1398. CComPtr<Symbol> SymTy;
  1399. IFR(SM.GetSymbolByID(dwBaseTypeID, &SymTy));
  1400. CComBSTR name;
  1401. IFR(SymTy->get_name(&name));
  1402. if (!name) {
  1403. OS << "???";
  1404. } else {
  1405. OS << CW2A((BSTR)name, CP_UTF8);
  1406. }
  1407. OS << Qualifier;
  1408. return S_OK;
  1409. };
  1410. switch (DT->getTag()) {
  1411. case llvm::dwarf::DW_TAG_member: {
  1412. // Type is not really a type, but rather a struct member.
  1413. IFR(CreateUDTField(dwParentID, DT));
  1414. return S_OK;
  1415. }
  1416. default:
  1417. st = SymTagBlock;
  1418. LazyName = [](Session *pSession, std::string *Name) -> HRESULT {
  1419. Name->clear();
  1420. return S_OK;
  1421. };
  1422. break;
  1423. case llvm::dwarf::DW_TAG_typedef: {
  1424. if (dwBaseTypeID == kNullSymbolID) {
  1425. return E_FAIL;
  1426. }
  1427. IFR(AddType<symbol_factory::TypedefType>(dwParentID, DT, pNewTypeID, DT, dwBaseTypeID));
  1428. TypeInfo *dtTI;
  1429. IFR(GetTypeInfo(DT, &dtTI));
  1430. TypeInfo *baseTI;
  1431. IFR(GetTypeInfo(BaseTy, &baseTI));
  1432. dtTI->Embed(*baseTI);
  1433. return S_OK;
  1434. }
  1435. case llvm::dwarf::DW_TAG_const_type: {
  1436. if (dwBaseTypeID == kNullSymbolID) {
  1437. return E_FAIL;
  1438. }
  1439. st = SymTagCustomType;
  1440. LazyName = std::bind(LazyNameWithQualifier, std::placeholders::_1, std::placeholders::_2, " const");
  1441. break;
  1442. }
  1443. case llvm::dwarf::DW_TAG_pointer_type: {
  1444. if (dwBaseTypeID == kNullSymbolID) {
  1445. return E_FAIL;
  1446. }
  1447. st = SymTagPointerType;
  1448. LazyName = std::bind(LazyNameWithQualifier, std::placeholders::_1, std::placeholders::_2, " *");
  1449. break;
  1450. }
  1451. case llvm::dwarf::DW_TAG_reference_type: {
  1452. if (dwBaseTypeID == kNullSymbolID) {
  1453. return E_FAIL;
  1454. }
  1455. st = SymTagCustomType;
  1456. LazyName = std::bind(LazyNameWithQualifier, std::placeholders::_1, std::placeholders::_2, " &");
  1457. break;
  1458. }
  1459. }
  1460. IFR(AddType<symbol_factory::Type>(dwParentID, DT, pNewTypeID, st, DT, LazyName));
  1461. if (DT->getTag() == llvm::dwarf::DW_TAG_const_type) {
  1462. TypeInfo *dtTI;
  1463. IFR(GetTypeInfo(DT, &dtTI));
  1464. TypeInfo *baseTI;
  1465. IFR(GetTypeInfo(BaseTy, &baseTI));
  1466. dtTI->Embed(*baseTI);
  1467. }
  1468. return S_OK;
  1469. }
  1470. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateLocalVariable(DWORD dwParentID, llvm::DILocalVariable *LV) {
  1471. auto *LVTy = dyn_cast_to_ditype<llvm::DIType>(LV->getType());
  1472. if (LVTy == nullptr) {
  1473. return E_FAIL;
  1474. }
  1475. if (m_VarToID.count(LV) != 0) {
  1476. return S_OK;
  1477. }
  1478. DWORD dwLVTypeID;
  1479. IFR(CreateType(LVTy, &dwLVTypeID));
  1480. TypeInfo *varTI;
  1481. IFR(GetTypeInfo(LVTy, &varTI));
  1482. DWORD dwOffsetInUDT = 0;
  1483. auto &newVars = m_VarToID[LV];
  1484. std::vector<llvm::DIType *> Tys = varTI->GetLayout();
  1485. for (llvm::DIType *Ty : Tys) {
  1486. TypeInfo *TI;
  1487. IFR(GetTypeInfo(Ty, &TI));
  1488. const DWORD dwTypeID = TI->GetTypeID();
  1489. DWORD dwNewLVID;
  1490. newVars.emplace_back(std::make_shared<symbol_factory::LocalVarInfo>());
  1491. std::shared_ptr<symbol_factory::LocalVarInfo> VI = newVars.back();
  1492. IFR(AddSymbol<symbol_factory::LocalVariable>(dwParentID, &dwNewLVID, LV, dwLVTypeID, LVTy, VI));
  1493. VI->SetVarID(dwNewLVID);
  1494. VI->SetOffsetInUDT(dwOffsetInUDT);
  1495. static constexpr DWORD kNumBitsPerByte = 8;
  1496. dwOffsetInUDT += Ty->getSizeInBits() / kNumBitsPerByte;
  1497. }
  1498. return S_OK;
  1499. }
  1500. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::GetTypeLayout(llvm::DIType *Ty, std::vector<DWORD> *pRet) {
  1501. pRet->clear();
  1502. TypeInfo *TI;
  1503. IFR(GetTypeInfo(Ty, &TI));
  1504. for (llvm::DIType * T : TI->GetLayout()) {
  1505. TypeInfo *eTI;
  1506. IFR(GetTypeInfo(T, &eTI));
  1507. pRet->emplace_back(eTI->GetTypeID());
  1508. }
  1509. return S_OK;
  1510. }
  1511. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateUDTField(DWORD dwParentID, llvm::DIDerivedType *Field) {
  1512. auto *FieldTy = dyn_cast_to_ditype<llvm::DIType>(Field->getBaseType());
  1513. if (FieldTy == nullptr) {
  1514. return E_FAIL;
  1515. }
  1516. if (m_FieldToID.count(Field) != 0) {
  1517. return S_OK;
  1518. }
  1519. DWORD dwLVTypeID;
  1520. IFR(CreateType(FieldTy, &dwLVTypeID));
  1521. if (m_pCurUDT != nullptr) {
  1522. const DWORD dwOffsetInBytes = CurrentUDTInfo().GetCurrentSizeInBytes();
  1523. DXASSERT_ARGS(dwOffsetInBytes == Field->getOffsetInBits() / 8,
  1524. "%d vs %d",
  1525. dwOffsetInBytes,
  1526. Field->getOffsetInBits() / 8);
  1527. TypeInfo *lvTI;
  1528. IFR(GetTypeInfo(FieldTy, &lvTI));
  1529. CurrentUDTInfo().Embed(*lvTI);
  1530. }
  1531. DWORD dwNewLVID;
  1532. IFR(AddSymbol<symbol_factory::UDTField>(dwParentID, &dwNewLVID, Field, dwLVTypeID, FieldTy));
  1533. m_FieldToID.insert(std::make_pair(Field, dwNewLVID));
  1534. return S_OK;
  1535. }
  1536. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateLocalVariables() {
  1537. llvm::Module *M = &m_Session.ModuleRef();
  1538. llvm::Function *DbgDeclare = llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::dbg_declare);
  1539. for (llvm::Value *U : DbgDeclare->users()) {
  1540. auto *CI = llvm::dyn_cast<llvm::CallInst>(U);
  1541. auto *LS = llvm::dyn_cast_or_null<llvm::DILocalScope>(CI->getDebugLoc()->getInlinedAtScope());
  1542. auto SymIt = m_ScopeToSym.find(LS);
  1543. if (SymIt == m_ScopeToSym.end()) {
  1544. return E_FAIL;
  1545. }
  1546. auto *LocalNameMetadata = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(1));
  1547. if (auto *LV = llvm::dyn_cast<llvm::DILocalVariable>(LocalNameMetadata->getMetadata())) {
  1548. const DWORD dwParentID = SymIt->second;
  1549. IFR(CreateLocalVariable(dwParentID, LV));
  1550. }
  1551. }
  1552. return S_OK;
  1553. }
  1554. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateLiveRanges() {
  1555. // Simple algorithm:
  1556. // live_range = map from SymbolID to SymbolManager.LiveRange
  1557. // end_of_scope = map from Scope to RVA
  1558. // for each I in reverse(pSession.InstructionsRef):
  1559. // scope = I.scope
  1560. // if scope not in end_of_scope:
  1561. // end_of_scope[scope] = rva(I)
  1562. // if I is dbg.declare:
  1563. // live_range[symbol of I] = SymbolManager.LiveRange[FirstUseRVA, end_of_scope[scope]]
  1564. llvm::Module *M = &m_Session.ModuleRef();
  1565. m_SymToLR.clear();
  1566. const auto &Instrs = m_Session.InstructionsRef();
  1567. llvm::DenseMap<llvm::DILocalScope *, Session::RVA> EndOfScope;
  1568. for (auto It = Instrs.rbegin(); It != Instrs.rend(); ++It) {
  1569. const Session::RVA RVA = It->first;
  1570. const auto *I = It->second;
  1571. const llvm::DebugLoc &DL = I->getDebugLoc();
  1572. if (!DL) {
  1573. continue;
  1574. }
  1575. llvm::MDNode *LocalScope = DL.getScope();
  1576. if (LocalScope == nullptr) {
  1577. continue;
  1578. }
  1579. auto *LS = llvm::dyn_cast<llvm::DILocalScope>(LocalScope);
  1580. if (LS == nullptr) {
  1581. return E_FAIL;
  1582. }
  1583. if (EndOfScope.count(LS) == 0) {
  1584. EndOfScope.insert(std::make_pair(LS, RVA + 1));
  1585. }
  1586. auto endOfScopeRVA = EndOfScope.find(LS)->second;
  1587. DWORD Reg;
  1588. DWORD RegSize;
  1589. llvm::DILocalVariable *LV;
  1590. uint64_t StartOffset;
  1591. uint64_t EndOffset;
  1592. Session::RVA FirstUseRVA;
  1593. Session::RVA LastUseRVA;
  1594. HRESULT hr = IsDbgDeclareCall(M, I, &Reg, &RegSize, &LV, &StartOffset,
  1595. &EndOffset, &FirstUseRVA, &LastUseRVA);
  1596. if (hr != S_OK) {
  1597. continue;
  1598. }
  1599. endOfScopeRVA = std::max<Session::RVA>(endOfScopeRVA, LastUseRVA);
  1600. auto varIt = m_VarToID.find(LV);
  1601. if (varIt == m_VarToID.end()) {
  1602. // All variables should already have been seen and created.
  1603. return E_FAIL;
  1604. }
  1605. for (auto &Var : varIt->second) {
  1606. const DWORD dwOffsetInUDT = Var->GetOffsetInUDT();
  1607. if (dwOffsetInUDT < StartOffset || dwOffsetInUDT >= EndOffset) {
  1608. continue;
  1609. }
  1610. DXASSERT_ARGS((dwOffsetInUDT - StartOffset) % 4 == 0,
  1611. "Invalid byte offset %d into variable",
  1612. (dwOffsetInUDT - StartOffset));
  1613. const DWORD dwRegIndex = (dwOffsetInUDT - StartOffset) / 4;
  1614. if (dwRegIndex >= RegSize) {
  1615. continue;
  1616. }
  1617. Var->SetDxilRegister(Reg + dwRegIndex);
  1618. m_SymToLR[Var->GetVarID()] = SymbolManager::LiveRange{
  1619. static_cast<uint32_t>(FirstUseRVA),
  1620. endOfScopeRVA - static_cast<uint32_t>(FirstUseRVA)
  1621. };
  1622. }
  1623. }
  1624. return S_OK;
  1625. }
  1626. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::IsDbgDeclareCall(
  1627. llvm::Module *M, const llvm::Instruction *I, DWORD *pReg, DWORD *pRegSize,
  1628. llvm::DILocalVariable **LV, uint64_t *pStartOffset, uint64_t *pEndOffset,
  1629. dxil_dia::Session::RVA *pLowestUserRVA,
  1630. dxil_dia::Session::RVA *pHighestUserRVA) {
  1631. auto *CI = llvm::dyn_cast<llvm::CallInst>(I);
  1632. if (CI == nullptr) {
  1633. return S_FALSE;
  1634. }
  1635. llvm::Function *DbgDeclare = llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::dbg_declare);
  1636. if (CI->getCalledFunction() != DbgDeclare) {
  1637. return S_FALSE;
  1638. }
  1639. *LV = nullptr;
  1640. *pReg = *pRegSize = 0;
  1641. *pStartOffset = *pEndOffset = 0;
  1642. *pLowestUserRVA = 0;
  1643. *pHighestUserRVA = 0;
  1644. std::vector<dxil_dia::Session::RVA> usesRVAs;
  1645. bool HasRegister = false;
  1646. if (auto *RegMV = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(0))) {
  1647. if (auto *RegVM = llvm::dyn_cast<llvm::ValueAsMetadata>(RegMV->getMetadata())) {
  1648. if (auto *Reg = llvm::dyn_cast<llvm::Instruction>(RegVM->getValue())) {
  1649. HRESULT hr;
  1650. IFR(hr = GetDxilAllocaRegister(Reg, pReg, pRegSize));
  1651. if (hr != S_OK) {
  1652. return hr;
  1653. }
  1654. HasRegister = true;
  1655. llvm::iterator_range<llvm::Value::user_iterator> users = Reg->users();
  1656. for (llvm::User *user : users) {
  1657. auto *inst = llvm::dyn_cast<llvm::Instruction>(user);
  1658. if (inst != nullptr) {
  1659. auto rva = m_Session.RvaMapRef().find(inst);
  1660. usesRVAs.push_back(rva->second);
  1661. }
  1662. }
  1663. }
  1664. }
  1665. }
  1666. if (!HasRegister) {
  1667. return E_FAIL;
  1668. }
  1669. if (!usesRVAs.empty()) {
  1670. *pLowestUserRVA = *std::min_element(usesRVAs.begin(), usesRVAs.end());
  1671. *pHighestUserRVA = *std::max_element(usesRVAs.begin(), usesRVAs.end());
  1672. }
  1673. if (auto *LVMV = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(1))) {
  1674. *LV = llvm::dyn_cast<llvm::DILocalVariable>(LVMV->getMetadata());
  1675. if (*LV == nullptr) {
  1676. return E_FAIL;
  1677. }
  1678. }
  1679. if (auto *FieldsMV = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(2))) {
  1680. auto *Fields = llvm::dyn_cast<llvm::DIExpression>(FieldsMV->getMetadata());
  1681. if (Fields == nullptr) {
  1682. return E_FAIL;
  1683. }
  1684. static constexpr uint64_t kNumBytesPerDword = 4;
  1685. if (Fields->isBitPiece()) {
  1686. const uint64_t BitPieceOffset = Fields->getBitPieceOffset();
  1687. const uint64_t BitPieceSize = Fields->getBitPieceSize();
  1688. // dxcompiler had a bug (fixed in
  1689. // 4870297404a37269e24ddce7db3bd94a8110fff8) where the BitPieceSize
  1690. // was defined in bytes, not bits. We use the register size in bits to
  1691. // verify if Size is bits or bytes.
  1692. if (*pRegSize * kNumBytesPerDword == BitPieceSize) {
  1693. // Size is bytes.
  1694. *pStartOffset = BitPieceOffset;
  1695. *pEndOffset = *pStartOffset + BitPieceSize;
  1696. } else {
  1697. // Size is (should be) bits; pStartOffset/pEndOffset should be bytes.
  1698. // We don't expect to encounter bit pieces more granular than bytes.
  1699. static constexpr uint64_t kNumBitsPerByte = 8;
  1700. (void)kNumBitsPerByte;
  1701. assert(BitPieceOffset % kNumBitsPerByte == 0);
  1702. assert(BitPieceSize % kNumBitsPerByte == 0);
  1703. *pStartOffset = BitPieceOffset / kNumBitsPerByte;
  1704. *pEndOffset = *pStartOffset + (BitPieceSize / kNumBitsPerByte);
  1705. }
  1706. } else {
  1707. *pStartOffset = 0;
  1708. *pEndOffset = *pRegSize * kNumBytesPerDword;
  1709. }
  1710. }
  1711. return S_OK;
  1712. }
  1713. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::GetDxilAllocaRegister(llvm::Instruction *I, DWORD *pRegNum, DWORD *pRegSize) {
  1714. auto *Alloca = llvm::dyn_cast<llvm::AllocaInst>(I);
  1715. if (Alloca == nullptr) {
  1716. return S_FALSE;
  1717. }
  1718. std::uint32_t uRegNum;
  1719. std::uint32_t uRegSize;
  1720. if (!pix_dxil::PixAllocaReg::FromInst(Alloca, &uRegNum, &uRegSize)) {
  1721. return S_FALSE;
  1722. }
  1723. *pRegNum = uRegNum;
  1724. *pRegSize = uRegSize;
  1725. return S_OK;
  1726. }
  1727. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::PopulateParentToChildrenIDMap(SymbolManager::ParentToChildrenMap *pParentToChildren) {
  1728. DXASSERT_ARGS(m_SymCtors.size() == m_Parent.size(),
  1729. "parents vector must be the same size of symbols ctor vector: %d vs %d",
  1730. m_SymCtors.size(),
  1731. m_Parent.size());
  1732. for (size_t i = 0; i < m_Parent.size(); ++i) {
  1733. #ifndef NDEBUG
  1734. {
  1735. CComPtr<Symbol> S;
  1736. IFT(m_SymCtors[i]->Create(&m_Session, &S));
  1737. DXASSERT_ARGS(S->GetID() == i + 1,
  1738. "Invalid symbol index %d for %d",
  1739. S->GetID(),
  1740. i + 1);
  1741. }
  1742. #endif // !NDEBUG
  1743. DXASSERT_ARGS(m_Parent[i] != kNullSymbolID || (i + 1) == HlslProgramId,
  1744. "Parentless symbol %d", i + 1);
  1745. if (m_Parent[i] != kNullSymbolID) {
  1746. pParentToChildren->emplace(m_Parent[i], i + 1);
  1747. }
  1748. }
  1749. return S_OK;
  1750. }
  1751. dxil_dia::SymbolManager::SymbolFactory::SymbolFactory(DWORD ID, DWORD ParentID)
  1752. : m_ID(ID), m_ParentID(ParentID) {}
  1753. dxil_dia::SymbolManager::SymbolFactory::~SymbolFactory() = default;
  1754. dxil_dia::SymbolManager::SymbolManager() = default;
  1755. dxil_dia::SymbolManager::~SymbolManager() {
  1756. m_pSession = nullptr;
  1757. }
  1758. void dxil_dia::SymbolManager::Init(Session *pSes) {
  1759. DXASSERT(m_pSession == nullptr, "SymbolManager already initialized");
  1760. m_pSession = pSes;
  1761. m_symbolCtors.clear();
  1762. m_parentToChildren.clear();
  1763. llvm::DebugInfoFinder &DIFinder = pSes->InfoRef();
  1764. if (DIFinder.compile_unit_count() != 1) {
  1765. throw hlsl::Exception(E_FAIL);
  1766. }
  1767. llvm::DICompileUnit *ShaderCU = *DIFinder.compile_units().begin();
  1768. hlsl_symbols::SymbolManagerInit SMI(pSes, &m_symbolCtors, &m_scopeToID, &m_symbolToLiveRange);
  1769. DWORD dwHlslProgramID;
  1770. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::GlobalScope>(kNullSymbolID, &dwHlslProgramID));
  1771. DXASSERT_ARGS(dwHlslProgramID == HlslProgramId,
  1772. "%d vs %d",
  1773. dwHlslProgramID,
  1774. HlslProgramId);
  1775. DWORD dwHlslCompilandID;
  1776. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::Compiland>(dwHlslProgramID, &dwHlslCompilandID, ShaderCU));
  1777. m_scopeToID.insert(std::make_pair(ShaderCU, dwHlslCompilandID));
  1778. DXASSERT_ARGS(dwHlslCompilandID == HlslCompilandId,
  1779. "%d vs %d",
  1780. dwHlslCompilandID,
  1781. HlslCompilandId);
  1782. DWORD dwHlslCompilandDetailsId;
  1783. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandDetails>(dwHlslCompilandID, &dwHlslCompilandDetailsId));
  1784. DXASSERT_ARGS(dwHlslCompilandDetailsId == HlslCompilandDetailsId,
  1785. "%d vs %d",
  1786. dwHlslCompilandDetailsId,
  1787. HlslCompilandDetailsId);
  1788. DWORD dwHlslCompilandEnvFlagsID;
  1789. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateFlags>>(dwHlslCompilandID, &dwHlslCompilandEnvFlagsID));
  1790. DXASSERT_ARGS(dwHlslCompilandEnvFlagsID == HlslCompilandEnvFlagsId,
  1791. "%d vs %d",
  1792. dwHlslCompilandEnvFlagsID,
  1793. HlslCompilandEnvFlagsId);
  1794. DWORD dwHlslCompilandEnvTargetID;
  1795. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateTarget>>(dwHlslCompilandID, &dwHlslCompilandEnvTargetID));
  1796. DXASSERT_ARGS(dwHlslCompilandEnvTargetID == HlslCompilandEnvTargetId,
  1797. "%d vs %d",
  1798. dwHlslCompilandEnvTargetID,
  1799. HlslCompilandEnvTargetId);
  1800. DWORD dwHlslCompilandEnvEntryID;
  1801. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateEntry>>(dwHlslCompilandID, &dwHlslCompilandEnvEntryID));
  1802. DXASSERT_ARGS(dwHlslCompilandEnvEntryID == HlslCompilandEnvEntryId,
  1803. "%d vs %d",
  1804. dwHlslCompilandEnvEntryID,
  1805. HlslCompilandEnvEntryId);
  1806. DWORD dwHlslCompilandEnvDefinesID;
  1807. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateDefines>>(dwHlslCompilandID, &dwHlslCompilandEnvDefinesID));
  1808. DXASSERT_ARGS(dwHlslCompilandEnvDefinesID == HlslCompilandEnvDefinesId,
  1809. "%d vs %d",
  1810. dwHlslCompilandEnvDefinesID,
  1811. HlslCompilandEnvDefinesId);
  1812. DWORD dwHlslCompilandEnvArgumentsID;
  1813. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateArguments>>(dwHlslCompilandID, &dwHlslCompilandEnvArgumentsID));
  1814. DXASSERT_ARGS(dwHlslCompilandEnvArgumentsID == HlslCompilandEnvArgumentsId,
  1815. "%d vs %d",
  1816. dwHlslCompilandEnvArgumentsID,
  1817. HlslCompilandEnvArgumentsId);
  1818. IFT(SMI.CreateFunctionsForAllCUs());
  1819. IFT(SMI.CreateGlobalVariablesForAllCUs());
  1820. IFT(SMI.CreateLocalVariables());
  1821. IFT(SMI.CreateLiveRanges());
  1822. IFT(SMI.PopulateParentToChildrenIDMap(&m_parentToChildren));
  1823. }
  1824. HRESULT dxil_dia::SymbolManager::GetSymbolByID(size_t id, Symbol **ppSym) const {
  1825. if (ppSym == nullptr) {
  1826. return E_INVALIDARG;
  1827. }
  1828. *ppSym = nullptr;
  1829. if (m_pSession == nullptr) {
  1830. return E_FAIL;
  1831. }
  1832. if (id <= 0) {
  1833. return E_INVALIDARG;
  1834. }
  1835. if (id > m_symbolCtors.size()) {
  1836. return S_FALSE;
  1837. }
  1838. DxcThreadMalloc TM(m_pSession->GetMallocNoRef());
  1839. IFR(m_symbolCtors[id - 1]->Create(m_pSession, ppSym));
  1840. return S_OK;
  1841. }
  1842. HRESULT dxil_dia::SymbolManager::GetLiveRangeOf(Symbol *pSym, LiveRange *LR) const {
  1843. const DWORD dwSymID = pSym->GetID();
  1844. if (dwSymID <= 0 || dwSymID > m_symbolCtors.size()) {
  1845. return E_INVALIDARG;
  1846. }
  1847. auto symIt = m_symbolToLiveRange.find(dwSymID);
  1848. if (symIt == m_symbolToLiveRange.end()) {
  1849. return S_FALSE;
  1850. }
  1851. *LR = symIt->second;
  1852. return S_OK;
  1853. }
  1854. HRESULT dxil_dia::SymbolManager::GetGlobalScope(Symbol **ppSym) const {
  1855. return GetSymbolByID(HlslProgramId, ppSym);
  1856. }
  1857. HRESULT dxil_dia::SymbolManager::ChildrenOf(DWORD ID, std::vector<CComPtr<Symbol>> *pChildren) const {
  1858. pChildren->clear();
  1859. auto childrenList = m_parentToChildren.equal_range(ID);
  1860. for (auto it = childrenList.first; it != childrenList.second; ++it) {
  1861. CComPtr<Symbol> Child;
  1862. IFR(GetSymbolByID(it->second, &Child));
  1863. pChildren->emplace_back(Child);
  1864. }
  1865. return S_OK;
  1866. }
  1867. HRESULT dxil_dia::SymbolManager::ChildrenOf(Symbol *pSym, std::vector<CComPtr<Symbol>> *pChildren) const {
  1868. const std::uint32_t pSymID = pSym->GetID();
  1869. IFR(ChildrenOf(pSymID, pChildren));
  1870. return S_OK;
  1871. }
  1872. HRESULT dxil_dia::SymbolManager::DbgScopeOf(const llvm::Instruction *instr, SymbolChildrenEnumerator **ppRet) const {
  1873. *ppRet = nullptr;
  1874. const llvm::DebugLoc &DL = instr->getDebugLoc();
  1875. if (!DL) {
  1876. return S_FALSE;
  1877. }
  1878. llvm::MDNode *LocalScope = DL.getInlinedAtScope();
  1879. if (LocalScope == nullptr) {
  1880. LocalScope = DL.getScope();
  1881. }
  1882. if (LocalScope == nullptr) {
  1883. return S_FALSE;
  1884. }
  1885. auto *LS = llvm::dyn_cast<llvm::DILocalScope>(LocalScope);
  1886. if (LS == nullptr) {
  1887. // This is a failure as instructions should always live in a DILocalScope
  1888. return E_FAIL;
  1889. }
  1890. auto scopeIt = m_scopeToID.find(LS);
  1891. if (scopeIt == m_scopeToID.end()) {
  1892. // This is a failure because all scopes should already exist in the symbol manager.
  1893. return E_FAIL;
  1894. }
  1895. CComPtr<SymbolChildrenEnumerator> ret = SymbolChildrenEnumerator::Alloc(m_pSession->GetMallocNoRef());
  1896. if (!ret) {
  1897. return E_OUTOFMEMORY;
  1898. }
  1899. CComPtr<Symbol> s;
  1900. IFR(GetSymbolByID(scopeIt->second, &s));
  1901. std::vector<CComPtr<Symbol>> children{s};
  1902. ret->Init(std::move(children));
  1903. *ppRet = ret.Detach();
  1904. return S_OK;
  1905. }