Commit 0f68463f by Olli Etuaho Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent daaff1cc
...@@ -3,10 +3,8 @@ ...@@ -3,10 +3,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Symbol table for parsing. The design principles and most of the functionality are documented in
// // the header file.
// Symbol table for parsing. Most functionaliy and main ideas
// are documented in the header file.
// //
#if defined(_MSC_VER) #if defined(_MSC_VER)
...@@ -271,6 +269,74 @@ const TType *VectorType(const TType *type, int size) ...@@ -271,6 +269,74 @@ const TType *VectorType(const TType *type, int size)
} }
} }
TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
{
return insertVariable(currentLevel(), name, type);
}
TVariable *TSymbolTable::declareStructType(TStructure *str)
{
return insertStructType(currentLevel(), str);
}
TInterfaceBlockName *TSymbolTable::declareInterfaceBlockName(const TString *name)
{
TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(name);
if (insert(currentLevel(), blockNameSymbol))
{
return blockNameSymbol;
}
return nullptr;
}
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
{
return insertVariable(level, NewPoolTString(name), type);
}
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
{
TVariable *var = new TVariable(name, type);
if (insert(level, var))
{
// Do lazy initialization for struct types, so we allocate to the current scope.
if (var->getType().getBasicType() == EbtStruct)
{
var->getType().realize();
}
return var;
}
return nullptr;
}
TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
const char *ext,
const char *name,
const TType &type)
{
TVariable *var = new TVariable(NewPoolTString(name), type);
if (insert(level, ext, var))
{
if (var->getType().getBasicType() == EbtStruct)
{
var->getType().realize();
}
return var;
}
return nullptr;
}
TVariable *TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
{
TVariable *var = new TVariable(&str->name(), TType(str), true);
if (insert(level, var))
{
var->getType().realize();
return var;
}
return nullptr;
}
void TSymbolTable::insertBuiltIn(ESymbolLevel level, void TSymbolTable::insertBuiltIn(ESymbolLevel level,
TOperator op, TOperator op,
const char *ext, const char *ext,
......
...@@ -83,21 +83,12 @@ class TSymbol : angle::NonCopyable ...@@ -83,21 +83,12 @@ class TSymbol : angle::NonCopyable
TString extension; 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; // May store the value of a constant variable of any type (float, int, bool or struct).
// 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.
class TVariable : public TSymbol class TVariable : public TSymbol
{ {
public: public:
TVariable(const TString *name, const TType &t, bool uT = false)
: TSymbol(name), type(t), userType(uT), unionArray(0)
{
}
~TVariable() override {} ~TVariable() override {}
bool isVariable() const override { return true; } bool isVariable() const override { return true; }
TType &getType() { return type; } TType &getType() { return type; }
...@@ -110,8 +101,18 @@ class TVariable : public TSymbol ...@@ -110,8 +101,18 @@ class TVariable : public TSymbol
void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; } void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
private: private:
friend class TSymbolTable;
TVariable(const TString *name, const TType &t, bool isUserTypeDefinition = false)
: TSymbol(name), type(t), userType(isUserTypeDefinition), unionArray(0)
{
}
TType type; TType type;
// Set to true if this represents a struct type, as opposed to a variable.
bool userType; bool userType;
// we are assuming that Pool Allocator will free the memory // we are assuming that Pool Allocator will free the memory
// allocated to unionArray when this object is destroyed. // allocated to unionArray when this object is destroyed.
const TConstantUnion *unionArray; const TConstantUnion *unionArray;
...@@ -224,9 +225,11 @@ class TFunction : public TSymbol ...@@ -224,9 +225,11 @@ class TFunction : public TSymbol
class TInterfaceBlockName : public TSymbol class TInterfaceBlockName : public TSymbol
{ {
public: public:
TInterfaceBlockName(const TString *name) : TSymbol(name) {}
virtual ~TInterfaceBlockName() {} virtual ~TInterfaceBlockName() {}
private:
friend class TSymbolTable;
TInterfaceBlockName(const TString *name) : TSymbol(name) {}
}; };
class TSymbolTableLevel class TSymbolTableLevel
...@@ -319,15 +322,22 @@ class TSymbolTable : angle::NonCopyable ...@@ -319,15 +322,22 @@ class TSymbolTable : angle::NonCopyable
precisionStack.pop_back(); 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
bool insert(ESymbolLevel level, TSymbol *symbol) { return table[level]->insert(symbol); } // declaration failed due to redefinition.
TVariable *declareVariable(const TString *name, const TType &type);
bool insert(ESymbolLevel level, const char *ext, TSymbol *symbol) TVariable *declareStructType(TStructure *str);
{ TInterfaceBlockName *declareInterfaceBlockName(const TString *name);
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) bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision)
{ {
...@@ -444,8 +454,6 @@ class TSymbolTable : angle::NonCopyable ...@@ -444,8 +454,6 @@ class TSymbolTable : angle::NonCopyable
return table[currentLevel() - 1]; return table[currentLevel() - 1];
} }
void dump(TInfoSink &infoSink) const;
void setDefaultPrecision(TBasicType type, TPrecision prec) void setDefaultPrecision(TBasicType type, TPrecision prec)
{ {
int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1; int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
...@@ -488,6 +496,16 @@ class TSymbolTable : angle::NonCopyable ...@@ -488,6 +496,16 @@ class TSymbolTable : angle::NonCopyable
private: private:
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); } 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 // Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and
// above. // above.
void insertUnmangledBuiltInName(const char *name, ESymbolLevel level); void insertUnmangledBuiltInName(const char *name, ESymbolLevel level);
......
...@@ -130,7 +130,7 @@ TType::TType(const TPublicType &p) ...@@ -130,7 +130,7 @@ TType::TType(const TPublicType &p)
ASSERT(primarySize <= 4); ASSERT(primarySize <= 4);
ASSERT(secondarySize <= 4); ASSERT(secondarySize <= 4);
if (p.getUserDef()) if (p.getUserDef())
structure = p.getUserDef()->getStruct(); structure = p.getUserDef();
} }
bool TStructure::equals(const TStructure &other) const bool TStructure::equals(const TStructure &other) const
......
...@@ -517,7 +517,7 @@ struct TTypeSpecifierNonArray ...@@ -517,7 +517,7 @@ struct TTypeSpecifierNonArray
TBasicType type; TBasicType type;
unsigned char primarySize; // size of vector or cols of matrix unsigned char primarySize; // size of vector or cols of matrix
unsigned char secondarySize; // rows of matrix unsigned char secondarySize; // rows of matrix
TType *userDef; TStructure *userDef;
TSourceLoc line; TSourceLoc line;
// true if the type was defined by a struct specifier rather than a reference to a type name. // true if the type was defined by a struct specifier rather than a reference to a type name.
...@@ -534,7 +534,7 @@ struct TTypeSpecifierNonArray ...@@ -534,7 +534,7 @@ struct TTypeSpecifierNonArray
isStructSpecifier = false; isStructSpecifier = false;
} }
void initializeStruct(TType *aUserDef, bool aIsStructSpecifier, const TSourceLoc &aLine) void initializeStruct(TStructure *aUserDef, bool aIsStructSpecifier, const TSourceLoc &aLine)
{ {
type = EbtStruct; type = EbtStruct;
primarySize = 1; primarySize = 1;
...@@ -610,7 +610,7 @@ struct TPublicType ...@@ -610,7 +610,7 @@ struct TPublicType
unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; } unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; } unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; }
const TType *getUserDef() const { return typeSpecifierNonArray.userDef; } TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; }
const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; } const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }
bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; } bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }
...@@ -622,7 +622,7 @@ struct TPublicType ...@@ -622,7 +622,7 @@ struct TPublicType
return false; return false;
} }
return typeSpecifierNonArray.userDef->isStructureContainingArrays(); return typeSpecifierNonArray.userDef->containsArrays();
} }
bool isStructureContainingType(TBasicType t) const bool isStructureContainingType(TBasicType t) const
...@@ -632,7 +632,7 @@ struct TPublicType ...@@ -632,7 +632,7 @@ struct TPublicType
return false; return false;
} }
return typeSpecifierNonArray.userDef->isStructureContainingType(t); return typeSpecifierNonArray.userDef->containsType(t);
} }
bool isUnsizedArray() const { return array && arraySize == 0; } bool isUnsizedArray() const { return array && arraySize == 0; }
......
...@@ -1175,7 +1175,7 @@ type_specifier_nonarray ...@@ -1175,7 +1175,7 @@ type_specifier_nonarray
| TYPE_NAME { | TYPE_NAME {
// This is for user defined type names. The lexical phase looked up the type. // This is for user defined type names. The lexical phase looked up the type.
TType& structure = static_cast<TVariable*>($1.symbol)->getType(); TType& structure = static_cast<TVariable*>($1.symbol)->getType();
$$.initializeStruct(&structure, false, @1); $$.initializeStruct(structure.getStruct(), false, @1);
} }
; ;
......
...@@ -4395,7 +4395,7 @@ yyreduce: ...@@ -4395,7 +4395,7 @@ yyreduce:
{ {
// This is for user defined type names. The lexical phase looked up the type. // This is for user defined type names. The lexical phase looked up the type.
TType& structure = static_cast<TVariable*>((yyvsp[0].lex).symbol)->getType(); TType& structure = static_cast<TVariable*>((yyvsp[0].lex).symbol)->getType();
(yyval.interm.typeSpecifierNonArray).initializeStruct(&structure, false, (yylsp[0])); (yyval.interm.typeSpecifierNonArray).initializeStruct(structure.getStruct(), false, (yylsp[0]));
} }
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment