summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/glslang/hlsl/hlslScanContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/glslang/hlsl/hlslScanContext.cpp')
-rw-r--r--src/3rdparty/glslang/hlsl/hlslScanContext.cpp903
1 files changed, 903 insertions, 0 deletions
diff --git a/src/3rdparty/glslang/hlsl/hlslScanContext.cpp b/src/3rdparty/glslang/hlsl/hlslScanContext.cpp
new file mode 100644
index 0000000..28a66bb
--- /dev/null
+++ b/src/3rdparty/glslang/hlsl/hlslScanContext.cpp
@@ -0,0 +1,903 @@
+//
+// Copyright (C) 2016 Google, Inc.
+// Copyright (C) 2016 LunarG, Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of Google, Inc., nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+
+//
+// HLSL scanning, leveraging the scanning done by the preprocessor.
+//
+
+#include <cstring>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "../glslang/Include/Types.h"
+#include "../glslang/MachineIndependent/SymbolTable.h"
+#include "../glslang/MachineIndependent/ParseHelper.h"
+#include "hlslScanContext.h"
+#include "hlslTokens.h"
+
+// preprocessor includes
+#include "../glslang/MachineIndependent/preprocessor/PpContext.h"
+#include "../glslang/MachineIndependent/preprocessor/PpTokens.h"
+
+namespace {
+
+struct str_eq
+{
+ bool operator()(const char* lhs, const char* rhs) const
+ {
+ return strcmp(lhs, rhs) == 0;
+ }
+};
+
+struct str_hash
+{
+ size_t operator()(const char* str) const
+ {
+ // djb2
+ unsigned long hash = 5381;
+ int c;
+
+ while ((c = *str++) != 0)
+ hash = ((hash << 5) + hash) + c;
+
+ return hash;
+ }
+};
+
+// A single global usable by all threads, by all versions, by all languages.
+// After a single process-level initialization, this is read only and thread safe
+std::unordered_map<const char*, glslang::EHlslTokenClass, str_hash, str_eq>* KeywordMap = nullptr;
+std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
+std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>* SemanticMap = nullptr;
+
+};
+
+namespace glslang {
+
+void HlslScanContext::fillInKeywordMap()
+{
+ if (KeywordMap != nullptr) {
+ // this is really an error, as this should called only once per process
+ // but, the only risk is if two threads called simultaneously
+ return;
+ }
+ KeywordMap = new std::unordered_map<const char*, EHlslTokenClass, str_hash, str_eq>;
+
+ (*KeywordMap)["static"] = EHTokStatic;
+ (*KeywordMap)["const"] = EHTokConst;
+ (*KeywordMap)["unorm"] = EHTokUnorm;
+ (*KeywordMap)["snorm"] = EHTokSNorm;
+ (*KeywordMap)["extern"] = EHTokExtern;
+ (*KeywordMap)["uniform"] = EHTokUniform;
+ (*KeywordMap)["volatile"] = EHTokVolatile;
+ (*KeywordMap)["precise"] = EHTokPrecise;
+ (*KeywordMap)["shared"] = EHTokShared;
+ (*KeywordMap)["groupshared"] = EHTokGroupShared;
+ (*KeywordMap)["linear"] = EHTokLinear;
+ (*KeywordMap)["centroid"] = EHTokCentroid;
+ (*KeywordMap)["nointerpolation"] = EHTokNointerpolation;
+ (*KeywordMap)["noperspective"] = EHTokNoperspective;
+ (*KeywordMap)["sample"] = EHTokSample;
+ (*KeywordMap)["row_major"] = EHTokRowMajor;
+ (*KeywordMap)["column_major"] = EHTokColumnMajor;
+ (*KeywordMap)["packoffset"] = EHTokPackOffset;
+ (*KeywordMap)["in"] = EHTokIn;
+ (*KeywordMap)["out"] = EHTokOut;
+ (*KeywordMap)["inout"] = EHTokInOut;
+ (*KeywordMap)["layout"] = EHTokLayout;
+ (*KeywordMap)["globallycoherent"] = EHTokGloballyCoherent;
+ (*KeywordMap)["inline"] = EHTokInline;
+
+ (*KeywordMap)["point"] = EHTokPoint;
+ (*KeywordMap)["line"] = EHTokLine;
+ (*KeywordMap)["triangle"] = EHTokTriangle;
+ (*KeywordMap)["lineadj"] = EHTokLineAdj;
+ (*KeywordMap)["triangleadj"] = EHTokTriangleAdj;
+
+ (*KeywordMap)["PointStream"] = EHTokPointStream;
+ (*KeywordMap)["LineStream"] = EHTokLineStream;
+ (*KeywordMap)["TriangleStream"] = EHTokTriangleStream;
+
+ (*KeywordMap)["InputPatch"] = EHTokInputPatch;
+ (*KeywordMap)["OutputPatch"] = EHTokOutputPatch;
+
+ (*KeywordMap)["Buffer"] = EHTokBuffer;
+ (*KeywordMap)["vector"] = EHTokVector;
+ (*KeywordMap)["matrix"] = EHTokMatrix;
+
+ (*KeywordMap)["void"] = EHTokVoid;
+ (*KeywordMap)["string"] = EHTokString;
+ (*KeywordMap)["bool"] = EHTokBool;
+ (*KeywordMap)["int"] = EHTokInt;
+ (*KeywordMap)["uint"] = EHTokUint;
+ (*KeywordMap)["uint64_t"] = EHTokUint64;
+ (*KeywordMap)["dword"] = EHTokDword;
+ (*KeywordMap)["half"] = EHTokHalf;
+ (*KeywordMap)["float"] = EHTokFloat;
+ (*KeywordMap)["double"] = EHTokDouble;
+ (*KeywordMap)["min16float"] = EHTokMin16float;
+ (*KeywordMap)["min10float"] = EHTokMin10float;
+ (*KeywordMap)["min16int"] = EHTokMin16int;
+ (*KeywordMap)["min12int"] = EHTokMin12int;
+ (*KeywordMap)["min16uint"] = EHTokMin16uint;
+
+ (*KeywordMap)["bool1"] = EHTokBool1;
+ (*KeywordMap)["bool2"] = EHTokBool2;
+ (*KeywordMap)["bool3"] = EHTokBool3;
+ (*KeywordMap)["bool4"] = EHTokBool4;
+ (*KeywordMap)["float1"] = EHTokFloat1;
+ (*KeywordMap)["float2"] = EHTokFloat2;
+ (*KeywordMap)["float3"] = EHTokFloat3;
+ (*KeywordMap)["float4"] = EHTokFloat4;
+ (*KeywordMap)["int1"] = EHTokInt1;
+ (*KeywordMap)["int2"] = EHTokInt2;
+ (*KeywordMap)["int3"] = EHTokInt3;
+ (*KeywordMap)["int4"] = EHTokInt4;
+ (*KeywordMap)["double1"] = EHTokDouble1;
+ (*KeywordMap)["double2"] = EHTokDouble2;
+ (*KeywordMap)["double3"] = EHTokDouble3;
+ (*KeywordMap)["double4"] = EHTokDouble4;
+ (*KeywordMap)["uint1"] = EHTokUint1;
+ (*KeywordMap)["uint2"] = EHTokUint2;
+ (*KeywordMap)["uint3"] = EHTokUint3;
+ (*KeywordMap)["uint4"] = EHTokUint4;
+
+ (*KeywordMap)["half1"] = EHTokHalf1;
+ (*KeywordMap)["half2"] = EHTokHalf2;
+ (*KeywordMap)["half3"] = EHTokHalf3;
+ (*KeywordMap)["half4"] = EHTokHalf4;
+ (*KeywordMap)["min16float1"] = EHTokMin16float1;
+ (*KeywordMap)["min16float2"] = EHTokMin16float2;
+ (*KeywordMap)["min16float3"] = EHTokMin16float3;
+ (*KeywordMap)["min16float4"] = EHTokMin16float4;
+ (*KeywordMap)["min10float1"] = EHTokMin10float1;
+ (*KeywordMap)["min10float2"] = EHTokMin10float2;
+ (*KeywordMap)["min10float3"] = EHTokMin10float3;
+ (*KeywordMap)["min10float4"] = EHTokMin10float4;
+ (*KeywordMap)["min16int1"] = EHTokMin16int1;
+ (*KeywordMap)["min16int2"] = EHTokMin16int2;
+ (*KeywordMap)["min16int3"] = EHTokMin16int3;
+ (*KeywordMap)["min16int4"] = EHTokMin16int4;
+ (*KeywordMap)["min12int1"] = EHTokMin12int1;
+ (*KeywordMap)["min12int2"] = EHTokMin12int2;
+ (*KeywordMap)["min12int3"] = EHTokMin12int3;
+ (*KeywordMap)["min12int4"] = EHTokMin12int4;
+ (*KeywordMap)["min16uint1"] = EHTokMin16uint1;
+ (*KeywordMap)["min16uint2"] = EHTokMin16uint2;
+ (*KeywordMap)["min16uint3"] = EHTokMin16uint3;
+ (*KeywordMap)["min16uint4"] = EHTokMin16uint4;
+
+ (*KeywordMap)["bool1x1"] = EHTokBool1x1;
+ (*KeywordMap)["bool1x2"] = EHTokBool1x2;
+ (*KeywordMap)["bool1x3"] = EHTokBool1x3;
+ (*KeywordMap)["bool1x4"] = EHTokBool1x4;
+ (*KeywordMap)["bool2x1"] = EHTokBool2x1;
+ (*KeywordMap)["bool2x2"] = EHTokBool2x2;
+ (*KeywordMap)["bool2x3"] = EHTokBool2x3;
+ (*KeywordMap)["bool2x4"] = EHTokBool2x4;
+ (*KeywordMap)["bool3x1"] = EHTokBool3x1;
+ (*KeywordMap)["bool3x2"] = EHTokBool3x2;
+ (*KeywordMap)["bool3x3"] = EHTokBool3x3;
+ (*KeywordMap)["bool3x4"] = EHTokBool3x4;
+ (*KeywordMap)["bool4x1"] = EHTokBool4x1;
+ (*KeywordMap)["bool4x2"] = EHTokBool4x2;
+ (*KeywordMap)["bool4x3"] = EHTokBool4x3;
+ (*KeywordMap)["bool4x4"] = EHTokBool4x4;
+ (*KeywordMap)["int1x1"] = EHTokInt1x1;
+ (*KeywordMap)["int1x2"] = EHTokInt1x2;
+ (*KeywordMap)["int1x3"] = EHTokInt1x3;
+ (*KeywordMap)["int1x4"] = EHTokInt1x4;
+ (*KeywordMap)["int2x1"] = EHTokInt2x1;
+ (*KeywordMap)["int2x2"] = EHTokInt2x2;
+ (*KeywordMap)["int2x3"] = EHTokInt2x3;
+ (*KeywordMap)["int2x4"] = EHTokInt2x4;
+ (*KeywordMap)["int3x1"] = EHTokInt3x1;
+ (*KeywordMap)["int3x2"] = EHTokInt3x2;
+ (*KeywordMap)["int3x3"] = EHTokInt3x3;
+ (*KeywordMap)["int3x4"] = EHTokInt3x4;
+ (*KeywordMap)["int4x1"] = EHTokInt4x1;
+ (*KeywordMap)["int4x2"] = EHTokInt4x2;
+ (*KeywordMap)["int4x3"] = EHTokInt4x3;
+ (*KeywordMap)["int4x4"] = EHTokInt4x4;
+ (*KeywordMap)["uint1x1"] = EHTokUint1x1;
+ (*KeywordMap)["uint1x2"] = EHTokUint1x2;
+ (*KeywordMap)["uint1x3"] = EHTokUint1x3;
+ (*KeywordMap)["uint1x4"] = EHTokUint1x4;
+ (*KeywordMap)["uint2x1"] = EHTokUint2x1;
+ (*KeywordMap)["uint2x2"] = EHTokUint2x2;
+ (*KeywordMap)["uint2x3"] = EHTokUint2x3;
+ (*KeywordMap)["uint2x4"] = EHTokUint2x4;
+ (*KeywordMap)["uint3x1"] = EHTokUint3x1;
+ (*KeywordMap)["uint3x2"] = EHTokUint3x2;
+ (*KeywordMap)["uint3x3"] = EHTokUint3x3;
+ (*KeywordMap)["uint3x4"] = EHTokUint3x4;
+ (*KeywordMap)["uint4x1"] = EHTokUint4x1;
+ (*KeywordMap)["uint4x2"] = EHTokUint4x2;
+ (*KeywordMap)["uint4x3"] = EHTokUint4x3;
+ (*KeywordMap)["uint4x4"] = EHTokUint4x4;
+ (*KeywordMap)["bool1x1"] = EHTokBool1x1;
+ (*KeywordMap)["bool1x2"] = EHTokBool1x2;
+ (*KeywordMap)["bool1x3"] = EHTokBool1x3;
+ (*KeywordMap)["bool1x4"] = EHTokBool1x4;
+ (*KeywordMap)["bool2x1"] = EHTokBool2x1;
+ (*KeywordMap)["bool2x2"] = EHTokBool2x2;
+ (*KeywordMap)["bool2x3"] = EHTokBool2x3;
+ (*KeywordMap)["bool2x4"] = EHTokBool2x4;
+ (*KeywordMap)["bool3x1"] = EHTokBool3x1;
+ (*KeywordMap)["bool3x2"] = EHTokBool3x2;
+ (*KeywordMap)["bool3x3"] = EHTokBool3x3;
+ (*KeywordMap)["bool3x4"] = EHTokBool3x4;
+ (*KeywordMap)["bool4x1"] = EHTokBool4x1;
+ (*KeywordMap)["bool4x2"] = EHTokBool4x2;
+ (*KeywordMap)["bool4x3"] = EHTokBool4x3;
+ (*KeywordMap)["bool4x4"] = EHTokBool4x4;
+ (*KeywordMap)["float1x1"] = EHTokFloat1x1;
+ (*KeywordMap)["float1x2"] = EHTokFloat1x2;
+ (*KeywordMap)["float1x3"] = EHTokFloat1x3;
+ (*KeywordMap)["float1x4"] = EHTokFloat1x4;
+ (*KeywordMap)["float2x1"] = EHTokFloat2x1;
+ (*KeywordMap)["float2x2"] = EHTokFloat2x2;
+ (*KeywordMap)["float2x3"] = EHTokFloat2x3;
+ (*KeywordMap)["float2x4"] = EHTokFloat2x4;
+ (*KeywordMap)["float3x1"] = EHTokFloat3x1;
+ (*KeywordMap)["float3x2"] = EHTokFloat3x2;
+ (*KeywordMap)["float3x3"] = EHTokFloat3x3;
+ (*KeywordMap)["float3x4"] = EHTokFloat3x4;
+ (*KeywordMap)["float4x1"] = EHTokFloat4x1;
+ (*KeywordMap)["float4x2"] = EHTokFloat4x2;
+ (*KeywordMap)["float4x3"] = EHTokFloat4x3;
+ (*KeywordMap)["float4x4"] = EHTokFloat4x4;
+ (*KeywordMap)["half1x1"] = EHTokHalf1x1;
+ (*KeywordMap)["half1x2"] = EHTokHalf1x2;
+ (*KeywordMap)["half1x3"] = EHTokHalf1x3;
+ (*KeywordMap)["half1x4"] = EHTokHalf1x4;
+ (*KeywordMap)["half2x1"] = EHTokHalf2x1;
+ (*KeywordMap)["half2x2"] = EHTokHalf2x2;
+ (*KeywordMap)["half2x3"] = EHTokHalf2x3;
+ (*KeywordMap)["half2x4"] = EHTokHalf2x4;
+ (*KeywordMap)["half3x1"] = EHTokHalf3x1;
+ (*KeywordMap)["half3x2"] = EHTokHalf3x2;
+ (*KeywordMap)["half3x3"] = EHTokHalf3x3;
+ (*KeywordMap)["half3x4"] = EHTokHalf3x4;
+ (*KeywordMap)["half4x1"] = EHTokHalf4x1;
+ (*KeywordMap)["half4x2"] = EHTokHalf4x2;
+ (*KeywordMap)["half4x3"] = EHTokHalf4x3;
+ (*KeywordMap)["half4x4"] = EHTokHalf4x4;
+ (*KeywordMap)["double1x1"] = EHTokDouble1x1;
+ (*KeywordMap)["double1x2"] = EHTokDouble1x2;
+ (*KeywordMap)["double1x3"] = EHTokDouble1x3;
+ (*KeywordMap)["double1x4"] = EHTokDouble1x4;
+ (*KeywordMap)["double2x1"] = EHTokDouble2x1;
+ (*KeywordMap)["double2x2"] = EHTokDouble2x2;
+ (*KeywordMap)["double2x3"] = EHTokDouble2x3;
+ (*KeywordMap)["double2x4"] = EHTokDouble2x4;
+ (*KeywordMap)["double3x1"] = EHTokDouble3x1;
+ (*KeywordMap)["double3x2"] = EHTokDouble3x2;
+ (*KeywordMap)["double3x3"] = EHTokDouble3x3;
+ (*KeywordMap)["double3x4"] = EHTokDouble3x4;
+ (*KeywordMap)["double4x1"] = EHTokDouble4x1;
+ (*KeywordMap)["double4x2"] = EHTokDouble4x2;
+ (*KeywordMap)["double4x3"] = EHTokDouble4x3;
+ (*KeywordMap)["double4x4"] = EHTokDouble4x4;
+
+ (*KeywordMap)["sampler"] = EHTokSampler;
+ (*KeywordMap)["sampler1D"] = EHTokSampler1d;
+ (*KeywordMap)["sampler2D"] = EHTokSampler2d;
+ (*KeywordMap)["sampler3D"] = EHTokSampler3d;
+ (*KeywordMap)["samplerCube"] = EHTokSamplerCube;
+ (*KeywordMap)["sampler_state"] = EHTokSamplerState;
+ (*KeywordMap)["SamplerState"] = EHTokSamplerState;
+ (*KeywordMap)["SamplerComparisonState"] = EHTokSamplerComparisonState;
+ (*KeywordMap)["texture"] = EHTokTexture;
+ (*KeywordMap)["Texture1D"] = EHTokTexture1d;
+ (*KeywordMap)["Texture1DArray"] = EHTokTexture1darray;
+ (*KeywordMap)["Texture2D"] = EHTokTexture2d;
+ (*KeywordMap)["Texture2DArray"] = EHTokTexture2darray;
+ (*KeywordMap)["Texture3D"] = EHTokTexture3d;
+ (*KeywordMap)["TextureCube"] = EHTokTextureCube;
+ (*KeywordMap)["TextureCubeArray"] = EHTokTextureCubearray;
+ (*KeywordMap)["Texture2DMS"] = EHTokTexture2DMS;
+ (*KeywordMap)["Texture2DMSArray"] = EHTokTexture2DMSarray;
+ (*KeywordMap)["RWTexture1D"] = EHTokRWTexture1d;
+ (*KeywordMap)["RWTexture1DArray"] = EHTokRWTexture1darray;
+ (*KeywordMap)["RWTexture2D"] = EHTokRWTexture2d;
+ (*KeywordMap)["RWTexture2DArray"] = EHTokRWTexture2darray;
+ (*KeywordMap)["RWTexture3D"] = EHTokRWTexture3d;
+ (*KeywordMap)["RWBuffer"] = EHTokRWBuffer;
+ (*KeywordMap)["SubpassInput"] = EHTokSubpassInput;
+ (*KeywordMap)["SubpassInputMS"] = EHTokSubpassInputMS;
+
+ (*KeywordMap)["AppendStructuredBuffer"] = EHTokAppendStructuredBuffer;
+ (*KeywordMap)["ByteAddressBuffer"] = EHTokByteAddressBuffer;
+ (*KeywordMap)["ConsumeStructuredBuffer"] = EHTokConsumeStructuredBuffer;
+ (*KeywordMap)["RWByteAddressBuffer"] = EHTokRWByteAddressBuffer;
+ (*KeywordMap)["RWStructuredBuffer"] = EHTokRWStructuredBuffer;
+ (*KeywordMap)["StructuredBuffer"] = EHTokStructuredBuffer;
+ (*KeywordMap)["TextureBuffer"] = EHTokTextureBuffer;
+
+ (*KeywordMap)["class"] = EHTokClass;
+ (*KeywordMap)["struct"] = EHTokStruct;
+ (*KeywordMap)["cbuffer"] = EHTokCBuffer;
+ (*KeywordMap)["ConstantBuffer"] = EHTokConstantBuffer;
+ (*KeywordMap)["tbuffer"] = EHTokTBuffer;
+ (*KeywordMap)["typedef"] = EHTokTypedef;
+ (*KeywordMap)["this"] = EHTokThis;
+ (*KeywordMap)["namespace"] = EHTokNamespace;
+
+ (*KeywordMap)["true"] = EHTokBoolConstant;
+ (*KeywordMap)["false"] = EHTokBoolConstant;
+
+ (*KeywordMap)["for"] = EHTokFor;
+ (*KeywordMap)["do"] = EHTokDo;
+ (*KeywordMap)["while"] = EHTokWhile;
+ (*KeywordMap)["break"] = EHTokBreak;
+ (*KeywordMap)["continue"] = EHTokContinue;
+ (*KeywordMap)["if"] = EHTokIf;
+ (*KeywordMap)["else"] = EHTokElse;
+ (*KeywordMap)["discard"] = EHTokDiscard;
+ (*KeywordMap)["return"] = EHTokReturn;
+ (*KeywordMap)["switch"] = EHTokSwitch;
+ (*KeywordMap)["case"] = EHTokCase;
+ (*KeywordMap)["default"] = EHTokDefault;
+
+ // TODO: get correct set here
+ ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
+
+ ReservedSet->insert("auto");
+ ReservedSet->insert("catch");
+ ReservedSet->insert("char");
+ ReservedSet->insert("const_cast");
+ ReservedSet->insert("enum");
+ ReservedSet->insert("explicit");
+ ReservedSet->insert("friend");
+ ReservedSet->insert("goto");
+ ReservedSet->insert("long");
+ ReservedSet->insert("mutable");
+ ReservedSet->insert("new");
+ ReservedSet->insert("operator");
+ ReservedSet->insert("private");
+ ReservedSet->insert("protected");
+ ReservedSet->insert("public");
+ ReservedSet->insert("reinterpret_cast");
+ ReservedSet->insert("short");
+ ReservedSet->insert("signed");
+ ReservedSet->insert("sizeof");
+ ReservedSet->insert("static_cast");
+ ReservedSet->insert("template");
+ ReservedSet->insert("throw");
+ ReservedSet->insert("try");
+ ReservedSet->insert("typename");
+ ReservedSet->insert("union");
+ ReservedSet->insert("unsigned");
+ ReservedSet->insert("using");
+ ReservedSet->insert("virtual");
+
+ SemanticMap = new std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>;
+
+ // in DX9, all outputs had to have a semantic associated with them, that was either consumed
+ // by the system or was a specific register assignment
+ // in DX10+, only semantics with the SV_ prefix have any meaning beyond decoration
+ // Fxc will only accept DX9 style semantics in compat mode
+ // Also, in DX10 if a SV value is present as the input of a stage, but isn't appropriate for that
+ // stage, it would just be ignored as it is likely there as part of an output struct from one stage
+ // to the next
+ bool bParseDX9 = false;
+ if (bParseDX9) {
+ (*SemanticMap)["PSIZE"] = EbvPointSize;
+ (*SemanticMap)["FOG"] = EbvFogFragCoord;
+ (*SemanticMap)["DEPTH"] = EbvFragDepth;
+ (*SemanticMap)["VFACE"] = EbvFace;
+ (*SemanticMap)["VPOS"] = EbvFragCoord;
+ }
+
+ (*SemanticMap)["SV_POSITION"] = EbvPosition;
+ (*SemanticMap)["SV_VERTEXID"] = EbvVertexIndex;
+ (*SemanticMap)["SV_VIEWPORTARRAYINDEX"] = EbvViewportIndex;
+ (*SemanticMap)["SV_TESSFACTOR"] = EbvTessLevelOuter;
+ (*SemanticMap)["SV_SAMPLEINDEX"] = EbvSampleId;
+ (*SemanticMap)["SV_RENDERTARGETARRAYINDEX"] = EbvLayer;
+ (*SemanticMap)["SV_PRIMITIVEID"] = EbvPrimitiveId;
+ (*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] = EbvInvocationId;
+ (*SemanticMap)["SV_ISFRONTFACE"] = EbvFace;
+ (*SemanticMap)["SV_INSTANCEID"] = EbvInstanceIndex;
+ (*SemanticMap)["SV_INSIDETESSFACTOR"] = EbvTessLevelInner;
+ (*SemanticMap)["SV_GSINSTANCEID"] = EbvInvocationId;
+ (*SemanticMap)["SV_DISPATCHTHREADID"] = EbvGlobalInvocationId;
+ (*SemanticMap)["SV_GROUPTHREADID"] = EbvLocalInvocationId;
+ (*SemanticMap)["SV_GROUPINDEX"] = EbvLocalInvocationIndex;
+ (*SemanticMap)["SV_GROUPID"] = EbvWorkGroupId;
+ (*SemanticMap)["SV_DOMAINLOCATION"] = EbvTessCoord;
+ (*SemanticMap)["SV_DEPTH"] = EbvFragDepth;
+ (*SemanticMap)["SV_COVERAGE"] = EbvSampleMask;
+ (*SemanticMap)["SV_DEPTHGREATEREQUAL"] = EbvFragDepthGreater;
+ (*SemanticMap)["SV_DEPTHLESSEQUAL"] = EbvFragDepthLesser;
+ (*SemanticMap)["SV_STENCILREF"] = EbvFragStencilRef;
+}
+
+void HlslScanContext::deleteKeywordMap()
+{
+ delete KeywordMap;
+ KeywordMap = nullptr;
+ delete ReservedSet;
+ ReservedSet = nullptr;
+ delete SemanticMap;
+ SemanticMap = nullptr;
+}
+
+// Wrapper for tokenizeClass() to get everything inside the token.
+void HlslScanContext::tokenize(HlslToken& token)
+{
+ EHlslTokenClass tokenClass = tokenizeClass(token);
+ token.tokenClass = tokenClass;
+}
+
+glslang::TBuiltInVariable HlslScanContext::mapSemantic(const char* upperCase)
+{
+ auto it = SemanticMap->find(upperCase);
+ if (it != SemanticMap->end())
+ return it->second;
+ else
+ return glslang::EbvNone;
+}
+
+//
+// Fill in token information for the next token, except for the token class.
+// Returns the enum value of the token class of the next token found.
+// Return 0 (EndOfTokens) on end of input.
+//
+EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
+{
+ do {
+ parserToken = &token;
+ TPpToken ppToken;
+ int token = ppContext.tokenize(ppToken);
+ if (token == EndOfInput)
+ return EHTokNone;
+
+ tokenText = ppToken.name;
+ loc = ppToken.loc;
+ parserToken->loc = loc;
+ switch (token) {
+ case ';': return EHTokSemicolon;
+ case ',': return EHTokComma;
+ case ':': return EHTokColon;
+ case '=': return EHTokAssign;
+ case '(': return EHTokLeftParen;
+ case ')': return EHTokRightParen;
+ case '.': return EHTokDot;
+ case '!': return EHTokBang;
+ case '-': return EHTokDash;
+ case '~': return EHTokTilde;
+ case '+': return EHTokPlus;
+ case '*': return EHTokStar;
+ case '/': return EHTokSlash;
+ case '%': return EHTokPercent;
+ case '<': return EHTokLeftAngle;
+ case '>': return EHTokRightAngle;
+ case '|': return EHTokVerticalBar;
+ case '^': return EHTokCaret;
+ case '&': return EHTokAmpersand;
+ case '?': return EHTokQuestion;
+ case '[': return EHTokLeftBracket;
+ case ']': return EHTokRightBracket;
+ case '{': return EHTokLeftBrace;
+ case '}': return EHTokRightBrace;
+ case '\\':
+ parseContext.error(loc, "illegal use of escape character", "\\", "");
+ break;
+
+ case PPAtomAddAssign: return EHTokAddAssign;
+ case PPAtomSubAssign: return EHTokSubAssign;
+ case PPAtomMulAssign: return EHTokMulAssign;
+ case PPAtomDivAssign: return EHTokDivAssign;
+ case PPAtomModAssign: return EHTokModAssign;
+
+ case PpAtomRight: return EHTokRightOp;
+ case PpAtomLeft: return EHTokLeftOp;
+
+ case PpAtomRightAssign: return EHTokRightAssign;
+ case PpAtomLeftAssign: return EHTokLeftAssign;
+ case PpAtomAndAssign: return EHTokAndAssign;
+ case PpAtomOrAssign: return EHTokOrAssign;
+ case PpAtomXorAssign: return EHTokXorAssign;
+
+ case PpAtomAnd: return EHTokAndOp;
+ case PpAtomOr: return EHTokOrOp;
+ case PpAtomXor: return EHTokXorOp;
+
+ case PpAtomEQ: return EHTokEqOp;
+ case PpAtomGE: return EHTokGeOp;
+ case PpAtomNE: return EHTokNeOp;
+ case PpAtomLE: return EHTokLeOp;
+
+ case PpAtomDecrement: return EHTokDecOp;
+ case PpAtomIncrement: return EHTokIncOp;
+
+ case PpAtomColonColon: return EHTokColonColon;
+
+ case PpAtomConstInt: parserToken->i = ppToken.ival; return EHTokIntConstant;
+ case PpAtomConstUint: parserToken->i = ppToken.ival; return EHTokUintConstant;
+ case PpAtomConstFloat16: parserToken->d = ppToken.dval; return EHTokFloat16Constant;
+ case PpAtomConstFloat: parserToken->d = ppToken.dval; return EHTokFloatConstant;
+ case PpAtomConstDouble: parserToken->d = ppToken.dval; return EHTokDoubleConstant;
+ case PpAtomIdentifier:
+ {
+ EHlslTokenClass token = tokenizeIdentifier();
+ return token;
+ }
+
+ case PpAtomConstString: {
+ parserToken->string = NewPoolTString(tokenText);
+ return EHTokStringConstant;
+ }
+
+ case EndOfInput: return EHTokNone;
+
+ default:
+ if (token < PpAtomMaxSingle) {
+ char buf[2];
+ buf[0] = (char)token;
+ buf[1] = 0;
+ parseContext.error(loc, "unexpected token", buf, "");
+ } else if (tokenText[0] != 0)
+ parseContext.error(loc, "unexpected token", tokenText, "");
+ else
+ parseContext.error(loc, "unexpected token", "", "");
+ break;
+ }
+ } while (true);
+}
+
+EHlslTokenClass HlslScanContext::tokenizeIdentifier()
+{
+ if (ReservedSet->find(tokenText) != ReservedSet->end())
+ return reservedWord();
+
+ auto it = KeywordMap->find(tokenText);
+ if (it == KeywordMap->end()) {
+ // Should have an identifier of some sort
+ return identifierOrType();
+ }
+ keyword = it->second;
+
+ switch (keyword) {
+
+ // qualifiers
+ case EHTokStatic:
+ case EHTokConst:
+ case EHTokSNorm:
+ case EHTokUnorm:
+ case EHTokExtern:
+ case EHTokUniform:
+ case EHTokVolatile:
+ case EHTokShared:
+ case EHTokGroupShared:
+ case EHTokLinear:
+ case EHTokCentroid:
+ case EHTokNointerpolation:
+ case EHTokNoperspective:
+ case EHTokSample:
+ case EHTokRowMajor:
+ case EHTokColumnMajor:
+ case EHTokPackOffset:
+ case EHTokIn:
+ case EHTokOut:
+ case EHTokInOut:
+ case EHTokPrecise:
+ case EHTokLayout:
+ case EHTokGloballyCoherent:
+ case EHTokInline:
+ return keyword;
+
+ // primitive types
+ case EHTokPoint:
+ case EHTokLine:
+ case EHTokTriangle:
+ case EHTokLineAdj:
+ case EHTokTriangleAdj:
+ return keyword;
+
+ // stream out types
+ case EHTokPointStream:
+ case EHTokLineStream:
+ case EHTokTriangleStream:
+ return keyword;
+
+ // Tessellation patches
+ case EHTokInputPatch:
+ case EHTokOutputPatch:
+ return keyword;
+
+ case EHTokBuffer:
+ case EHTokVector:
+ case EHTokMatrix:
+ return keyword;
+
+ // scalar types
+ case EHTokVoid:
+ case EHTokString:
+ case EHTokBool:
+ case EHTokInt:
+ case EHTokUint:
+ case EHTokUint64:
+ case EHTokDword:
+ case EHTokHalf:
+ case EHTokFloat:
+ case EHTokDouble:
+ case EHTokMin16float:
+ case EHTokMin10float:
+ case EHTokMin16int:
+ case EHTokMin12int:
+ case EHTokMin16uint:
+
+ // vector types
+ case EHTokBool1:
+ case EHTokBool2:
+ case EHTokBool3:
+ case EHTokBool4:
+ case EHTokFloat1:
+ case EHTokFloat2:
+ case EHTokFloat3:
+ case EHTokFloat4:
+ case EHTokInt1:
+ case EHTokInt2:
+ case EHTokInt3:
+ case EHTokInt4:
+ case EHTokDouble1:
+ case EHTokDouble2:
+ case EHTokDouble3:
+ case EHTokDouble4:
+ case EHTokUint1:
+ case EHTokUint2:
+ case EHTokUint3:
+ case EHTokUint4:
+ case EHTokHalf1:
+ case EHTokHalf2:
+ case EHTokHalf3:
+ case EHTokHalf4:
+ case EHTokMin16float1:
+ case EHTokMin16float2:
+ case EHTokMin16float3:
+ case EHTokMin16float4:
+ case EHTokMin10float1:
+ case EHTokMin10float2:
+ case EHTokMin10float3:
+ case EHTokMin10float4:
+ case EHTokMin16int1:
+ case EHTokMin16int2:
+ case EHTokMin16int3:
+ case EHTokMin16int4:
+ case EHTokMin12int1:
+ case EHTokMin12int2:
+ case EHTokMin12int3:
+ case EHTokMin12int4:
+ case EHTokMin16uint1:
+ case EHTokMin16uint2:
+ case EHTokMin16uint3:
+ case EHTokMin16uint4:
+
+ // matrix types
+ case EHTokBool1x1:
+ case EHTokBool1x2:
+ case EHTokBool1x3:
+ case EHTokBool1x4:
+ case EHTokBool2x1:
+ case EHTokBool2x2:
+ case EHTokBool2x3:
+ case EHTokBool2x4:
+ case EHTokBool3x1:
+ case EHTokBool3x2:
+ case EHTokBool3x3:
+ case EHTokBool3x4:
+ case EHTokBool4x1:
+ case EHTokBool4x2:
+ case EHTokBool4x3:
+ case EHTokBool4x4:
+ case EHTokInt1x1:
+ case EHTokInt1x2:
+ case EHTokInt1x3:
+ case EHTokInt1x4:
+ case EHTokInt2x1:
+ case EHTokInt2x2:
+ case EHTokInt2x3:
+ case EHTokInt2x4:
+ case EHTokInt3x1:
+ case EHTokInt3x2:
+ case EHTokInt3x3:
+ case EHTokInt3x4:
+ case EHTokInt4x1:
+ case EHTokInt4x2:
+ case EHTokInt4x3:
+ case EHTokInt4x4:
+ case EHTokUint1x1:
+ case EHTokUint1x2:
+ case EHTokUint1x3:
+ case EHTokUint1x4:
+ case EHTokUint2x1:
+ case EHTokUint2x2:
+ case EHTokUint2x3:
+ case EHTokUint2x4:
+ case EHTokUint3x1:
+ case EHTokUint3x2:
+ case EHTokUint3x3:
+ case EHTokUint3x4:
+ case EHTokUint4x1:
+ case EHTokUint4x2:
+ case EHTokUint4x3:
+ case EHTokUint4x4:
+ case EHTokFloat1x1:
+ case EHTokFloat1x2:
+ case EHTokFloat1x3:
+ case EHTokFloat1x4:
+ case EHTokFloat2x1:
+ case EHTokFloat2x2:
+ case EHTokFloat2x3:
+ case EHTokFloat2x4:
+ case EHTokFloat3x1:
+ case EHTokFloat3x2:
+ case EHTokFloat3x3:
+ case EHTokFloat3x4:
+ case EHTokFloat4x1:
+ case EHTokFloat4x2:
+ case EHTokFloat4x3:
+ case EHTokFloat4x4:
+ case EHTokHalf1x1:
+ case EHTokHalf1x2:
+ case EHTokHalf1x3:
+ case EHTokHalf1x4:
+ case EHTokHalf2x1:
+ case EHTokHalf2x2:
+ case EHTokHalf2x3:
+ case EHTokHalf2x4:
+ case EHTokHalf3x1:
+ case EHTokHalf3x2:
+ case EHTokHalf3x3:
+ case EHTokHalf3x4:
+ case EHTokHalf4x1:
+ case EHTokHalf4x2:
+ case EHTokHalf4x3:
+ case EHTokHalf4x4:
+ case EHTokDouble1x1:
+ case EHTokDouble1x2:
+ case EHTokDouble1x3:
+ case EHTokDouble1x4:
+ case EHTokDouble2x1:
+ case EHTokDouble2x2:
+ case EHTokDouble2x3:
+ case EHTokDouble2x4:
+ case EHTokDouble3x1:
+ case EHTokDouble3x2:
+ case EHTokDouble3x3:
+ case EHTokDouble3x4:
+ case EHTokDouble4x1:
+ case EHTokDouble4x2:
+ case EHTokDouble4x3:
+ case EHTokDouble4x4:
+ return keyword;
+
+ // texturing types
+ case EHTokSampler:
+ case EHTokSampler1d:
+ case EHTokSampler2d:
+ case EHTokSampler3d:
+ case EHTokSamplerCube:
+ case EHTokSamplerState:
+ case EHTokSamplerComparisonState:
+ case EHTokTexture:
+ case EHTokTexture1d:
+ case EHTokTexture1darray:
+ case EHTokTexture2d:
+ case EHTokTexture2darray:
+ case EHTokTexture3d:
+ case EHTokTextureCube:
+ case EHTokTextureCubearray:
+ case EHTokTexture2DMS:
+ case EHTokTexture2DMSarray:
+ case EHTokRWTexture1d:
+ case EHTokRWTexture1darray:
+ case EHTokRWTexture2d:
+ case EHTokRWTexture2darray:
+ case EHTokRWTexture3d:
+ case EHTokRWBuffer:
+ case EHTokAppendStructuredBuffer:
+ case EHTokByteAddressBuffer:
+ case EHTokConsumeStructuredBuffer:
+ case EHTokRWByteAddressBuffer:
+ case EHTokRWStructuredBuffer:
+ case EHTokStructuredBuffer:
+ case EHTokTextureBuffer:
+ case EHTokSubpassInput:
+ case EHTokSubpassInputMS:
+ return keyword;
+
+ // variable, user type, ...
+ case EHTokClass:
+ case EHTokStruct:
+ case EHTokTypedef:
+ case EHTokCBuffer:
+ case EHTokConstantBuffer:
+ case EHTokTBuffer:
+ case EHTokThis:
+ case EHTokNamespace:
+ return keyword;
+
+ case EHTokBoolConstant:
+ if (strcmp("true", tokenText) == 0)
+ parserToken->b = true;
+ else
+ parserToken->b = false;
+ return keyword;
+
+ // control flow
+ case EHTokFor:
+ case EHTokDo:
+ case EHTokWhile:
+ case EHTokBreak:
+ case EHTokContinue:
+ case EHTokIf:
+ case EHTokElse:
+ case EHTokDiscard:
+ case EHTokReturn:
+ case EHTokCase:
+ case EHTokSwitch:
+ case EHTokDefault:
+ return keyword;
+
+ default:
+ parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
+ return EHTokNone;
+ }
+}
+
+EHlslTokenClass HlslScanContext::identifierOrType()
+{
+ parserToken->string = NewPoolTString(tokenText);
+
+ return EHTokIdentifier;
+}
+
+// Give an error for use of a reserved symbol.
+// However, allow built-in declarations to use reserved words, to allow
+// extension support before the extension is enabled.
+EHlslTokenClass HlslScanContext::reservedWord()
+{
+ if (! parseContext.symbolTable.atBuiltInLevel())
+ parseContext.error(loc, "Reserved word.", tokenText, "", "");
+
+ return EHTokNone;
+}
+
+} // end namespace glslang