Guarantee that symbol nodes get unique ids
The code is refactored so that symbol nodes can only be initialized
with an unique id object. This prevents accidentally forgetting to
create an id for a symbol node.
This opens up possibilities for future optimization: For example the
names and types of symbols could be stored in a central location
inside the SymbolTable, and TIntermSymbol nodes would only need to
store the symbol id. The symbol id could be used to look up the name
and type of the node.
BUG=angleproject:1490
TEST=angle_unittests
Change-Id: Ib8c8675d31493037a5a28c7b36bb9d1113cc10f6
Reviewed-on: https://chromium-review.googlesource.com/580955
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index bcd51fd..21b2b15 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -38,26 +38,11 @@
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolUniqueId.h"
namespace sh
{
-// Encapsulates a unique id for a symbol.
-class TSymbolUniqueId
-{
- public:
- POOL_ALLOCATOR_NEW_DELETE();
- TSymbolUniqueId(TSymbolTable *symbolTable);
- TSymbolUniqueId(const TSymbol &symbol);
- TSymbolUniqueId(const TSymbolUniqueId &) = default;
- TSymbolUniqueId &operator=(const TSymbolUniqueId &) = default;
-
- int get() const;
-
- private:
- int mId;
-};
-
// Symbol base class. (Can build functions or variables out of these...)
class TSymbol : angle::NonCopyable
{
@@ -74,12 +59,12 @@
virtual const TString &getMangledName() const { return getName(); }
virtual bool isFunction() const { return false; }
virtual bool isVariable() const { return false; }
- int getUniqueId() const { return uniqueId; }
+ const TSymbolUniqueId &getUniqueId() const { return uniqueId; }
void relateToExtension(TExtension ext) { extension = ext; }
TExtension getExtension() const { return extension; }
private:
- const int uniqueId;
+ const TSymbolUniqueId uniqueId;
const TString *name;
TExtension extension;
};
@@ -302,7 +287,7 @@
class TSymbolTable : angle::NonCopyable
{
public:
- TSymbolTable() : mUniqueIdCounter(0)
+ TSymbolTable() : mUniqueIdCounter(0), 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
@@ -514,12 +499,20 @@
table[currentLevel()]->setGlobalInvariant(invariant);
}
- int nextUniqueId() { return ++mUniqueIdCounter; }
+ const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); }
+
+ // The empty symbol id is shared between all empty string ("") symbols. They are used in the
+ // AST for unused function parameters and struct type declarations that don't declare a
+ // variable, for example.
+ const TSymbolUniqueId &getEmptySymbolId() { return mEmptySymbolId; }
// Checks whether there is a built-in accessible by a shader with the specified version.
bool hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion);
private:
+ friend class TSymbolUniqueId;
+ int nextUniqueIdValue() { return ++mUniqueIdCounter; }
+
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
TVariable *insertVariable(ESymbolLevel level, const TString *name, const TType &type);
@@ -543,6 +536,8 @@
std::vector<PrecisionStackLevel *> precisionStack;
int mUniqueIdCounter;
+
+ const TSymbolUniqueId mEmptySymbolId;
};
} // namespace sh