Support multiple source languages, adding HLSL as an option.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 7a7baa2..1c6abec 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -160,15 +160,22 @@
 //
 
 // Translate glslang profile to SPIR-V source language.
-spv::SourceLanguage TranslateSourceLanguage(EProfile profile)
+spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile)
 {
-    switch (profile) {
-    case ENoProfile:
-    case ECoreProfile:
-    case ECompatibilityProfile:
-        return spv::SourceLanguageGLSL;
-    case EEsProfile:
-        return spv::SourceLanguageESSL;
+    switch (source) {
+    case glslang::EShSourceGlsl:
+        switch (profile) {
+        case ENoProfile:
+        case ECoreProfile:
+        case ECompatibilityProfile:
+            return spv::SourceLanguageGLSL;
+        case EEsProfile:
+            return spv::SourceLanguageESSL;
+        default:
+            return spv::SourceLanguageUnknown;
+        }
+    case glslang::EShSourceHlsl:
+        return spv::SourceLanguageHLSL;
     default:
         return spv::SourceLanguageUnknown;
     }
@@ -587,7 +594,7 @@
     spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage());
 
     builder.clearAccessChain();
-    builder.setSource(TranslateSourceLanguage(glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
+    builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
     stdBuiltins = builder.import("GLSL.std.450");
     builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
     shaderEntry = builder.makeEntrypoint(glslangIntermediate->getEntryPoint().c_str());
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index 7cf1c87..7ee86b5 100755
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -64,7 +64,7 @@
 //    (for non-sparse mask enums, this is the number of enumurants)
 //
 
-const int SourceLanguageCeiling = 5;
+const int SourceLanguageCeiling = 6; // HLSL todo: need official enumerant
 
 const char* SourceString(int source)
 {
@@ -74,6 +74,7 @@
     case 2:  return "GLSL";
     case 3:  return "OpenCL_C";
     case 4:  return "OpenCL_CPP";
+    case 5:  return "HLSL";
 
     case SourceLanguageCeiling:
     default: return "Bad";
diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp
index 5620aba..7447fcf 100755
--- a/SPIRV/spirv.hpp
+++ b/SPIRV/spirv.hpp
@@ -61,6 +61,7 @@
     SourceLanguageGLSL = 2,

     SourceLanguageOpenCL_C = 3,

     SourceLanguageOpenCL_CPP = 4,

+    SourceLanguageHLSL = 5,

 };

 

 enum ExecutionModel {

diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 408f114..2e0db6d 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -74,6 +74,7 @@
     EOptionVulkanRules        = 0x2000,
     EOptionDefaultDesktop     = 0x4000,
     EOptionOutputPreprocessed = 0x8000,
+    EOptionReadHlsl          = 0x10000,
 };
 
 //
@@ -538,6 +539,9 @@
             case 'd':
                 Options |= EOptionDefaultDesktop;
                 break;
+            case 'D':
+                Options |= EOptionReadHlsl;
+                break;
             case 'e':
                 // HLSL todo: entry point handle needs much more sophistication.
                 // This is okay for one compilation unit with one entry point.
@@ -627,6 +631,8 @@
         messages = (EShMessages)(messages | EShMsgVulkanRules);
     if (Options & EOptionOutputPreprocessed)
         messages = (EShMessages)(messages | EShMsgOnlyPreprocessor);
+    if (Options & EOptionReadHlsl)
+        messages = (EShMessages)(messages | EShMsgReadHlsl);
 }
 
 //
@@ -1047,6 +1053,7 @@
            "              creates the default configuration file (redirect to a .conf file)\n"
            "  -d          default to desktop (#version 110) when there is no shader #version\n"
            "              (default is ES version 100)\n"
+           "  -D          input is HLSL\n"
            "  -e          specify entry-point name\n"
            "  -h          print this usage message\n"
            "  -i          intermediate tree (glslang AST) is printed out\n"
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index 4b2bf83..230929a 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -307,11 +307,19 @@
     glslang::ReleaseGlobalLock();
 }
 
-bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion, int& version, EProfile& profile, int spv)
+// Return true if the shader was correctly specified for version/profile/stage.
+bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion,
+                          EShSource source, int& version, EProfile& profile, int spv)
 {
     const int FirstProfileVersion = 150;
     bool correct = true;
 
+    if (source == EShSourceHlsl) {
+        version = defaultVersion;
+        profile = ENoProfile;
+        return correct;
+    }
+
     // Get a good version...
     if (version == 0) {
         version = defaultVersion;
@@ -552,7 +560,8 @@
     }
 
     int spv = (messages & EShMsgSpvRules) ? 100 : 0;         // TODO find path to get real version number here, for now non-0 is what matters
-    bool goodVersion = DeduceVersionProfile(compiler->infoSink, compiler->getLanguage(), versionNotFirst, defaultVersion, version, profile, spv);
+    EShSource source = (messages & EShMsgReadHlsl) ? EShSourceHlsl : EShSourceGlsl;
+    bool goodVersion = DeduceVersionProfile(compiler->infoSink, compiler->getLanguage(), versionNotFirst, defaultVersion, source, version, profile, spv);
     bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
     bool warnVersionNotFirst = false;
     if (! versionWillBeError && versionNotFirstToken) {
@@ -563,6 +572,7 @@
     }
 
     int vulkan = (messages & EShMsgVulkanRules) ? 100 : 0;     // TODO find path to get real version number here, for now non-0 is what matters
+    intermediate.setSource(source);
     intermediate.setVersion(version);
     intermediate.setProfile(profile);
     intermediate.setSpv(spv);
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index b1e833b..efffb71 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -124,7 +124,8 @@
 //
 class TIntermediate {
 public:
-    explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), spv(0),
+    explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
+        source(EShSourceNone), language(l), profile(p), version(v), spv(0), treeRoot(0),
         numMains(0), numErrors(0), numPushConstants(0), recursive(false),
         invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), inputPrimitive(ElgNone), outputPrimitive(ElgNone),
         pixelCenterInteger(false), originUpperLeft(false),
@@ -143,8 +144,10 @@
 
     bool postProcess(TIntermNode*, EShLanguage);
     void output(TInfoSink&, bool tree);
-	void removeTree();
+    void removeTree();
 
+    void setSource(EShSource s) { source = s; }
+    EShSource getSource() const { return source; }
     void setEntryPoint(const char* ep) { entryPoint = ep; }
     const TString& getEntryPoint() const { return entryPoint; }
     void setVersion(int v) { version = v; }
@@ -339,12 +342,13 @@
     bool userOutputUsed() const;
     static int getBaseAlignmentScalar(const TType&, int& size);
 
-    const EShLanguage language;
+    const EShLanguage language;  // stage, known at construction time
+    EShSource source;            // source language, known a bit later
     TString entryPoint;
-    TIntermNode* treeRoot;
     EProfile profile;
     int version;
     int spv;
+    TIntermNode* treeRoot;
     std::set<std::string> requestedExtensions;  // cumulation of all enabled or required extensions; not connected to what subset of the shader used them
     TBuiltInResource resources;
     int numMains;
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index 7a708f2..e676211 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -86,7 +86,7 @@
     EShLangFragment,
     EShLangCompute,
     EShLangCount,
-} EShLanguage;
+} EShLanguage;         // would be better as stage, but this is ancient now
 
 typedef enum {
     EShLangVertexMask         = (1 << EShLangVertex),
@@ -99,6 +99,12 @@
 
 namespace glslang {
 
+typedef enum {
+    EShSourceNone,
+    EShSourceGlsl,
+    EShSourceHlsl,
+} EShSource;          // if EShLanguage were EShStage, this could be EShLanguage instead
+
 const char* StageName(EShLanguage);
 
 } // end namespace glslang
@@ -132,6 +138,7 @@
     EShMsgSpvRules         = (1 << 3),  // issue messages for SPIR-V generation
     EShMsgVulkanRules      = (1 << 4),  // issue messages for Vulkan-requirements of GLSL for SPIR-V
     EShMsgOnlyPreprocessor = (1 << 5),  // only print out errors produced by the preprocessor
+    EShMsgReadHlsl         = (1 << 6),  // use HLSL parsing rules and semantics
 };
 
 //