Clean up inserting variables to symbol table

This makes the TSymbolTable interface cleaner and prepares for making
unique id counting thread-safe.

BUG=angleproject:624
TEST=angle_unittests

Change-Id: Ief99c9fc777603de28ba1517e351bc8a00633590
Reviewed-on: https://chromium-review.googlesource.com/570418
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index 48c2dfe..97615d9 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -83,21 +83,12 @@
     TString extension;
 };
 
-// Variable class, meaning a symbol that's not a function.
+// Variable, meaning a symbol that's not a function.
 //
-// There could be a separate class heirarchy for Constant variables;
-// Only one of int, bool, or float, (or none) is correct for
-// any particular use, but it's easy to do this way, and doesn't
-// seem worth having separate classes, and "getConst" can't simply return
-// different values for different types polymorphically, so this is
-// just simple and pragmatic.
+// May store the value of a constant variable of any type (float, int, bool or struct).
 class TVariable : public TSymbol
 {
   public:
-    TVariable(const TString *name, const TType &t, bool uT = false)
-        : TSymbol(name), type(t), userType(uT), unionArray(0)
-    {
-    }
     ~TVariable() override {}
     bool isVariable() const override { return true; }
     TType &getType() { return type; }
@@ -110,8 +101,18 @@
     void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
 
   private:
+    friend class TSymbolTable;
+
+    TVariable(const TString *name, const TType &t, bool isUserTypeDefinition = false)
+        : TSymbol(name), type(t), userType(isUserTypeDefinition), unionArray(0)
+    {
+    }
+
     TType type;
+
+    // Set to true if this represents a struct type, as opposed to a variable.
     bool userType;
+
     // we are assuming that Pool Allocator will free the memory
     // allocated to unionArray when this object is destroyed.
     const TConstantUnion *unionArray;
@@ -224,9 +225,11 @@
 class TInterfaceBlockName : public TSymbol
 {
   public:
-    TInterfaceBlockName(const TString *name) : TSymbol(name) {}
-
     virtual ~TInterfaceBlockName() {}
+
+  private:
+    friend class TSymbolTable;
+    TInterfaceBlockName(const TString *name) : TSymbol(name) {}
 };
 
 class TSymbolTableLevel
@@ -319,15 +322,22 @@
         precisionStack.pop_back();
     }
 
-    bool declare(TSymbol *symbol) { return insert(currentLevel(), symbol); }
+    // The declare* entry points are used when parsing and declare symbols at the current scope.
+    // They return the created symbol in case the declaration was successful, and nullptr if the
+    // declaration failed due to redefinition.
+    TVariable *declareVariable(const TString *name, const TType &type);
+    TVariable *declareStructType(TStructure *str);
+    TInterfaceBlockName *declareInterfaceBlockName(const TString *name);
 
-    bool insert(ESymbolLevel level, TSymbol *symbol) { return table[level]->insert(symbol); }
-
-    bool insert(ESymbolLevel level, const char *ext, TSymbol *symbol)
-    {
-        symbol->relateToExtension(ext);
-        return table[level]->insert(symbol);
-    }
+    // The insert* entry points are used when initializing the symbol table with built-ins.
+    // They return the created symbol in case the declaration was successful, and nullptr if the
+    // declaration failed due to redefinition.
+    TVariable *insertVariable(ESymbolLevel level, const char *name, const TType &type);
+    TVariable *insertVariableExt(ESymbolLevel level,
+                                 const char *ext,
+                                 const char *name,
+                                 const TType &type);
+    TVariable *insertStructType(ESymbolLevel level, TStructure *str);
 
     bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision)
     {
@@ -444,8 +454,6 @@
         return table[currentLevel() - 1];
     }
 
-    void dump(TInfoSink &infoSink) const;
-
     void setDefaultPrecision(TBasicType type, TPrecision prec)
     {
         int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
@@ -488,6 +496,16 @@
   private:
     ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
 
+    TVariable *insertVariable(ESymbolLevel level, const TString *name, const TType &type);
+
+    bool insert(ESymbolLevel level, TSymbol *symbol) { return table[level]->insert(symbol); }
+
+    bool insert(ESymbolLevel level, const char *ext, TSymbol *symbol)
+    {
+        symbol->relateToExtension(ext);
+        return table[level]->insert(symbol);
+    }
+
     // Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and
     // above.
     void insertUnmangledBuiltInName(const char *name, ESymbolLevel level);