2 // Copyright (C) 2016 Google, Inc.
3 // Copyright (C) 2016 LunarG, Inc.
5 // All rights reserved.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
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.
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.
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.
38 // HLSL scanning, leveraging the scanning done by the preprocessor.
42 #include <unordered_map>
43 #include <unordered_set>
45 #include "../glslang/Include/Types.h"
46 #include "../glslang/MachineIndependent/SymbolTable.h"
47 #include "../glslang/MachineIndependent/ParseHelper.h"
48 #include "hlslScanContext.h"
49 #include "hlslTokens.h"
51 // preprocessor includes
52 #include "../glslang/MachineIndependent/preprocessor/PpContext.h"
53 #include "../glslang/MachineIndependent/preprocessor/PpTokens.h"
59 bool operator()(const char* lhs, const char* rhs) const
61 return strcmp(lhs, rhs) == 0;
67 size_t operator()(const char* str) const
70 unsigned long hash = 5381;
73 while ((c = *str++) != 0)
74 hash = ((hash << 5) + hash) + c;
80 // A single global usable by all threads, by all versions, by all languages.
81 // After a single process-level initialization, this is read only and thread safe
82 std::unordered_map<const char*, glslang::EHlslTokenClass, str_hash, str_eq>* KeywordMap = nullptr;
83 std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
84 std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>* SemanticMap = nullptr;
90 void HlslScanContext::fillInKeywordMap()
92 if (KeywordMap != nullptr) {
93 // this is really an error, as this should called only once per process
94 // but, the only risk is if two threads called simultaneously
97 KeywordMap = new std::unordered_map<const char*, EHlslTokenClass, str_hash, str_eq>;
99 (*KeywordMap)["static"] = EHTokStatic;
100 (*KeywordMap)["const"] = EHTokConst;
101 (*KeywordMap)["unorm"] = EHTokUnorm;
102 (*KeywordMap)["snorm"] = EHTokSNorm;
103 (*KeywordMap)["extern"] = EHTokExtern;
104 (*KeywordMap)["uniform"] = EHTokUniform;
105 (*KeywordMap)["volatile"] = EHTokVolatile;
106 (*KeywordMap)["precise"] = EHTokPrecise;
107 (*KeywordMap)["shared"] = EHTokShared;
108 (*KeywordMap)["groupshared"] = EHTokGroupShared;
109 (*KeywordMap)["linear"] = EHTokLinear;
110 (*KeywordMap)["centroid"] = EHTokCentroid;
111 (*KeywordMap)["nointerpolation"] = EHTokNointerpolation;
112 (*KeywordMap)["noperspective"] = EHTokNoperspective;
113 (*KeywordMap)["sample"] = EHTokSample;
114 (*KeywordMap)["row_major"] = EHTokRowMajor;
115 (*KeywordMap)["column_major"] = EHTokColumnMajor;
116 (*KeywordMap)["packoffset"] = EHTokPackOffset;
117 (*KeywordMap)["in"] = EHTokIn;
118 (*KeywordMap)["out"] = EHTokOut;
119 (*KeywordMap)["inout"] = EHTokInOut;
120 (*KeywordMap)["layout"] = EHTokLayout;
121 (*KeywordMap)["globallycoherent"] = EHTokGloballyCoherent;
122 (*KeywordMap)["inline"] = EHTokInline;
124 (*KeywordMap)["point"] = EHTokPoint;
125 (*KeywordMap)["line"] = EHTokLine;
126 (*KeywordMap)["triangle"] = EHTokTriangle;
127 (*KeywordMap)["lineadj"] = EHTokLineAdj;
128 (*KeywordMap)["triangleadj"] = EHTokTriangleAdj;
130 (*KeywordMap)["PointStream"] = EHTokPointStream;
131 (*KeywordMap)["LineStream"] = EHTokLineStream;
132 (*KeywordMap)["TriangleStream"] = EHTokTriangleStream;
134 (*KeywordMap)["InputPatch"] = EHTokInputPatch;
135 (*KeywordMap)["OutputPatch"] = EHTokOutputPatch;
137 (*KeywordMap)["Buffer"] = EHTokBuffer;
138 (*KeywordMap)["vector"] = EHTokVector;
139 (*KeywordMap)["matrix"] = EHTokMatrix;
141 (*KeywordMap)["void"] = EHTokVoid;
142 (*KeywordMap)["string"] = EHTokString;
143 (*KeywordMap)["bool"] = EHTokBool;
144 (*KeywordMap)["int"] = EHTokInt;
145 (*KeywordMap)["uint"] = EHTokUint;
146 (*KeywordMap)["dword"] = EHTokDword;
147 (*KeywordMap)["half"] = EHTokHalf;
148 (*KeywordMap)["float"] = EHTokFloat;
149 (*KeywordMap)["double"] = EHTokDouble;
150 (*KeywordMap)["min16float"] = EHTokMin16float;
151 (*KeywordMap)["min10float"] = EHTokMin10float;
152 (*KeywordMap)["min16int"] = EHTokMin16int;
153 (*KeywordMap)["min12int"] = EHTokMin12int;
154 (*KeywordMap)["min16uint"] = EHTokMin16uint;
156 (*KeywordMap)["bool1"] = EHTokBool1;
157 (*KeywordMap)["bool2"] = EHTokBool2;
158 (*KeywordMap)["bool3"] = EHTokBool3;
159 (*KeywordMap)["bool4"] = EHTokBool4;
160 (*KeywordMap)["float1"] = EHTokFloat1;
161 (*KeywordMap)["float2"] = EHTokFloat2;
162 (*KeywordMap)["float3"] = EHTokFloat3;
163 (*KeywordMap)["float4"] = EHTokFloat4;
164 (*KeywordMap)["int1"] = EHTokInt1;
165 (*KeywordMap)["int2"] = EHTokInt2;
166 (*KeywordMap)["int3"] = EHTokInt3;
167 (*KeywordMap)["int4"] = EHTokInt4;
168 (*KeywordMap)["double1"] = EHTokDouble1;
169 (*KeywordMap)["double2"] = EHTokDouble2;
170 (*KeywordMap)["double3"] = EHTokDouble3;
171 (*KeywordMap)["double4"] = EHTokDouble4;
172 (*KeywordMap)["uint1"] = EHTokUint1;
173 (*KeywordMap)["uint2"] = EHTokUint2;
174 (*KeywordMap)["uint3"] = EHTokUint3;
175 (*KeywordMap)["uint4"] = EHTokUint4;
177 (*KeywordMap)["half1"] = EHTokHalf1;
178 (*KeywordMap)["half2"] = EHTokHalf2;
179 (*KeywordMap)["half3"] = EHTokHalf3;
180 (*KeywordMap)["half4"] = EHTokHalf4;
181 (*KeywordMap)["min16float1"] = EHTokMin16float1;
182 (*KeywordMap)["min16float2"] = EHTokMin16float2;
183 (*KeywordMap)["min16float3"] = EHTokMin16float3;
184 (*KeywordMap)["min16float4"] = EHTokMin16float4;
185 (*KeywordMap)["min10float1"] = EHTokMin10float1;
186 (*KeywordMap)["min10float2"] = EHTokMin10float2;
187 (*KeywordMap)["min10float3"] = EHTokMin10float3;
188 (*KeywordMap)["min10float4"] = EHTokMin10float4;
189 (*KeywordMap)["min16int1"] = EHTokMin16int1;
190 (*KeywordMap)["min16int2"] = EHTokMin16int2;
191 (*KeywordMap)["min16int3"] = EHTokMin16int3;
192 (*KeywordMap)["min16int4"] = EHTokMin16int4;
193 (*KeywordMap)["min12int1"] = EHTokMin12int1;
194 (*KeywordMap)["min12int2"] = EHTokMin12int2;
195 (*KeywordMap)["min12int3"] = EHTokMin12int3;
196 (*KeywordMap)["min12int4"] = EHTokMin12int4;
197 (*KeywordMap)["min16uint1"] = EHTokMin16uint1;
198 (*KeywordMap)["min16uint2"] = EHTokMin16uint2;
199 (*KeywordMap)["min16uint3"] = EHTokMin16uint3;
200 (*KeywordMap)["min16uint4"] = EHTokMin16uint4;
202 (*KeywordMap)["bool1x1"] = EHTokBool1x1;
203 (*KeywordMap)["bool1x2"] = EHTokBool1x2;
204 (*KeywordMap)["bool1x3"] = EHTokBool1x3;
205 (*KeywordMap)["bool1x4"] = EHTokBool1x4;
206 (*KeywordMap)["bool2x1"] = EHTokBool2x1;
207 (*KeywordMap)["bool2x2"] = EHTokBool2x2;
208 (*KeywordMap)["bool2x3"] = EHTokBool2x3;
209 (*KeywordMap)["bool2x4"] = EHTokBool2x4;
210 (*KeywordMap)["bool3x1"] = EHTokBool3x1;
211 (*KeywordMap)["bool3x2"] = EHTokBool3x2;
212 (*KeywordMap)["bool3x3"] = EHTokBool3x3;
213 (*KeywordMap)["bool3x4"] = EHTokBool3x4;
214 (*KeywordMap)["bool4x1"] = EHTokBool4x1;
215 (*KeywordMap)["bool4x2"] = EHTokBool4x2;
216 (*KeywordMap)["bool4x3"] = EHTokBool4x3;
217 (*KeywordMap)["bool4x4"] = EHTokBool4x4;
218 (*KeywordMap)["int1x1"] = EHTokInt1x1;
219 (*KeywordMap)["int1x2"] = EHTokInt1x2;
220 (*KeywordMap)["int1x3"] = EHTokInt1x3;
221 (*KeywordMap)["int1x4"] = EHTokInt1x4;
222 (*KeywordMap)["int2x1"] = EHTokInt2x1;
223 (*KeywordMap)["int2x2"] = EHTokInt2x2;
224 (*KeywordMap)["int2x3"] = EHTokInt2x3;
225 (*KeywordMap)["int2x4"] = EHTokInt2x4;
226 (*KeywordMap)["int3x1"] = EHTokInt3x1;
227 (*KeywordMap)["int3x2"] = EHTokInt3x2;
228 (*KeywordMap)["int3x3"] = EHTokInt3x3;
229 (*KeywordMap)["int3x4"] = EHTokInt3x4;
230 (*KeywordMap)["int4x1"] = EHTokInt4x1;
231 (*KeywordMap)["int4x2"] = EHTokInt4x2;
232 (*KeywordMap)["int4x3"] = EHTokInt4x3;
233 (*KeywordMap)["int4x4"] = EHTokInt4x4;
234 (*KeywordMap)["uint1x1"] = EHTokUint1x1;
235 (*KeywordMap)["uint1x2"] = EHTokUint1x2;
236 (*KeywordMap)["uint1x3"] = EHTokUint1x3;
237 (*KeywordMap)["uint1x4"] = EHTokUint1x4;
238 (*KeywordMap)["uint2x1"] = EHTokUint2x1;
239 (*KeywordMap)["uint2x2"] = EHTokUint2x2;
240 (*KeywordMap)["uint2x3"] = EHTokUint2x3;
241 (*KeywordMap)["uint2x4"] = EHTokUint2x4;
242 (*KeywordMap)["uint3x1"] = EHTokUint3x1;
243 (*KeywordMap)["uint3x2"] = EHTokUint3x2;
244 (*KeywordMap)["uint3x3"] = EHTokUint3x3;
245 (*KeywordMap)["uint3x4"] = EHTokUint3x4;
246 (*KeywordMap)["uint4x1"] = EHTokUint4x1;
247 (*KeywordMap)["uint4x2"] = EHTokUint4x2;
248 (*KeywordMap)["uint4x3"] = EHTokUint4x3;
249 (*KeywordMap)["uint4x4"] = EHTokUint4x4;
250 (*KeywordMap)["bool1x1"] = EHTokBool1x1;
251 (*KeywordMap)["bool1x2"] = EHTokBool1x2;
252 (*KeywordMap)["bool1x3"] = EHTokBool1x3;
253 (*KeywordMap)["bool1x4"] = EHTokBool1x4;
254 (*KeywordMap)["bool2x1"] = EHTokBool2x1;
255 (*KeywordMap)["bool2x2"] = EHTokBool2x2;
256 (*KeywordMap)["bool2x3"] = EHTokBool2x3;
257 (*KeywordMap)["bool2x4"] = EHTokBool2x4;
258 (*KeywordMap)["bool3x1"] = EHTokBool3x1;
259 (*KeywordMap)["bool3x2"] = EHTokBool3x2;
260 (*KeywordMap)["bool3x3"] = EHTokBool3x3;
261 (*KeywordMap)["bool3x4"] = EHTokBool3x4;
262 (*KeywordMap)["bool4x1"] = EHTokBool4x1;
263 (*KeywordMap)["bool4x2"] = EHTokBool4x2;
264 (*KeywordMap)["bool4x3"] = EHTokBool4x3;
265 (*KeywordMap)["bool4x4"] = EHTokBool4x4;
266 (*KeywordMap)["float1x1"] = EHTokFloat1x1;
267 (*KeywordMap)["float1x2"] = EHTokFloat1x2;
268 (*KeywordMap)["float1x3"] = EHTokFloat1x3;
269 (*KeywordMap)["float1x4"] = EHTokFloat1x4;
270 (*KeywordMap)["float2x1"] = EHTokFloat2x1;
271 (*KeywordMap)["float2x2"] = EHTokFloat2x2;
272 (*KeywordMap)["float2x3"] = EHTokFloat2x3;
273 (*KeywordMap)["float2x4"] = EHTokFloat2x4;
274 (*KeywordMap)["float3x1"] = EHTokFloat3x1;
275 (*KeywordMap)["float3x2"] = EHTokFloat3x2;
276 (*KeywordMap)["float3x3"] = EHTokFloat3x3;
277 (*KeywordMap)["float3x4"] = EHTokFloat3x4;
278 (*KeywordMap)["float4x1"] = EHTokFloat4x1;
279 (*KeywordMap)["float4x2"] = EHTokFloat4x2;
280 (*KeywordMap)["float4x3"] = EHTokFloat4x3;
281 (*KeywordMap)["float4x4"] = EHTokFloat4x4;
282 (*KeywordMap)["double1x1"] = EHTokDouble1x1;
283 (*KeywordMap)["double1x2"] = EHTokDouble1x2;
284 (*KeywordMap)["double1x3"] = EHTokDouble1x3;
285 (*KeywordMap)["double1x4"] = EHTokDouble1x4;
286 (*KeywordMap)["double2x1"] = EHTokDouble2x1;
287 (*KeywordMap)["double2x2"] = EHTokDouble2x2;
288 (*KeywordMap)["double2x3"] = EHTokDouble2x3;
289 (*KeywordMap)["double2x4"] = EHTokDouble2x4;
290 (*KeywordMap)["double3x1"] = EHTokDouble3x1;
291 (*KeywordMap)["double3x2"] = EHTokDouble3x2;
292 (*KeywordMap)["double3x3"] = EHTokDouble3x3;
293 (*KeywordMap)["double3x4"] = EHTokDouble3x4;
294 (*KeywordMap)["double4x1"] = EHTokDouble4x1;
295 (*KeywordMap)["double4x2"] = EHTokDouble4x2;
296 (*KeywordMap)["double4x3"] = EHTokDouble4x3;
297 (*KeywordMap)["double4x4"] = EHTokDouble4x4;
299 (*KeywordMap)["sampler"] = EHTokSampler;
300 (*KeywordMap)["sampler1D"] = EHTokSampler1d;
301 (*KeywordMap)["sampler2D"] = EHTokSampler2d;
302 (*KeywordMap)["sampler3D"] = EHTokSampler3d;
303 (*KeywordMap)["samplerCube"] = EHTokSamplerCube;
304 (*KeywordMap)["sampler_state"] = EHTokSamplerState;
305 (*KeywordMap)["SamplerState"] = EHTokSamplerState;
306 (*KeywordMap)["SamplerComparisonState"] = EHTokSamplerComparisonState;
307 (*KeywordMap)["texture"] = EHTokTexture;
308 (*KeywordMap)["Texture1D"] = EHTokTexture1d;
309 (*KeywordMap)["Texture1DArray"] = EHTokTexture1darray;
310 (*KeywordMap)["Texture2D"] = EHTokTexture2d;
311 (*KeywordMap)["Texture2DArray"] = EHTokTexture2darray;
312 (*KeywordMap)["Texture3D"] = EHTokTexture3d;
313 (*KeywordMap)["TextureCube"] = EHTokTextureCube;
314 (*KeywordMap)["TextureCubeArray"] = EHTokTextureCubearray;
315 (*KeywordMap)["Texture2DMS"] = EHTokTexture2DMS;
316 (*KeywordMap)["Texture2DMSArray"] = EHTokTexture2DMSarray;
317 (*KeywordMap)["RWTexture1D"] = EHTokRWTexture1d;
318 (*KeywordMap)["RWTexture1DArray"] = EHTokRWTexture1darray;
319 (*KeywordMap)["RWTexture2D"] = EHTokRWTexture2d;
320 (*KeywordMap)["RWTexture2DArray"] = EHTokRWTexture2darray;
321 (*KeywordMap)["RWTexture3D"] = EHTokRWTexture3d;
322 (*KeywordMap)["RWBuffer"] = EHTokRWBuffer;
324 (*KeywordMap)["AppendStructuredBuffer"] = EHTokAppendStructuredBuffer;
325 (*KeywordMap)["ByteAddressBuffer"] = EHTokByteAddressBuffer;
326 (*KeywordMap)["ConsumeStructuredBuffer"] = EHTokConsumeStructuredBuffer;
327 (*KeywordMap)["RWByteAddressBuffer"] = EHTokRWByteAddressBuffer;
328 (*KeywordMap)["RWStructuredBuffer"] = EHTokRWStructuredBuffer;
329 (*KeywordMap)["StructuredBuffer"] = EHTokStructuredBuffer;
331 (*KeywordMap)["class"] = EHTokClass;
332 (*KeywordMap)["struct"] = EHTokStruct;
333 (*KeywordMap)["cbuffer"] = EHTokCBuffer;
334 (*KeywordMap)["tbuffer"] = EHTokTBuffer;
335 (*KeywordMap)["typedef"] = EHTokTypedef;
336 (*KeywordMap)["this"] = EHTokThis;
337 (*KeywordMap)["namespace"] = EHTokNamespace;
339 (*KeywordMap)["true"] = EHTokBoolConstant;
340 (*KeywordMap)["false"] = EHTokBoolConstant;
342 (*KeywordMap)["for"] = EHTokFor;
343 (*KeywordMap)["do"] = EHTokDo;
344 (*KeywordMap)["while"] = EHTokWhile;
345 (*KeywordMap)["break"] = EHTokBreak;
346 (*KeywordMap)["continue"] = EHTokContinue;
347 (*KeywordMap)["if"] = EHTokIf;
348 (*KeywordMap)["else"] = EHTokElse;
349 (*KeywordMap)["discard"] = EHTokDiscard;
350 (*KeywordMap)["return"] = EHTokReturn;
351 (*KeywordMap)["switch"] = EHTokSwitch;
352 (*KeywordMap)["case"] = EHTokCase;
353 (*KeywordMap)["default"] = EHTokDefault;
355 // TODO: get correct set here
356 ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
358 ReservedSet->insert("auto");
359 ReservedSet->insert("catch");
360 ReservedSet->insert("char");
361 ReservedSet->insert("const_cast");
362 ReservedSet->insert("enum");
363 ReservedSet->insert("explicit");
364 ReservedSet->insert("friend");
365 ReservedSet->insert("goto");
366 ReservedSet->insert("long");
367 ReservedSet->insert("mutable");
368 ReservedSet->insert("new");
369 ReservedSet->insert("operator");
370 ReservedSet->insert("private");
371 ReservedSet->insert("protected");
372 ReservedSet->insert("public");
373 ReservedSet->insert("reinterpret_cast");
374 ReservedSet->insert("short");
375 ReservedSet->insert("signed");
376 ReservedSet->insert("sizeof");
377 ReservedSet->insert("static_cast");
378 ReservedSet->insert("template");
379 ReservedSet->insert("throw");
380 ReservedSet->insert("try");
381 ReservedSet->insert("typename");
382 ReservedSet->insert("union");
383 ReservedSet->insert("unsigned");
384 ReservedSet->insert("using");
385 ReservedSet->insert("virtual");
387 SemanticMap = new std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>;
389 // in DX9, all outputs had to have a semantic associated with them, that was either consumed
390 // by the system or was a specific register assignment
391 // in DX10+, only semantics with the SV_ prefix have any meaning beyond decoration
392 // Fxc will only accept DX9 style semantics in compat mode
393 // Also, in DX10 if a SV value is present as the input of a stage, but isn't appropriate for that
394 // stage, it would just be ignored as it is likely there as part of an output struct from one stage
396 bool bParseDX9 = false;
398 (*SemanticMap)["PSIZE"] = EbvPointSize;
399 (*SemanticMap)["FOG"] = EbvFogFragCoord;
400 (*SemanticMap)["DEPTH"] = EbvFragDepth;
401 (*SemanticMap)["VFACE"] = EbvFace;
402 (*SemanticMap)["VPOS"] = EbvFragCoord;
405 (*SemanticMap)["SV_POSITION"] = EbvPosition;
406 (*SemanticMap)["SV_CLIPDISTANCE"] = EbvClipDistance;
407 (*SemanticMap)["SV_CLIPDISTANCE0"] = EbvClipDistance;
408 (*SemanticMap)["SV_CLIPDISTANCE1"] = EbvClipDistance;
409 (*SemanticMap)["SV_CLIPDISTANCE2"] = EbvClipDistance;
410 (*SemanticMap)["SV_CLIPDISTANCE3"] = EbvClipDistance;
411 (*SemanticMap)["SV_CLIPDISTANCE4"] = EbvClipDistance;
412 (*SemanticMap)["SV_CLIPDISTANCE5"] = EbvClipDistance;
413 (*SemanticMap)["SV_CLIPDISTANCE6"] = EbvClipDistance;
414 (*SemanticMap)["SV_CLIPDISTANCE7"] = EbvClipDistance;
415 (*SemanticMap)["SV_CLIPDISTANCE8"] = EbvClipDistance;
416 (*SemanticMap)["SV_CLIPDISTANCE9"] = EbvClipDistance;
417 (*SemanticMap)["SV_CLIPDISTANCE10"] = EbvClipDistance;
418 (*SemanticMap)["SV_CLIPDISTANCE11"] = EbvClipDistance;
419 (*SemanticMap)["SV_CULLDISTANCE"] = EbvCullDistance;
420 (*SemanticMap)["SV_CULLDISTANCE0"] = EbvCullDistance;
421 (*SemanticMap)["SV_CULLDISTANCE1"] = EbvCullDistance;
422 (*SemanticMap)["SV_CULLDISTANCE2"] = EbvCullDistance;
423 (*SemanticMap)["SV_CULLDISTANCE3"] = EbvCullDistance;
424 (*SemanticMap)["SV_CULLDISTANCE4"] = EbvCullDistance;
425 (*SemanticMap)["SV_CULLDISTANCE5"] = EbvCullDistance;
426 (*SemanticMap)["SV_CULLDISTANCE6"] = EbvCullDistance;
427 (*SemanticMap)["SV_CULLDISTANCE7"] = EbvCullDistance;
428 (*SemanticMap)["SV_CULLDISTANCE8"] = EbvCullDistance;
429 (*SemanticMap)["SV_CULLDISTANCE9"] = EbvCullDistance;
430 (*SemanticMap)["SV_CULLDISTANCE10"] = EbvCullDistance;
431 (*SemanticMap)["SV_CULLDISTANCE11"] = EbvCullDistance;
432 (*SemanticMap)["SV_VERTEXID"] = EbvVertexIndex;
433 (*SemanticMap)["SV_VIEWPORTARRAYINDEX"] = EbvViewportIndex;
434 (*SemanticMap)["SV_TESSFACTOR"] = EbvTessLevelOuter;
435 (*SemanticMap)["SV_SAMPLEINDEX"] = EbvSampleId;
436 (*SemanticMap)["SV_RENDERTARGETARRAYINDEX"] = EbvLayer;
437 (*SemanticMap)["SV_PRIMITIVEID"] = EbvPrimitiveId;
438 (*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] = EbvInvocationId;
439 (*SemanticMap)["SV_ISFRONTFACE"] = EbvFace;
440 (*SemanticMap)["SV_INSTANCEID"] = EbvInstanceIndex;
441 (*SemanticMap)["SV_INSIDETESSFACTOR"] = EbvTessLevelInner;
442 (*SemanticMap)["SV_GSINSTANCEID"] = EbvInvocationId;
443 (*SemanticMap)["SV_DISPATCHTHREADID"] = EbvGlobalInvocationId;
444 (*SemanticMap)["SV_GROUPTHREADID"] = EbvLocalInvocationId;
445 (*SemanticMap)["SV_GROUPINDEX"] = EbvLocalInvocationIndex;
446 (*SemanticMap)["SV_GROUPID"] = EbvWorkGroupId;
447 (*SemanticMap)["SV_DOMAINLOCATION"] = EbvTessCoord;
448 (*SemanticMap)["SV_DEPTH"] = EbvFragDepth;
449 (*SemanticMap)["SV_COVERAGE"] = EbvSampleMask;
450 (*SemanticMap)["SV_DEPTHGREATEREQUAL"] = EbvFragDepthGreater;
451 (*SemanticMap)["SV_DEPTHLESSEQUAL"] = EbvFragDepthLesser;
452 (*SemanticMap)["SV_STENCILREF"] = EbvStencilRef;
455 void HlslScanContext::deleteKeywordMap()
458 KeywordMap = nullptr;
460 ReservedSet = nullptr;
462 SemanticMap = nullptr;
465 // Wrapper for tokenizeClass() to get everything inside the token.
466 void HlslScanContext::tokenize(HlslToken& token)
468 EHlslTokenClass tokenClass = tokenizeClass(token);
469 token.tokenClass = tokenClass;
472 glslang::TBuiltInVariable HlslScanContext::mapSemantic(const char* upperCase)
474 auto it = SemanticMap->find(upperCase);
475 if (it != SemanticMap->end())
478 return glslang::EbvNone;
482 // Fill in token information for the next token, except for the token class.
483 // Returns the enum value of the token class of the next token found.
484 // Return 0 (EndOfTokens) on end of input.
486 EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
489 parserToken = &token;
491 int token = ppContext.tokenize(ppToken);
492 if (token == EndOfInput)
495 tokenText = ppToken.name;
497 parserToken->loc = loc;
499 case ';': return EHTokSemicolon;
500 case ',': return EHTokComma;
501 case ':': return EHTokColon;
502 case '=': return EHTokAssign;
503 case '(': return EHTokLeftParen;
504 case ')': return EHTokRightParen;
505 case '.': return EHTokDot;
506 case '!': return EHTokBang;
507 case '-': return EHTokDash;
508 case '~': return EHTokTilde;
509 case '+': return EHTokPlus;
510 case '*': return EHTokStar;
511 case '/': return EHTokSlash;
512 case '%': return EHTokPercent;
513 case '<': return EHTokLeftAngle;
514 case '>': return EHTokRightAngle;
515 case '|': return EHTokVerticalBar;
516 case '^': return EHTokCaret;
517 case '&': return EHTokAmpersand;
518 case '?': return EHTokQuestion;
519 case '[': return EHTokLeftBracket;
520 case ']': return EHTokRightBracket;
521 case '{': return EHTokLeftBrace;
522 case '}': return EHTokRightBrace;
524 parseContext.error(loc, "illegal use of escape character", "\\", "");
527 case PPAtomAddAssign: return EHTokAddAssign;
528 case PPAtomSubAssign: return EHTokSubAssign;
529 case PPAtomMulAssign: return EHTokMulAssign;
530 case PPAtomDivAssign: return EHTokDivAssign;
531 case PPAtomModAssign: return EHTokModAssign;
533 case PpAtomRight: return EHTokRightOp;
534 case PpAtomLeft: return EHTokLeftOp;
536 case PpAtomRightAssign: return EHTokRightAssign;
537 case PpAtomLeftAssign: return EHTokLeftAssign;
538 case PpAtomAndAssign: return EHTokAndAssign;
539 case PpAtomOrAssign: return EHTokOrAssign;
540 case PpAtomXorAssign: return EHTokXorAssign;
542 case PpAtomAnd: return EHTokAndOp;
543 case PpAtomOr: return EHTokOrOp;
544 case PpAtomXor: return EHTokXorOp;
546 case PpAtomEQ: return EHTokEqOp;
547 case PpAtomGE: return EHTokGeOp;
548 case PpAtomNE: return EHTokNeOp;
549 case PpAtomLE: return EHTokLeOp;
551 case PpAtomDecrement: return EHTokDecOp;
552 case PpAtomIncrement: return EHTokIncOp;
554 case PpAtomColonColon: return EHTokColonColon;
556 case PpAtomConstInt: parserToken->i = ppToken.ival; return EHTokIntConstant;
557 case PpAtomConstUint: parserToken->i = ppToken.ival; return EHTokUintConstant;
558 case PpAtomConstFloat: parserToken->d = ppToken.dval; return EHTokFloatConstant;
559 case PpAtomConstDouble: parserToken->d = ppToken.dval; return EHTokDoubleConstant;
560 case PpAtomIdentifier:
562 EHlslTokenClass token = tokenizeIdentifier();
566 case PpAtomConstString: {
567 parserToken->string = NewPoolTString(tokenText);
568 return EHTokStringConstant;
571 case EndOfInput: return EHTokNone;
575 buf[0] = (char)token;
577 parseContext.error(loc, "unexpected token", buf, "");
583 EHlslTokenClass HlslScanContext::tokenizeIdentifier()
585 if (ReservedSet->find(tokenText) != ReservedSet->end())
586 return reservedWord();
588 auto it = KeywordMap->find(tokenText);
589 if (it == KeywordMap->end()) {
590 // Should have an identifier of some sort
591 return identifierOrType();
593 keyword = it->second;
606 case EHTokGroupShared:
609 case EHTokNointerpolation:
610 case EHTokNoperspective:
613 case EHTokColumnMajor:
614 case EHTokPackOffset:
620 case EHTokGloballyCoherent:
629 case EHTokTriangleAdj:
633 case EHTokPointStream:
634 case EHTokLineStream:
635 case EHTokTriangleStream:
638 // Tessellation patches
639 case EHTokInputPatch:
640 case EHTokOutputPatch:
658 case EHTokMin16float:
659 case EHTokMin10float:
689 case EHTokMin16float1:
690 case EHTokMin16float2:
691 case EHTokMin16float3:
692 case EHTokMin16float4:
693 case EHTokMin10float1:
694 case EHTokMin10float2:
695 case EHTokMin10float3:
696 case EHTokMin10float4:
705 case EHTokMin16uint1:
706 case EHTokMin16uint2:
707 case EHTokMin16uint3:
708 case EHTokMin16uint4:
798 case EHTokSamplerCube:
799 case EHTokSamplerState:
800 case EHTokSamplerComparisonState:
803 case EHTokTexture1darray:
805 case EHTokTexture2darray:
807 case EHTokTextureCube:
808 case EHTokTextureCubearray:
809 case EHTokTexture2DMS:
810 case EHTokTexture2DMSarray:
811 case EHTokRWTexture1d:
812 case EHTokRWTexture1darray:
813 case EHTokRWTexture2d:
814 case EHTokRWTexture2darray:
815 case EHTokRWTexture3d:
817 case EHTokAppendStructuredBuffer:
818 case EHTokByteAddressBuffer:
819 case EHTokConsumeStructuredBuffer:
820 case EHTokRWByteAddressBuffer:
821 case EHTokRWStructuredBuffer:
822 case EHTokStructuredBuffer:
825 // variable, user type, ...
835 case EHTokBoolConstant:
836 if (strcmp("true", tokenText) == 0)
837 parserToken->b = true;
839 parserToken->b = false;
858 parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
863 EHlslTokenClass HlslScanContext::identifierOrType()
865 parserToken->string = NewPoolTString(tokenText);
867 return EHTokIdentifier;
870 // Give an error for use of a reserved symbol.
871 // However, allow built-in declarations to use reserved words, to allow
872 // extension support before the extension is enabled.
873 EHlslTokenClass HlslScanContext::reservedWord()
875 if (! parseContext.symbolTable.atBuiltInLevel())
876 parseContext.error(loc, "Reserved word.", tokenText, "", "");
881 EHlslTokenClass HlslScanContext::identifierOrReserved(bool reserved)
889 if (parseContext.forwardCompatible)
890 parseContext.warn(loc, "using future reserved keyword", tokenText, "");
892 return identifierOrType();
895 // For a keyword that was never reserved, until it suddenly
897 EHlslTokenClass HlslScanContext::nonreservedKeyword(int version)
899 if (parseContext.version < version)
900 return identifierOrType();
905 } // end namespace glslang