Commit e5fe7aad by Olli Etuaho Committed by Commit Bot

Store builtin symbols as const pointers

To do this we need two types of symbol table levels: A level for built-ins and a level for user-defined symbols. User-defined symbols are non-const because function symbols created based on function prototypes are changed when the function definition is parsed. On the other hand, we want to make built-in symbols constexpr, so we should only handle them through const pointers. This also gets rid of extra empty precision stack levels. Only one level is needed to store predefined precisions. BUG=angleproject:2267 TEST=angle_unittests Change-Id: I9f14b24c2cfce272f22c16e7a8dfb653b849cbeb Reviewed-on: https://chromium-review.googlesource.com/892879 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 8f27b050
...@@ -336,7 +336,8 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -336,7 +336,8 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
// We preserve symbols at the built-in level from compile-to-compile. // We preserve symbols at the built-in level from compile-to-compile.
// Start pushing the user-defined symbols at global level. // Start pushing the user-defined symbols at global level.
TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable); TScopedSymbolTableLevel globalLevel(&symbolTable);
ASSERT(symbolTable.atGlobalLevel());
// Parse shader. // Parse shader.
if (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr, if (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr,
......
...@@ -13,12 +13,13 @@ ...@@ -13,12 +13,13 @@
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
#include <algorithm>
#include <set>
#include "angle_gl.h" #include "angle_gl.h"
#include "compiler/translator/ImmutableString.h" #include "compiler/translator/ImmutableString.h"
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
#include "compiler/translator/StaticType.h"
#include <stdio.h>
#include <algorithm>
namespace sh namespace sh
{ {
...@@ -44,9 +45,6 @@ class TSymbolTable::TSymbolTableLevel ...@@ -44,9 +45,6 @@ class TSymbolTable::TSymbolTableLevel
void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; } void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; }
void insertUnmangledBuiltInName(const char *name);
bool hasUnmangledBuiltIn(const char *name) const;
private: private:
using tLevel = TUnorderedMap<ImmutableString, using tLevel = TUnorderedMap<ImmutableString,
TSymbol *, TSymbol *,
...@@ -55,8 +53,34 @@ class TSymbolTable::TSymbolTableLevel ...@@ -55,8 +53,34 @@ class TSymbolTable::TSymbolTableLevel
using tInsertResult = std::pair<tLevel::iterator, bool>; using tInsertResult = std::pair<tLevel::iterator, bool>;
tLevel level; tLevel level;
std::set<std::string> mInvariantVaryings; std::set<std::string> mInvariantVaryings;
bool mGlobalInvariant; bool mGlobalInvariant;
};
class TSymbolTable::TSymbolTableBuiltInLevel
{
public:
TSymbolTableBuiltInLevel() = default;
bool insert(const TSymbol *symbol);
// Insert a function using its unmangled name as the key.
bool insertUnmangled(const TFunction *function);
const TSymbol *find(const ImmutableString &name) const;
void insertUnmangledBuiltInName(const char *name);
bool hasUnmangledBuiltIn(const char *name) const;
private:
using tLevel = TUnorderedMap<ImmutableString,
const TSymbol *,
ImmutableString::FowlerNollVoHash<sizeof(size_t)>>;
using tLevelPair = const tLevel::value_type;
using tInsertResult = std::pair<tLevel::iterator, bool>;
tLevel mLevel;
std::set<ImmutableString> mUnmangledBuiltInNames; std::set<ImmutableString> mUnmangledBuiltInNames;
}; };
...@@ -65,7 +89,6 @@ bool TSymbolTable::TSymbolTableLevel::insert(TSymbol *symbol) ...@@ -65,7 +89,6 @@ bool TSymbolTable::TSymbolTableLevel::insert(TSymbol *symbol)
{ {
// returning true means symbol was added to the table // returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol)); tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
return result.second; return result.second;
} }
...@@ -73,7 +96,6 @@ bool TSymbolTable::TSymbolTableLevel::insertUnmangled(TFunction *function) ...@@ -73,7 +96,6 @@ bool TSymbolTable::TSymbolTableLevel::insertUnmangled(TFunction *function)
{ {
// returning true means symbol was added to the table // returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(function->name(), function)); tInsertResult result = level.insert(tLevelPair(function->name(), function));
return result.second; return result.second;
} }
...@@ -81,34 +103,66 @@ TSymbol *TSymbolTable::TSymbolTableLevel::find(const ImmutableString &name) cons ...@@ -81,34 +103,66 @@ TSymbol *TSymbolTable::TSymbolTableLevel::find(const ImmutableString &name) cons
{ {
tLevel::const_iterator it = level.find(name); tLevel::const_iterator it = level.find(name);
if (it == level.end()) if (it == level.end())
return 0; return nullptr;
else else
return (*it).second; return (*it).second;
} }
void TSymbolTable::TSymbolTableLevel::insertUnmangledBuiltInName(const char *name) bool TSymbolTable::TSymbolTableBuiltInLevel::insert(const TSymbol *symbol)
{
// returning true means symbol was added to the table
tInsertResult result = mLevel.insert(tLevelPair(symbol->getMangledName(), symbol));
return result.second;
}
bool TSymbolTable::TSymbolTableBuiltInLevel::insertUnmangled(const TFunction *function)
{
// returning true means symbol was added to the table
tInsertResult result = mLevel.insert(tLevelPair(function->name(), function));
return result.second;
}
const TSymbol *TSymbolTable::TSymbolTableBuiltInLevel::find(const ImmutableString &name) const
{
tLevel::const_iterator it = mLevel.find(name);
if (it == mLevel.end())
return nullptr;
else
return (*it).second;
}
void TSymbolTable::TSymbolTableBuiltInLevel::insertUnmangledBuiltInName(const char *name)
{ {
mUnmangledBuiltInNames.insert(ImmutableString(name)); mUnmangledBuiltInNames.insert(ImmutableString(name));
} }
bool TSymbolTable::TSymbolTableLevel::hasUnmangledBuiltIn(const char *name) const bool TSymbolTable::TSymbolTableBuiltInLevel::hasUnmangledBuiltIn(const char *name) const
{ {
return mUnmangledBuiltInNames.count(ImmutableString(name)) > 0; return mUnmangledBuiltInNames.count(ImmutableString(name)) > 0;
} }
TSymbolTable::TSymbolTable() : mUniqueIdCounter(0), mUserDefinedUniqueIdsStart(-1)
{
}
TSymbolTable::~TSymbolTable() = default;
void TSymbolTable::pushBuiltInLevel()
{
mBuiltInTable.push_back(
std::unique_ptr<TSymbolTableBuiltInLevel>(new TSymbolTableBuiltInLevel));
}
void TSymbolTable::push() void TSymbolTable::push()
{ {
table.push_back(new TSymbolTableLevel); mTable.push_back(std::unique_ptr<TSymbolTableLevel>(new TSymbolTableLevel));
precisionStack.push_back(new PrecisionStackLevel); mPrecisionStack.push_back(std::unique_ptr<PrecisionStackLevel>(new PrecisionStackLevel));
} }
void TSymbolTable::pop() void TSymbolTable::pop()
{ {
delete table.back(); mTable.pop_back();
table.pop_back(); mPrecisionStack.pop_back();
delete precisionStack.back();
precisionStack.pop_back();
} }
const TFunction *TSymbolTable::markUserDefinedFunctionHasPrototypeDeclaration( const TFunction *TSymbolTable::markUserDefinedFunctionHasPrototypeDeclaration(
...@@ -144,37 +198,31 @@ const TFunction *TSymbolTable::setUserDefinedFunctionParameterNamesFromDefinitio ...@@ -144,37 +198,31 @@ const TFunction *TSymbolTable::setUserDefinedFunctionParameterNamesFromDefinitio
const TSymbol *TSymbolTable::find(const ImmutableString &name, int shaderVersion) const const TSymbol *TSymbolTable::find(const ImmutableString &name, int shaderVersion) const
{ {
int level = currentLevel(); int userDefinedLevel = static_cast<int>(mTable.size()) - 1;
TSymbol *symbol = nullptr; while (userDefinedLevel >= 0)
do {
const TSymbol *symbol = mTable[userDefinedLevel]->find(name);
if (symbol)
{ {
if (level == GLSL_BUILTINS)
level--;
if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
level--;
if (level == ESSL3_BUILTINS && shaderVersion < 300)
level--;
if (level == ESSL1_BUILTINS && shaderVersion != 100)
level--;
symbol = table[level]->find(name);
level--;
} while (symbol == nullptr && level >= 0);
return symbol; return symbol;
}
userDefinedLevel--;
}
return findBuiltIn(name, shaderVersion, false);
} }
TFunction *TSymbolTable::findUserDefinedFunction(const ImmutableString &name) const TFunction *TSymbolTable::findUserDefinedFunction(const ImmutableString &name) const
{ {
// User-defined functions are always declared at the global level. // User-defined functions are always declared at the global level.
ASSERT(currentLevel() >= GLOBAL_LEVEL); ASSERT(!mTable.empty());
return static_cast<TFunction *>(table[GLOBAL_LEVEL]->find(name)); return static_cast<TFunction *>(mTable[0]->find(name));
} }
const TSymbol *TSymbolTable::findGlobal(const ImmutableString &name) const const TSymbol *TSymbolTable::findGlobal(const ImmutableString &name) const
{ {
ASSERT(table.size() > GLOBAL_LEVEL); ASSERT(!mTable.empty());
return table[GLOBAL_LEVEL]->find(name); return mTable[0]->find(name);
} }
const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, int shaderVersion) const const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, int shaderVersion) const
...@@ -197,7 +245,7 @@ const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, ...@@ -197,7 +245,7 @@ const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name,
if (level == ESSL1_BUILTINS && shaderVersion != 100) if (level == ESSL1_BUILTINS && shaderVersion != 100)
level--; level--;
TSymbol *symbol = table[level]->find(name); const TSymbol *symbol = mBuiltInTable[level]->find(name);
if (symbol) if (symbol)
return symbol; return symbol;
...@@ -206,12 +254,6 @@ const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, ...@@ -206,12 +254,6 @@ const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name,
return nullptr; return nullptr;
} }
TSymbolTable::~TSymbolTable()
{
while (table.size() > 0)
pop();
}
constexpr bool IsGenType(const TType *type) constexpr bool IsGenType(const TType *type)
{ {
if (type) if (type)
...@@ -314,9 +356,9 @@ void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUn ...@@ -314,9 +356,9 @@ void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUn
if (insertUnmangledName) if (insertUnmangledName)
{ {
// Insert the unmangled name to detect potential future redefinition as a variable. // Insert the unmangled name to detect potential future redefinition as a variable.
table[GLOBAL_LEVEL]->insertUnmangled(function); mTable[0]->insertUnmangled(function);
} }
table[GLOBAL_LEVEL]->insert(function); mTable[0]->insert(function);
} }
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
...@@ -342,7 +384,7 @@ TVariable *TSymbolTable::insertVariable(ESymbolLevel level, ...@@ -342,7 +384,7 @@ TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
return nullptr; return nullptr;
} }
TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level, void TSymbolTable::insertVariableExt(ESymbolLevel level,
TExtension ext, TExtension ext,
const ImmutableString &name, const ImmutableString &name,
const TType *type) const TType *type)
...@@ -350,11 +392,9 @@ TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level, ...@@ -350,11 +392,9 @@ TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
ASSERT(level <= LAST_BUILTIN_LEVEL); ASSERT(level <= LAST_BUILTIN_LEVEL);
ASSERT(type->isRealized()); ASSERT(type->isRealized());
TVariable *var = new TVariable(this, name, type, SymbolType::BuiltIn, ext); TVariable *var = new TVariable(this, name, type, SymbolType::BuiltIn, ext);
if (insert(level, var)) bool inserted = insert(level, var);
{ UNUSED_VARIABLE(inserted);
return var; ASSERT(inserted);
}
return nullptr;
} }
bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable) bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
...@@ -367,7 +407,14 @@ bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable) ...@@ -367,7 +407,14 @@ bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
bool TSymbolTable::insert(ESymbolLevel level, TSymbol *symbol) bool TSymbolTable::insert(ESymbolLevel level, TSymbol *symbol)
{ {
ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1); ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
return table[level]->insert(symbol); if (level <= LAST_BUILTIN_LEVEL)
{
return mBuiltInTable[level]->insert(symbol);
}
else
{
return mTable[level - LAST_BUILTIN_LEVEL - 1]->insert(symbol);
}
} }
bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str) bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
...@@ -638,6 +685,13 @@ void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level, ...@@ -638,6 +685,13 @@ void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext)); new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
} }
void TSymbolTable::setDefaultPrecision(TBasicType type, TPrecision prec)
{
int indexOfLastElement = static_cast<int>(mPrecisionStack.size()) - 1;
// Uses map operator [], overwrites the current value
(*mPrecisionStack[indexOfLastElement])[type] = prec;
}
TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
{ {
if (!SupportsPrecision(type)) if (!SupportsPrecision(type))
...@@ -646,14 +700,14 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const ...@@ -646,14 +700,14 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
// unsigned integers use the same precision as signed // unsigned integers use the same precision as signed
TBasicType baseType = (type == EbtUInt) ? EbtInt : type; TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
int level = static_cast<int>(precisionStack.size()) - 1; int level = static_cast<int>(mPrecisionStack.size()) - 1;
assert(level >= 0); // Just to be safe. Should not happen. ASSERT(level >= 0); // Just to be safe. Should not happen.
// If we dont find anything we return this. Some types don't have predefined default precision. // If we dont find anything we return this. Some types don't have predefined default precision.
TPrecision prec = EbpUndefined; TPrecision prec = EbpUndefined;
while (level >= 0) while (level >= 0)
{ {
PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType); PrecisionStackLevel::iterator it = mPrecisionStack[level]->find(baseType);
if (it != precisionStack[level]->end()) if (it != mPrecisionStack[level]->end())
{ {
prec = (*it).second; prec = (*it).second;
break; break;
...@@ -666,38 +720,36 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const ...@@ -666,38 +720,36 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
void TSymbolTable::addInvariantVarying(const std::string &originalName) void TSymbolTable::addInvariantVarying(const std::string &originalName)
{ {
ASSERT(atGlobalLevel()); ASSERT(atGlobalLevel());
table[currentLevel()]->addInvariantVarying(originalName); mTable.back()->addInvariantVarying(originalName);
} }
bool TSymbolTable::isVaryingInvariant(const std::string &originalName) const bool TSymbolTable::isVaryingInvariant(const std::string &originalName) const
{ {
ASSERT(atGlobalLevel()); ASSERT(atGlobalLevel());
return table[currentLevel()]->isVaryingInvariant(originalName); return mTable.back()->isVaryingInvariant(originalName);
} }
void TSymbolTable::setGlobalInvariant(bool invariant) void TSymbolTable::setGlobalInvariant(bool invariant)
{ {
ASSERT(atGlobalLevel()); ASSERT(atGlobalLevel());
table[currentLevel()]->setGlobalInvariant(invariant); mTable.back()->setGlobalInvariant(invariant);
} }
void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level) void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
{ {
ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size())); ASSERT(level >= 0 && level <= LAST_BUILTIN_LEVEL);
ASSERT(mUserDefinedUniqueIdsStart == -1); ASSERT(mUserDefinedUniqueIdsStart == -1);
table[level]->insertUnmangledBuiltInName(name); mBuiltInTable[level]->insertUnmangledBuiltInName(name);
} }
bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level) bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
{ {
ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size())); ASSERT(level >= 0 && level <= LAST_BUILTIN_LEVEL);
return table[level]->hasUnmangledBuiltIn(name); return mBuiltInTable[level]->hasUnmangledBuiltIn(name);
} }
bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion) bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
{ {
ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level) for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
{ {
if (level == ESSL3_1_BUILTINS && shaderVersion != 310) if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
...@@ -713,7 +765,7 @@ bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int sha ...@@ -713,7 +765,7 @@ bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int sha
--level; --level;
} }
if (table[level]->hasUnmangledBuiltIn(name)) if (mBuiltInTable[level]->hasUnmangledBuiltIn(name))
{ {
return true; return true;
} }
...@@ -731,7 +783,7 @@ void TSymbolTable::clearCompilationResults() ...@@ -731,7 +783,7 @@ void TSymbolTable::clearCompilationResults()
mUniqueIdCounter = mUserDefinedUniqueIdsStart; mUniqueIdCounter = mUserDefinedUniqueIdsStart;
// User-defined scopes should have already been cleared when the compilation finished. // User-defined scopes should have already been cleared when the compilation finished.
ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u); ASSERT(mTable.size() == 0u);
} }
int TSymbolTable::nextUniqueIdValue() int TSymbolTable::nextUniqueIdValue()
...@@ -745,11 +797,14 @@ void TSymbolTable::initializeBuiltIns(sh::GLenum type, ...@@ -745,11 +797,14 @@ void TSymbolTable::initializeBuiltIns(sh::GLenum type,
const ShBuiltInResources &resources) const ShBuiltInResources &resources)
{ {
ASSERT(isEmpty()); ASSERT(isEmpty());
push(); // COMMON_BUILTINS pushBuiltInLevel(); // COMMON_BUILTINS
push(); // ESSL1_BUILTINS pushBuiltInLevel(); // ESSL1_BUILTINS
push(); // ESSL3_BUILTINS pushBuiltInLevel(); // ESSL3_BUILTINS
push(); // ESSL3_1_BUILTINS pushBuiltInLevel(); // ESSL3_1_BUILTINS
push(); // GLSL_BUILTINS pushBuiltInLevel(); // GLSL_BUILTINS
// We need just one precision stack level for predefined precisions.
mPrecisionStack.push_back(std::unique_ptr<PrecisionStackLevel>(new PrecisionStackLevel));
switch (type) switch (type)
{ {
......
...@@ -31,15 +31,13 @@ ...@@ -31,15 +31,13 @@
// //
#include <array> #include <array>
#include <assert.h> #include <memory>
#include <set>
#include "common/angleutils.h" #include "common/angleutils.h"
#include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/ImmutableString.h" #include "compiler/translator/ImmutableString.h"
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/Symbol.h" #include "compiler/translator/Symbol.h"
namespace sh namespace sh
...@@ -62,19 +60,17 @@ const int GLOBAL_LEVEL = 5; ...@@ -62,19 +60,17 @@ const int GLOBAL_LEVEL = 5;
class TSymbolTable : angle::NonCopyable class TSymbolTable : angle::NonCopyable
{ {
public: public:
TSymbolTable() : mUniqueIdCounter(0), mUserDefinedUniqueIdsStart(-1) TSymbolTable();
{ // To start using the symbol table after construction:
// The symbol table cannot be used until push() is called, but // * initializeBuiltIns() needs to be called.
// the lack of an initial call to push() can be used to detect // * push() needs to be called to push the global level.
// that the symbol table has not been preloaded with built-ins.
}
~TSymbolTable(); ~TSymbolTable();
// When the symbol table is initialized with the built-ins, there should // When the symbol table is initialized with the built-ins, there should
// 'push' calls, so that built-ins are at level 0 and the shader // 'push' calls, so that built-ins are at level 0 and the shader
// globals are at level 1. // globals are at level 1.
bool isEmpty() const { return table.empty(); } bool isEmpty() const { return mTable.empty(); }
bool atBuiltInLevel() const { return currentLevel() <= LAST_BUILTIN_LEVEL; } bool atBuiltInLevel() const { return currentLevel() <= LAST_BUILTIN_LEVEL; }
bool atGlobalLevel() const { return currentLevel() == GLOBAL_LEVEL; } bool atGlobalLevel() const { return currentLevel() == GLOBAL_LEVEL; }
...@@ -109,12 +105,7 @@ class TSymbolTable : angle::NonCopyable ...@@ -109,12 +105,7 @@ class TSymbolTable : angle::NonCopyable
int shaderVersion, int shaderVersion,
bool includeGLSLBuiltins) const; bool includeGLSLBuiltins) const;
void setDefaultPrecision(TBasicType type, TPrecision prec) void setDefaultPrecision(TBasicType type, TPrecision prec);
{
int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
// Uses map operator [], overwrites the current value
(*precisionStack[indexOfLastElement])[type] = prec;
}
// Searches down the precisionStack for a precision qualifier // Searches down the precisionStack for a precision qualifier
// for the specified TBasicType // for the specified TBasicType
...@@ -146,15 +137,21 @@ class TSymbolTable : angle::NonCopyable ...@@ -146,15 +137,21 @@ class TSymbolTable : angle::NonCopyable
friend class TSymbolUniqueId; friend class TSymbolUniqueId;
int nextUniqueIdValue(); int nextUniqueIdValue();
class TSymbolTableBuiltInLevel;
class TSymbolTableLevel; class TSymbolTableLevel;
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); } void pushBuiltInLevel();
ESymbolLevel currentLevel() const
{
return static_cast<ESymbolLevel>(mTable.size() + LAST_BUILTIN_LEVEL);
}
// The insert* entry points are used when initializing the symbol table with built-ins. // The insert* entry points are used when initializing the symbol table with built-ins.
// They return the created symbol / true in case the declaration was successful, and nullptr / // They return the created symbol / true in case the declaration was successful, and nullptr /
// false if the declaration failed due to redefinition. // false if the declaration failed due to redefinition.
TVariable *insertVariable(ESymbolLevel level, const ImmutableString &name, const TType *type); TVariable *insertVariable(ESymbolLevel level, const ImmutableString &name, const TType *type);
TVariable *insertVariableExt(ESymbolLevel level, void insertVariableExt(ESymbolLevel level,
TExtension ext, TExtension ext,
const ImmutableString &name, const ImmutableString &name,
const TType *type); const TType *type);
...@@ -272,9 +269,13 @@ class TSymbolTable : angle::NonCopyable ...@@ -272,9 +269,13 @@ class TSymbolTable : angle::NonCopyable
const ShBuiltInResources &resources); const ShBuiltInResources &resources);
void markBuiltInInitializationFinished(); void markBuiltInInitializationFinished();
std::vector<TSymbolTableLevel *> table; std::vector<std::unique_ptr<TSymbolTableBuiltInLevel>> mBuiltInTable;
std::vector<std::unique_ptr<TSymbolTableLevel>> mTable;
// There's one precision stack level for predefined precisions and then one level for each scope
// in table.
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel; typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector<PrecisionStackLevel *> precisionStack; std::vector<std::unique_ptr<PrecisionStackLevel>> mPrecisionStack;
int mUniqueIdCounter; int mUniqueIdCounter;
......
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