Commit dd21ecf8 by Olli Etuaho Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org>
parent 66f73b73
......@@ -259,8 +259,8 @@ std::string CollectVariablesTraverser::getMappedName(const TSymbol *symbol) cons
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();
......
......@@ -147,9 +147,9 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
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 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
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();
......
......@@ -28,13 +28,13 @@ class FlagStd140StructsTraverser : public TIntermTraverser
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 @@ bool FlagStd140StructsTraverser::visitDeclaration(Visit visit, TIntermDeclaratio
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);
......
......@@ -22,7 +22,7 @@ const TFunction *LookUpBuiltInFunction(const TString &name,
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 @@ TIntermBlock *EnsureBlock(TIntermNode *node)
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);
}
......
......@@ -738,10 +738,10 @@ void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
{
// 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));
}
......
......@@ -260,7 +260,7 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
}
if (type.getBasicType() == EbtInterfaceBlock)
{
TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
declareInterfaceBlockLayout(interfaceBlock);
}
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
......@@ -317,7 +317,7 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
}
else if (type.getBasicType() == EbtInterfaceBlock)
{
TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
declareInterfaceBlock(interfaceBlock);
}
else
......
......@@ -349,7 +349,7 @@ TString OutputHLSL::generateStructMapping(const std::vector<MappedStruct> &std14
for (auto &mappedStruct : std140Structs)
{
TInterfaceBlock *interfaceBlock =
const TInterfaceBlock *interfaceBlock =
mappedStruct.blockDeclarator->getType().getInterfaceBlock();
if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
{
......@@ -1259,7 +1259,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
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()] =
......
......@@ -1134,7 +1134,7 @@ bool TParseContext::declareVariable(const TSourceLoc &line,
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 @@ void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
{
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 @@ TIntermFunctionPrototype *TParseContext::addFunctionPrototypeDeclaration(
// 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 @@ TIntermFunctionDefinition *TParseContext::addFunctionDefinition(
}
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 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
// 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 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
}
}
//
// 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")
......
......@@ -285,7 +285,7 @@ class TParseContext : angle::NonCopyable
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,
......
......@@ -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 @@ bool TSymbolTableLevel::insert(TSymbol *symbol)
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 @@ bool TSymbolTableLevel::insertUnmangled(TFunction *function)
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 @@ TSymbol *TSymbolTableLevel::find(const TString &name) const
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()
{
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)
{
int level = currentLevel();
TSymbol *symbol;
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 @@ TSymbol *TSymbolTable::find(const TString &name,
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 @@ TSymbol *TSymbolTable::find(const TString &name,
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 @@ bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
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 @@ bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
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 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
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()));
......
......@@ -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 @@ class TSymbolTable : angle::NonCopyable
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 @@ class TSymbolTable : angle::NonCopyable
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 @@ class TSymbolTable : angle::NonCopyable
// 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 @@ class TSymbolTable : angle::NonCopyable
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 @@ class TSymbolTable : angle::NonCopyable
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.
......
......@@ -210,7 +210,7 @@ TType::TType(const TStructure *userDef)
{
}
TType::TType(TInterfaceBlock *interfaceBlockIn,
TType::TType(const TInterfaceBlock *interfaceBlockIn,
TQualifier qualifierIn,
TLayoutQualifier layoutQualifierIn)
: type(EbtInterfaceBlock),
......@@ -757,7 +757,7 @@ void TType::toArrayElementType()
}
}
void TType::setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
{
if (mInterfaceBlock != interfaceBlockIn)
{
......
......@@ -98,7 +98,7 @@ class TType
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 @@ class TType
// 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 @@ class TType
// 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 @@ struct TTypeSpecifierNonArray
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 @@ struct TTypeSpecifierNonArray
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 @@ struct TPublicType
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; }
......
......@@ -441,7 +441,7 @@ int check_type(yyscan_t yyscanner) {
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;
......
......@@ -69,7 +69,7 @@ using namespace sh;
unsigned int u;
bool b;
};
TSymbol* symbol;
const TSymbol* symbol;
} lex;
struct {
TOperator op;
......@@ -1196,7 +1196,7 @@ type_specifier_nonarray
}
| 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 @@ external_declaration
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);
......
......@@ -3797,7 +3797,7 @@ int check_type(yyscan_t yyscanner) {
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;
......
......@@ -310,7 +310,7 @@ union YYSTYPE
unsigned int u;
bool b;
};
TSymbol* symbol;
const TSymbol* symbol;
} lex;
struct {
TOperator op;
......@@ -743,36 +743,36 @@ static const yytype_uint8 yytranslate[] =
/* 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 @@ yyreduce:
{
// 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 @@ yyreduce:
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;
......
......@@ -221,7 +221,7 @@ union YYSTYPE
unsigned int u;
bool b;
};
TSymbol* symbol;
const TSymbol *symbol;
} lex;
struct {
TOperator op;
......
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