translator: Store symbol type in TField.

This allows us to keep a separate symbol type for each field in a
struct. This can allow us to assign internal names to struct types.
It could also allow us to add internal fields to user defined stucts.

Bug: angleproject:2665
Change-Id: I6a129107d9db66c54b98b07684c3ead5801712ba
Reviewed-on: https://chromium-review.googlesource.com/1101565
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 14140eb..ea25855 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -581,7 +581,7 @@
                 const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
                 const TField *field               = structure->fields()[index->getIConst(0)];
 
-                out << hashFieldName(structure, field->name());
+                out << hashFieldName(field);
                 visitChildren = false;
             }
             break;
@@ -595,7 +595,7 @@
                 const TField *field               = interfaceBlock->fields()[index->getIConst(0)];
                 ASSERT(interfaceBlock->symbolType() == SymbolType::UserDefined ||
                        interfaceBlock->name() == "gl_PerVertex");
-                out << hashFieldName(interfaceBlock, field->name());
+                out << hashFieldName(field);
                 visitChildren = false;
             }
             break;
@@ -1115,18 +1115,15 @@
     return HashName(symbol, mHashFunction, &mNameMap);
 }
 
-ImmutableString TOutputGLSLBase::hashFieldName(const TSymbol *containingStruct,
-                                               const ImmutableString &fieldName)
+ImmutableString TOutputGLSLBase::hashFieldName(const TField *field)
 {
-    if (containingStruct->symbolType() == SymbolType::UserDefined ||
-        containingStruct->symbolType() == SymbolType::Empty)
+    ASSERT(field->symbolType() != SymbolType::Empty);
+    if (field->symbolType() == SymbolType::UserDefined)
     {
-        return HashName(fieldName, mHashFunction, &mNameMap);
+        return HashName(field->name(), mHashFunction, &mNameMap);
     }
-    else
-    {
-        return fieldName;
-    }
+
+    return field->name();
 }
 
 ImmutableString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunction *func)
@@ -1169,7 +1166,7 @@
         const TField *field = fields[i];
         if (writeVariablePrecision(field->type()->getPrecision()))
             out << " ";
-        out << getTypeName(*field->type()) << " " << hashFieldName(structure, field->name());
+        out << getTypeName(*field->type()) << " " << hashFieldName(field);
         if (field->type()->isArray())
             out << ArrayString(*field->type());
         out << ";\n";
@@ -1254,7 +1251,7 @@
 
         if (writeVariablePrecision(field->type()->getPrecision()))
             out << " ";
-        out << getTypeName(*field->type()) << " " << hashFieldName(interfaceBlock, field->name());
+        out << getTypeName(*field->type()) << " " << hashFieldName(field);
         if (field->type()->isArray())
             out << ArrayString(*field->type());
         out << ";\n";
diff --git a/src/compiler/translator/OutputGLSLBase.h b/src/compiler/translator/OutputGLSLBase.h
index 20c2146..da11d1b 100644
--- a/src/compiler/translator/OutputGLSLBase.h
+++ b/src/compiler/translator/OutputGLSLBase.h
@@ -69,8 +69,7 @@
 
     void visitCodeBlock(TIntermBlock *node);
 
-    ImmutableString hashFieldName(const TSymbol *containingStruct,
-                                  const ImmutableString &fieldName);
+    ImmutableString hashFieldName(const TField *field);
     // Same as hashName(), but without hashing "main".
     ImmutableString hashFunctionNameIfNeeded(const TFunction *func);
     // Used to translate function names for differences between ESSL and GLSL
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index e3df66a..f8df136 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -4714,7 +4714,8 @@
             type->makeArrays(*declarator->arraySizes());
         }
 
-        TField *field = new TField(type, declarator->name(), declarator->line());
+        TField *field =
+            new TField(type, declarator->name(), declarator->line(), SymbolType::UserDefined);
         checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *field);
         fieldList->push_back(field);
     }
diff --git a/src/compiler/translator/Symbol.h b/src/compiler/translator/Symbol.h
index e4fbd45..cd6a3fc 100644
--- a/src/compiler/translator/Symbol.h
+++ b/src/compiler/translator/Symbol.h
@@ -20,22 +20,6 @@
 
 class TSymbolTable;
 
-enum class SymbolType
-{
-    BuiltIn,
-    UserDefined,
-    AngleInternal,
-    Empty  // Meaning symbol without a name.
-};
-
-enum class SymbolClass
-{
-    Function,
-    Variable,
-    Struct,
-    InterfaceBlock
-};
-
 // Symbol base class. (Can build functions or variables out of these...)
 class TSymbol : angle::NonCopyable
 {
diff --git a/src/compiler/translator/SymbolTable_autogen.cpp b/src/compiler/translator/SymbolTable_autogen.cpp
index 71cf356..07f752b 100644
--- a/src/compiler/translator/SymbolTable_autogen.cpp
+++ b/src/compiler/translator/SymbolTable_autogen.cpp
@@ -10344,12 +10344,15 @@
 {
     const TSourceLoc zeroSourceLoc             = {0, 0, 0, 0};
     TFieldList *fields_gl_DepthRangeParameters = new TFieldList();
-    fields_gl_DepthRangeParameters->push_back(new TField(
-        new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::near, zeroSourceLoc));
     fields_gl_DepthRangeParameters->push_back(
-        new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::far, zeroSourceLoc));
-    fields_gl_DepthRangeParameters->push_back(new TField(
-        new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::diff, zeroSourceLoc));
+        new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::near, zeroSourceLoc,
+                   SymbolType::BuiltIn));
+    fields_gl_DepthRangeParameters->push_back(
+        new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::far, zeroSourceLoc,
+                   SymbolType::BuiltIn));
+    fields_gl_DepthRangeParameters->push_back(
+        new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::diff, zeroSourceLoc,
+                   SymbolType::BuiltIn));
     TStructure *gl_DepthRangeParameters =
         new TStructure(BuiltInId::gl_DepthRangeParameters, BuiltInName::gl_DepthRangeParameters,
                        TExtension::UNDEFINED, fields_gl_DepthRangeParameters);
@@ -10789,7 +10792,8 @@
         TExtension::NV_shader_framebuffer_fetch, type_gl_LastFragDataNV);
     TFieldList *fields_gl_PerVertex = new TFieldList();
     fields_gl_PerVertex->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
-                                              BuiltInName::gl_Position, zeroSourceLoc));
+                                              BuiltInName::gl_Position, zeroSourceLoc,
+                                              SymbolType::BuiltIn));
     TInterfaceBlock *gl_PerVertex =
         new TInterfaceBlock(BuiltInId::gl_PerVertex, BuiltInName::gl_PerVertex,
                             TExtension::EXT_geometry_shader, fields_gl_PerVertex);
@@ -10803,8 +10807,9 @@
                                    TExtension::EXT_geometry_shader, type_gl_in);
     }
     TFieldList *fields_gl_PerVertexOutBlock = new TFieldList();
-    fields_gl_PerVertexOutBlock->push_back(new TField(
-        new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position, zeroSourceLoc));
+    fields_gl_PerVertexOutBlock->push_back(
+        new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+                   zeroSourceLoc, SymbolType::BuiltIn));
     TInterfaceBlock *gl_PerVertexOutBlock =
         new TInterfaceBlock(BuiltInId::gl_PerVertexOutBlock, BuiltInName::gl_PerVertex,
                             TExtension::EXT_geometry_shader, fields_gl_PerVertexOutBlock);
diff --git a/src/compiler/translator/SymbolUniqueId.h b/src/compiler/translator/SymbolUniqueId.h
index 55a59ca..c9b7648 100644
--- a/src/compiler/translator/SymbolUniqueId.h
+++ b/src/compiler/translator/SymbolUniqueId.h
@@ -37,6 +37,22 @@
     int mId;
 };
 
+enum class SymbolType
+{
+    BuiltIn,
+    UserDefined,
+    AngleInternal,
+    Empty  // Meaning symbol without a name.
+};
+
+enum class SymbolClass
+{
+    Function,
+    Variable,
+    Struct,
+    InterfaceBlock
+};
+
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
diff --git a/src/compiler/translator/Types.h b/src/compiler/translator/Types.h
index 102fabe..3a7be65 100644
--- a/src/compiler/translator/Types.h
+++ b/src/compiler/translator/Types.h
@@ -31,9 +31,10 @@
 {
   public:
     POOL_ALLOCATOR_NEW_DELETE();
-    TField(TType *type, const ImmutableString &name, const TSourceLoc &line)
-        : mType(type), mName(name), mLine(line)
+    TField(TType *type, const ImmutableString &name, const TSourceLoc &line, SymbolType symbolType)
+        : mType(type), mName(name), mLine(line), mSymbolType(symbolType)
     {
+        ASSERT(mSymbolType != SymbolType::Empty);
     }
 
     // TODO(alokp): We should only return const type.
@@ -42,11 +43,13 @@
     const TType *type() const { return mType; }
     const ImmutableString &name() const { return mName; }
     const TSourceLoc &line() const { return mLine; }
+    SymbolType symbolType() const { return mSymbolType; }
 
   private:
     TType *mType;
     const ImmutableString mName;
     const TSourceLoc mLine;
+    const SymbolType mSymbolType;
 };
 
 typedef TVector<TField *> TFieldList;
diff --git a/src/compiler/translator/builtin_symbols_hash_autogen.txt b/src/compiler/translator/builtin_symbols_hash_autogen.txt
index 93a9158..4f8389f 100644
--- a/src/compiler/translator/builtin_symbols_hash_autogen.txt
+++ b/src/compiler/translator/builtin_symbols_hash_autogen.txt
@@ -1 +1 @@
-e7cb1a4f677413aec61815b10019f608
\ No newline at end of file
+35ac43f73bd7b675a938f550d518ea8f
\ No newline at end of file
diff --git a/src/compiler/translator/gen_builtin_symbols.py b/src/compiler/translator/gen_builtin_symbols.py
index c201eb5..abbb948 100644
--- a/src/compiler/translator/gen_builtin_symbols.py
+++ b/src/compiler/translator/gen_builtin_symbols.py
@@ -1133,7 +1133,7 @@
                 template_args['field_type'] = TType(field_type).get_dynamic_type_string()
                 template_name_declaration = 'constexpr const ImmutableString {field_name}("{field_name}");'
                 name_declarations.add(template_name_declaration.format(**template_args))
-                template_add_field = '    {fields}->push_back(new TField({field_type}, BuiltInName::{field_name}, zeroSourceLoc));'
+                template_add_field = '    {fields}->push_back(new TField({field_type}, BuiltInName::{field_name}, zeroSourceLoc, SymbolType::BuiltIn));'
                 init_member_variables.append(template_add_field.format(**template_args))
             template_init_temp_variable = '    {class} *{name_with_suffix} = new {class}(BuiltInId::{name_with_suffix}, BuiltInName::{name}, TExtension::{extension}, {fields});'
             init_member_variables.append(template_init_temp_variable.format(**template_args))