Generalize "main" to a settable entry point name.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 8c1c84f..7a7baa2 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -590,8 +590,8 @@
     builder.setSource(TranslateSourceLanguage(glslangIntermediate->getProfile()), glslangIntermediate->getVersion());
     stdBuiltins = builder.import("GLSL.std.450");
     builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
-    shaderEntry = builder.makeMain();
-    entryPoint = builder.addEntryPoint(executionModel, shaderEntry, "main");
+    shaderEntry = builder.makeEntrypoint(glslangIntermediate->getEntryPoint().c_str());
+    entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPoint().c_str());
 
     // Add the source extensions
     const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
@@ -2082,7 +2082,9 @@
 
 bool TGlslangToSpvTraverser::isShaderEntrypoint(const glslang::TIntermAggregate* node)
 {
-    return node->getName() == "main(";
+    // have to ignore mangling and just look at the base name
+    int firstOpen = node->getName().find('(');
+    return node->getName().compare(0, firstOpen, glslangIntermediate->getEntryPoint()) == 0;
 }
 
 // Make all the functions, skeletally, without actually visiting their bodies.
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 336d3de..06d7a02 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -893,7 +893,7 @@
 }
 
 // Comments in header
-Function* Builder::makeMain()
+Function* Builder::makeEntrypoint(const char* entryPoint)
 {
     assert(! mainFunction);
 
@@ -901,7 +901,7 @@
     std::vector<Id> params;
     std::vector<Decoration> precisions;
 
-    mainFunction = makeFunctionEntry(NoPrecision, makeVoidType(), "main", params, precisions, &entry);
+    mainFunction = makeFunctionEntry(NoPrecision, makeVoidType(), entryPoint, params, precisions, &entry);
 
     return mainFunction;
 }
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index e16ba38..162e79e 100755
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -205,9 +205,9 @@
     void setBuildPoint(Block* bp) { buildPoint = bp; }
     Block* getBuildPoint() const { return buildPoint; }
 
-    // Make the main function. The returned pointer is only valid
+    // Make the entry-point function. The returned pointer is only valid
     // for the lifetime of this builder.
-    Function* makeMain();
+    Function* makeEntrypoint(const char*);
 
     // Make a shader-style function, and create its entry block if entry is non-zero.
     // Return the function, pass back the entry.
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index cc59d38..408f114 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -449,6 +449,7 @@
 int Options = 0;
 const char* ExecutableName = nullptr;
 const char* binaryFileName = nullptr;
+const char* entryPointName = nullptr;
 
 //
 // Create the default name for saving a binary if -o is not provided.
@@ -537,6 +538,16 @@
             case 'd':
                 Options |= EOptionDefaultDesktop;
                 break;
+            case 'e':
+                // HLSL todo: entry point handle needs much more sophistication.
+                // This is okay for one compilation unit with one entry point.
+                entryPointName = argv[1];
+                if (argc > 0) {
+                    argc--;
+                    argv++;
+                } else
+                    Error("no <entry-point> provided for -e");
+                break;
             case 'h':
                 usage();
                 break;
@@ -693,6 +704,8 @@
         const auto &compUnit = *it;
         glslang::TShader* shader = new glslang::TShader(compUnit.stage);
         shader->setStrings(compUnit.text, 1);
+        if (entryPointName) // HLSL todo: this needs to be tracked per compUnits
+            shader->setEntryPoint(entryPointName);
         shaders.push_back(shader);
 
         const int defaultVersion = Options & EOptionDefaultDesktop? 110: 100;
@@ -726,20 +739,24 @@
     // Program-level processing...
     //
 
+    // Link
     if (! (Options & EOptionOutputPreprocessed) && ! program.link(messages))
         LinkFailed = true;
 
+    // Report
     if (! (Options & EOptionSuppressInfolog) &&
         ! (Options & EOptionMemoryLeakMode)) {
         PutsIfNonEmpty(program.getInfoLog());
         PutsIfNonEmpty(program.getInfoDebugLog());
     }
 
+    // Reflect
     if (Options & EOptionDumpReflection) {
         program.buildReflection();
         program.dumpReflection();
     }
 
+    // Dump SPIR-V
     if (Options & EOptionSpv) {
         if (CompileFailed || LinkFailed)
             printf("SPIR-V is not generated for failed compile or link\n");
@@ -1030,6 +1047,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"
+           "  -e          specify entry-point name\n"
            "  -h          print this usage message\n"
            "  -i          intermediate tree (glslang AST) is printed out\n"
            "  -l          link all input files together to form a single module\n"
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 8cee3e4..a43df95 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -975,7 +975,7 @@
     //
     // Raise error message if main function takes any parameters or returns anything other than void
     //
-    if (function.getName() == "main") {
+    if (function.getName() == intermediate.getEntryPoint()) {
         if (function.getParamCount() > 0)
             error(loc, "function cannot take any parameter(s)", function.getName().c_str(), "");
         if (function.getType().getBasicType() != EbtVoid)
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index 1f83553..4b2bf83 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -588,6 +588,7 @@
     // Now we can process the full shader under proper symbols and rules.
     //
 
+    intermediate.setEntryPoint("main");
     TParseContext parseContext(symbolTable, intermediate, false, version, profile, spv, vulkan, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
     glslang::TScanContext scanContext(parseContext);
     TPpContext ppContext(parseContext, includer);
@@ -1355,6 +1356,11 @@
     stringNames = names;
 }
 
+void TShader::setEntryPoint(const char* entryPoint)
+{
+    intermediate->setEntryPoint(entryPoint);
+}
+
 //
 // Turn the shader strings into a parse tree in the TIntermediate.
 //
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index 9926747..b1e833b 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -145,6 +145,8 @@
     void output(TInfoSink&, bool tree);
 	void removeTree();
 
+    void setEntryPoint(const char* ep) { entryPoint = ep; }
+    const TString& getEntryPoint() const { return entryPoint; }
     void setVersion(int v) { version = v; }
     int getVersion() const { return version; }
     void setProfile(EProfile p) { profile = p; }
@@ -338,6 +340,7 @@
     static int getBaseAlignmentScalar(const TType&, int& size);
 
     const EShLanguage language;
+    TString entryPoint;
     TIntermNode* treeRoot;
     EProfile profile;
     int version;
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index 702b66f..7a708f2 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -290,6 +290,7 @@
     void setStringsWithLengthsAndNames(
         const char* const* s, const int* l, const char* const* names, int n);
     void setPreamble(const char* s) { preamble = s; }
+    void setEntryPoint(const char* entryPoint);
 
     // Interface to #include handlers.
     class Includer {