Add const qualification to symbol accesses
All accesses to built-in symbols now happen through const-qualified
pointers.
This also encapsulates TSymbolTableLevel inside TSymbolTable.
This prepares for statically allocating built-in symbols.
BUG=angleproject:2267
TEST=angle_unittests
Change-Id: I473014d978daa765b4a733d761d6c08b28288776
Reviewed-on: https://chromium-review.googlesource.com/859959
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/CollectVariables.cpp b/src/compiler/translator/CollectVariables.cpp
index 846bc64..0b7cd70 100644
--- a/src/compiler/translator/CollectVariables.cpp
+++ b/src/compiler/translator/CollectVariables.cpp
@@ -259,8 +259,8 @@
void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const char *name,
ShaderVariable *info)
{
- TVariable *symbolTableVar =
- reinterpret_cast<TVariable *>(mSymbolTable->findBuiltIn(name, mShaderVersion));
+ const TVariable *symbolTableVar =
+ reinterpret_cast<const TVariable *>(mSymbolTable->findBuiltIn(name, mShaderVersion));
ASSERT(symbolTableVar);
const TType &type = symbolTableVar->getType();
diff --git a/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp b/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
index 8748cff..837e4bc 100644
--- a/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
+++ b/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp
@@ -147,9 +147,9 @@
SymbolType::AngleInternal);
DeclareGlobalVariable(root, viewID);
- ReplaceVariable(root,
- static_cast<TVariable *>(symbolTable->findBuiltIn("gl_ViewID_OVR", 300, true)),
- viewID);
+ ReplaceVariable(
+ root, static_cast<const TVariable *>(symbolTable->findBuiltIn("gl_ViewID_OVR", 300, true)),
+ viewID);
if (shaderType == GL_VERTEX_SHADER)
{
// Replacing gl_InstanceID with InstanceID should happen before adding the initializers of
@@ -160,7 +160,8 @@
symbolTable, instanceIDVariableName, instanceIDVariableType, SymbolType::AngleInternal);
DeclareGlobalVariable(root, instanceID);
ReplaceVariable(
- root, static_cast<TVariable *>(symbolTable->findBuiltIn("gl_InstanceID", 300, true)),
+ root,
+ static_cast<const TVariable *>(symbolTable->findBuiltIn("gl_InstanceID", 300, true)),
instanceID);
TIntermSequence *initializers = new TIntermSequence();
diff --git a/src/compiler/translator/FlagStd140Structs.cpp b/src/compiler/translator/FlagStd140Structs.cpp
index 37f7225..886de30 100644
--- a/src/compiler/translator/FlagStd140Structs.cpp
+++ b/src/compiler/translator/FlagStd140Structs.cpp
@@ -28,13 +28,13 @@
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
private:
- void mapBlockStructMembers(TIntermSymbol *blockDeclarator, TInterfaceBlock *block);
+ void mapBlockStructMembers(TIntermSymbol *blockDeclarator, const TInterfaceBlock *block);
std::vector<MappedStruct> mMappedStructs;
};
void FlagStd140StructsTraverser::mapBlockStructMembers(TIntermSymbol *blockDeclarator,
- TInterfaceBlock *block)
+ const TInterfaceBlock *block)
{
for (auto *field : block->fields())
{
@@ -53,7 +53,7 @@
TIntermTyped *declarator = node->getSequence()->back()->getAsTyped();
if (declarator->getBasicType() == EbtInterfaceBlock)
{
- TInterfaceBlock *block = declarator->getType().getInterfaceBlock();
+ const TInterfaceBlock *block = declarator->getType().getInterfaceBlock();
if (block->blockStorage() == EbsStd140)
{
mapBlockStructMembers(declarator->getAsSymbolNode(), block);
diff --git a/src/compiler/translator/IntermNode_util.cpp b/src/compiler/translator/IntermNode_util.cpp
index 8443767..a58b170 100644
--- a/src/compiler/translator/IntermNode_util.cpp
+++ b/src/compiler/translator/IntermNode_util.cpp
@@ -22,7 +22,7 @@
int shaderVersion)
{
TString mangledName = TFunction::GetMangledNameFromCall(name, *arguments);
- TSymbol *symbol = symbolTable.findBuiltIn(mangledName, shaderVersion);
+ const TSymbol *symbol = symbolTable.findBuiltIn(mangledName, shaderVersion);
if (symbol)
{
ASSERT(symbol->isFunction());
@@ -235,7 +235,7 @@
TIntermSymbol *ReferenceGlobalVariable(const TString &name, const TSymbolTable &symbolTable)
{
- TVariable *var = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
+ const TVariable *var = reinterpret_cast<const TVariable *>(symbolTable.findGlobal(name));
ASSERT(var);
return new TIntermSymbol(var);
}
diff --git a/src/compiler/translator/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index 8c45d75..dbfc19b 100644
--- a/src/compiler/translator/IntermTraverse.cpp
+++ b/src/compiler/translator/IntermTraverse.cpp
@@ -738,10 +738,10 @@
{
// Find the built-in function corresponding to this op so that we can determine the
// in/out qualifiers of its parameters.
- TFunction *builtInFunc = nullptr;
+ const TFunction *builtInFunc = nullptr;
if (!node->isFunctionCall() && !node->isConstructor())
{
- builtInFunc = static_cast<TFunction *>(
+ builtInFunc = static_cast<const TFunction *>(
mSymbolTable->findBuiltIn(node->getSymbolTableMangledName(), mShaderVersion));
}
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index ec4a65a..b3e8476 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -260,7 +260,7 @@
}
if (type.getBasicType() == EbtInterfaceBlock)
{
- TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
declareInterfaceBlockLayout(interfaceBlock);
}
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
@@ -317,7 +317,7 @@
}
else if (type.getBasicType() == EbtInterfaceBlock)
{
- TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
declareInterfaceBlock(interfaceBlock);
}
else
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 825bbad..55c57c9 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -349,7 +349,7 @@
for (auto &mappedStruct : std140Structs)
{
- TInterfaceBlock *interfaceBlock =
+ const TInterfaceBlock *interfaceBlock =
mappedStruct.blockDeclarator->getType().getInterfaceBlock();
if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
{
@@ -1259,7 +1259,7 @@
if (visit == PreVisit)
{
TIntermSymbol *instanceArraySymbol = node->getLeft()->getAsSymbolNode();
- TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock();
+ const TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock();
if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
{
mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index c6bb87f..4766077 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1134,7 +1134,7 @@
else if (static_cast<int>(type->getOutermostArraySize()) ==
maxDrawBuffers->getConstPointer()->getIConst())
{
- if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
+ if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
{
needsReservedCheck = !checkCanUseExtension(line, builtInSymbol->extension());
}
@@ -2838,8 +2838,8 @@
{
if (mGlInVariableWithArraySize == nullptr)
{
- TSymbol *glPerVertex = symbolTable.findBuiltIn("gl_PerVertex", 310);
- TInterfaceBlock *glPerVertexBlock = static_cast<TInterfaceBlock *>(glPerVertex);
+ const TSymbol *glPerVertex = symbolTable.findBuiltIn("gl_PerVertex", 310);
+ const TInterfaceBlock *glPerVertexBlock = static_cast<const TInterfaceBlock *>(glPerVertex);
TType *glInType = new TType(glPerVertexBlock, EvqPerVertexIn, TLayoutQualifier::Create());
glInType->makeArray(inputArraySize);
mGlInVariableWithArraySize =
@@ -3213,15 +3213,16 @@
// Note: function found from the symbol table could be the same as parsedFunction if this is the
// first declaration. Either way the instance in the symbol table is used to track whether the
// function is declared multiple times.
- TFunction *function = static_cast<TFunction *>(
- symbolTable.find(parsedFunction.getMangledName(), getShaderVersion()));
- if (function->hasPrototypeDeclaration() && mShaderVersion == 100)
+ bool hadPrototypeDeclaration = false;
+ const TFunction *function = symbolTable.markUserDefinedFunctionHasPrototypeDeclaration(
+ parsedFunction.getMangledName(), &hadPrototypeDeclaration);
+
+ if (hadPrototypeDeclaration && mShaderVersion == 100)
{
// ESSL 1.00.17 section 4.2.7.
// Doesn't apply to ESSL 3.00.4: see section 4.2.3.
error(location, "duplicate function prototype declarations are not allowed", "function");
}
- function->setHasPrototypeDeclaration();
TIntermFunctionPrototype *prototype =
createPrototypeNodeFromFunction(*function, location, false);
@@ -3263,49 +3264,33 @@
}
void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
- TFunction **function,
+ const TFunction *function,
TIntermFunctionPrototype **prototypeOut)
{
ASSERT(function);
- ASSERT(*function);
const TSymbol *builtIn =
- symbolTable.findBuiltIn((*function)->getMangledName(), getShaderVersion());
+ symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
if (builtIn)
{
- error(location, "built-in functions cannot be redefined", (*function)->name().c_str());
+ error(location, "built-in functions cannot be redefined", function->name().c_str());
}
else
{
- TFunction *prevDec = static_cast<TFunction *>(
- symbolTable.find((*function)->getMangledName(), getShaderVersion()));
-
- // Note: 'prevDec' could be 'function' if this is the first time we've seen function as it
- // would have just been put in the symbol table. Otherwise, we're looking up an earlier
- // occurance.
- if (*function != prevDec)
+ bool wasDefined = false;
+ function =
+ symbolTable.setUserDefinedFunctionParameterNamesFromDefinition(function, &wasDefined);
+ if (wasDefined)
{
- // Swap the parameters of the previous declaration to the parameters of the function
- // definition (parameter names may differ).
- prevDec->swapParameters(**function);
-
- // The function definition will share the same symbol as any previous declaration.
- *function = prevDec;
+ error(location, "function already has a body", function->name().c_str());
}
-
- if ((*function)->isDefined())
- {
- error(location, "function already has a body", (*function)->name().c_str());
- }
-
- (*function)->setDefined();
}
// Remember the return type for later checking for return statements.
- mCurrentFunctionType = &((*function)->getReturnType());
+ mCurrentFunctionType = &(function->getReturnType());
mFunctionReturnsValue = false;
- *prototypeOut = createPrototypeNodeFromFunction(**function, location, true);
+ *prototypeOut = createPrototypeNodeFromFunction(*function, location, true);
setLoopNestingLevel(0);
}
@@ -3319,8 +3304,8 @@
// Return types and parameter qualifiers must match in all redeclarations, so those are checked
// here.
//
- TFunction *prevDec =
- static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
+ const TFunction *prevDec = static_cast<const TFunction *>(
+ symbolTable.find(function->getMangledName(), getShaderVersion()));
for (size_t i = 0u; i < function->getParamCount(); ++i)
{
@@ -3360,26 +3345,21 @@
}
}
- //
// Check for previously declared variables using the same name.
- //
- TSymbol *prevSym = symbolTable.find(function->name(), getShaderVersion());
+ const TSymbol *prevSym = symbolTable.find(function->name(), getShaderVersion());
+ bool insertUnmangledName = true;
if (prevSym)
{
if (!prevSym->isFunction())
{
error(location, "redefinition of a function", function->name().c_str());
}
+ insertUnmangledName = false;
}
- else
- {
- // Insert the unmangled name to detect potential future redefinition as a variable.
- symbolTable.getOuterLevel()->insertUnmangled(function);
- }
-
- // We're at the inner scope level of the function's arguments and body statement.
- // Add the function prototype to the surrounding scope instead.
- symbolTable.getOuterLevel()->insert(function);
+ // Parsing is at the inner scope level of the function's arguments and body statement at this
+ // point, but declareUserDefinedFunction takes care of declaring the function at the global
+ // scope.
+ symbolTable.declareUserDefinedFunction(function, insertUnmangledName);
// Raise error message if main function takes any parameters or return anything other than void
if (function->name() == "main")
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 354f6fe..8527a20 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -285,7 +285,7 @@
TIntermBlock *functionBody,
const TSourceLoc &location);
void parseFunctionDefinitionHeader(const TSourceLoc &location,
- TFunction **function,
+ const TFunction *function,
TIntermFunctionPrototype **prototypeOut);
TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
TFunction *parseFunctionHeader(const TPublicType &type,
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index 39dd6cc..7d841b6 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -21,16 +21,57 @@
namespace sh
{
+class TSymbolTable::TSymbolTableLevel
+{
+ public:
+ TSymbolTableLevel() : mGlobalInvariant(false) {}
+ ~TSymbolTableLevel();
+
+ bool insert(TSymbol *symbol);
+
+ // Insert a function using its unmangled name as the key.
+ bool insertUnmangled(TFunction *function);
+
+ TSymbol *find(const TString &name) const;
+
+ void addInvariantVarying(const std::string &name) { mInvariantVaryings.insert(name); }
+
+ bool isVaryingInvariant(const std::string &name)
+ {
+ return (mGlobalInvariant || mInvariantVaryings.count(name) > 0);
+ }
+
+ void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; }
+
+ void insertUnmangledBuiltInName(const char *name);
+ bool hasUnmangledBuiltIn(const char *name) const;
+
+ private:
+ using tLevel = TUnorderedMap<TString, TSymbol *>;
+ using tLevelPair = const tLevel::value_type;
+ using tInsertResult = std::pair<tLevel::iterator, bool>;
+
+ tLevel level;
+ std::set<std::string> mInvariantVaryings;
+ bool mGlobalInvariant;
+
+ struct CharArrayComparator
+ {
+ bool operator()(const char *a, const char *b) const { return strcmp(a, b) < 0; }
+ };
+ std::set<const char *, CharArrayComparator> mUnmangledBuiltInNames;
+};
+
//
// Symbol table levels are a map of pointers to symbols that have to be deleted.
//
-TSymbolTableLevel::~TSymbolTableLevel()
+TSymbolTable::TSymbolTableLevel::~TSymbolTableLevel()
{
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
delete (*it).second;
}
-bool TSymbolTableLevel::insert(TSymbol *symbol)
+bool TSymbolTable::TSymbolTableLevel::insert(TSymbol *symbol)
{
// returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
@@ -38,7 +79,7 @@
return result.second;
}
-bool TSymbolTableLevel::insertUnmangled(TFunction *function)
+bool TSymbolTable::TSymbolTableLevel::insertUnmangled(TFunction *function)
{
// returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(function->name(), function));
@@ -46,7 +87,7 @@
return result.second;
}
-TSymbol *TSymbolTableLevel::find(const TString &name) const
+TSymbol *TSymbolTable::TSymbolTableLevel::find(const TString &name) const
{
tLevel::const_iterator it = level.find(name);
if (it == level.end())
@@ -55,24 +96,69 @@
return (*it).second;
}
-void TSymbolTableLevel::insertUnmangledBuiltInName(const char *name)
+void TSymbolTable::TSymbolTableLevel::insertUnmangledBuiltInName(const char *name)
{
mUnmangledBuiltInNames.insert(name);
}
-bool TSymbolTableLevel::hasUnmangledBuiltIn(const char *name) const
+bool TSymbolTable::TSymbolTableLevel::hasUnmangledBuiltIn(const char *name) const
{
return mUnmangledBuiltInNames.count(name) > 0;
}
-TSymbol *TSymbolTable::find(const TString &name,
- int shaderVersion,
- bool *builtIn,
- bool *sameScope) const
+void TSymbolTable::push()
{
- int level = currentLevel();
- TSymbol *symbol;
+ table.push_back(new TSymbolTableLevel);
+ precisionStack.push_back(new PrecisionStackLevel);
+}
+void TSymbolTable::pop()
+{
+ delete table.back();
+ table.pop_back();
+
+ delete precisionStack.back();
+ precisionStack.pop_back();
+}
+
+const TFunction *TSymbolTable::markUserDefinedFunctionHasPrototypeDeclaration(
+ const TString &mangledName,
+ bool *hadPrototypeDeclarationOut)
+{
+ TFunction *function = findUserDefinedFunction(mangledName);
+ *hadPrototypeDeclarationOut = function->hasPrototypeDeclaration();
+ function->setHasPrototypeDeclaration();
+ return function;
+}
+
+const TFunction *TSymbolTable::setUserDefinedFunctionParameterNamesFromDefinition(
+ const TFunction *function,
+ bool *wasDefinedOut)
+{
+ TFunction *firstDeclaration = findUserDefinedFunction(function->getMangledName());
+ ASSERT(firstDeclaration);
+ // Note: 'firstDeclaration' could be 'function' if this is the first time we've seen function as
+ // it would have just been put in the symbol table. Otherwise, we're looking up an earlier
+ // occurance.
+ if (function != firstDeclaration)
+ {
+ // Swap the parameters of the previous declaration to the parameters of the function
+ // definition (parameter names may differ).
+ firstDeclaration->swapParameters(*function);
+ }
+
+ *wasDefinedOut = firstDeclaration->isDefined();
+ firstDeclaration->setDefined();
+ return firstDeclaration;
+}
+
+const TSymbol *TSymbolTable::find(const TString &name,
+ int shaderVersion,
+ bool *builtIn,
+ bool *sameScope) const
+{
+ int level = currentLevel();
+ TSymbol *symbol = nullptr;
do
{
if (level == GLSL_BUILTINS)
@@ -85,7 +171,7 @@
level--;
symbol = table[level]->find(name);
- } while (symbol == 0 && --level >= 0);
+ } while (symbol == nullptr && --level >= 0);
if (builtIn)
*builtIn = (level <= LAST_BUILTIN_LEVEL);
@@ -95,20 +181,27 @@
return symbol;
}
-TSymbol *TSymbolTable::findGlobal(const TString &name) const
+TFunction *TSymbolTable::findUserDefinedFunction(const TString &name) const
+{
+ // User-defined functions are always declared at the global level.
+ ASSERT(currentLevel() >= GLOBAL_LEVEL);
+ return static_cast<TFunction *>(table[GLOBAL_LEVEL]->find(name));
+}
+
+const TSymbol *TSymbolTable::findGlobal(const TString &name) const
{
ASSERT(table.size() > GLOBAL_LEVEL);
return table[GLOBAL_LEVEL]->find(name);
}
-TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
+const TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
{
return findBuiltIn(name, shaderVersion, false);
}
-TSymbol *TSymbolTable::findBuiltIn(const TString &name,
- int shaderVersion,
- bool includeGLSLBuiltins) const
+const TSymbol *TSymbolTable::findBuiltIn(const TString &name,
+ int shaderVersion,
+ bool includeGLSLBuiltins) const
{
for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
{
@@ -232,6 +325,17 @@
return insert(currentLevel(), interfaceBlock);
}
+void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUnmangledName)
+{
+ ASSERT(currentLevel() >= GLOBAL_LEVEL);
+ if (insertUnmangledName)
+ {
+ // Insert the unmangled name to detect potential future redefinition as a variable.
+ table[GLOBAL_LEVEL]->insertUnmangled(function);
+ }
+ table[GLOBAL_LEVEL]->insert(function);
+}
+
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType *type)
{
ASSERT(level <= LAST_BUILTIN_LEVEL);
@@ -275,6 +379,12 @@
return insert(level, variable);
}
+bool TSymbolTable::insert(ESymbolLevel level, TSymbol *symbol)
+{
+ ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
+ return table[level]->insert(symbol);
+}
+
bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
{
ASSERT(str);
@@ -525,6 +635,24 @@
return prec;
}
+void TSymbolTable::addInvariantVarying(const std::string &originalName)
+{
+ ASSERT(atGlobalLevel());
+ table[currentLevel()]->addInvariantVarying(originalName);
+}
+
+bool TSymbolTable::isVaryingInvariant(const std::string &originalName) const
+{
+ ASSERT(atGlobalLevel());
+ return table[currentLevel()]->isVaryingInvariant(originalName);
+}
+
+void TSymbolTable::setGlobalInvariant(bool invariant)
+{
+ ASSERT(atGlobalLevel());
+ table[currentLevel()]->setGlobalInvariant(invariant);
+}
+
void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
{
ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index f66863e..269fe43 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -44,49 +44,6 @@
namespace sh
{
-class TSymbolTableLevel
-{
- public:
- typedef TUnorderedMap<TString, TSymbol *> tLevel;
- typedef tLevel::const_iterator const_iterator;
- typedef const tLevel::value_type tLevelPair;
- typedef std::pair<tLevel::iterator, bool> tInsertResult;
-
- TSymbolTableLevel() : mGlobalInvariant(false) {}
- ~TSymbolTableLevel();
-
- bool insert(TSymbol *symbol);
-
- // Insert a function using its unmangled name as the key.
- bool insertUnmangled(TFunction *function);
-
- TSymbol *find(const TString &name) const;
-
- void addInvariantVarying(const std::string &name) { mInvariantVaryings.insert(name); }
-
- bool isVaryingInvariant(const std::string &name)
- {
- return (mGlobalInvariant || mInvariantVaryings.count(name) > 0);
- }
-
- void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; }
-
- void insertUnmangledBuiltInName(const char *name);
- bool hasUnmangledBuiltIn(const char *name) const;
-
- protected:
- tLevel level;
- std::set<std::string> mInvariantVaryings;
- bool mGlobalInvariant;
-
- private:
- struct CharArrayComparator
- {
- bool operator()(const char *a, const char *b) const { return strcmp(a, b) < 0; }
- };
- std::set<const char *, CharArrayComparator> mUnmangledBuiltInNames;
-};
-
// Define ESymbolLevel as int rather than an enum since level can go
// above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the
// compiler optimizes the >= of the last element to ==.
@@ -119,27 +76,18 @@
bool isEmpty() const { return table.empty(); }
bool atBuiltInLevel() const { return currentLevel() <= LAST_BUILTIN_LEVEL; }
bool atGlobalLevel() const { return currentLevel() == GLOBAL_LEVEL; }
- void push()
- {
- table.push_back(new TSymbolTableLevel);
- precisionStack.push_back(new PrecisionStackLevel);
- }
- void pop()
- {
- delete table.back();
- table.pop_back();
-
- delete precisionStack.back();
- precisionStack.pop_back();
- }
+ void push();
+ void pop();
// The declare* entry points are used when parsing and declare symbols at the current scope.
- // They return the created symbol / true in case the declaration was successful, and nullptr /
- // false if the declaration failed due to redefinition.
+ // They return the created true in case the declaration was successful, and false if the
+ // declaration failed due to redefinition.
bool declareVariable(TVariable *variable);
bool declareStructType(TStructure *str);
bool declareInterfaceBlock(TInterfaceBlock *interfaceBlock);
+ // Functions are always declared at global scope.
+ void declareUserDefinedFunction(TFunction *function, bool insertUnmangledName);
// 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 /
@@ -233,22 +181,25 @@
const TType *rvalue,
const char *name);
- TSymbol *find(const TString &name,
- int shaderVersion,
- bool *builtIn = nullptr,
- bool *sameScope = nullptr) const;
+ // These return the TFunction pointer to keep using to refer to this function.
+ const TFunction *markUserDefinedFunctionHasPrototypeDeclaration(
+ const TString &mangledName,
+ bool *hadPrototypeDeclarationOut);
+ const TFunction *setUserDefinedFunctionParameterNamesFromDefinition(const TFunction *function,
+ bool *wasDefinedOut);
- TSymbol *findGlobal(const TString &name) const;
+ const TSymbol *find(const TString &name,
+ int shaderVersion,
+ bool *builtIn = nullptr,
+ bool *sameScope = nullptr) const;
- TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
+ const TSymbol *findGlobal(const TString &name) const;
- TSymbol *findBuiltIn(const TString &name, int shaderVersion, bool includeGLSLBuiltins) const;
+ const TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
- TSymbolTableLevel *getOuterLevel()
- {
- assert(currentLevel() >= 1);
- return table[currentLevel() - 1];
- }
+ const TSymbol *findBuiltIn(const TString &name,
+ int shaderVersion,
+ bool includeGLSLBuiltins) const;
void setDefaultPrecision(TBasicType type, TPrecision prec)
{
@@ -263,26 +214,15 @@
// This records invariant varyings declared through
// "invariant varying_name;".
- void addInvariantVarying(const std::string &originalName)
- {
- ASSERT(atGlobalLevel());
- table[currentLevel()]->addInvariantVarying(originalName);
- }
+ void addInvariantVarying(const std::string &originalName);
+
// If this returns false, the varying could still be invariant
// if it is set as invariant during the varying variable
// declaration - this piece of information is stored in the
// variable's type, not here.
- bool isVaryingInvariant(const std::string &originalName) const
- {
- ASSERT(atGlobalLevel());
- return table[currentLevel()]->isVaryingInvariant(originalName);
- }
+ bool isVaryingInvariant(const std::string &originalName) const;
- void setGlobalInvariant(bool invariant)
- {
- ASSERT(atGlobalLevel());
- table[currentLevel()]->setGlobalInvariant(invariant);
- }
+ void setGlobalInvariant(bool invariant);
const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); }
@@ -296,6 +236,8 @@
friend class TSymbolUniqueId;
int nextUniqueIdValue();
+ class TSymbolTableLevel;
+
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
TVariable *insertVariable(ESymbolLevel level,
@@ -303,11 +245,9 @@
const TType *type,
SymbolType symbolType);
- bool insert(ESymbolLevel level, TSymbol *symbol)
- {
- ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
- return table[level]->insert(symbol);
- }
+ bool insert(ESymbolLevel level, TSymbol *symbol);
+
+ TFunction *findUserDefinedFunction(const TString &name) const;
// Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and
// above.
diff --git a/src/compiler/translator/Types.cpp b/src/compiler/translator/Types.cpp
index fb01658..b53bee3 100644
--- a/src/compiler/translator/Types.cpp
+++ b/src/compiler/translator/Types.cpp
@@ -210,7 +210,7 @@
{
}
-TType::TType(TInterfaceBlock *interfaceBlockIn,
+TType::TType(const TInterfaceBlock *interfaceBlockIn,
TQualifier qualifierIn,
TLayoutQualifier layoutQualifierIn)
: type(EbtInterfaceBlock),
@@ -757,7 +757,7 @@
}
}
-void TType::setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
+void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
{
if (mInterfaceBlock != interfaceBlockIn)
{
diff --git a/src/compiler/translator/Types.h b/src/compiler/translator/Types.h
index bd5df2d..d56b07c 100644
--- a/src/compiler/translator/Types.h
+++ b/src/compiler/translator/Types.h
@@ -98,7 +98,7 @@
unsigned char ss = 1);
explicit TType(const TPublicType &p);
explicit TType(const TStructure *userDef);
- TType(TInterfaceBlock *interfaceBlockIn,
+ TType(const TInterfaceBlock *interfaceBlockIn,
TQualifier qualifierIn,
TLayoutQualifier layoutQualifierIn);
TType(const TType &t);
@@ -213,8 +213,8 @@
// Note that the array element type might still be an array type in GLSL ES version >= 3.10.
void toArrayElementType();
- TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; }
- void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn);
+ const TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; }
+ void setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn);
bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
bool isVector() const { return primarySize > 1 && secondarySize == 1; }
@@ -341,7 +341,7 @@
// 1) Represents an interface block.
// 2) Represents the member variable of an unnamed interface block.
// It's nullptr also for members of named interface blocks.
- TInterfaceBlock *mInterfaceBlock;
+ const TInterfaceBlock *mInterfaceBlock;
// nullptr unless this is a struct
const TStructure *mStructure;
@@ -357,7 +357,7 @@
TBasicType type;
unsigned char primarySize; // size of vector or cols of matrix
unsigned char secondarySize; // rows of matrix
- TStructure *userDef;
+ const TStructure *userDef;
TSourceLoc line;
// true if the type was defined by a struct specifier rather than a reference to a type name.
@@ -374,7 +374,9 @@
isStructSpecifier = false;
}
- void initializeStruct(TStructure *aUserDef, bool aIsStructSpecifier, const TSourceLoc &aLine)
+ void initializeStruct(const TStructure *aUserDef,
+ bool aIsStructSpecifier,
+ const TSourceLoc &aLine)
{
type = EbtStruct;
primarySize = 1;
@@ -421,7 +423,7 @@
unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; }
- TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; }
+ const TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; }
const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }
bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }
diff --git a/src/compiler/translator/glslang.l b/src/compiler/translator/glslang.l
index c12161d..6a52f4b 100644
--- a/src/compiler/translator/glslang.l
+++ b/src/compiler/translator/glslang.l
@@ -441,7 +441,7 @@
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
int token = IDENTIFIER;
- TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
+ const TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
if (symbol && symbol->isStruct())
{
token = TYPE_NAME;
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index 214eac0..aeddf29 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -69,7 +69,7 @@
unsigned int u;
bool b;
};
- TSymbol* symbol;
+ const TSymbol* symbol;
} lex;
struct {
TOperator op;
@@ -1196,7 +1196,7 @@
}
| TYPE_NAME {
// This is for user defined type names. The lexical phase looked up the type.
- TStructure *structure = static_cast<TStructure*>($1.symbol);
+ const TStructure *structure = static_cast<const TStructure*>($1.symbol);
$$.initializeStruct(structure, false, @1);
}
;
@@ -1456,7 +1456,7 @@
function_definition
: function_prototype {
- context->parseFunctionDefinitionHeader(@1, &($1.function), &($1.intermFunctionPrototype));
+ context->parseFunctionDefinitionHeader(@1, $1.function, &($1.intermFunctionPrototype));
}
compound_statement_no_new_scope {
$$ = context->addFunctionDefinition($1.intermFunctionPrototype, $3, @1);
diff --git a/src/compiler/translator/glslang_lex.cpp b/src/compiler/translator/glslang_lex.cpp
index 71b2f2e..c1221a8 100644
--- a/src/compiler/translator/glslang_lex.cpp
+++ b/src/compiler/translator/glslang_lex.cpp
@@ -3797,7 +3797,7 @@
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
int token = IDENTIFIER;
- TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
+ const TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
if (symbol && symbol->isStruct())
{
token = TYPE_NAME;
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index e567197..00809dd 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -310,7 +310,7 @@
unsigned int u;
bool b;
};
- TSymbol* symbol;
+ const TSymbol* symbol;
} lex;
struct {
TOperator op;
@@ -743,36 +743,36 @@
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 251, 251, 252, 255, 265, 268, 273, 278, 283,
- 288, 297, 303, 306, 309, 312, 315, 318, 324, 331,
- 337, 341, 349, 352, 358, 362, 369, 374, 381, 389,
- 392, 395, 401, 404, 407, 410, 417, 418, 419, 420,
- 428, 429, 432, 435, 442, 443, 446, 452, 453, 457,
- 464, 465, 468, 471, 474, 480, 481, 484, 490, 491,
- 498, 499, 506, 507, 514, 515, 521, 522, 528, 529,
- 535, 536, 542, 543, 549, 550, 551, 552, 556, 557,
- 558, 562, 566, 570, 574, 581, 584, 590, 597, 604,
- 607, 610, 614, 618, 622, 626, 630, 637, 644, 647,
- 654, 662, 679, 689, 692, 698, 702, 706, 710, 717,
- 724, 727, 731, 735, 740, 747, 751, 755, 759, 764,
- 771, 775, 781, 784, 790, 794, 801, 807, 811, 815,
- 818, 821, 830, 835, 839, 842, 845, 848, 851, 855,
- 858, 862, 865, 868, 871, 874, 877, 884, 891, 894,
- 897, 903, 910, 913, 919, 922, 925, 928, 934, 937,
- 944, 949, 956, 961, 972, 975, 978, 981, 984, 987,
- 991, 995, 999, 1003, 1007, 1011, 1015, 1019, 1023, 1027,
- 1031, 1035, 1039, 1043, 1047, 1051, 1055, 1059, 1063, 1067,
- 1071, 1078, 1081, 1084, 1087, 1090, 1093, 1096, 1099, 1102,
- 1105, 1108, 1111, 1114, 1117, 1120, 1123, 1126, 1129, 1132,
- 1142, 1149, 1156, 1159, 1162, 1165, 1168, 1171, 1174, 1177,
- 1180, 1183, 1186, 1189, 1192, 1195, 1198, 1206, 1206, 1209,
- 1209, 1215, 1218, 1224, 1227, 1234, 1238, 1244, 1247, 1253,
- 1257, 1261, 1262, 1268, 1269, 1270, 1271, 1272, 1273, 1274,
- 1278, 1282, 1282, 1282, 1289, 1290, 1294, 1294, 1295, 1295,
- 1300, 1304, 1311, 1315, 1322, 1323, 1327, 1333, 1337, 1346,
- 1346, 1353, 1356, 1362, 1366, 1372, 1372, 1377, 1377, 1381,
- 1381, 1389, 1392, 1398, 1401, 1407, 1411, 1418, 1421, 1424,
- 1427, 1430, 1438, 1444, 1450, 1453, 1459, 1459
+ 0, 250, 250, 251, 254, 264, 267, 272, 277, 282,
+ 287, 296, 302, 305, 308, 311, 314, 317, 323, 330,
+ 336, 340, 348, 351, 357, 361, 368, 373, 380, 388,
+ 391, 394, 400, 403, 406, 409, 416, 417, 418, 419,
+ 427, 428, 431, 434, 441, 442, 445, 451, 452, 456,
+ 463, 464, 467, 470, 473, 479, 480, 483, 489, 490,
+ 497, 498, 505, 506, 513, 514, 520, 521, 527, 528,
+ 534, 535, 541, 542, 548, 549, 550, 551, 555, 556,
+ 557, 561, 565, 569, 573, 580, 583, 589, 596, 603,
+ 606, 609, 613, 617, 621, 625, 629, 636, 643, 646,
+ 653, 661, 678, 688, 691, 697, 701, 705, 709, 716,
+ 723, 726, 730, 734, 739, 746, 750, 754, 758, 763,
+ 770, 774, 780, 783, 789, 793, 800, 806, 810, 814,
+ 817, 820, 829, 834, 838, 841, 844, 847, 850, 854,
+ 857, 861, 864, 867, 870, 873, 876, 883, 890, 893,
+ 896, 902, 909, 912, 918, 921, 924, 927, 933, 936,
+ 943, 948, 955, 960, 971, 974, 977, 980, 983, 986,
+ 990, 994, 998, 1002, 1006, 1010, 1014, 1018, 1022, 1026,
+ 1030, 1034, 1038, 1042, 1046, 1050, 1054, 1058, 1062, 1066,
+ 1070, 1077, 1080, 1083, 1086, 1089, 1092, 1095, 1098, 1101,
+ 1104, 1107, 1110, 1113, 1116, 1119, 1122, 1125, 1128, 1131,
+ 1141, 1148, 1155, 1158, 1161, 1164, 1167, 1170, 1173, 1176,
+ 1179, 1182, 1185, 1188, 1191, 1194, 1197, 1205, 1205, 1208,
+ 1208, 1214, 1217, 1223, 1226, 1233, 1237, 1243, 1246, 1252,
+ 1256, 1260, 1261, 1267, 1268, 1269, 1270, 1271, 1272, 1273,
+ 1277, 1281, 1281, 1281, 1288, 1289, 1293, 1293, 1294, 1294,
+ 1299, 1303, 1310, 1314, 1321, 1322, 1326, 1332, 1336, 1345,
+ 1345, 1352, 1355, 1361, 1365, 1371, 1371, 1376, 1376, 1380,
+ 1380, 1388, 1391, 1397, 1400, 1406, 1410, 1417, 1420, 1423,
+ 1426, 1429, 1437, 1443, 1449, 1452, 1458, 1458
};
#endif
@@ -4383,7 +4383,7 @@
{
// This is for user defined type names. The lexical phase looked up the type.
- TStructure *structure = static_cast<TStructure*>((yyvsp[0].lex).symbol);
+ const TStructure *structure = static_cast<const TStructure*>((yyvsp[0].lex).symbol);
(yyval.interm.typeSpecifierNonArray).initializeStruct(structure, false, (yylsp[0]));
}
@@ -4912,7 +4912,7 @@
case 296:
{
- context->parseFunctionDefinitionHeader((yylsp[0]), &((yyvsp[0].interm).function), &((yyvsp[0].interm).intermFunctionPrototype));
+ context->parseFunctionDefinitionHeader((yylsp[0]), (yyvsp[0].interm).function, &((yyvsp[0].interm).intermFunctionPrototype));
}
break;
diff --git a/src/compiler/translator/glslang_tab.h b/src/compiler/translator/glslang_tab.h
index ae436c7..048831b 100644
--- a/src/compiler/translator/glslang_tab.h
+++ b/src/compiler/translator/glslang_tab.h
@@ -221,7 +221,7 @@
unsigned int u;
bool b;
};
- TSymbol* symbol;
+ const TSymbol *symbol;
} lex;
struct {
TOperator op;