Reset symbol unique id counter between compilations
This guarantees identical compilation results on different
compilations using the same compiler instance, guards against
overflow, and is useful as a building block for tracking more symbol
information in the symbol table.
BUG=angleproject:2267
TEST=angle_unittests
Change-Id: Ib5a7cec2fff6712ead969d935d238d28a87fd4a7
Reviewed-on: https://chromium-review.googlesource.com/796795
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index e0fd0cb..f0df223 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -734,6 +734,8 @@
IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
+ symbolTable.markBuiltInInitializationFinished();
+
return true;
}
@@ -868,6 +870,8 @@
nameMap.clear();
mSourcePath = nullptr;
+
+ symbolTable.clearCompilationResults();
}
bool TCompiler::initCallDag(TIntermNode *root)
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index 3cfa8b7..9e7270d 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -291,7 +291,8 @@
const TString *name)
{
TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
- if (insert(level, ext, blockNameSymbol))
+ blockNameSymbol->relateToExtension(ext);
+ if (insert(level, blockNameSymbol))
{
return blockNameSymbol;
}
@@ -324,7 +325,8 @@
const TType &type)
{
TVariable *var = new TVariable(this, NewPoolTString(name), type);
- if (insert(level, ext, var))
+ var->relateToExtension(ext);
+ if (insert(level, var))
{
if (var->getType().getBasicType() == EbtStruct)
{
@@ -583,6 +585,7 @@
void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
{
ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
+ ASSERT(mUserDefinedUniqueIdsStart == -1);
table[level]->insertUnmangledBuiltInName(std::string(name));
}
@@ -619,4 +622,23 @@
return false;
}
+void TSymbolTable::markBuiltInInitializationFinished()
+{
+ mUserDefinedUniqueIdsStart = mUniqueIdCounter;
+}
+
+void TSymbolTable::clearCompilationResults()
+{
+ mUniqueIdCounter = mUserDefinedUniqueIdsStart;
+
+ // User-defined scopes should have already been cleared when the compilation finished.
+ ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
+}
+
+int TSymbolTable::nextUniqueIdValue()
+{
+ ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
+ return ++mUniqueIdCounter;
+}
+
} // namespace sh
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index b09f643..e92ac8f 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -287,7 +287,7 @@
class TSymbolTable : angle::NonCopyable
{
public:
- TSymbolTable() : mUniqueIdCounter(0), mEmptySymbolId(this)
+ TSymbolTable() : mUniqueIdCounter(0), mUserDefinedUniqueIdsStart(-1), mEmptySymbolId(this)
{
// The symbol table cannot be used until push() is called, but
// the lack of an initial call to push() can be used to detect
@@ -358,7 +358,8 @@
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
- return insert(level, ext, constant);
+ constant->relateToExtension(ext);
+ return insert(level, constant);
}
bool insertConstIvec3(ESymbolLevel level,
@@ -509,19 +510,20 @@
// Checks whether there is a built-in accessible by a shader with the specified version.
bool hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion);
+ void markBuiltInInitializationFinished();
+ void clearCompilationResults();
+
private:
friend class TSymbolUniqueId;
- int nextUniqueIdValue() { return ++mUniqueIdCounter; }
+ int nextUniqueIdValue();
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, TExtension ext, TSymbol *symbol)
+ bool insert(ESymbolLevel level, TSymbol *symbol)
{
- symbol->relateToExtension(ext);
+ ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
return table[level]->insert(symbol);
}
@@ -537,6 +539,11 @@
int mUniqueIdCounter;
+ // -1 before built-in init has finished, one past the last built-in id afterwards.
+ // TODO(oetuaho): Make this a compile-time constant once the symbol table is initialized at
+ // compile time. http://anglebug.com/1432
+ int mUserDefinedUniqueIdsStart;
+
const TSymbolUniqueId mEmptySymbolId;
};