Commit 2d88e9bc by Olli Etuaho Committed by Commit Bot

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/580955Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent bf90b603
...@@ -140,6 +140,8 @@ ...@@ -140,6 +140,8 @@
'compiler/translator/SplitSequenceOperator.h', 'compiler/translator/SplitSequenceOperator.h',
'compiler/translator/SymbolTable.cpp', 'compiler/translator/SymbolTable.cpp',
'compiler/translator/SymbolTable.h', 'compiler/translator/SymbolTable.h',
'compiler/translator/SymbolUniqueId.cpp',
'compiler/translator/SymbolUniqueId.h',
'compiler/translator/Types.cpp', 'compiler/translator/Types.cpp',
'compiler/translator/Types.h', 'compiler/translator/Types.h',
'compiler/translator/UnfoldShortCircuitAST.cpp', 'compiler/translator/UnfoldShortCircuitAST.cpp',
......
...@@ -30,7 +30,7 @@ void CopyAggregateChildren(TIntermAggregateBase *from, TIntermAggregateBase *to) ...@@ -30,7 +30,7 @@ void CopyAggregateChildren(TIntermAggregateBase *from, TIntermAggregateBase *to)
TIntermSymbol *CreateReturnValueSymbol(const TSymbolUniqueId &id, const TType &type) TIntermSymbol *CreateReturnValueSymbol(const TSymbolUniqueId &id, const TType &type)
{ {
TIntermSymbol *node = new TIntermSymbol(id.get(), "angle_return", type); TIntermSymbol *node = new TIntermSymbol(id, "angle_return", type);
node->setInternal(true); node->setInternal(true);
node->getTypePointer()->setQualifier(EvqOut); node->getTypePointer()->setQualifier(EvqOut);
return node; return node;
......
...@@ -132,7 +132,7 @@ void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol, ...@@ -132,7 +132,7 @@ void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol,
new TIntermBinary(EOpAssign, viewportIndexSymbol, viewIDAsInt)); new TIntermBinary(EOpAssign, viewportIndexSymbol, viewIDAsInt));
// Create a gl_Layer node. // Create a gl_Layer node.
TIntermSymbol *layerSymbol = new TIntermSymbol(0, "gl_Layer", TType(EbtInt, EbpHigh, EvqLayer)); TIntermSymbol *layerSymbol = ReferenceBuiltInVariable("gl_Layer", symbolTable, 0);
// Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node // Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node
TIntermBinary *sumOfViewIDAndBaseViewIndex = TIntermBinary *sumOfViewIDAndBaseViewIndex =
......
...@@ -964,6 +964,8 @@ void IdentifyBuiltIns(sh::GLenum type, ...@@ -964,6 +964,8 @@ void IdentifyBuiltIns(sh::GLenum type,
// For internal use by ANGLE - not exposed to the parser. // For internal use by ANGLE - not exposed to the parser.
symbolTable.insertVariable(GLSL_BUILTINS, "gl_ViewportIndex", symbolTable.insertVariable(GLSL_BUILTINS, "gl_ViewportIndex",
TType(EbtInt, EbpHigh, EvqViewportIndex)); TType(EbtInt, EbpHigh, EvqViewportIndex));
// gl_Layer exists in other shader stages in ESSL, but not in vertex shader so far.
symbolTable.insertVariable(GLSL_BUILTINS, "gl_Layer", TType(EbtInt, EbpHigh, EvqLayer));
break; break;
} }
case GL_COMPUTE_SHADER: case GL_COMPUTE_SHADER:
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "compiler/translator/Common.h" #include "compiler/translator/Common.h"
#include "compiler/translator/ConstantUnion.h" #include "compiler/translator/ConstantUnion.h"
#include "compiler/translator/Operator.h" #include "compiler/translator/Operator.h"
#include "compiler/translator/SymbolUniqueId.h"
#include "compiler/translator/Types.h" #include "compiler/translator/Types.h"
namespace sh namespace sh
...@@ -56,7 +57,6 @@ class TIntermRaw; ...@@ -56,7 +57,6 @@ class TIntermRaw;
class TIntermBranch; class TIntermBranch;
class TSymbolTable; class TSymbolTable;
class TSymbolUniqueId;
class TFunction; class TFunction;
// Encapsulate an identifier string and track whether it is coming from the original shader code // Encapsulate an identifier string and track whether it is coming from the original shader code
...@@ -257,7 +257,7 @@ class TIntermSymbol : public TIntermTyped ...@@ -257,7 +257,7 @@ class TIntermSymbol : public TIntermTyped
// if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym.
// If sym comes from per process globalpoolallocator, then it causes increased memory usage // If sym comes from per process globalpoolallocator, then it causes increased memory usage
// per compile it is essential to use "symbol = sym" to assign to symbol // per compile it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(int id, const TString &symbol, const TType &type) TIntermSymbol(const TSymbolUniqueId &id, const TString &symbol, const TType &type)
: TIntermTyped(type), mId(id), mSymbol(symbol) : TIntermTyped(type), mId(id), mSymbol(symbol)
{ {
} }
...@@ -266,7 +266,7 @@ class TIntermSymbol : public TIntermTyped ...@@ -266,7 +266,7 @@ class TIntermSymbol : public TIntermTyped
bool hasSideEffects() const override { return false; } bool hasSideEffects() const override { return false; }
int getId() const { return mId; } int getId() const { return mId.get(); }
const TString &getSymbol() const { return mSymbol.getString(); } const TString &getSymbol() const { return mSymbol.getString(); }
const TName &getName() const { return mSymbol; } const TName &getName() const { return mSymbol; }
TName &getName() { return mSymbol; } TName &getName() { return mSymbol; }
...@@ -278,7 +278,7 @@ class TIntermSymbol : public TIntermTyped ...@@ -278,7 +278,7 @@ class TIntermSymbol : public TIntermTyped
bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; } bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
protected: protected:
const int mId; const TSymbolUniqueId mId;
TName mSymbol; TName mSymbol;
private: private:
......
...@@ -178,7 +178,7 @@ TIntermSymbol *CreateTempSymbolNode(const TSymbolUniqueId &id, ...@@ -178,7 +178,7 @@ TIntermSymbol *CreateTempSymbolNode(const TSymbolUniqueId &id,
symbolNameOut << "s" << id.get(); symbolNameOut << "s" << id.get();
TString symbolName = symbolNameOut.c_str(); TString symbolName = symbolNameOut.c_str();
TIntermSymbol *node = new TIntermSymbol(id.get(), symbolName, type); TIntermSymbol *node = new TIntermSymbol(id, symbolName, type);
node->setInternal(true); node->setInternal(true);
ASSERT(qualifier == EvqTemporary || qualifier == EvqConst || qualifier == EvqGlobal); ASSERT(qualifier == EvqTemporary || qualifier == EvqConst || qualifier == EvqGlobal);
......
...@@ -119,8 +119,9 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -119,8 +119,9 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
ShShaderOutput outputType, ShShaderOutput outputType,
int numRenderTargets, int numRenderTargets,
const std::vector<Uniform> &uniforms, const std::vector<Uniform> &uniforms,
ShCompileOptions compileOptions) ShCompileOptions compileOptions,
: TIntermTraverser(true, true, true), TSymbolTable *symbolTable)
: TIntermTraverser(true, true, true, symbolTable),
mShaderType(shaderType), mShaderType(shaderType),
mShaderVersion(shaderVersion), mShaderVersion(shaderVersion),
mExtensionBehavior(extensionBehavior), mExtensionBehavior(extensionBehavior),
...@@ -375,7 +376,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built ...@@ -375,7 +376,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built
out << mStructureHLSL->structsHeader(); out << mStructureHLSL->structsHeader();
mUniformHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms); mUniformHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms, mSymbolTable);
out << mUniformHLSL->uniformBlocksHeader(mReferencedUniformBlocks); out << mUniformHLSL->uniformBlocksHeader(mReferencedUniformBlocks);
if (!mEqualityFunctions.empty()) if (!mEqualityFunctions.empty())
...@@ -1895,8 +1896,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1895,8 +1896,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
const TType &argType = typedArg->getType(); const TType &argType = typedArg->getType();
TVector<TIntermSymbol *> samplerSymbols; TVector<TIntermSymbol *> samplerSymbols;
TString structName = samplerNamePrefixFromStruct(typedArg); TString structName = samplerNamePrefixFromStruct(typedArg);
argType.createSamplerSymbols("angle_" + structName, "", argType.createSamplerSymbols("angle_" + structName, "", &samplerSymbols,
&samplerSymbols, nullptr); nullptr, mSymbolTable);
for (const TIntermSymbol *sampler : samplerSymbols) for (const TIntermSymbol *sampler : samplerSymbols)
{ {
if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
...@@ -2626,7 +2627,7 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol) ...@@ -2626,7 +2627,7 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
{ {
ASSERT(qualifier != EvqOut && qualifier != EvqInOut); ASSERT(qualifier != EvqOut && qualifier != EvqInOut);
TVector<TIntermSymbol *> samplerSymbols; TVector<TIntermSymbol *> samplerSymbols;
type.createSamplerSymbols("angle" + nameStr, "", &samplerSymbols, nullptr); type.createSamplerSymbols("angle" + nameStr, "", &samplerSymbols, nullptr, mSymbolTable);
for (const TIntermSymbol *sampler : samplerSymbols) for (const TIntermSymbol *sampler : samplerSymbols)
{ {
const TType &samplerType = sampler->getType(); const TType &samplerType = sampler->getType();
......
...@@ -22,6 +22,7 @@ namespace sh ...@@ -22,6 +22,7 @@ namespace sh
{ {
class StructureHLSL; class StructureHLSL;
class TextureFunctionHLSL; class TextureFunctionHLSL;
class TSymbolTable;
class UnfoldShortCircuit; class UnfoldShortCircuit;
class UniformHLSL; class UniformHLSL;
...@@ -37,7 +38,8 @@ class OutputHLSL : public TIntermTraverser ...@@ -37,7 +38,8 @@ class OutputHLSL : public TIntermTraverser
ShShaderOutput outputType, ShShaderOutput outputType,
int numRenderTargets, int numRenderTargets,
const std::vector<Uniform> &uniforms, const std::vector<Uniform> &uniforms,
ShCompileOptions compileOptions); ShCompileOptions compileOptions,
TSymbolTable *symbolTable);
~OutputHLSL(); ~OutputHLSL();
......
...@@ -2311,7 +2311,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2311,7 +2311,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
// But if the empty declaration is declaring a struct type, the symbol node will store that. // But if the empty declaration is declaring a struct type, the symbol node will store that.
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
{ {
symbol = new TIntermSymbol(0, "", type); symbol = new TIntermSymbol(symbolTable.getEmptySymbolId(), "", type);
} }
else if (IsAtomicCounter(publicType.getBasicType())) else if (IsAtomicCounter(publicType.getBasicType()))
{ {
...@@ -3075,7 +3075,7 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction( ...@@ -3075,7 +3075,7 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
{ {
// The parameter had no name or declaring the symbol failed - either way, add a nameless // The parameter had no name or declaring the symbol failed - either way, add a nameless
// symbol. // symbol.
symbol = new TIntermSymbol(0, "", *param.type); symbol = new TIntermSymbol(symbolTable.getEmptySymbolId(), "", *param.type);
} }
symbol->setLine(location); symbol->setLine(location);
prototype->appendParameter(symbol); prototype->appendParameter(symbol);
...@@ -3637,7 +3637,7 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -3637,7 +3637,7 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
} }
TString symbolName = ""; TString symbolName = "";
int symbolId = 0; const TSymbolUniqueId *symbolId = nullptr;
if (!instanceName) if (!instanceName)
{ {
...@@ -3662,6 +3662,7 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -3662,6 +3662,7 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
field->name().c_str()); field->name().c_str());
} }
} }
symbolId = &symbolTable.getEmptySymbolId();
} }
else else
{ {
...@@ -3672,7 +3673,7 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -3672,7 +3673,7 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
if (instanceTypeDef) if (instanceTypeDef)
{ {
instanceTypeDef->setQualifier(typeQualifier.qualifier); instanceTypeDef->setQualifier(typeQualifier.qualifier);
symbolId = instanceTypeDef->getUniqueId(); symbolId = &instanceTypeDef->getUniqueId();
} }
else else
{ {
...@@ -3682,11 +3683,16 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -3682,11 +3683,16 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
symbolName = *instanceName; symbolName = *instanceName;
} }
TIntermSymbol *blockSymbol = new TIntermSymbol(symbolId, symbolName, interfaceBlockType); TIntermDeclaration *declaration = nullptr;
blockSymbol->setLine(typeQualifier.line);
TIntermDeclaration *declaration = new TIntermDeclaration(); if (symbolId)
declaration->appendDeclarator(blockSymbol); {
declaration->setLine(nameLine); TIntermSymbol *blockSymbol = new TIntermSymbol(*symbolId, symbolName, interfaceBlockType);
blockSymbol->setLine(typeQualifier.line);
declaration = new TIntermDeclaration();
declaration->appendDeclarator(blockSymbol);
declaration->setLine(nameLine);
}
exitStructDeclaration(); exitStructDeclaration();
return declaration; return declaration;
......
...@@ -29,19 +29,6 @@ static const char kFunctionMangledNameSeparator = '('; ...@@ -29,19 +29,6 @@ static const char kFunctionMangledNameSeparator = '(';
} // anonymous namespace } // anonymous namespace
TSymbolUniqueId::TSymbolUniqueId(TSymbolTable *symbolTable) : mId(symbolTable->nextUniqueId())
{
}
TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.getUniqueId())
{
}
int TSymbolUniqueId::get() const
{
return mId;
}
TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *n) TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *n)
: uniqueId(symbolTable->nextUniqueId()), name(n), extension(TExtension::UNDEFINED) : uniqueId(symbolTable->nextUniqueId()), name(n), extension(TExtension::UNDEFINED)
{ {
......
...@@ -38,26 +38,11 @@ ...@@ -38,26 +38,11 @@
#include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolUniqueId.h"
namespace sh 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...) // Symbol base class. (Can build functions or variables out of these...)
class TSymbol : angle::NonCopyable class TSymbol : angle::NonCopyable
{ {
...@@ -74,12 +59,12 @@ class TSymbol : angle::NonCopyable ...@@ -74,12 +59,12 @@ class TSymbol : angle::NonCopyable
virtual const TString &getMangledName() const { return getName(); } virtual const TString &getMangledName() const { return getName(); }
virtual bool isFunction() const { return false; } virtual bool isFunction() const { return false; }
virtual bool isVariable() 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; } void relateToExtension(TExtension ext) { extension = ext; }
TExtension getExtension() const { return extension; } TExtension getExtension() const { return extension; }
private: private:
const int uniqueId; const TSymbolUniqueId uniqueId;
const TString *name; const TString *name;
TExtension extension; TExtension extension;
}; };
...@@ -302,7 +287,7 @@ const int GLOBAL_LEVEL = 5; ...@@ -302,7 +287,7 @@ const int GLOBAL_LEVEL = 5;
class TSymbolTable : angle::NonCopyable class TSymbolTable : angle::NonCopyable
{ {
public: public:
TSymbolTable() : mUniqueIdCounter(0) TSymbolTable() : mUniqueIdCounter(0), mEmptySymbolId(this)
{ {
// The symbol table cannot be used until push() is called, but // The symbol table cannot be used until push() is called, but
// the lack of an initial call to push() can be used to detect // the lack of an initial call to push() can be used to detect
...@@ -514,12 +499,20 @@ class TSymbolTable : angle::NonCopyable ...@@ -514,12 +499,20 @@ class TSymbolTable : angle::NonCopyable
table[currentLevel()]->setGlobalInvariant(invariant); 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. // Checks whether there is a built-in accessible by a shader with the specified version.
bool hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion); bool hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion);
private: private:
friend class TSymbolUniqueId;
int nextUniqueIdValue() { return ++mUniqueIdCounter; }
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); } ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
TVariable *insertVariable(ESymbolLevel level, const TString *name, const TType &type); TVariable *insertVariable(ESymbolLevel level, const TString *name, const TType &type);
...@@ -543,6 +536,8 @@ class TSymbolTable : angle::NonCopyable ...@@ -543,6 +536,8 @@ class TSymbolTable : angle::NonCopyable
std::vector<PrecisionStackLevel *> precisionStack; std::vector<PrecisionStackLevel *> precisionStack;
int mUniqueIdCounter; int mUniqueIdCounter;
const TSymbolUniqueId mEmptySymbolId;
}; };
} // namespace sh } // namespace sh
......
//
// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SymbolUniqueId.cpp: Encapsulates a unique id for a symbol.
#include "compiler/translator/SymbolUniqueId.h"
#include "compiler/translator/SymbolTable.h"
namespace sh
{
TSymbolUniqueId::TSymbolUniqueId(TSymbolTable *symbolTable) : mId(symbolTable->nextUniqueIdValue())
{
}
TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.getUniqueId().get())
{
}
int TSymbolUniqueId::get() const
{
return mId;
}
} // namespace sh
//
// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SymbolUniqueId.h: Encapsulates a unique id for a symbol.
#ifndef COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
#define COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
#include "compiler/translator/Common.h"
namespace sh
{
class TSymbolTable;
class TSymbol;
class TSymbolUniqueId
{
public:
POOL_ALLOCATOR_NEW_DELETE();
explicit TSymbolUniqueId(TSymbolTable *symbolTable);
explicit TSymbolUniqueId(const TSymbol &symbol);
TSymbolUniqueId(const TSymbolUniqueId &) = default;
TSymbolUniqueId &operator=(const TSymbolUniqueId &) = default;
int get() const;
private:
int mId;
};
} // namespace sh
#endif // COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
...@@ -126,7 +126,7 @@ void TranslatorHLSL::translate(TIntermBlock *root, ShCompileOptions compileOptio ...@@ -126,7 +126,7 @@ void TranslatorHLSL::translate(TIntermBlock *root, ShCompileOptions compileOptio
sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(), sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(),
getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), getSourcePath(), getOutputType(), numRenderTargets, getUniforms(),
compileOptions); compileOptions, &getSymbolTable());
outputHLSL.output(root, getInfoSink().obj); outputHLSL.output(root, getInfoSink().obj);
......
...@@ -621,7 +621,8 @@ bool TStructure::containsSamplers() const ...@@ -621,7 +621,8 @@ bool TStructure::containsSamplers() const
void TType::createSamplerSymbols(const TString &namePrefix, void TType::createSamplerSymbols(const TString &namePrefix,
const TString &apiNamePrefix, const TString &apiNamePrefix,
TVector<TIntermSymbol *> *outputSymbols, TVector<TIntermSymbol *> *outputSymbols,
TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
TSymbolTable *symbolTable) const
{ {
if (isStructureContainingSamplers()) if (isStructureContainingSamplers())
{ {
...@@ -636,18 +637,20 @@ void TType::createSamplerSymbols(const TString &namePrefix, ...@@ -636,18 +637,20 @@ void TType::createSamplerSymbols(const TString &namePrefix,
TStringStream elementApiName; TStringStream elementApiName;
elementApiName << apiNamePrefix << "[" << arrayIndex << "]"; elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
elementType.createSamplerSymbols(elementName.str(), elementApiName.str(), elementType.createSamplerSymbols(elementName.str(), elementApiName.str(),
outputSymbols, outputSymbolsToAPINames); outputSymbols, outputSymbolsToAPINames,
symbolTable);
} }
} }
else else
{ {
structure->createSamplerSymbols(namePrefix, apiNamePrefix, outputSymbols, structure->createSamplerSymbols(namePrefix, apiNamePrefix, outputSymbols,
outputSymbolsToAPINames); outputSymbolsToAPINames, symbolTable);
} }
return; return;
} }
ASSERT(IsSampler(type)); ASSERT(IsSampler(type));
TIntermSymbol *symbol = new TIntermSymbol(0, namePrefix, *this); TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), namePrefix, *this);
outputSymbols->push_back(symbol); outputSymbols->push_back(symbol);
if (outputSymbolsToAPINames) if (outputSymbolsToAPINames)
{ {
...@@ -658,7 +661,8 @@ void TType::createSamplerSymbols(const TString &namePrefix, ...@@ -658,7 +661,8 @@ void TType::createSamplerSymbols(const TString &namePrefix,
void TStructure::createSamplerSymbols(const TString &namePrefix, void TStructure::createSamplerSymbols(const TString &namePrefix,
const TString &apiNamePrefix, const TString &apiNamePrefix,
TVector<TIntermSymbol *> *outputSymbols, TVector<TIntermSymbol *> *outputSymbols,
TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
TSymbolTable *symbolTable) const
{ {
ASSERT(containsSamplers()); ASSERT(containsSamplers());
for (auto &field : *mFields) for (auto &field : *mFields)
...@@ -669,7 +673,7 @@ void TStructure::createSamplerSymbols(const TString &namePrefix, ...@@ -669,7 +673,7 @@ void TStructure::createSamplerSymbols(const TString &namePrefix,
TString fieldName = namePrefix + "_" + field->name(); TString fieldName = namePrefix + "_" + field->name();
TString fieldApiName = apiNamePrefix + "." + field->name(); TString fieldApiName = apiNamePrefix + "." + field->name();
fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols, fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
outputSymbolsToAPINames); outputSymbolsToAPINames, symbolTable);
} }
} }
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "compiler/translator/BaseTypes.h" #include "compiler/translator/BaseTypes.h"
#include "compiler/translator/Common.h" #include "compiler/translator/Common.h"
#include "compiler/translator/SymbolUniqueId.h"
namespace sh namespace sh
{ {
...@@ -103,15 +104,12 @@ class TStructure : public TFieldListCollection ...@@ -103,15 +104,12 @@ class TStructure : public TFieldListCollection
void createSamplerSymbols(const TString &namePrefix, void createSamplerSymbols(const TString &namePrefix,
const TString &apiNamePrefix, const TString &apiNamePrefix,
TVector<TIntermSymbol *> *outputSymbols, TVector<TIntermSymbol *> *outputSymbols,
TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const; TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
TSymbolTable *symbolTable) const;
bool equals(const TStructure &other) const; bool equals(const TStructure &other) const;
int uniqueId() const int uniqueId() const { return mUniqueId.get(); }
{
ASSERT(mUniqueId != 0);
return mUniqueId;
}
void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; } void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }
...@@ -138,7 +136,7 @@ class TStructure : public TFieldListCollection ...@@ -138,7 +136,7 @@ class TStructure : public TFieldListCollection
int calculateDeepestNesting() const; int calculateDeepestNesting() const;
mutable int mDeepestNesting; mutable int mDeepestNesting;
const int mUniqueId; const TSymbolUniqueId mUniqueId;
bool mAtGlobalScope; bool mAtGlobalScope;
}; };
...@@ -478,7 +476,8 @@ class TType ...@@ -478,7 +476,8 @@ class TType
void createSamplerSymbols(const TString &namePrefix, void createSamplerSymbols(const TString &namePrefix,
const TString &apiNamePrefix, const TString &apiNamePrefix,
TVector<TIntermSymbol *> *outputSymbols, TVector<TIntermSymbol *> *outputSymbols,
TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const; TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
TSymbolTable *symbolTable) const;
// Initializes all lazily-initialized members. // Initializes all lazily-initialized members.
void realize() { getMangledName(); } void realize() { getMangledName(); }
......
...@@ -278,7 +278,8 @@ void UniformHLSL::outputUniform(TInfoSinkBase &out, ...@@ -278,7 +278,8 @@ void UniformHLSL::outputUniform(TInfoSinkBase &out,
void UniformHLSL::uniformsHeader(TInfoSinkBase &out, void UniformHLSL::uniformsHeader(TInfoSinkBase &out,
ShShaderOutput outputType, ShShaderOutput outputType,
const ReferencedSymbols &referencedUniforms) const ReferencedSymbols &referencedUniforms,
TSymbolTable *symbolTable)
{ {
if (!referencedUniforms.empty()) if (!referencedUniforms.empty())
{ {
...@@ -313,7 +314,7 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out, ...@@ -313,7 +314,7 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out,
TVector<TIntermSymbol *> samplerSymbols; TVector<TIntermSymbol *> samplerSymbols;
TMap<TIntermSymbol *, TString> symbolsToAPINames; TMap<TIntermSymbol *, TString> symbolsToAPINames;
type.createSamplerSymbols("angle_" + name.getString(), name.getString(), type.createSamplerSymbols("angle_" + name.getString(), name.getString(),
&samplerSymbols, &symbolsToAPINames); &samplerSymbols, &symbolsToAPINames, symbolTable);
for (TIntermSymbol *sampler : samplerSymbols) for (TIntermSymbol *sampler : samplerSymbols)
{ {
const TType &samplerType = sampler->getType(); const TType &samplerType = sampler->getType();
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
namespace sh namespace sh
{ {
class StructureHLSL; class StructureHLSL;
class TSymbolTable;
class UniformHLSL : angle::NonCopyable class UniformHLSL : angle::NonCopyable
{ {
...@@ -28,7 +29,8 @@ class UniformHLSL : angle::NonCopyable ...@@ -28,7 +29,8 @@ class UniformHLSL : angle::NonCopyable
void reserveUniformBlockRegisters(unsigned int registerCount); void reserveUniformBlockRegisters(unsigned int registerCount);
void uniformsHeader(TInfoSinkBase &out, void uniformsHeader(TInfoSinkBase &out,
ShShaderOutput outputType, ShShaderOutput outputType,
const ReferencedSymbols &referencedUniforms); const ReferencedSymbols &referencedUniforms,
TSymbolTable *symbolTable);
// Must be called after uniformsHeader // Must be called after uniformsHeader
void samplerMetadataUniforms(TInfoSinkBase &out, const char *reg); void samplerMetadataUniforms(TInfoSinkBase &out, const char *reg);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "compiler/translator/FindMain.h" #include "compiler/translator/FindMain.h"
#include "compiler/translator/IntermNode_util.h" #include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/SymbolTable.h"
#include "tests/test_utils/ShaderCompileTreeTest.h" #include "tests/test_utils/ShaderCompileTreeTest.h"
#include <algorithm> #include <algorithm>
...@@ -63,7 +64,9 @@ bool AreLValuesTheSame(TIntermTyped *expected, TIntermTyped *candidate) ...@@ -63,7 +64,9 @@ bool AreLValuesTheSame(TIntermTyped *expected, TIntermTyped *candidate)
TIntermTyped *CreateLValueNode(const TString &lValueName, const TType &type) TIntermTyped *CreateLValueNode(const TString &lValueName, const TType &type)
{ {
return new TIntermSymbol(0, lValueName, type); // We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
TSymbolTable symbolTable;
return new TIntermSymbol(symbolTable.nextUniqueId(), lValueName, type);
} }
ExpectedLValues CreateIndexedLValueNodeList(const TString &lValueName, ExpectedLValues CreateIndexedLValueNodeList(const TString &lValueName,
...@@ -73,12 +76,16 @@ ExpectedLValues CreateIndexedLValueNodeList(const TString &lValueName, ...@@ -73,12 +76,16 @@ ExpectedLValues CreateIndexedLValueNodeList(const TString &lValueName,
ASSERT(elementType.isArray() == false); ASSERT(elementType.isArray() == false);
elementType.makeArray(arraySize); elementType.makeArray(arraySize);
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
TSymbolTable symbolTable;
TIntermSymbol *arraySymbol =
new TIntermSymbol(symbolTable.nextUniqueId(), lValueName, elementType);
ExpectedLValues expected(arraySize); ExpectedLValues expected(arraySize);
for (unsigned index = 0u; index < arraySize; ++index) for (unsigned index = 0u; index < arraySize; ++index)
{ {
expected[index] = expected[index] = new TIntermBinary(EOpIndexDirect, arraySymbol->deepCopy(),
new TIntermBinary(EOpIndexDirect, new TIntermSymbol(0, lValueName, elementType), CreateIndexNode(static_cast<int>(index)));
CreateIndexNode(static_cast<int>(index)));
} }
return expected; return expected;
} }
......
...@@ -7,11 +7,12 @@ ...@@ -7,11 +7,12 @@
// Unit tests for the AST node classes. // Unit tests for the AST node classes.
// //
#include "compiler/translator/IntermNode.h"
#include "angle_gl.h" #include "angle_gl.h"
#include "gtest/gtest.h"
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/PoolAlloc.h" #include "compiler/translator/PoolAlloc.h"
#include "compiler/translator/SymbolTable.h"
#include "gtest/gtest.h"
using namespace sh; using namespace sh;
...@@ -40,7 +41,11 @@ class IntermNodeTest : public testing::Test ...@@ -40,7 +41,11 @@ class IntermNodeTest : public testing::Test
TString symbolName = symbolNameOut.c_str(); TString symbolName = symbolNameOut.c_str();
++mUniqueIndex; ++mUniqueIndex;
TIntermSymbol *node = new TIntermSymbol(0, symbolName, type); // We're using a dummy symbol table here, don't need to assign proper symbol ids to these
// nodes.
TSymbolTable symbolTable;
TIntermSymbol *node = new TIntermSymbol(symbolTable.nextUniqueId(), symbolName, type);
node->setLine(createUniqueSourceLoc()); node->setLine(createUniqueSourceLoc());
node->setInternal(true); node->setInternal(true);
node->getTypePointer()->setQualifier(EvqTemporary); node->getTypePointer()->setQualifier(EvqTemporary);
...@@ -117,7 +122,11 @@ class IntermNodeTest : public testing::Test ...@@ -117,7 +122,11 @@ class IntermNodeTest : public testing::Test
TEST_F(IntermNodeTest, DeepCopySymbolNode) TEST_F(IntermNodeTest, DeepCopySymbolNode)
{ {
TType type(EbtInt, EbpHigh); TType type(EbtInt, EbpHigh);
TIntermSymbol *original = new TIntermSymbol(0, TString("name"), type);
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
TSymbolTable symbolTable;
TIntermSymbol *original = new TIntermSymbol(symbolTable.nextUniqueId(), TString("name"), type);
original->setLine(getTestSourceLoc()); original->setLine(getTestSourceLoc());
original->setInternal(true); original->setInternal(true);
TIntermTyped *copy = original->deepCopy(); TIntermTyped *copy = original->deepCopy();
......
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