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 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
//
// Symbol table for parsing. Most functionaliy and main ideas
// are documented in the header file.
// Symbol table for parsing. The design principles and most of the functionality are documented in
// the header file.
//
#if defined(_MSC_VER)
......@@ -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,
TOperator op,
const char *ext,
......
......@@ -83,21 +83,12 @@ class TSymbol : angle::NonCopyable
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 @@ class TVariable : public TSymbol
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 TFunction : public TSymbol
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 @@ class TSymbolTable : angle::NonCopyable
precisionStack.pop_back();
}
bool declare(TSymbol *symbol) { return insert(currentLevel(), symbol); }
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 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);
// 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 @@ class TSymbolTable : angle::NonCopyable
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 @@ class TSymbolTable : angle::NonCopyable
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);
......
......@@ -130,7 +130,7 @@ TType::TType(const TPublicType &p)
ASSERT(primarySize <= 4);
ASSERT(secondarySize <= 4);
if (p.getUserDef())
structure = p.getUserDef()->getStruct();
structure = p.getUserDef();
}
bool TStructure::equals(const TStructure &other) const
......
......@@ -517,7 +517,7 @@ struct TTypeSpecifierNonArray
TBasicType type;
unsigned char primarySize; // size of vector or cols of matrix
unsigned char secondarySize; // rows of matrix
TType *userDef;
TStructure *userDef;
TSourceLoc line;
// true if the type was defined by a struct specifier rather than a reference to a type name.
......@@ -534,7 +534,7 @@ struct TTypeSpecifierNonArray
isStructSpecifier = false;
}
void initializeStruct(TType *aUserDef, bool aIsStructSpecifier, const TSourceLoc &aLine)
void initializeStruct(TStructure *aUserDef, bool aIsStructSpecifier, const TSourceLoc &aLine)
{
type = EbtStruct;
primarySize = 1;
......@@ -610,7 +610,7 @@ struct TPublicType
unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
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; }
bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }
......@@ -622,7 +622,7 @@ struct TPublicType
return false;
}
return typeSpecifierNonArray.userDef->isStructureContainingArrays();
return typeSpecifierNonArray.userDef->containsArrays();
}
bool isStructureContainingType(TBasicType t) const
......@@ -632,7 +632,7 @@ struct TPublicType
return false;
}
return typeSpecifierNonArray.userDef->isStructureContainingType(t);
return typeSpecifierNonArray.userDef->containsType(t);
}
bool isUnsizedArray() const { return array && arraySize == 0; }
......
......@@ -1175,7 +1175,7 @@ type_specifier_nonarray
| TYPE_NAME {
// This is for user defined type names. The lexical phase looked up the type.
TType& structure = static_cast<TVariable*>($1.symbol)->getType();
$$.initializeStruct(&structure, false, @1);
$$.initializeStruct(structure.getStruct(), false, @1);
}
;
......
......@@ -4395,7 +4395,7 @@ yyreduce:
{
// This is for user defined type names. The lexical phase looked up the type.
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;
......
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