GL_EXT_vulkan_glsl_relaxed - retarget gl_VertexID to gl_VertexIndex

instead of allowing for multiple declarations of the variable in the
resulting SPIR-V, instead use a retargeted mechanism to cause references
to gl_VertexID and gl_InstanceID to use the gl_VertexIndex and
gl_InstanceIndex symbol.
diff --git a/Test/baseResults/vk.relaxed.changeSet.vert.out b/Test/baseResults/vk.relaxed.changeSet.vert.out
index f6bce29..d2beff9 100755
--- a/Test/baseResults/vk.relaxed.changeSet.vert.out
+++ b/Test/baseResults/vk.relaxed.changeSet.vert.out
@@ -34,8 +34,8 @@
 0:?     'Color' ( smooth out highp 4-component vector of float)
 0:?     'UV' ( smooth out highp 2-component vector of float)
 0:?     'anon@1' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out unsized 1-element array of float ClipDistance gl_ClipDistance,  out unsized 1-element array of float CullDistance gl_CullDistance})
-0:?     'gl_VertexID' ( in int VertexIndex)
-0:?     'gl_InstanceID' ( in int InstanceIndex)
+0:?     'gl_VertexIndex' ( in int VertexIndex)
+0:?     'gl_InstanceIndex' ( in int InstanceIndex)
 
 vk.relaxed.changeSet.frag
 Shader version: 460
@@ -108,8 +108,8 @@
 0:?     'Color' ( smooth out highp 4-component vector of float)
 0:?     'UV' ( smooth out highp 2-component vector of float)
 0:?     'anon@1' ( out block{ gl_Position 4-component vector of float Position gl_Position,  gl_PointSize float PointSize gl_PointSize,  out 1-element array of float ClipDistance gl_ClipDistance,  out 1-element array of float CullDistance gl_CullDistance})
-0:?     'gl_VertexID' ( in int VertexIndex)
-0:?     'gl_InstanceID' ( in int InstanceIndex)
+0:?     'gl_VertexIndex' ( in int VertexIndex)
+0:?     'gl_InstanceIndex' ( in int InstanceIndex)
 Shader version: 460
 gl_FragCoord origin is upper left
 0:? Sequence
@@ -162,8 +162,8 @@
                               MemberName 28(gl_DefaultUniformBlock) 0  "projectionMatrix"
                               Name 30  ""
                               Name 34  "aPos"
-                              Name 44  "gl_VertexID"
-                              Name 45  "gl_InstanceID"
+                              Name 44  "gl_VertexIndex"
+                              Name 45  "gl_InstanceIndex"
                               Decorate 9(Color) Location 0
                               Decorate 11(aColor) Location 2
                               Decorate 15(UV) Location 1
@@ -180,8 +180,8 @@
                               Decorate 30 DescriptorSet 0
                               Decorate 30 Binding 0
                               Decorate 34(aPos) Location 0
-                              Decorate 44(gl_VertexID) BuiltIn VertexIndex
-                              Decorate 45(gl_InstanceID) BuiltIn InstanceIndex
+                              Decorate 44(gl_VertexIndex) BuiltIn VertexIndex
+                              Decorate 45(gl_InstanceIndex) BuiltIn InstanceIndex
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
@@ -212,8 +212,8 @@
               36:    6(float) Constant 0
               37:    6(float) Constant 1065353216
               43:             TypePointer Input 25(int)
- 44(gl_VertexID):     43(ptr) Variable Input
-45(gl_InstanceID):     43(ptr) Variable Input
+44(gl_VertexIndex):     43(ptr) Variable Input
+45(gl_InstanceIndex):     43(ptr) Variable Input
          4(main):           2 Function None 3
                5:             Label
               12:    7(fvec4) Load 11(aColor)
diff --git a/Test/baseResults/vk.relaxed.errorcheck.vert.out b/Test/baseResults/vk.relaxed.errorcheck.vert.out
index f19eae6..5c6ecf9 100644
--- a/Test/baseResults/vk.relaxed.errorcheck.vert.out
+++ b/Test/baseResults/vk.relaxed.errorcheck.vert.out
@@ -28,8 +28,8 @@
 0:?   Linker Objects
 0:?     'io' (layout( location=0) smooth out highp 4-component vector of float)
 0:?     'anon@0' (layout( column_major std140) uniform block{ uniform highp 2-component vector of float a})
-0:?     'gl_VertexID' ( in int VertexIndex)
-0:?     'gl_InstanceID' ( in int InstanceIndex)
+0:?     'gl_VertexIndex' ( in int VertexIndex)
+0:?     'gl_InstanceIndex' ( in int InstanceIndex)
 
 vk.relaxed.errorcheck.frag
 Shader version: 460
@@ -94,8 +94,8 @@
 0:?   Linker Objects
 0:?     'io' (layout( location=0) smooth out highp 4-component vector of float)
 0:?     'anon@0' (layout( column_major std140) uniform block{ uniform highp 2-component vector of float a})
-0:?     'gl_VertexID' ( in int VertexIndex)
-0:?     'gl_InstanceID' ( in int InstanceIndex)
+0:?     'gl_VertexIndex' ( in int VertexIndex)
+0:?     'gl_InstanceIndex' ( in int InstanceIndex)
 Shader version: 460
 gl_FragCoord origin is upper left
 0:? Sequence
diff --git a/Test/baseResults/vk.relaxed.stagelink.vert.out b/Test/baseResults/vk.relaxed.stagelink.vert.out
index a63f10c..b9173f2 100644
--- a/Test/baseResults/vk.relaxed.stagelink.vert.out
+++ b/Test/baseResults/vk.relaxed.stagelink.vert.out
@@ -93,7 +93,9 @@
 0:28              'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a,  uniform highp 2-component vector of float b2,  uniform highp 2-component vector of float b1,  uniform highp 4-component vector of float c2,  uniform highp 4-component vector of float d,  uniform 4-element array of highp 4-component vector of float s})
 0:28              Constant:
 0:28                5 (const uint)
-0:28            'gl_VertexID' ( in int VertexIndex)
+0:28            subtract ( temp int)
+0:28              'gl_VertexIndex' ( in int VertexIndex)
+0:28              'gl_VertexIndex' ( in int VertexIndex)
 0:29      move second child to first child ( temp highp float)
 0:29        direct index ( temp highp float)
 0:29          'v' ( temp highp 4-component vector of float)
@@ -105,7 +107,9 @@
 0:29            Constant:
 0:29              0 (const int)
 0:29          Convert int to float ( temp highp float)
-0:29            'gl_InstanceID' ( in highp int InstanceIndex)
+0:29            subtract ( temp highp int)
+0:29              'gl_InstanceIndex' ( in highp int InstanceIndex)
+0:29              'gl_InstanceIndex' ( in highp int InstanceIndex)
 0:30      move second child to first child ( temp highp 4-component vector of float)
 0:30        'io' (layout( location=0) smooth out highp 4-component vector of float)
 0:30        'v' ( temp highp 4-component vector of float)
@@ -113,8 +117,8 @@
 0:?     'io' (layout( location=0) smooth out highp 4-component vector of float)
 0:?     'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a,  uniform highp 2-component vector of float b2,  uniform highp 2-component vector of float b1,  uniform highp 4-component vector of float c2,  uniform highp 4-component vector of float d,  uniform 4-element array of highp 4-component vector of float s})
 0:?     'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3,  coherent volatile buffer highp uint counter2})
-0:?     'gl_VertexID' ( in int VertexIndex)
-0:?     'gl_InstanceID' ( in int InstanceIndex)
+0:?     'gl_VertexIndex' ( in int VertexIndex)
+0:?     'gl_InstanceIndex' ( in int InstanceIndex)
 
 vk.relaxed.stagelink.frag
 Shader version: 460
@@ -311,7 +315,9 @@
 0:28              'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a,  uniform highp 2-component vector of float b2,  uniform highp 2-component vector of float b1,  uniform highp 4-component vector of float c2,  uniform highp 4-component vector of float d,  uniform 4-element array of highp 4-component vector of float s})
 0:28              Constant:
 0:28                5 (const uint)
-0:28            'gl_VertexID' ( in int VertexIndex)
+0:28            subtract ( temp int)
+0:28              'gl_VertexIndex' ( in int VertexIndex)
+0:28              'gl_VertexIndex' ( in int VertexIndex)
 0:29      move second child to first child ( temp highp float)
 0:29        direct index ( temp highp float)
 0:29          'v' ( temp highp 4-component vector of float)
@@ -323,7 +329,9 @@
 0:29            Constant:
 0:29              0 (const int)
 0:29          Convert int to float ( temp highp float)
-0:29            'gl_InstanceID' ( in highp int InstanceIndex)
+0:29            subtract ( temp highp int)
+0:29              'gl_InstanceIndex' ( in highp int InstanceIndex)
+0:29              'gl_InstanceIndex' ( in highp int InstanceIndex)
 0:30      move second child to first child ( temp highp 4-component vector of float)
 0:30        'io' (layout( location=0) smooth out highp 4-component vector of float)
 0:30        'v' ( temp highp 4-component vector of float)
@@ -331,8 +339,8 @@
 0:?     'io' (layout( location=0) smooth out highp 4-component vector of float)
 0:?     'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a,  uniform highp 2-component vector of float b2,  uniform highp 2-component vector of float b1,  uniform highp 4-component vector of float c2,  uniform highp 4-component vector of float d,  uniform 4-element array of highp 4-component vector of float s})
 0:?     'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3,  coherent volatile buffer highp uint counter2})
-0:?     'gl_VertexID' ( in int VertexIndex)
-0:?     'gl_InstanceID' ( in int InstanceIndex)
+0:?     'gl_VertexIndex' ( in int VertexIndex)
+0:?     'gl_InstanceIndex' ( in int InstanceIndex)
 Shader version: 460
 gl_FragCoord origin is upper left
 0:? Sequence
@@ -428,12 +436,12 @@
 
 // Module Version 10000
 // Generated by (magic number): 8000a
-// Id's are bound by 88
+// Id's are bound by 92
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Vertex 4  "main" 72 80 86
+                              EntryPoint Vertex 4  "main" 72 82 90
                               Source GLSL 460
                               Name 4  "main"
                               Name 9  "foo("
@@ -454,9 +462,9 @@
                               MemberName 35(gl_DefaultUniformBlock) 6  "c1"
                               Name 37  ""
                               Name 67  "v"
-                              Name 72  "gl_VertexID"
-                              Name 80  "gl_InstanceID"
-                              Name 86  "io"
+                              Name 72  "gl_VertexIndex"
+                              Name 82  "gl_InstanceIndex"
+                              Name 90  "io"
                               MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Coherent
                               MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Volatile
                               MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Coherent
@@ -483,9 +491,9 @@
                               Decorate 35(gl_DefaultUniformBlock) Block
                               Decorate 37 DescriptorSet 0
                               Decorate 37 Binding 0
-                              Decorate 72(gl_VertexID) BuiltIn VertexIndex
-                              Decorate 80(gl_InstanceID) BuiltIn InstanceIndex
-                              Decorate 86(io) Location 0
+                              Decorate 72(gl_VertexIndex) BuiltIn VertexIndex
+                              Decorate 82(gl_InstanceIndex) BuiltIn InstanceIndex
+                              Decorate 90(io) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
@@ -517,31 +525,35 @@
               57:     17(int) Constant 4
               70:     17(int) Constant 5
               71:             TypePointer Input 17(int)
- 72(gl_VertexID):     71(ptr) Variable Input
-              77:             TypePointer Function 6(float)
-80(gl_InstanceID):     71(ptr) Variable Input
-              85:             TypePointer Output 7(fvec4)
-          86(io):     85(ptr) Variable Output
+72(gl_VertexIndex):     71(ptr) Variable Input
+              79:             TypePointer Function 6(float)
+82(gl_InstanceIndex):     71(ptr) Variable Input
+              89:             TypePointer Output 7(fvec4)
+          90(io):     89(ptr) Variable Output
          4(main):           2 Function None 3
                5:             Label
            67(v):     30(ptr) Variable Function
               68:    7(fvec4) FunctionCall 9(foo()
                               Store 67(v) 68
               69:    7(fvec4) Load 67(v)
-              73:     17(int) Load 72(gl_VertexID)
-              74:     38(ptr) AccessChain 37 70 73
-              75:    7(fvec4) Load 74
-              76:    7(fvec4) FAdd 69 75
-                              Store 67(v) 76
-              78:     77(ptr) AccessChain 67(v) 22
-              79:    6(float) Load 78
-              81:     17(int) Load 80(gl_InstanceID)
-              82:    6(float) ConvertSToF 81
-              83:    6(float) FSub 79 82
-              84:     77(ptr) AccessChain 67(v) 22
-                              Store 84 83
-              87:    7(fvec4) Load 67(v)
-                              Store 86(io) 87
+              73:     17(int) Load 72(gl_VertexIndex)
+              74:     17(int) Load 72(gl_VertexIndex)
+              75:     17(int) ISub 73 74
+              76:     38(ptr) AccessChain 37 70 75
+              77:    7(fvec4) Load 76
+              78:    7(fvec4) FAdd 69 77
+                              Store 67(v) 78
+              80:     79(ptr) AccessChain 67(v) 22
+              81:    6(float) Load 80
+              83:     17(int) Load 82(gl_InstanceIndex)
+              84:     17(int) Load 82(gl_InstanceIndex)
+              85:     17(int) ISub 83 84
+              86:    6(float) ConvertSToF 85
+              87:    6(float) FSub 81 86
+              88:     79(ptr) AccessChain 67(v) 22
+                              Store 88 87
+              91:    7(fvec4) Load 67(v)
+                              Store 90(io) 91
                               Return
                               FunctionEnd
          9(foo():    7(fvec4) Function None 8
diff --git a/Test/vk.relaxed.stagelink.vert b/Test/vk.relaxed.stagelink.vert
index 52396ac..d2ac6af 100644
--- a/Test/vk.relaxed.stagelink.vert
+++ b/Test/vk.relaxed.stagelink.vert
@@ -25,7 +25,7 @@
 void main() {

 

     vec4 v = foo();

-    v = v + s[gl_VertexID];

-    v.x = v.x - float(gl_InstanceID);

+    v = v + s[gl_VertexID - gl_VertexIndex];

+    v.x = v.x - float(gl_InstanceID - gl_InstanceIndex);

     io = v;

-}
\ No newline at end of file
+}

diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 823406c..ee4e2ca 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -7701,6 +7701,11 @@
     symQualifier.builtIn = builtIn;
 }
 
+static void RetargetVariable(const char* from, const char* to, TSymbolTable& symbolTable)
+{
+    symbolTable.retargetSymbol(from, to);
+}
+
 //
 // For built-in variables inside a named block.
 // SpecialQualifier() won't ever go inside a block; their member's qualifier come
@@ -7768,8 +7773,8 @@
 
         if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
             // treat these built-ins as aliases of VertexIndex and InstanceIndex
-            BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
-            BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
+            RetargetVariable("gl_InstanceID", "gl_InstanceIndex", symbolTable);
+            RetargetVariable("gl_VertexID", "gl_VertexIndex", symbolTable);
         }
 
         if (profile != EEsProfile) {
diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp
index 747b436..5b7e27f 100644
--- a/glslang/MachineIndependent/SymbolTable.cpp
+++ b/glslang/MachineIndependent/SymbolTable.cpp
@@ -279,8 +279,14 @@
 //
 TSymbolTableLevel::~TSymbolTableLevel()
 {
-    for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
-        delete (*it).second;
+    for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
+        const TString& name = it->first;
+        auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
+                                      [&name](const std::pair<TString, TString>& i) { return i.first == name; });
+        if (retargetIter == retargetedSymbols.end())
+            delete (*it).second;
+    }
+
 
     delete [] defaultPrecision;
 }
@@ -418,6 +424,15 @@
     TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
     symTableLevel->anonId = anonId;
     symTableLevel->thisLevel = thisLevel;
+    symTableLevel->retargetedSymbols.clear();
+    for (auto &s : retargetedSymbols) {
+        // Extra constructions to make sure they use the correct allocator pool
+        TString newFrom;
+        newFrom = s.first;
+        TString newTo;
+        newTo = s.second;
+        symTableLevel->retargetedSymbols.push_back({std::move(newFrom), std::move(newTo)});
+    }
     std::vector<bool> containerCopied(anonId, false);
     tLevel::const_iterator iter;
     for (iter = level.begin(); iter != level.end(); ++iter) {
@@ -433,8 +448,25 @@
                 symTableLevel->insert(*container, false);
                 containerCopied[anon->getAnonId()] = true;
             }
-        } else
+        } else {
+            const TString& name = iter->first;
+            auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
+                                          [&name](const std::pair<TString, TString>& i) { return i.first == name; });
+            if (retargetIter != retargetedSymbols.end())
+                continue;
             symTableLevel->insert(*iter->second->clone(), false);
+        }
+    }
+    // Now point retargeted symbols to the newly created versions of them
+    for (auto &s : retargetedSymbols) {
+        TSymbol* sym = symTableLevel->find(s.second);
+        if (!sym)
+            continue;
+
+        // Need to declare and assign so newS is using the correct pool allocator
+        TString newS;
+        newS = s.first;
+        symTableLevel->insert(newS, sym);
     }
 
     return symTableLevel;
diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h
index 2196093..720999a 100644
--- a/glslang/MachineIndependent/SymbolTable.h
+++ b/glslang/MachineIndependent/SymbolTable.h
@@ -413,13 +413,20 @@
     TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
     ~TSymbolTableLevel();
 
-    bool insert(TSymbol& symbol, bool separateNameSpaces)
+    bool insert(const TString& name, TSymbol* symbol) {
+        return level.insert(tLevelPair(name, symbol)).second;
+    }
+
+    bool insert(TSymbol& symbol, bool separateNameSpaces, const TString& forcedKeyName = TString())
     {
         //
         // returning true means symbol was added to the table with no semantic errors
         //
         const TString& name = symbol.getName();
-        if (name == "") {
+        if (forcedKeyName.length()) {
+            return level.insert(tLevelPair(forcedKeyName, &symbol)).second;
+        }
+        else if (name == "") {
             symbol.getAsVariable()->setAnonId(anonId++);
             // An empty name means an anonymous container, exposing its members to the external scope.
             // Give it a name and insert its members in the symbol table, pointing to the container.
@@ -471,6 +478,16 @@
         return true;
     }
 
+    void retargetSymbol(const TString& from, const TString& to) {
+        tLevel::const_iterator fromIt = level.find(from);
+        tLevel::const_iterator toIt = level.find(to);
+        if (fromIt == level.end() || toIt == level.end())
+            return;
+        delete fromIt->second;
+        level[from] = toIt->second;
+        retargetedSymbols.push_back({from, to});
+    }
+
     TSymbol* find(const TString& name) const
     {
         tLevel::const_iterator it = level.find(name);
@@ -583,6 +600,8 @@
 
     tLevel level;  // named mappings
     TPrecisionQualifier *defaultPrecision;
+    // pair<FromName, ToName>
+    TVector<std::pair<TString, TString>> retargetedSymbols;
     int anonId;
     bool thisLevel;  // True if this level of the symbol table is a structure scope containing member function
                      // that are supposed to see anonymous access to member variables.
@@ -788,6 +807,12 @@
         return symbol;
     }
 
+    void retargetSymbol(const TString& from, const TString& to) {
+        int level = currentLevel();
+        table[level]->retargetSymbol(from, to);
+    }
+
+
     // Find of a symbol that returns how many layers deep of nested
     // structures-with-member-functions ('this' scopes) deep the symbol was
     // found in.