hlslScanContext.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. //
  2. // Copyright (C) 2016 Google, Inc.
  3. // Copyright (C) 2016 LunarG, Inc.
  4. //
  5. // All rights reserved.
  6. //
  7. // Redistribution and use in source and binary forms, with or without
  8. // modification, are permitted provided that the following conditions
  9. // are met:
  10. //
  11. // Redistributions of source code must retain the above copyright
  12. // notice, this list of conditions and the following disclaimer.
  13. //
  14. // Redistributions in binary form must reproduce the above
  15. // copyright notice, this list of conditions and the following
  16. // disclaimer in the documentation and/or other materials provided
  17. // with the distribution.
  18. //
  19. // Neither the name of Google, Inc., nor the names of its
  20. // contributors may be used to endorse or promote products derived
  21. // from this software without specific prior written permission.
  22. //
  23. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  25. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  26. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  27. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  28. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  29. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  31. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  33. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34. // POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. //
  37. // HLSL scanning, leveraging the scanning done by the preprocessor.
  38. //
  39. #include <cstring>
  40. #include <unordered_map>
  41. #include <unordered_set>
  42. #include "../glslang/Include/Types.h"
  43. #include "../glslang/MachineIndependent/SymbolTable.h"
  44. #include "../glslang/MachineIndependent/ParseHelper.h"
  45. #include "hlslScanContext.h"
  46. #include "hlslTokens.h"
  47. // preprocessor includes
  48. #include "../glslang/MachineIndependent/preprocessor/PpContext.h"
  49. #include "../glslang/MachineIndependent/preprocessor/PpTokens.h"
  50. namespace {
  51. struct str_eq
  52. {
  53. bool operator()(const char* lhs, const char* rhs) const
  54. {
  55. return strcmp(lhs, rhs) == 0;
  56. }
  57. };
  58. struct str_hash
  59. {
  60. size_t operator()(const char* str) const
  61. {
  62. // djb2
  63. unsigned long hash = 5381;
  64. int c;
  65. while ((c = *str++) != 0)
  66. hash = ((hash << 5) + hash) + c;
  67. return hash;
  68. }
  69. };
  70. // A single global usable by all threads, by all versions, by all languages.
  71. // After a single process-level initialization, this is read only and thread safe
  72. std::unordered_map<const char*, glslang::EHlslTokenClass, str_hash, str_eq>* KeywordMap = nullptr;
  73. std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
  74. std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>* SemanticMap = nullptr;
  75. };
  76. namespace glslang {
  77. void HlslScanContext::fillInKeywordMap()
  78. {
  79. if (KeywordMap != nullptr) {
  80. // this is really an error, as this should called only once per process
  81. // but, the only risk is if two threads called simultaneously
  82. return;
  83. }
  84. KeywordMap = new std::unordered_map<const char*, EHlslTokenClass, str_hash, str_eq>;
  85. (*KeywordMap)["static"] = EHTokStatic;
  86. (*KeywordMap)["const"] = EHTokConst;
  87. (*KeywordMap)["unorm"] = EHTokUnorm;
  88. (*KeywordMap)["snorm"] = EHTokSNorm;
  89. (*KeywordMap)["extern"] = EHTokExtern;
  90. (*KeywordMap)["uniform"] = EHTokUniform;
  91. (*KeywordMap)["volatile"] = EHTokVolatile;
  92. (*KeywordMap)["precise"] = EHTokPrecise;
  93. (*KeywordMap)["shared"] = EHTokShared;
  94. (*KeywordMap)["groupshared"] = EHTokGroupShared;
  95. (*KeywordMap)["linear"] = EHTokLinear;
  96. (*KeywordMap)["centroid"] = EHTokCentroid;
  97. (*KeywordMap)["nointerpolation"] = EHTokNointerpolation;
  98. (*KeywordMap)["noperspective"] = EHTokNoperspective;
  99. (*KeywordMap)["sample"] = EHTokSample;
  100. (*KeywordMap)["row_major"] = EHTokRowMajor;
  101. (*KeywordMap)["column_major"] = EHTokColumnMajor;
  102. (*KeywordMap)["packoffset"] = EHTokPackOffset;
  103. (*KeywordMap)["in"] = EHTokIn;
  104. (*KeywordMap)["out"] = EHTokOut;
  105. (*KeywordMap)["inout"] = EHTokInOut;
  106. (*KeywordMap)["layout"] = EHTokLayout;
  107. (*KeywordMap)["globallycoherent"] = EHTokGloballyCoherent;
  108. (*KeywordMap)["inline"] = EHTokInline;
  109. (*KeywordMap)["point"] = EHTokPoint;
  110. (*KeywordMap)["line"] = EHTokLine;
  111. (*KeywordMap)["triangle"] = EHTokTriangle;
  112. (*KeywordMap)["lineadj"] = EHTokLineAdj;
  113. (*KeywordMap)["triangleadj"] = EHTokTriangleAdj;
  114. (*KeywordMap)["PointStream"] = EHTokPointStream;
  115. (*KeywordMap)["LineStream"] = EHTokLineStream;
  116. (*KeywordMap)["TriangleStream"] = EHTokTriangleStream;
  117. (*KeywordMap)["InputPatch"] = EHTokInputPatch;
  118. (*KeywordMap)["OutputPatch"] = EHTokOutputPatch;
  119. (*KeywordMap)["Buffer"] = EHTokBuffer;
  120. (*KeywordMap)["vector"] = EHTokVector;
  121. (*KeywordMap)["matrix"] = EHTokMatrix;
  122. (*KeywordMap)["void"] = EHTokVoid;
  123. (*KeywordMap)["string"] = EHTokString;
  124. (*KeywordMap)["bool"] = EHTokBool;
  125. (*KeywordMap)["int"] = EHTokInt;
  126. (*KeywordMap)["uint"] = EHTokUint;
  127. (*KeywordMap)["uint64_t"] = EHTokUint64;
  128. (*KeywordMap)["dword"] = EHTokDword;
  129. (*KeywordMap)["half"] = EHTokHalf;
  130. (*KeywordMap)["float"] = EHTokFloat;
  131. (*KeywordMap)["double"] = EHTokDouble;
  132. (*KeywordMap)["min16float"] = EHTokMin16float;
  133. (*KeywordMap)["min10float"] = EHTokMin10float;
  134. (*KeywordMap)["min16int"] = EHTokMin16int;
  135. (*KeywordMap)["min12int"] = EHTokMin12int;
  136. (*KeywordMap)["min16uint"] = EHTokMin16uint;
  137. (*KeywordMap)["bool1"] = EHTokBool1;
  138. (*KeywordMap)["bool2"] = EHTokBool2;
  139. (*KeywordMap)["bool3"] = EHTokBool3;
  140. (*KeywordMap)["bool4"] = EHTokBool4;
  141. (*KeywordMap)["float1"] = EHTokFloat1;
  142. (*KeywordMap)["float2"] = EHTokFloat2;
  143. (*KeywordMap)["float3"] = EHTokFloat3;
  144. (*KeywordMap)["float4"] = EHTokFloat4;
  145. (*KeywordMap)["int1"] = EHTokInt1;
  146. (*KeywordMap)["int2"] = EHTokInt2;
  147. (*KeywordMap)["int3"] = EHTokInt3;
  148. (*KeywordMap)["int4"] = EHTokInt4;
  149. (*KeywordMap)["double1"] = EHTokDouble1;
  150. (*KeywordMap)["double2"] = EHTokDouble2;
  151. (*KeywordMap)["double3"] = EHTokDouble3;
  152. (*KeywordMap)["double4"] = EHTokDouble4;
  153. (*KeywordMap)["uint1"] = EHTokUint1;
  154. (*KeywordMap)["uint2"] = EHTokUint2;
  155. (*KeywordMap)["uint3"] = EHTokUint3;
  156. (*KeywordMap)["uint4"] = EHTokUint4;
  157. (*KeywordMap)["half1"] = EHTokHalf1;
  158. (*KeywordMap)["half2"] = EHTokHalf2;
  159. (*KeywordMap)["half3"] = EHTokHalf3;
  160. (*KeywordMap)["half4"] = EHTokHalf4;
  161. (*KeywordMap)["min16float1"] = EHTokMin16float1;
  162. (*KeywordMap)["min16float2"] = EHTokMin16float2;
  163. (*KeywordMap)["min16float3"] = EHTokMin16float3;
  164. (*KeywordMap)["min16float4"] = EHTokMin16float4;
  165. (*KeywordMap)["min10float1"] = EHTokMin10float1;
  166. (*KeywordMap)["min10float2"] = EHTokMin10float2;
  167. (*KeywordMap)["min10float3"] = EHTokMin10float3;
  168. (*KeywordMap)["min10float4"] = EHTokMin10float4;
  169. (*KeywordMap)["min16int1"] = EHTokMin16int1;
  170. (*KeywordMap)["min16int2"] = EHTokMin16int2;
  171. (*KeywordMap)["min16int3"] = EHTokMin16int3;
  172. (*KeywordMap)["min16int4"] = EHTokMin16int4;
  173. (*KeywordMap)["min12int1"] = EHTokMin12int1;
  174. (*KeywordMap)["min12int2"] = EHTokMin12int2;
  175. (*KeywordMap)["min12int3"] = EHTokMin12int3;
  176. (*KeywordMap)["min12int4"] = EHTokMin12int4;
  177. (*KeywordMap)["min16uint1"] = EHTokMin16uint1;
  178. (*KeywordMap)["min16uint2"] = EHTokMin16uint2;
  179. (*KeywordMap)["min16uint3"] = EHTokMin16uint3;
  180. (*KeywordMap)["min16uint4"] = EHTokMin16uint4;
  181. (*KeywordMap)["bool1x1"] = EHTokBool1x1;
  182. (*KeywordMap)["bool1x2"] = EHTokBool1x2;
  183. (*KeywordMap)["bool1x3"] = EHTokBool1x3;
  184. (*KeywordMap)["bool1x4"] = EHTokBool1x4;
  185. (*KeywordMap)["bool2x1"] = EHTokBool2x1;
  186. (*KeywordMap)["bool2x2"] = EHTokBool2x2;
  187. (*KeywordMap)["bool2x3"] = EHTokBool2x3;
  188. (*KeywordMap)["bool2x4"] = EHTokBool2x4;
  189. (*KeywordMap)["bool3x1"] = EHTokBool3x1;
  190. (*KeywordMap)["bool3x2"] = EHTokBool3x2;
  191. (*KeywordMap)["bool3x3"] = EHTokBool3x3;
  192. (*KeywordMap)["bool3x4"] = EHTokBool3x4;
  193. (*KeywordMap)["bool4x1"] = EHTokBool4x1;
  194. (*KeywordMap)["bool4x2"] = EHTokBool4x2;
  195. (*KeywordMap)["bool4x3"] = EHTokBool4x3;
  196. (*KeywordMap)["bool4x4"] = EHTokBool4x4;
  197. (*KeywordMap)["int1x1"] = EHTokInt1x1;
  198. (*KeywordMap)["int1x2"] = EHTokInt1x2;
  199. (*KeywordMap)["int1x3"] = EHTokInt1x3;
  200. (*KeywordMap)["int1x4"] = EHTokInt1x4;
  201. (*KeywordMap)["int2x1"] = EHTokInt2x1;
  202. (*KeywordMap)["int2x2"] = EHTokInt2x2;
  203. (*KeywordMap)["int2x3"] = EHTokInt2x3;
  204. (*KeywordMap)["int2x4"] = EHTokInt2x4;
  205. (*KeywordMap)["int3x1"] = EHTokInt3x1;
  206. (*KeywordMap)["int3x2"] = EHTokInt3x2;
  207. (*KeywordMap)["int3x3"] = EHTokInt3x3;
  208. (*KeywordMap)["int3x4"] = EHTokInt3x4;
  209. (*KeywordMap)["int4x1"] = EHTokInt4x1;
  210. (*KeywordMap)["int4x2"] = EHTokInt4x2;
  211. (*KeywordMap)["int4x3"] = EHTokInt4x3;
  212. (*KeywordMap)["int4x4"] = EHTokInt4x4;
  213. (*KeywordMap)["uint1x1"] = EHTokUint1x1;
  214. (*KeywordMap)["uint1x2"] = EHTokUint1x2;
  215. (*KeywordMap)["uint1x3"] = EHTokUint1x3;
  216. (*KeywordMap)["uint1x4"] = EHTokUint1x4;
  217. (*KeywordMap)["uint2x1"] = EHTokUint2x1;
  218. (*KeywordMap)["uint2x2"] = EHTokUint2x2;
  219. (*KeywordMap)["uint2x3"] = EHTokUint2x3;
  220. (*KeywordMap)["uint2x4"] = EHTokUint2x4;
  221. (*KeywordMap)["uint3x1"] = EHTokUint3x1;
  222. (*KeywordMap)["uint3x2"] = EHTokUint3x2;
  223. (*KeywordMap)["uint3x3"] = EHTokUint3x3;
  224. (*KeywordMap)["uint3x4"] = EHTokUint3x4;
  225. (*KeywordMap)["uint4x1"] = EHTokUint4x1;
  226. (*KeywordMap)["uint4x2"] = EHTokUint4x2;
  227. (*KeywordMap)["uint4x3"] = EHTokUint4x3;
  228. (*KeywordMap)["uint4x4"] = EHTokUint4x4;
  229. (*KeywordMap)["bool1x1"] = EHTokBool1x1;
  230. (*KeywordMap)["bool1x2"] = EHTokBool1x2;
  231. (*KeywordMap)["bool1x3"] = EHTokBool1x3;
  232. (*KeywordMap)["bool1x4"] = EHTokBool1x4;
  233. (*KeywordMap)["bool2x1"] = EHTokBool2x1;
  234. (*KeywordMap)["bool2x2"] = EHTokBool2x2;
  235. (*KeywordMap)["bool2x3"] = EHTokBool2x3;
  236. (*KeywordMap)["bool2x4"] = EHTokBool2x4;
  237. (*KeywordMap)["bool3x1"] = EHTokBool3x1;
  238. (*KeywordMap)["bool3x2"] = EHTokBool3x2;
  239. (*KeywordMap)["bool3x3"] = EHTokBool3x3;
  240. (*KeywordMap)["bool3x4"] = EHTokBool3x4;
  241. (*KeywordMap)["bool4x1"] = EHTokBool4x1;
  242. (*KeywordMap)["bool4x2"] = EHTokBool4x2;
  243. (*KeywordMap)["bool4x3"] = EHTokBool4x3;
  244. (*KeywordMap)["bool4x4"] = EHTokBool4x4;
  245. (*KeywordMap)["float1x1"] = EHTokFloat1x1;
  246. (*KeywordMap)["float1x2"] = EHTokFloat1x2;
  247. (*KeywordMap)["float1x3"] = EHTokFloat1x3;
  248. (*KeywordMap)["float1x4"] = EHTokFloat1x4;
  249. (*KeywordMap)["float2x1"] = EHTokFloat2x1;
  250. (*KeywordMap)["float2x2"] = EHTokFloat2x2;
  251. (*KeywordMap)["float2x3"] = EHTokFloat2x3;
  252. (*KeywordMap)["float2x4"] = EHTokFloat2x4;
  253. (*KeywordMap)["float3x1"] = EHTokFloat3x1;
  254. (*KeywordMap)["float3x2"] = EHTokFloat3x2;
  255. (*KeywordMap)["float3x3"] = EHTokFloat3x3;
  256. (*KeywordMap)["float3x4"] = EHTokFloat3x4;
  257. (*KeywordMap)["float4x1"] = EHTokFloat4x1;
  258. (*KeywordMap)["float4x2"] = EHTokFloat4x2;
  259. (*KeywordMap)["float4x3"] = EHTokFloat4x3;
  260. (*KeywordMap)["float4x4"] = EHTokFloat4x4;
  261. (*KeywordMap)["half1x1"] = EHTokHalf1x1;
  262. (*KeywordMap)["half1x2"] = EHTokHalf1x2;
  263. (*KeywordMap)["half1x3"] = EHTokHalf1x3;
  264. (*KeywordMap)["half1x4"] = EHTokHalf1x4;
  265. (*KeywordMap)["half2x1"] = EHTokHalf2x1;
  266. (*KeywordMap)["half2x2"] = EHTokHalf2x2;
  267. (*KeywordMap)["half2x3"] = EHTokHalf2x3;
  268. (*KeywordMap)["half2x4"] = EHTokHalf2x4;
  269. (*KeywordMap)["half3x1"] = EHTokHalf3x1;
  270. (*KeywordMap)["half3x2"] = EHTokHalf3x2;
  271. (*KeywordMap)["half3x3"] = EHTokHalf3x3;
  272. (*KeywordMap)["half3x4"] = EHTokHalf3x4;
  273. (*KeywordMap)["half4x1"] = EHTokHalf4x1;
  274. (*KeywordMap)["half4x2"] = EHTokHalf4x2;
  275. (*KeywordMap)["half4x3"] = EHTokHalf4x3;
  276. (*KeywordMap)["half4x4"] = EHTokHalf4x4;
  277. (*KeywordMap)["double1x1"] = EHTokDouble1x1;
  278. (*KeywordMap)["double1x2"] = EHTokDouble1x2;
  279. (*KeywordMap)["double1x3"] = EHTokDouble1x3;
  280. (*KeywordMap)["double1x4"] = EHTokDouble1x4;
  281. (*KeywordMap)["double2x1"] = EHTokDouble2x1;
  282. (*KeywordMap)["double2x2"] = EHTokDouble2x2;
  283. (*KeywordMap)["double2x3"] = EHTokDouble2x3;
  284. (*KeywordMap)["double2x4"] = EHTokDouble2x4;
  285. (*KeywordMap)["double3x1"] = EHTokDouble3x1;
  286. (*KeywordMap)["double3x2"] = EHTokDouble3x2;
  287. (*KeywordMap)["double3x3"] = EHTokDouble3x3;
  288. (*KeywordMap)["double3x4"] = EHTokDouble3x4;
  289. (*KeywordMap)["double4x1"] = EHTokDouble4x1;
  290. (*KeywordMap)["double4x2"] = EHTokDouble4x2;
  291. (*KeywordMap)["double4x3"] = EHTokDouble4x3;
  292. (*KeywordMap)["double4x4"] = EHTokDouble4x4;
  293. (*KeywordMap)["sampler"] = EHTokSampler;
  294. (*KeywordMap)["sampler1D"] = EHTokSampler1d;
  295. (*KeywordMap)["sampler2D"] = EHTokSampler2d;
  296. (*KeywordMap)["sampler3D"] = EHTokSampler3d;
  297. (*KeywordMap)["samplerCube"] = EHTokSamplerCube;
  298. (*KeywordMap)["sampler_state"] = EHTokSamplerState;
  299. (*KeywordMap)["SamplerState"] = EHTokSamplerState;
  300. (*KeywordMap)["SamplerComparisonState"] = EHTokSamplerComparisonState;
  301. (*KeywordMap)["texture"] = EHTokTexture;
  302. (*KeywordMap)["Texture1D"] = EHTokTexture1d;
  303. (*KeywordMap)["Texture1DArray"] = EHTokTexture1darray;
  304. (*KeywordMap)["Texture2D"] = EHTokTexture2d;
  305. (*KeywordMap)["Texture2DArray"] = EHTokTexture2darray;
  306. (*KeywordMap)["Texture3D"] = EHTokTexture3d;
  307. (*KeywordMap)["TextureCube"] = EHTokTextureCube;
  308. (*KeywordMap)["TextureCubeArray"] = EHTokTextureCubearray;
  309. (*KeywordMap)["Texture2DMS"] = EHTokTexture2DMS;
  310. (*KeywordMap)["Texture2DMSArray"] = EHTokTexture2DMSarray;
  311. (*KeywordMap)["RWTexture1D"] = EHTokRWTexture1d;
  312. (*KeywordMap)["RWTexture1DArray"] = EHTokRWTexture1darray;
  313. (*KeywordMap)["RWTexture2D"] = EHTokRWTexture2d;
  314. (*KeywordMap)["RWTexture2DArray"] = EHTokRWTexture2darray;
  315. (*KeywordMap)["RWTexture3D"] = EHTokRWTexture3d;
  316. (*KeywordMap)["RWBuffer"] = EHTokRWBuffer;
  317. (*KeywordMap)["SubpassInput"] = EHTokSubpassInput;
  318. (*KeywordMap)["SubpassInputMS"] = EHTokSubpassInputMS;
  319. (*KeywordMap)["AppendStructuredBuffer"] = EHTokAppendStructuredBuffer;
  320. (*KeywordMap)["ByteAddressBuffer"] = EHTokByteAddressBuffer;
  321. (*KeywordMap)["ConsumeStructuredBuffer"] = EHTokConsumeStructuredBuffer;
  322. (*KeywordMap)["RWByteAddressBuffer"] = EHTokRWByteAddressBuffer;
  323. (*KeywordMap)["RWStructuredBuffer"] = EHTokRWStructuredBuffer;
  324. (*KeywordMap)["StructuredBuffer"] = EHTokStructuredBuffer;
  325. (*KeywordMap)["TextureBuffer"] = EHTokTextureBuffer;
  326. (*KeywordMap)["class"] = EHTokClass;
  327. (*KeywordMap)["struct"] = EHTokStruct;
  328. (*KeywordMap)["cbuffer"] = EHTokCBuffer;
  329. (*KeywordMap)["ConstantBuffer"] = EHTokConstantBuffer;
  330. (*KeywordMap)["tbuffer"] = EHTokTBuffer;
  331. (*KeywordMap)["typedef"] = EHTokTypedef;
  332. (*KeywordMap)["this"] = EHTokThis;
  333. (*KeywordMap)["namespace"] = EHTokNamespace;
  334. (*KeywordMap)["true"] = EHTokBoolConstant;
  335. (*KeywordMap)["false"] = EHTokBoolConstant;
  336. (*KeywordMap)["for"] = EHTokFor;
  337. (*KeywordMap)["do"] = EHTokDo;
  338. (*KeywordMap)["while"] = EHTokWhile;
  339. (*KeywordMap)["break"] = EHTokBreak;
  340. (*KeywordMap)["continue"] = EHTokContinue;
  341. (*KeywordMap)["if"] = EHTokIf;
  342. (*KeywordMap)["else"] = EHTokElse;
  343. (*KeywordMap)["discard"] = EHTokDiscard;
  344. (*KeywordMap)["return"] = EHTokReturn;
  345. (*KeywordMap)["switch"] = EHTokSwitch;
  346. (*KeywordMap)["case"] = EHTokCase;
  347. (*KeywordMap)["default"] = EHTokDefault;
  348. // TODO: get correct set here
  349. ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
  350. ReservedSet->insert("auto");
  351. ReservedSet->insert("catch");
  352. ReservedSet->insert("char");
  353. ReservedSet->insert("const_cast");
  354. ReservedSet->insert("enum");
  355. ReservedSet->insert("explicit");
  356. ReservedSet->insert("friend");
  357. ReservedSet->insert("goto");
  358. ReservedSet->insert("long");
  359. ReservedSet->insert("mutable");
  360. ReservedSet->insert("new");
  361. ReservedSet->insert("operator");
  362. ReservedSet->insert("private");
  363. ReservedSet->insert("protected");
  364. ReservedSet->insert("public");
  365. ReservedSet->insert("reinterpret_cast");
  366. ReservedSet->insert("short");
  367. ReservedSet->insert("signed");
  368. ReservedSet->insert("sizeof");
  369. ReservedSet->insert("static_cast");
  370. ReservedSet->insert("template");
  371. ReservedSet->insert("throw");
  372. ReservedSet->insert("try");
  373. ReservedSet->insert("typename");
  374. ReservedSet->insert("union");
  375. ReservedSet->insert("unsigned");
  376. ReservedSet->insert("using");
  377. ReservedSet->insert("virtual");
  378. SemanticMap = new std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>;
  379. // in DX9, all outputs had to have a semantic associated with them, that was either consumed
  380. // by the system or was a specific register assignment
  381. // in DX10+, only semantics with the SV_ prefix have any meaning beyond decoration
  382. // Fxc will only accept DX9 style semantics in compat mode
  383. // Also, in DX10 if a SV value is present as the input of a stage, but isn't appropriate for that
  384. // stage, it would just be ignored as it is likely there as part of an output struct from one stage
  385. // to the next
  386. bool bParseDX9 = false;
  387. if (bParseDX9) {
  388. (*SemanticMap)["PSIZE"] = EbvPointSize;
  389. (*SemanticMap)["FOG"] = EbvFogFragCoord;
  390. (*SemanticMap)["DEPTH"] = EbvFragDepth;
  391. (*SemanticMap)["VFACE"] = EbvFace;
  392. (*SemanticMap)["VPOS"] = EbvFragCoord;
  393. }
  394. (*SemanticMap)["SV_POSITION"] = EbvPosition;
  395. (*SemanticMap)["SV_VERTEXID"] = EbvVertexIndex;
  396. (*SemanticMap)["SV_VIEWPORTARRAYINDEX"] = EbvViewportIndex;
  397. (*SemanticMap)["SV_TESSFACTOR"] = EbvTessLevelOuter;
  398. (*SemanticMap)["SV_SAMPLEINDEX"] = EbvSampleId;
  399. (*SemanticMap)["SV_RENDERTARGETARRAYINDEX"] = EbvLayer;
  400. (*SemanticMap)["SV_PRIMITIVEID"] = EbvPrimitiveId;
  401. (*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] = EbvInvocationId;
  402. (*SemanticMap)["SV_ISFRONTFACE"] = EbvFace;
  403. (*SemanticMap)["SV_INSTANCEID"] = EbvInstanceIndex;
  404. (*SemanticMap)["SV_INSIDETESSFACTOR"] = EbvTessLevelInner;
  405. (*SemanticMap)["SV_GSINSTANCEID"] = EbvInvocationId;
  406. (*SemanticMap)["SV_DISPATCHTHREADID"] = EbvGlobalInvocationId;
  407. (*SemanticMap)["SV_GROUPTHREADID"] = EbvLocalInvocationId;
  408. (*SemanticMap)["SV_GROUPINDEX"] = EbvLocalInvocationIndex;
  409. (*SemanticMap)["SV_GROUPID"] = EbvWorkGroupId;
  410. (*SemanticMap)["SV_DOMAINLOCATION"] = EbvTessCoord;
  411. (*SemanticMap)["SV_DEPTH"] = EbvFragDepth;
  412. (*SemanticMap)["SV_COVERAGE"] = EbvSampleMask;
  413. (*SemanticMap)["SV_DEPTHGREATEREQUAL"] = EbvFragDepthGreater;
  414. (*SemanticMap)["SV_DEPTHLESSEQUAL"] = EbvFragDepthLesser;
  415. (*SemanticMap)["SV_STENCILREF"] = EbvFragStencilRef;
  416. }
  417. void HlslScanContext::deleteKeywordMap()
  418. {
  419. delete KeywordMap;
  420. KeywordMap = nullptr;
  421. delete ReservedSet;
  422. ReservedSet = nullptr;
  423. delete SemanticMap;
  424. SemanticMap = nullptr;
  425. }
  426. // Wrapper for tokenizeClass() to get everything inside the token.
  427. void HlslScanContext::tokenize(HlslToken& token)
  428. {
  429. EHlslTokenClass tokenClass = tokenizeClass(token);
  430. token.tokenClass = tokenClass;
  431. }
  432. glslang::TBuiltInVariable HlslScanContext::mapSemantic(const char* upperCase)
  433. {
  434. auto it = SemanticMap->find(upperCase);
  435. if (it != SemanticMap->end())
  436. return it->second;
  437. else
  438. return glslang::EbvNone;
  439. }
  440. //
  441. // Fill in token information for the next token, except for the token class.
  442. // Returns the enum value of the token class of the next token found.
  443. // Return 0 (EndOfTokens) on end of input.
  444. //
  445. EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
  446. {
  447. do {
  448. parserToken = &token;
  449. TPpToken ppToken;
  450. int token = ppContext.tokenize(ppToken);
  451. if (token == EndOfInput)
  452. return EHTokNone;
  453. tokenText = ppToken.name;
  454. loc = ppToken.loc;
  455. parserToken->loc = loc;
  456. switch (token) {
  457. case ';': return EHTokSemicolon;
  458. case ',': return EHTokComma;
  459. case ':': return EHTokColon;
  460. case '=': return EHTokAssign;
  461. case '(': return EHTokLeftParen;
  462. case ')': return EHTokRightParen;
  463. case '.': return EHTokDot;
  464. case '!': return EHTokBang;
  465. case '-': return EHTokDash;
  466. case '~': return EHTokTilde;
  467. case '+': return EHTokPlus;
  468. case '*': return EHTokStar;
  469. case '/': return EHTokSlash;
  470. case '%': return EHTokPercent;
  471. case '<': return EHTokLeftAngle;
  472. case '>': return EHTokRightAngle;
  473. case '|': return EHTokVerticalBar;
  474. case '^': return EHTokCaret;
  475. case '&': return EHTokAmpersand;
  476. case '?': return EHTokQuestion;
  477. case '[': return EHTokLeftBracket;
  478. case ']': return EHTokRightBracket;
  479. case '{': return EHTokLeftBrace;
  480. case '}': return EHTokRightBrace;
  481. case '\\':
  482. parseContext.error(loc, "illegal use of escape character", "\\", "");
  483. break;
  484. case PPAtomAddAssign: return EHTokAddAssign;
  485. case PPAtomSubAssign: return EHTokSubAssign;
  486. case PPAtomMulAssign: return EHTokMulAssign;
  487. case PPAtomDivAssign: return EHTokDivAssign;
  488. case PPAtomModAssign: return EHTokModAssign;
  489. case PpAtomRight: return EHTokRightOp;
  490. case PpAtomLeft: return EHTokLeftOp;
  491. case PpAtomRightAssign: return EHTokRightAssign;
  492. case PpAtomLeftAssign: return EHTokLeftAssign;
  493. case PpAtomAndAssign: return EHTokAndAssign;
  494. case PpAtomOrAssign: return EHTokOrAssign;
  495. case PpAtomXorAssign: return EHTokXorAssign;
  496. case PpAtomAnd: return EHTokAndOp;
  497. case PpAtomOr: return EHTokOrOp;
  498. case PpAtomXor: return EHTokXorOp;
  499. case PpAtomEQ: return EHTokEqOp;
  500. case PpAtomGE: return EHTokGeOp;
  501. case PpAtomNE: return EHTokNeOp;
  502. case PpAtomLE: return EHTokLeOp;
  503. case PpAtomDecrement: return EHTokDecOp;
  504. case PpAtomIncrement: return EHTokIncOp;
  505. case PpAtomColonColon: return EHTokColonColon;
  506. case PpAtomConstInt: parserToken->i = ppToken.ival; return EHTokIntConstant;
  507. case PpAtomConstUint: parserToken->i = ppToken.ival; return EHTokUintConstant;
  508. case PpAtomConstFloat16: parserToken->d = ppToken.dval; return EHTokFloat16Constant;
  509. case PpAtomConstFloat: parserToken->d = ppToken.dval; return EHTokFloatConstant;
  510. case PpAtomConstDouble: parserToken->d = ppToken.dval; return EHTokDoubleConstant;
  511. case PpAtomIdentifier:
  512. {
  513. EHlslTokenClass token = tokenizeIdentifier();
  514. return token;
  515. }
  516. case PpAtomConstString: {
  517. parserToken->string = NewPoolTString(tokenText);
  518. return EHTokStringConstant;
  519. }
  520. case EndOfInput: return EHTokNone;
  521. default:
  522. if (token < PpAtomMaxSingle) {
  523. char buf[2];
  524. buf[0] = (char)token;
  525. buf[1] = 0;
  526. parseContext.error(loc, "unexpected token", buf, "");
  527. } else if (tokenText[0] != 0)
  528. parseContext.error(loc, "unexpected token", tokenText, "");
  529. else
  530. parseContext.error(loc, "unexpected token", "", "");
  531. break;
  532. }
  533. } while (true);
  534. }
  535. EHlslTokenClass HlslScanContext::tokenizeIdentifier()
  536. {
  537. if (ReservedSet->find(tokenText) != ReservedSet->end())
  538. return reservedWord();
  539. auto it = KeywordMap->find(tokenText);
  540. if (it == KeywordMap->end()) {
  541. // Should have an identifier of some sort
  542. return identifierOrType();
  543. }
  544. keyword = it->second;
  545. switch (keyword) {
  546. // qualifiers
  547. case EHTokStatic:
  548. case EHTokConst:
  549. case EHTokSNorm:
  550. case EHTokUnorm:
  551. case EHTokExtern:
  552. case EHTokUniform:
  553. case EHTokVolatile:
  554. case EHTokShared:
  555. case EHTokGroupShared:
  556. case EHTokLinear:
  557. case EHTokCentroid:
  558. case EHTokNointerpolation:
  559. case EHTokNoperspective:
  560. case EHTokSample:
  561. case EHTokRowMajor:
  562. case EHTokColumnMajor:
  563. case EHTokPackOffset:
  564. case EHTokIn:
  565. case EHTokOut:
  566. case EHTokInOut:
  567. case EHTokPrecise:
  568. case EHTokLayout:
  569. case EHTokGloballyCoherent:
  570. case EHTokInline:
  571. return keyword;
  572. // primitive types
  573. case EHTokPoint:
  574. case EHTokLine:
  575. case EHTokTriangle:
  576. case EHTokLineAdj:
  577. case EHTokTriangleAdj:
  578. return keyword;
  579. // stream out types
  580. case EHTokPointStream:
  581. case EHTokLineStream:
  582. case EHTokTriangleStream:
  583. return keyword;
  584. // Tessellation patches
  585. case EHTokInputPatch:
  586. case EHTokOutputPatch:
  587. return keyword;
  588. case EHTokBuffer:
  589. case EHTokVector:
  590. case EHTokMatrix:
  591. return keyword;
  592. // scalar types
  593. case EHTokVoid:
  594. case EHTokString:
  595. case EHTokBool:
  596. case EHTokInt:
  597. case EHTokUint:
  598. case EHTokUint64:
  599. case EHTokDword:
  600. case EHTokHalf:
  601. case EHTokFloat:
  602. case EHTokDouble:
  603. case EHTokMin16float:
  604. case EHTokMin10float:
  605. case EHTokMin16int:
  606. case EHTokMin12int:
  607. case EHTokMin16uint:
  608. // vector types
  609. case EHTokBool1:
  610. case EHTokBool2:
  611. case EHTokBool3:
  612. case EHTokBool4:
  613. case EHTokFloat1:
  614. case EHTokFloat2:
  615. case EHTokFloat3:
  616. case EHTokFloat4:
  617. case EHTokInt1:
  618. case EHTokInt2:
  619. case EHTokInt3:
  620. case EHTokInt4:
  621. case EHTokDouble1:
  622. case EHTokDouble2:
  623. case EHTokDouble3:
  624. case EHTokDouble4:
  625. case EHTokUint1:
  626. case EHTokUint2:
  627. case EHTokUint3:
  628. case EHTokUint4:
  629. case EHTokHalf1:
  630. case EHTokHalf2:
  631. case EHTokHalf3:
  632. case EHTokHalf4:
  633. case EHTokMin16float1:
  634. case EHTokMin16float2:
  635. case EHTokMin16float3:
  636. case EHTokMin16float4:
  637. case EHTokMin10float1:
  638. case EHTokMin10float2:
  639. case EHTokMin10float3:
  640. case EHTokMin10float4:
  641. case EHTokMin16int1:
  642. case EHTokMin16int2:
  643. case EHTokMin16int3:
  644. case EHTokMin16int4:
  645. case EHTokMin12int1:
  646. case EHTokMin12int2:
  647. case EHTokMin12int3:
  648. case EHTokMin12int4:
  649. case EHTokMin16uint1:
  650. case EHTokMin16uint2:
  651. case EHTokMin16uint3:
  652. case EHTokMin16uint4:
  653. // matrix types
  654. case EHTokBool1x1:
  655. case EHTokBool1x2:
  656. case EHTokBool1x3:
  657. case EHTokBool1x4:
  658. case EHTokBool2x1:
  659. case EHTokBool2x2:
  660. case EHTokBool2x3:
  661. case EHTokBool2x4:
  662. case EHTokBool3x1:
  663. case EHTokBool3x2:
  664. case EHTokBool3x3:
  665. case EHTokBool3x4:
  666. case EHTokBool4x1:
  667. case EHTokBool4x2:
  668. case EHTokBool4x3:
  669. case EHTokBool4x4:
  670. case EHTokInt1x1:
  671. case EHTokInt1x2:
  672. case EHTokInt1x3:
  673. case EHTokInt1x4:
  674. case EHTokInt2x1:
  675. case EHTokInt2x2:
  676. case EHTokInt2x3:
  677. case EHTokInt2x4:
  678. case EHTokInt3x1:
  679. case EHTokInt3x2:
  680. case EHTokInt3x3:
  681. case EHTokInt3x4:
  682. case EHTokInt4x1:
  683. case EHTokInt4x2:
  684. case EHTokInt4x3:
  685. case EHTokInt4x4:
  686. case EHTokUint1x1:
  687. case EHTokUint1x2:
  688. case EHTokUint1x3:
  689. case EHTokUint1x4:
  690. case EHTokUint2x1:
  691. case EHTokUint2x2:
  692. case EHTokUint2x3:
  693. case EHTokUint2x4:
  694. case EHTokUint3x1:
  695. case EHTokUint3x2:
  696. case EHTokUint3x3:
  697. case EHTokUint3x4:
  698. case EHTokUint4x1:
  699. case EHTokUint4x2:
  700. case EHTokUint4x3:
  701. case EHTokUint4x4:
  702. case EHTokFloat1x1:
  703. case EHTokFloat1x2:
  704. case EHTokFloat1x3:
  705. case EHTokFloat1x4:
  706. case EHTokFloat2x1:
  707. case EHTokFloat2x2:
  708. case EHTokFloat2x3:
  709. case EHTokFloat2x4:
  710. case EHTokFloat3x1:
  711. case EHTokFloat3x2:
  712. case EHTokFloat3x3:
  713. case EHTokFloat3x4:
  714. case EHTokFloat4x1:
  715. case EHTokFloat4x2:
  716. case EHTokFloat4x3:
  717. case EHTokFloat4x4:
  718. case EHTokHalf1x1:
  719. case EHTokHalf1x2:
  720. case EHTokHalf1x3:
  721. case EHTokHalf1x4:
  722. case EHTokHalf2x1:
  723. case EHTokHalf2x2:
  724. case EHTokHalf2x3:
  725. case EHTokHalf2x4:
  726. case EHTokHalf3x1:
  727. case EHTokHalf3x2:
  728. case EHTokHalf3x3:
  729. case EHTokHalf3x4:
  730. case EHTokHalf4x1:
  731. case EHTokHalf4x2:
  732. case EHTokHalf4x3:
  733. case EHTokHalf4x4:
  734. case EHTokDouble1x1:
  735. case EHTokDouble1x2:
  736. case EHTokDouble1x3:
  737. case EHTokDouble1x4:
  738. case EHTokDouble2x1:
  739. case EHTokDouble2x2:
  740. case EHTokDouble2x3:
  741. case EHTokDouble2x4:
  742. case EHTokDouble3x1:
  743. case EHTokDouble3x2:
  744. case EHTokDouble3x3:
  745. case EHTokDouble3x4:
  746. case EHTokDouble4x1:
  747. case EHTokDouble4x2:
  748. case EHTokDouble4x3:
  749. case EHTokDouble4x4:
  750. return keyword;
  751. // texturing types
  752. case EHTokSampler:
  753. case EHTokSampler1d:
  754. case EHTokSampler2d:
  755. case EHTokSampler3d:
  756. case EHTokSamplerCube:
  757. case EHTokSamplerState:
  758. case EHTokSamplerComparisonState:
  759. case EHTokTexture:
  760. case EHTokTexture1d:
  761. case EHTokTexture1darray:
  762. case EHTokTexture2d:
  763. case EHTokTexture2darray:
  764. case EHTokTexture3d:
  765. case EHTokTextureCube:
  766. case EHTokTextureCubearray:
  767. case EHTokTexture2DMS:
  768. case EHTokTexture2DMSarray:
  769. case EHTokRWTexture1d:
  770. case EHTokRWTexture1darray:
  771. case EHTokRWTexture2d:
  772. case EHTokRWTexture2darray:
  773. case EHTokRWTexture3d:
  774. case EHTokRWBuffer:
  775. case EHTokAppendStructuredBuffer:
  776. case EHTokByteAddressBuffer:
  777. case EHTokConsumeStructuredBuffer:
  778. case EHTokRWByteAddressBuffer:
  779. case EHTokRWStructuredBuffer:
  780. case EHTokStructuredBuffer:
  781. case EHTokTextureBuffer:
  782. case EHTokSubpassInput:
  783. case EHTokSubpassInputMS:
  784. return keyword;
  785. // variable, user type, ...
  786. case EHTokClass:
  787. case EHTokStruct:
  788. case EHTokTypedef:
  789. case EHTokCBuffer:
  790. case EHTokConstantBuffer:
  791. case EHTokTBuffer:
  792. case EHTokThis:
  793. case EHTokNamespace:
  794. return keyword;
  795. case EHTokBoolConstant:
  796. if (strcmp("true", tokenText) == 0)
  797. parserToken->b = true;
  798. else
  799. parserToken->b = false;
  800. return keyword;
  801. // control flow
  802. case EHTokFor:
  803. case EHTokDo:
  804. case EHTokWhile:
  805. case EHTokBreak:
  806. case EHTokContinue:
  807. case EHTokIf:
  808. case EHTokElse:
  809. case EHTokDiscard:
  810. case EHTokReturn:
  811. case EHTokCase:
  812. case EHTokSwitch:
  813. case EHTokDefault:
  814. return keyword;
  815. default:
  816. parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
  817. return EHTokNone;
  818. }
  819. }
  820. EHlslTokenClass HlslScanContext::identifierOrType()
  821. {
  822. parserToken->string = NewPoolTString(tokenText);
  823. return EHTokIdentifier;
  824. }
  825. // Give an error for use of a reserved symbol.
  826. // However, allow built-in declarations to use reserved words, to allow
  827. // extension support before the extension is enabled.
  828. EHlslTokenClass HlslScanContext::reservedWord()
  829. {
  830. if (! parseContext.symbolTable.atBuiltInLevel())
  831. parseContext.error(loc, "Reserved word.", tokenText, "", "");
  832. return EHTokNone;
  833. }
  834. } // end namespace glslang