DxilDiaSymbolManager.cpp 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247
  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. continue;
  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. if (FAILED(CreateLocalVariable(dwParentID, LV))) {
  1550. continue;
  1551. }
  1552. }
  1553. }
  1554. return S_OK;
  1555. }
  1556. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateLiveRanges() {
  1557. // Simple algorithm:
  1558. // live_range = map from SymbolID to SymbolManager.LiveRange
  1559. // end_of_scope = map from Scope to RVA
  1560. // for each I in reverse(pSession.InstructionsRef):
  1561. // scope = I.scope
  1562. // if scope not in end_of_scope:
  1563. // end_of_scope[scope] = rva(I)
  1564. // if I is dbg.declare:
  1565. // live_range[symbol of I] = SymbolManager.LiveRange[FirstUseRVA, end_of_scope[scope]]
  1566. llvm::Module *M = &m_Session.ModuleRef();
  1567. m_SymToLR.clear();
  1568. const auto &Instrs = m_Session.InstructionsRef();
  1569. llvm::DenseMap<llvm::DILocalScope *, Session::RVA> EndOfScope;
  1570. for (auto It = Instrs.rbegin(); It != Instrs.rend(); ++It) {
  1571. const Session::RVA RVA = It->first;
  1572. const auto *I = It->second;
  1573. const llvm::DebugLoc &DL = I->getDebugLoc();
  1574. if (!DL) {
  1575. continue;
  1576. }
  1577. llvm::MDNode *LocalScope = DL.getScope();
  1578. if (LocalScope == nullptr) {
  1579. continue;
  1580. }
  1581. auto *LS = llvm::dyn_cast<llvm::DILocalScope>(LocalScope);
  1582. if (LS == nullptr) {
  1583. return E_FAIL;
  1584. }
  1585. if (EndOfScope.count(LS) == 0) {
  1586. EndOfScope.insert(std::make_pair(LS, RVA + 1));
  1587. }
  1588. auto endOfScopeRVA = EndOfScope.find(LS)->second;
  1589. DWORD Reg;
  1590. DWORD RegSize;
  1591. llvm::DILocalVariable *LV;
  1592. uint64_t StartOffset;
  1593. uint64_t EndOffset;
  1594. Session::RVA FirstUseRVA;
  1595. Session::RVA LastUseRVA;
  1596. HRESULT hr = IsDbgDeclareCall(M, I, &Reg, &RegSize, &LV, &StartOffset,
  1597. &EndOffset, &FirstUseRVA, &LastUseRVA);
  1598. if (hr != S_OK) {
  1599. continue;
  1600. }
  1601. endOfScopeRVA = std::max<Session::RVA>(endOfScopeRVA, LastUseRVA);
  1602. auto varIt = m_VarToID.find(LV);
  1603. if (varIt == m_VarToID.end()) {
  1604. // All variables should already have been seen and created.
  1605. return E_FAIL;
  1606. }
  1607. for (auto &Var : varIt->second) {
  1608. const DWORD dwOffsetInUDT = Var->GetOffsetInUDT();
  1609. if (dwOffsetInUDT < StartOffset || dwOffsetInUDT >= EndOffset) {
  1610. continue;
  1611. }
  1612. DXASSERT_ARGS((dwOffsetInUDT - StartOffset) % 4 == 0,
  1613. "Invalid byte offset %d into variable",
  1614. (dwOffsetInUDT - StartOffset));
  1615. const DWORD dwRegIndex = (dwOffsetInUDT - StartOffset) / 4;
  1616. if (dwRegIndex >= RegSize) {
  1617. continue;
  1618. }
  1619. Var->SetDxilRegister(Reg + dwRegIndex);
  1620. m_SymToLR[Var->GetVarID()] = SymbolManager::LiveRange{
  1621. static_cast<uint32_t>(FirstUseRVA),
  1622. endOfScopeRVA - static_cast<uint32_t>(FirstUseRVA)
  1623. };
  1624. }
  1625. }
  1626. return S_OK;
  1627. }
  1628. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::IsDbgDeclareCall(
  1629. llvm::Module *M, const llvm::Instruction *I, DWORD *pReg, DWORD *pRegSize,
  1630. llvm::DILocalVariable **LV, uint64_t *pStartOffset, uint64_t *pEndOffset,
  1631. dxil_dia::Session::RVA *pLowestUserRVA,
  1632. dxil_dia::Session::RVA *pHighestUserRVA) {
  1633. auto *CI = llvm::dyn_cast<llvm::CallInst>(I);
  1634. if (CI == nullptr) {
  1635. return S_FALSE;
  1636. }
  1637. llvm::Function *DbgDeclare = llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::dbg_declare);
  1638. if (CI->getCalledFunction() != DbgDeclare) {
  1639. return S_FALSE;
  1640. }
  1641. *LV = nullptr;
  1642. *pReg = *pRegSize = 0;
  1643. *pStartOffset = *pEndOffset = 0;
  1644. *pLowestUserRVA = 0;
  1645. *pHighestUserRVA = 0;
  1646. std::vector<dxil_dia::Session::RVA> usesRVAs;
  1647. bool HasRegister = false;
  1648. if (auto *RegMV = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(0))) {
  1649. if (auto *RegVM = llvm::dyn_cast<llvm::ValueAsMetadata>(RegMV->getMetadata())) {
  1650. if (auto *Reg = llvm::dyn_cast<llvm::Instruction>(RegVM->getValue())) {
  1651. HRESULT hr;
  1652. IFR(hr = GetDxilAllocaRegister(Reg, pReg, pRegSize));
  1653. if (hr != S_OK) {
  1654. return hr;
  1655. }
  1656. HasRegister = true;
  1657. llvm::iterator_range<llvm::Value::user_iterator> users = Reg->users();
  1658. for (llvm::User *user : users) {
  1659. auto *inst = llvm::dyn_cast<llvm::Instruction>(user);
  1660. if (inst != nullptr) {
  1661. auto rva = m_Session.RvaMapRef().find(inst);
  1662. usesRVAs.push_back(rva->second);
  1663. }
  1664. }
  1665. }
  1666. }
  1667. }
  1668. if (!HasRegister) {
  1669. return E_FAIL;
  1670. }
  1671. if (!usesRVAs.empty()) {
  1672. *pLowestUserRVA = *std::min_element(usesRVAs.begin(), usesRVAs.end());
  1673. *pHighestUserRVA = *std::max_element(usesRVAs.begin(), usesRVAs.end());
  1674. }
  1675. if (auto *LVMV = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(1))) {
  1676. *LV = llvm::dyn_cast<llvm::DILocalVariable>(LVMV->getMetadata());
  1677. if (*LV == nullptr) {
  1678. return E_FAIL;
  1679. }
  1680. }
  1681. if (auto *FieldsMV = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(2))) {
  1682. auto *Fields = llvm::dyn_cast<llvm::DIExpression>(FieldsMV->getMetadata());
  1683. if (Fields == nullptr) {
  1684. return E_FAIL;
  1685. }
  1686. static constexpr uint64_t kNumBytesPerDword = 4;
  1687. if (Fields->isBitPiece()) {
  1688. const uint64_t BitPieceOffset = Fields->getBitPieceOffset();
  1689. const uint64_t BitPieceSize = Fields->getBitPieceSize();
  1690. // dxcompiler had a bug (fixed in
  1691. // 4870297404a37269e24ddce7db3bd94a8110fff8) where the BitPieceSize
  1692. // was defined in bytes, not bits. We use the register size in bits to
  1693. // verify if Size is bits or bytes.
  1694. if (*pRegSize * kNumBytesPerDword == BitPieceSize) {
  1695. // Size is bytes.
  1696. *pStartOffset = BitPieceOffset;
  1697. *pEndOffset = *pStartOffset + BitPieceSize;
  1698. } else {
  1699. // Size is (should be) bits; pStartOffset/pEndOffset should be bytes.
  1700. // We don't expect to encounter bit pieces more granular than bytes.
  1701. static constexpr uint64_t kNumBitsPerByte = 8;
  1702. (void)kNumBitsPerByte;
  1703. assert(BitPieceOffset % kNumBitsPerByte == 0);
  1704. assert(BitPieceSize % kNumBitsPerByte == 0);
  1705. *pStartOffset = BitPieceOffset / kNumBitsPerByte;
  1706. *pEndOffset = *pStartOffset + (BitPieceSize / kNumBitsPerByte);
  1707. }
  1708. } else {
  1709. *pStartOffset = 0;
  1710. *pEndOffset = *pRegSize * kNumBytesPerDword;
  1711. }
  1712. }
  1713. return S_OK;
  1714. }
  1715. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::GetDxilAllocaRegister(llvm::Instruction *I, DWORD *pRegNum, DWORD *pRegSize) {
  1716. auto *Alloca = llvm::dyn_cast<llvm::AllocaInst>(I);
  1717. if (Alloca == nullptr) {
  1718. return S_FALSE;
  1719. }
  1720. std::uint32_t uRegNum;
  1721. std::uint32_t uRegSize;
  1722. if (!pix_dxil::PixAllocaReg::FromInst(Alloca, &uRegNum, &uRegSize)) {
  1723. return S_FALSE;
  1724. }
  1725. *pRegNum = uRegNum;
  1726. *pRegSize = uRegSize;
  1727. return S_OK;
  1728. }
  1729. HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::PopulateParentToChildrenIDMap(SymbolManager::ParentToChildrenMap *pParentToChildren) {
  1730. DXASSERT_ARGS(m_SymCtors.size() == m_Parent.size(),
  1731. "parents vector must be the same size of symbols ctor vector: %d vs %d",
  1732. m_SymCtors.size(),
  1733. m_Parent.size());
  1734. for (size_t i = 0; i < m_Parent.size(); ++i) {
  1735. #ifndef NDEBUG
  1736. {
  1737. CComPtr<Symbol> S;
  1738. IFT(m_SymCtors[i]->Create(&m_Session, &S));
  1739. DXASSERT_ARGS(S->GetID() == i + 1,
  1740. "Invalid symbol index %d for %d",
  1741. S->GetID(),
  1742. i + 1);
  1743. }
  1744. #endif // !NDEBUG
  1745. DXASSERT_ARGS(m_Parent[i] != kNullSymbolID || (i + 1) == HlslProgramId,
  1746. "Parentless symbol %d", i + 1);
  1747. if (m_Parent[i] != kNullSymbolID) {
  1748. pParentToChildren->emplace(m_Parent[i], i + 1);
  1749. }
  1750. }
  1751. return S_OK;
  1752. }
  1753. dxil_dia::SymbolManager::SymbolFactory::SymbolFactory(DWORD ID, DWORD ParentID)
  1754. : m_ID(ID), m_ParentID(ParentID) {}
  1755. dxil_dia::SymbolManager::SymbolFactory::~SymbolFactory() = default;
  1756. dxil_dia::SymbolManager::SymbolManager() = default;
  1757. dxil_dia::SymbolManager::~SymbolManager() {
  1758. m_pSession = nullptr;
  1759. }
  1760. void dxil_dia::SymbolManager::Init(Session *pSes) {
  1761. DXASSERT(m_pSession == nullptr, "SymbolManager already initialized");
  1762. m_pSession = pSes;
  1763. m_symbolCtors.clear();
  1764. m_parentToChildren.clear();
  1765. llvm::DebugInfoFinder &DIFinder = pSes->InfoRef();
  1766. if (DIFinder.compile_unit_count() != 1) {
  1767. throw hlsl::Exception(E_FAIL);
  1768. }
  1769. llvm::DICompileUnit *ShaderCU = *DIFinder.compile_units().begin();
  1770. hlsl_symbols::SymbolManagerInit SMI(pSes, &m_symbolCtors, &m_scopeToID, &m_symbolToLiveRange);
  1771. DWORD dwHlslProgramID;
  1772. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::GlobalScope>(kNullSymbolID, &dwHlslProgramID));
  1773. DXASSERT_ARGS(dwHlslProgramID == HlslProgramId,
  1774. "%d vs %d",
  1775. dwHlslProgramID,
  1776. HlslProgramId);
  1777. DWORD dwHlslCompilandID;
  1778. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::Compiland>(dwHlslProgramID, &dwHlslCompilandID, ShaderCU));
  1779. m_scopeToID.insert(std::make_pair(ShaderCU, dwHlslCompilandID));
  1780. DXASSERT_ARGS(dwHlslCompilandID == HlslCompilandId,
  1781. "%d vs %d",
  1782. dwHlslCompilandID,
  1783. HlslCompilandId);
  1784. DWORD dwHlslCompilandDetailsId;
  1785. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandDetails>(dwHlslCompilandID, &dwHlslCompilandDetailsId));
  1786. DXASSERT_ARGS(dwHlslCompilandDetailsId == HlslCompilandDetailsId,
  1787. "%d vs %d",
  1788. dwHlslCompilandDetailsId,
  1789. HlslCompilandDetailsId);
  1790. DWORD dwHlslCompilandEnvFlagsID;
  1791. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateFlags>>(dwHlslCompilandID, &dwHlslCompilandEnvFlagsID));
  1792. DXASSERT_ARGS(dwHlslCompilandEnvFlagsID == HlslCompilandEnvFlagsId,
  1793. "%d vs %d",
  1794. dwHlslCompilandEnvFlagsID,
  1795. HlslCompilandEnvFlagsId);
  1796. DWORD dwHlslCompilandEnvTargetID;
  1797. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateTarget>>(dwHlslCompilandID, &dwHlslCompilandEnvTargetID));
  1798. DXASSERT_ARGS(dwHlslCompilandEnvTargetID == HlslCompilandEnvTargetId,
  1799. "%d vs %d",
  1800. dwHlslCompilandEnvTargetID,
  1801. HlslCompilandEnvTargetId);
  1802. DWORD dwHlslCompilandEnvEntryID;
  1803. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateEntry>>(dwHlslCompilandID, &dwHlslCompilandEnvEntryID));
  1804. DXASSERT_ARGS(dwHlslCompilandEnvEntryID == HlslCompilandEnvEntryId,
  1805. "%d vs %d",
  1806. dwHlslCompilandEnvEntryID,
  1807. HlslCompilandEnvEntryId);
  1808. DWORD dwHlslCompilandEnvDefinesID;
  1809. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateDefines>>(dwHlslCompilandID, &dwHlslCompilandEnvDefinesID));
  1810. DXASSERT_ARGS(dwHlslCompilandEnvDefinesID == HlslCompilandEnvDefinesId,
  1811. "%d vs %d",
  1812. dwHlslCompilandEnvDefinesID,
  1813. HlslCompilandEnvDefinesId);
  1814. DWORD dwHlslCompilandEnvArgumentsID;
  1815. IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateArguments>>(dwHlslCompilandID, &dwHlslCompilandEnvArgumentsID));
  1816. DXASSERT_ARGS(dwHlslCompilandEnvArgumentsID == HlslCompilandEnvArgumentsId,
  1817. "%d vs %d",
  1818. dwHlslCompilandEnvArgumentsID,
  1819. HlslCompilandEnvArgumentsId);
  1820. IFT(SMI.CreateFunctionsForAllCUs());
  1821. IFT(SMI.CreateGlobalVariablesForAllCUs());
  1822. IFT(SMI.CreateLocalVariables());
  1823. IFT(SMI.CreateLiveRanges());
  1824. IFT(SMI.PopulateParentToChildrenIDMap(&m_parentToChildren));
  1825. }
  1826. HRESULT dxil_dia::SymbolManager::GetSymbolByID(size_t id, Symbol **ppSym) const {
  1827. if (ppSym == nullptr) {
  1828. return E_INVALIDARG;
  1829. }
  1830. *ppSym = nullptr;
  1831. if (m_pSession == nullptr) {
  1832. return E_FAIL;
  1833. }
  1834. if (id <= 0) {
  1835. return E_INVALIDARG;
  1836. }
  1837. if (id > m_symbolCtors.size()) {
  1838. return S_FALSE;
  1839. }
  1840. DxcThreadMalloc TM(m_pSession->GetMallocNoRef());
  1841. IFR(m_symbolCtors[id - 1]->Create(m_pSession, ppSym));
  1842. return S_OK;
  1843. }
  1844. HRESULT dxil_dia::SymbolManager::GetLiveRangeOf(Symbol *pSym, LiveRange *LR) const {
  1845. const DWORD dwSymID = pSym->GetID();
  1846. if (dwSymID <= 0 || dwSymID > m_symbolCtors.size()) {
  1847. return E_INVALIDARG;
  1848. }
  1849. auto symIt = m_symbolToLiveRange.find(dwSymID);
  1850. if (symIt == m_symbolToLiveRange.end()) {
  1851. return S_FALSE;
  1852. }
  1853. *LR = symIt->second;
  1854. return S_OK;
  1855. }
  1856. HRESULT dxil_dia::SymbolManager::GetGlobalScope(Symbol **ppSym) const {
  1857. return GetSymbolByID(HlslProgramId, ppSym);
  1858. }
  1859. HRESULT dxil_dia::SymbolManager::ChildrenOf(DWORD ID, std::vector<CComPtr<Symbol>> *pChildren) const {
  1860. pChildren->clear();
  1861. auto childrenList = m_parentToChildren.equal_range(ID);
  1862. for (auto it = childrenList.first; it != childrenList.second; ++it) {
  1863. CComPtr<Symbol> Child;
  1864. IFR(GetSymbolByID(it->second, &Child));
  1865. pChildren->emplace_back(Child);
  1866. }
  1867. return S_OK;
  1868. }
  1869. HRESULT dxil_dia::SymbolManager::ChildrenOf(Symbol *pSym, std::vector<CComPtr<Symbol>> *pChildren) const {
  1870. const std::uint32_t pSymID = pSym->GetID();
  1871. IFR(ChildrenOf(pSymID, pChildren));
  1872. return S_OK;
  1873. }
  1874. HRESULT dxil_dia::SymbolManager::DbgScopeOf(const llvm::Instruction *instr, SymbolChildrenEnumerator **ppRet) const {
  1875. *ppRet = nullptr;
  1876. const llvm::DebugLoc &DL = instr->getDebugLoc();
  1877. if (!DL) {
  1878. return S_FALSE;
  1879. }
  1880. llvm::MDNode *LocalScope = DL.getInlinedAtScope();
  1881. if (LocalScope == nullptr) {
  1882. LocalScope = DL.getScope();
  1883. }
  1884. if (LocalScope == nullptr) {
  1885. return S_FALSE;
  1886. }
  1887. auto *LS = llvm::dyn_cast<llvm::DILocalScope>(LocalScope);
  1888. if (LS == nullptr) {
  1889. // This is a failure as instructions should always live in a DILocalScope
  1890. return E_FAIL;
  1891. }
  1892. auto scopeIt = m_scopeToID.find(LS);
  1893. if (scopeIt == m_scopeToID.end()) {
  1894. // This is a failure because all scopes should already exist in the symbol manager.
  1895. return E_FAIL;
  1896. }
  1897. CComPtr<SymbolChildrenEnumerator> ret = SymbolChildrenEnumerator::Alloc(m_pSession->GetMallocNoRef());
  1898. if (!ret) {
  1899. return E_OUTOFMEMORY;
  1900. }
  1901. CComPtr<Symbol> s;
  1902. IFR(GetSymbolByID(scopeIt->second, &s));
  1903. std::vector<CComPtr<Symbol>> children{s};
  1904. ret->Init(std::move(children));
  1905. *ppRet = ret.Detach();
  1906. return S_OK;
  1907. }