Commit 8b5e8fdb by Olli Etuaho Committed by Commit Bot

Replace remaining usage of TName with TSymbol

TName used to contain just a subset of the information stored in TSymbol. It makes more sense to use TSymbol directly instead of converting it to TName. This also improves type safety a bit by making some functions only take in TVariable or TFunction instead of the more generic TName. BUG=angleproject:2267 TEST=angle_unittests Change-Id: Icb46923c25d33ebbbbc06ddc487da25957dda771 Reviewed-on: https://chromium-review.googlesource.com/829143 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 93b059db
......@@ -123,16 +123,20 @@ class CollectVariablesTraverser : public TIntermTraverser
bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
private:
std::string getMappedName(const TName &name) const;
std::string getMappedName(const TSymbol *symbol) const;
void setFieldOrVariableProperties(const TType &type, ShaderVariable *variableOut) const;
void setFieldProperties(const TType &type,
const TString &name,
ShaderVariable *variableOut) const;
void setCommonVariableProperties(const TType &type,
const TName &name,
const TVariable &variable,
ShaderVariable *variableOut) const;
Attribute recordAttribute(const TIntermSymbol &variable) const;
OutputVariable recordOutputVariable(const TIntermSymbol &variable) const;
Varying recordVarying(const TIntermSymbol &variable) const;
void recordInterfaceBlock(const TString &instanceName,
void recordInterfaceBlock(const char *instanceName,
const TType &interfaceBlockType,
InterfaceBlock *interfaceBlock) const;
Uniform recordUniform(const TIntermSymbol &variable) const;
......@@ -247,9 +251,9 @@ CollectVariablesTraverser::CollectVariablesTraverser(
{
}
std::string CollectVariablesTraverser::getMappedName(const TName &name) const
std::string CollectVariablesTraverser::getMappedName(const TSymbol *symbol) const
{
return HashName(name, mHashFunction, nullptr).c_str();
return HashName(symbol, mHashFunction, nullptr).c_str();
}
void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const char *name,
......@@ -339,14 +343,16 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
{
ASSERT(symbol != nullptr);
if (symbol->getName().isInternal())
if (symbol->variable().symbolType() == SymbolType::AngleInternal ||
symbol->variable().symbolType() == SymbolType::Empty)
{
// Internal variables are not collected.
// Internal variables or nameless variables are not collected.
return;
}
ShaderVariable *var = nullptr;
const TString &symbolName = symbol->getName().getString();
const TString &symbolName = symbol->getName();
// Check the qualifier from the variable, not from the symbol node. The node may have a
// different qualifier if it's the result of a folded ternary node.
......@@ -556,14 +562,12 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
}
}
void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
const TName &name,
ShaderVariable *variableOut) const
void CollectVariablesTraverser::setFieldOrVariableProperties(const TType &type,
ShaderVariable *variableOut) const
{
ASSERT(variableOut);
const TStructure *structure = type.getStruct();
if (!structure)
{
variableOut->type = GLVariableType(type);
......@@ -585,26 +589,45 @@ void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
// Regardless of the variable type (uniform, in/out etc.) its fields are always plain
// ShaderVariable objects.
ShaderVariable fieldVariable;
setCommonVariableProperties(*field->type(), TName(field->name()), &fieldVariable);
setFieldProperties(*field->type(), field->name(), &fieldVariable);
variableOut->fields.push_back(fieldVariable);
}
}
variableOut->name = name.getString().c_str();
variableOut->mappedName = getMappedName(name);
if (auto *arraySizes = type.getArraySizes())
{
variableOut->arraySizes.assign(arraySizes->begin(), arraySizes->end());
}
}
void CollectVariablesTraverser::setFieldProperties(const TType &type,
const TString &name,
ShaderVariable *variableOut) const
{
ASSERT(variableOut);
setFieldOrVariableProperties(type, variableOut);
variableOut->name = name.c_str();
variableOut->mappedName = HashName(name, mHashFunction, nullptr).c_str();
}
void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
const TVariable &variable,
ShaderVariable *variableOut) const
{
ASSERT(variableOut);
setFieldOrVariableProperties(type, variableOut);
ASSERT(variable.symbolType() != SymbolType::Empty);
variableOut->name = variable.name().c_str();
variableOut->mappedName = getMappedName(&variable);
}
Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
{
const TType &type = variable.getType();
ASSERT(!type.getStruct());
Attribute attribute;
setCommonVariableProperties(type, variable.getName(), &attribute);
setCommonVariableProperties(type, variable.variable(), &attribute);
attribute.location = type.getLayoutQualifier().location;
return attribute;
......@@ -616,7 +639,7 @@ OutputVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymb
ASSERT(!type.getStruct());
OutputVariable outputVariable;
setCommonVariableProperties(type, variable.getName(), &outputVariable);
setCommonVariableProperties(type, variable.variable(), &outputVariable);
outputVariable.location = type.getLayoutQualifier().location;
return outputVariable;
......@@ -627,7 +650,7 @@ Varying CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable)
const TType &type = variable.getType();
Varying varying;
setCommonVariableProperties(type, variable.getName(), &varying);
setCommonVariableProperties(type, variable.variable(), &varying);
varying.location = type.getLayoutQualifier().location;
switch (type.getQualifier())
......@@ -639,8 +662,7 @@ Varying CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable)
case EvqFlatOut:
case EvqCentroidOut:
case EvqGeometryOut:
if (mSymbolTable->isVaryingInvariant(std::string(variable.getSymbol().c_str())) ||
type.isInvariant())
if (mSymbolTable->isVaryingInvariant(varying.name) || type.isInvariant())
{
varying.isInvariant = true;
}
......@@ -654,7 +676,7 @@ Varying CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable)
}
// TODO(jiawei.shao@intel.com): implement GL_EXT_shader_io_blocks.
void CollectVariablesTraverser::recordInterfaceBlock(const TString &instanceName,
void CollectVariablesTraverser::recordInterfaceBlock(const char *instanceName,
const TType &interfaceBlockType,
InterfaceBlock *interfaceBlock) const
{
......@@ -664,9 +686,12 @@ void CollectVariablesTraverser::recordInterfaceBlock(const TString &instanceName
const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
ASSERT(blockType);
interfaceBlock->name = blockType->name().c_str();
interfaceBlock->mappedName = getMappedName(TName(blockType->name()));
interfaceBlock->instanceName = instanceName.c_str();
interfaceBlock->name = blockType->name().c_str();
interfaceBlock->mappedName = getMappedName(blockType);
if (instanceName != nullptr)
{
interfaceBlock->instanceName = instanceName;
}
ASSERT(!interfaceBlockType.isArrayOfArrays()); // Disallowed by GLSL ES 3.10 section 4.3.9
interfaceBlock->arraySize = interfaceBlockType.isArray() ? interfaceBlockType.getOutermostArraySize() : 0;
......@@ -686,7 +711,7 @@ void CollectVariablesTraverser::recordInterfaceBlock(const TString &instanceName
const TType &fieldType = *field->type();
InterfaceBlockField fieldVariable;
setCommonVariableProperties(fieldType, TName(field->name()), &fieldVariable);
setFieldProperties(fieldType, field->name(), &fieldVariable);
fieldVariable.isRowMajorLayout =
(fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
interfaceBlock->fields.push_back(fieldVariable);
......@@ -696,7 +721,7 @@ void CollectVariablesTraverser::recordInterfaceBlock(const TString &instanceName
Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
{
Uniform uniform;
setCommonVariableProperties(variable.getType(), variable.getName(), &uniform);
setCommonVariableProperties(variable.getType(), variable.variable(), &uniform);
uniform.binding = variable.getType().getLayoutQualifier().binding;
uniform.location = variable.getType().getLayoutQualifier().location;
uniform.offset = variable.getType().getLayoutQualifier().offset;
......@@ -729,7 +754,7 @@ bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node
// uniforms, varyings, outputs and interface blocks cannot be initialized in a shader, we
// must have only TIntermSymbol nodes in the sequence in the cases we are interested in.
const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
if (variable.getName().isInternal())
if (variable.variable().symbolType() == SymbolType::AngleInternal)
{
// Internal variables are not collected.
continue;
......@@ -739,7 +764,10 @@ bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node
if (typedNode.getBasicType() == EbtInterfaceBlock)
{
InterfaceBlock interfaceBlock;
recordInterfaceBlock(variable.getSymbol(), variable.getType(), &interfaceBlock);
recordInterfaceBlock(variable.variable().symbolType() != SymbolType::Empty
? variable.getName().c_str()
: nullptr,
variable.getType(), &interfaceBlock);
switch (qualifier)
{
......@@ -755,6 +783,7 @@ bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node
}
else
{
ASSERT(variable.variable().symbolType() != SymbolType::Empty);
switch (qualifier)
{
case EvqAttribute:
......
......@@ -25,23 +25,24 @@ namespace
class ReplaceVariableTraverser : public TIntermTraverser
{
public:
ReplaceVariableTraverser(const TString &symbolName, TIntermSymbol *newSymbol)
: TIntermTraverser(true, false, false), mSymbolName(symbolName), mNewSymbol(newSymbol)
ReplaceVariableTraverser(const TVariable *toBeReplaced, const TVariable *replacement)
: TIntermTraverser(true, false, false),
mToBeReplaced(toBeReplaced),
mReplacement(replacement)
{
}
void visitSymbol(TIntermSymbol *node) override
{
const TName &name = node->getName();
if (name.getString() == mSymbolName)
if (&node->variable() == mToBeReplaced)
{
queueReplacement(mNewSymbol->deepCopy(), OriginalNode::IS_DROPPED);
queueReplacement(new TIntermSymbol(mReplacement), OriginalNode::IS_DROPPED);
}
}
private:
TString mSymbolName;
TIntermSymbol *mNewSymbol;
const TVariable *const mToBeReplaced;
const TVariable *const mReplacement;
};
TIntermSymbol *CreateGLInstanceIDSymbol(const TSymbolTable &symbolTable)
......@@ -50,8 +51,8 @@ TIntermSymbol *CreateGLInstanceIDSymbol(const TSymbolTable &symbolTable)
}
// Adds the InstanceID and ViewID_OVR initializers to the end of the initializers' sequence.
void InitializeViewIDAndInstanceID(TIntermTyped *viewIDSymbol,
TIntermTyped *instanceIDSymbol,
void InitializeViewIDAndInstanceID(const TVariable *viewID,
const TVariable *instanceID,
unsigned numberOfViews,
const TSymbolTable &symbolTable,
TIntermSequence *initializers)
......@@ -80,7 +81,7 @@ void InitializeViewIDAndInstanceID(TIntermTyped *viewIDSymbol,
// Create an InstanceID = int(uint(gl_InstanceID) / numberOfViews) node.
TIntermBinary *instanceIDInitializer =
new TIntermBinary(EOpAssign, instanceIDSymbol->deepCopy(), normalizedInstanceIDAsInt);
new TIntermBinary(EOpAssign, new TIntermSymbol(instanceID), normalizedInstanceIDAsInt);
initializers->push_back(instanceIDInitializer);
// Create a uint(gl_InstanceID) % numberOfViews node.
......@@ -89,36 +90,37 @@ void InitializeViewIDAndInstanceID(TIntermTyped *viewIDSymbol,
// Create a ViewID_OVR = uint(gl_InstanceID) % numberOfViews node.
TIntermBinary *viewIDInitializer =
new TIntermBinary(EOpAssign, viewIDSymbol->deepCopy(), normalizedViewID);
new TIntermBinary(EOpAssign, new TIntermSymbol(viewID), normalizedViewID);
initializers->push_back(viewIDInitializer);
}
// Replaces every occurrence of a symbol with the name specified in symbolName with newSymbolNode.
void ReplaceSymbol(TIntermBlock *root, const TString &symbolName, TIntermSymbol *newSymbolNode)
// Replaces every occurrence of a variable with another variable.
void ReplaceSymbol(TIntermBlock *root, const TVariable *toBeReplaced, const TVariable *replacement)
{
ReplaceVariableTraverser traverser(symbolName, newSymbolNode);
ReplaceVariableTraverser traverser(toBeReplaced, replacement);
root->traverse(&traverser);
traverser.updateTree();
}
void DeclareGlobalVariable(TIntermBlock *root, TIntermTyped *typedNode)
void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
{
TIntermSequence *globalSequence = root->getSequence();
TIntermDeclaration *declaration = new TIntermDeclaration();
declaration->appendDeclarator(typedNode->deepCopy());
declaration->appendDeclarator(new TIntermSymbol(variable));
TIntermSequence *globalSequence = root->getSequence();
globalSequence->insert(globalSequence->begin(), declaration);
}
// Adds a branch to write int(ViewID_OVR) to either gl_ViewportIndex or gl_Layer. The branch is
// added to the end of the initializers' sequence.
void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol,
TIntermTyped *multiviewBaseViewLayerIndexSymbol,
void SelectViewIndexInVertexShader(const TVariable *viewID,
const TVariable *multiviewBaseViewLayerIndex,
TIntermSequence *initializers,
const TSymbolTable &symbolTable)
{
// Create an int(ViewID_OVR) node.
TIntermSequence *viewIDSymbolCastArguments = new TIntermSequence();
viewIDSymbolCastArguments->push_back(viewIDSymbol);
viewIDSymbolCastArguments->push_back(new TIntermSymbol(viewID));
TIntermAggregate *viewIDAsInt = TIntermAggregate::CreateConstructor(
TType(EbtInt, EbpHigh, EvqTemporary), viewIDSymbolCastArguments);
......@@ -135,8 +137,8 @@ void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol,
TIntermSymbol *layerSymbol = ReferenceBuiltInVariable("gl_Layer", symbolTable, 0);
// Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node
TIntermBinary *sumOfViewIDAndBaseViewIndex =
new TIntermBinary(EOpAdd, viewIDAsInt->deepCopy(), multiviewBaseViewLayerIndexSymbol);
TIntermBinary *sumOfViewIDAndBaseViewIndex = new TIntermBinary(
EOpAdd, viewIDAsInt->deepCopy(), new TIntermSymbol(multiviewBaseViewLayerIndex));
// Create a { gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex } node.
TIntermBlock *layerInitializerInBlock = new TIntermBlock();
......@@ -145,7 +147,7 @@ void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol,
// Create a node to compare whether the base view index uniform is less than zero.
TIntermBinary *multiviewBaseViewLayerIndexZeroComparison =
new TIntermBinary(EOpLessThan, multiviewBaseViewLayerIndexSymbol->deepCopy(),
new TIntermBinary(EOpLessThan, new TIntermSymbol(multiviewBaseViewLayerIndex),
CreateZeroNode(TType(EbtInt, EbpHigh, EvqConst)));
// Create an if-else statement to select the code path.
......@@ -169,27 +171,29 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
TQualifier viewIDQualifier = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn;
const TString *viewIDVariableName = NewPoolTString("ViewID_OVR");
const TVariable *viewIDVariable =
const TVariable *viewID =
new TVariable(symbolTable, viewIDVariableName, TType(EbtUInt, EbpHigh, viewIDQualifier),
SymbolType::AngleInternal);
TIntermSymbol *viewIDSymbol = new TIntermSymbol(viewIDVariable);
DeclareGlobalVariable(root, viewIDSymbol);
ReplaceSymbol(root, "gl_ViewID_OVR", viewIDSymbol);
DeclareGlobalVariable(root, viewID);
ReplaceSymbol(root,
static_cast<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
// InstanceID and ViewID.
const TString *instanceIDVariableName = NewPoolTString("InstanceID");
const TVariable *instanceIDVariable =
const TVariable *instanceID =
new TVariable(symbolTable, instanceIDVariableName, TType(EbtInt, EbpHigh, EvqGlobal),
SymbolType::AngleInternal);
TIntermSymbol *instanceIDSymbol = new TIntermSymbol(instanceIDVariable);
DeclareGlobalVariable(root, instanceIDSymbol);
ReplaceSymbol(root, "gl_InstanceID", instanceIDSymbol);
DeclareGlobalVariable(root, instanceID);
ReplaceSymbol(
root, static_cast<TVariable *>(symbolTable->findBuiltIn("gl_InstanceID", 300, true)),
instanceID);
TIntermSequence *initializers = new TIntermSequence();
InitializeViewIDAndInstanceID(viewIDSymbol, instanceIDSymbol, numberOfViews, *symbolTable,
InitializeViewIDAndInstanceID(viewID, instanceID, numberOfViews, *symbolTable,
initializers);
// The AST transformation which adds the expression to select the viewport index should
......@@ -203,18 +207,15 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// Add a uniform to switch between side-by-side and layered rendering.
const TString *multiviewBaseViewLayerIndexVariableName =
NewPoolTString("multiviewBaseViewLayerIndex");
const TVariable *multiviewBaseViewLayerIndexVariable =
const TVariable *multiviewBaseViewLayerIndex =
new TVariable(symbolTable, multiviewBaseViewLayerIndexVariableName,
TType(EbtInt, EbpHigh, EvqUniform), SymbolType::AngleInternal);
TIntermSymbol *multiviewBaseViewLayerIndexSymbol =
new TIntermSymbol(multiviewBaseViewLayerIndexVariable);
DeclareGlobalVariable(root, multiviewBaseViewLayerIndexSymbol);
DeclareGlobalVariable(root, multiviewBaseViewLayerIndex);
// Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's
// initialization.
SelectViewIndexInVertexShader(viewIDSymbol->deepCopy(),
multiviewBaseViewLayerIndexSymbol->deepCopy(),
initializers, *symbolTable);
SelectViewIndexInVertexShader(viewID, multiviewBaseViewLayerIndex, initializers,
*symbolTable);
}
// Insert initializers at the beginning of main().
......
......@@ -78,11 +78,12 @@ void GetDeferredInitializers(TIntermDeclaration *declaration,
TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
ASSERT(symbolNode);
// Ignore ANGLE internal variables.
if (symbolNode->getName().isInternal())
// Ignore ANGLE internal variables and nameless declarations.
if (symbolNode->variable().symbolType() == SymbolType::AngleInternal ||
symbolNode->variable().symbolType() == SymbolType::Empty)
return;
if (symbolNode->getQualifier() == EvqGlobal && symbolNode->getSymbol() != "")
if (symbolNode->getQualifier() == EvqGlobal)
{
TIntermSequence *initCode = CreateInitCode(symbolNode, canUseLoopsToInitialize,
highPrecisionSupported, symbolTable);
......
......@@ -16,6 +16,7 @@
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/RunAtTheEndOfShader.h"
#include "compiler/translator/Symbol.h"
namespace sh
{
......@@ -70,7 +71,7 @@ TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataAssignNode(int
void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
{
if (node->getSymbol() == "gl_FragColor")
if (node->variable().symbolType() == SymbolType::BuiltIn && node->getName() == "gl_FragColor")
{
queueReplacement(constructGLFragDataNode(0), OriginalNode::IS_DROPPED);
mGLFragColorUsed = true;
......
......@@ -9,6 +9,7 @@
#include "compiler/translator/FindSymbolNode.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/Symbol.h"
namespace sh
{
......@@ -26,7 +27,7 @@ class SymbolFinder : public TIntermTraverser
void visitSymbol(TIntermSymbol *node)
{
if (node->getSymbol() == mSymbolName)
if (node->variable().symbolType() != SymbolType::Empty && node->getName() == mSymbolName)
{
mNodeFound = node;
}
......
......@@ -7,6 +7,7 @@
#include "compiler/translator/HashNames.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/Symbol.h"
namespace sh
{
......@@ -38,35 +39,45 @@ TString HashName(const TString &name, ShHashFunction64 hashFunction)
} // anonymous namespace
TString HashName(const TName &name, ShHashFunction64 hashFunction, NameMap *nameMap)
TString HashName(const TString &name, ShHashFunction64 hashFunction, NameMap *nameMap)
{
if (name.getString().empty() || name.isInternal())
{
return name.getString();
}
if (hashFunction == nullptr)
{
if (name.getString().length() + kUnhashedNamePrefixLength > kESSLMaxIdentifierLength)
if (name.length() + kUnhashedNamePrefixLength > kESSLMaxIdentifierLength)
{
// If the identifier length is already close to the limit, we can't prefix it. This is
// not a problem since there are no builtins or ANGLE's internal variables that would
// have as long names and could conflict.
return name.getString();
return name;
}
return kUnhashedNamePrefix + name.getString();
return kUnhashedNamePrefix + name;
}
if (nameMap)
{
NameMap::const_iterator it = nameMap->find(name.getString().c_str());
NameMap::const_iterator it = nameMap->find(name.c_str());
if (it != nameMap->end())
return it->second.c_str();
}
TString hashedName = HashName(name.getString(), hashFunction);
TString hashedName = HashName(name, hashFunction);
if (nameMap)
{
(*nameMap)[name.getString().c_str()] = hashedName.c_str();
(*nameMap)[name.c_str()] = hashedName.c_str();
}
return hashedName;
}
TString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
{
if (symbol->symbolType() == SymbolType::Empty)
{
return TString();
}
if (symbol->symbolType() == SymbolType::AngleInternal ||
symbol->symbolType() == SymbolType::BuiltIn)
{
return symbol->name();
}
return HashName(symbol->name(), hashFunction, nameMap);
}
} // namespace sh
......@@ -17,11 +17,13 @@ namespace sh
typedef std::map<TPersistString, TPersistString> NameMap;
class TName;
class TSymbol;
TString HashName(const TString &name, ShHashFunction64 hashFunction, NameMap *nameMap);
// Hash user-defined name for GLSL output, with special handling for internal names.
// The nameMap parameter is optional and is used to cache hashed names if set.
TString HashName(const TName &name, ShHashFunction64 hashFunction, NameMap *nameMap);
TString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap);
} // namespace sh
......
......@@ -224,7 +224,7 @@ class InitializeLocalsTraverser : public TIntermTraverser
{
TIntermSymbol *symbol = declarator->getAsSymbolNode();
ASSERT(symbol);
if (symbol->getSymbol() == "")
if (symbol->variable().symbolType() == SymbolType::Empty)
{
continue;
}
......
......@@ -140,16 +140,6 @@ void SetUnionArrayFromMatrix(const angle::Matrix<float> &m, TConstantUnion *resu
} // namespace anonymous
TName::TName(const TString &name) : mName(name), mIsInternal(false)
{
}
TName::TName(const TSymbol *symbol)
: mName(symbol->symbolType() == SymbolType::Empty ? "" : symbol->name()),
mIsInternal(symbol->symbolType() == SymbolType::AngleInternal)
{
}
////////////////////////////////////////////////////////////////
//
// Member functions of the nodes used for building the tree.
......@@ -278,7 +268,7 @@ bool TIntermAggregateBase::insertChildNodes(TIntermSequence::size_type position,
}
TIntermSymbol::TIntermSymbol(const TVariable *variable)
: TIntermTyped(variable->getType()), mVariable(variable), mSymbol(variable)
: TIntermTyped(variable->getType()), mVariable(variable)
{
}
......@@ -287,6 +277,11 @@ const TSymbolUniqueId &TIntermSymbol::uniqueId() const
return mVariable->uniqueId();
}
const TString &TIntermSymbol::getName() const
{
return mVariable->name();
}
TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TFunction &func,
TIntermSequence *arguments)
{
......
......@@ -60,28 +60,6 @@ class TSymbolTable;
class TFunction;
class TVariable;
// Encapsulate an identifier string and track whether it is coming from the original shader code
// (not internal) or from ANGLE (internal). Usually internal names shouldn't be decorated or hashed.
class TName
{
public:
POOL_ALLOCATOR_NEW_DELETE();
explicit TName(const TString &name);
explicit TName(const TSymbol *symbol);
TName() : mName(), mIsInternal(false) {}
TName(const TName &) = default;
TName &operator=(const TName &) = default;
const TString &getString() const { return mName; }
void setString(const TString &string) { mName = string; }
bool isInternal() const { return mIsInternal; }
void setInternal(bool isInternal) { mIsInternal = isInternal; }
private:
TString mName;
bool mIsInternal;
};
//
// Base class for the tree nodes
//
......@@ -267,8 +245,7 @@ class TIntermSymbol : public TIntermTyped
bool hasSideEffects() const override { return false; }
const TSymbolUniqueId &uniqueId() const;
const TString &getSymbol() const { return mSymbol.getString(); }
const TName &getName() const { return mSymbol; }
const TString &getName() const;
const TVariable &variable() const { return *mVariable; }
void traverse(TIntermTraverser *it) override;
......@@ -279,7 +256,6 @@ class TIntermSymbol : public TIntermTyped
TIntermSymbol(const TIntermSymbol &) = default; // Note: not deleted, just private!
const TVariable *const mVariable; // Guaranteed to be non-null
TName mSymbol;
};
// A Raw node stores raw code, that the translator will insert verbatim
......
......@@ -41,24 +41,32 @@ void TOutputGLSL::visitSymbol(TIntermSymbol *node)
{
TInfoSinkBase &out = objSink();
const TString &symbol = node->getSymbol();
if (symbol == "gl_FragDepthEXT")
// All the special cases are built-ins, so if it's not a built-in we can return early.
if (node->variable().symbolType() != SymbolType::BuiltIn)
{
TOutputGLSLBase::visitSymbol(node);
return;
}
// Some built-ins get a special translation.
const TString &name = node->getName();
if (name == "gl_FragDepthEXT")
{
out << "gl_FragDepth";
}
else if (symbol == "gl_FragColor" && sh::IsGLSL130OrNewer(getShaderOutput()))
else if (name == "gl_FragColor" && sh::IsGLSL130OrNewer(getShaderOutput()))
{
out << "webgl_FragColor";
}
else if (symbol == "gl_FragData" && sh::IsGLSL130OrNewer(getShaderOutput()))
else if (name == "gl_FragData" && sh::IsGLSL130OrNewer(getShaderOutput()))
{
out << "webgl_FragData";
}
else if (symbol == "gl_SecondaryFragColorEXT")
else if (name == "gl_SecondaryFragColorEXT")
{
out << "angle_SecondaryFragColor";
}
else if (symbol == "gl_SecondaryFragDataEXT")
else if (name == "gl_SecondaryFragDataEXT")
{
out << "angle_SecondaryFragData";
}
......
......@@ -339,8 +339,8 @@ void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args)
const TType &type = arg->getType();
writeVariableType(type);
if (!arg->getName().getString().empty())
out << " " << hashName(arg->getName());
if (arg->variable().symbolType() != SymbolType::Empty)
out << " " << hashName(&arg->variable());
if (type.isArray())
out << ArrayString(type);
......@@ -358,7 +358,7 @@ const TConstantUnion *TOutputGLSLBase::writeConstantUnion(const TType &type,
if (type.getBasicType() == EbtStruct)
{
const TStructure *structure = type.getStruct();
out << hashName(TName(structure->name())) << "(";
out << hashName(structure) << "(";
const TFieldList &fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
......@@ -433,7 +433,7 @@ void TOutputGLSLBase::writeConstructorTriplet(Visit visit, const TType &type)
void TOutputGLSLBase::visitSymbol(TIntermSymbol *node)
{
TInfoSinkBase &out = objSink();
out << hashVariableName(node->getName());
out << hashName(&node->variable());
if (mDeclaringVariable && node->getType().isArray())
out << ArrayString(node->getType());
......@@ -582,12 +582,7 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
const TField *field = structure->fields()[index->getIConst(0)];
TString fieldName = field->name();
if (structure->symbolType() == SymbolType::UserDefined ||
structure->symbolType() == SymbolType::Empty)
fieldName = hashName(TName(fieldName));
out << fieldName;
out << hashFieldName(structure, field->name());
visitChildren = false;
}
break;
......@@ -599,19 +594,9 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
node->getLeft()->getType().getInterfaceBlock();
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
const TField *field = interfaceBlock->fields()[index->getIConst(0)];
TString fieldName = field->name();
ASSERT(interfaceBlock->symbolType() != SymbolType::Empty);
if (interfaceBlock->symbolType() == SymbolType::UserDefined)
{
fieldName = hashName(TName(fieldName));
}
else
{
ASSERT(interfaceBlock->name() == "gl_PerVertex");
}
out << fieldName;
ASSERT(interfaceBlock->symbolType() == SymbolType::UserDefined ||
interfaceBlock->name() == "gl_PerVertex");
out << hashFieldName(interfaceBlock, field->name());
visitChildren = false;
}
break;
......@@ -901,7 +886,7 @@ bool TOutputGLSLBase::visitInvariantDeclaration(Visit visit, TIntermInvariantDec
TInfoSinkBase &out = objSink();
ASSERT(visit == PreVisit);
const TIntermSymbol *symbol = node->getSymbol();
out << "invariant " << hashVariableName(symbol->getName());
out << "invariant " << hashName(&symbol->variable());
return false;
}
......@@ -1016,7 +1001,7 @@ bool TOutputGLSLBase::visitDeclaration(Visit visit, TIntermDeclaration *node)
writeLayoutQualifier(variable);
writeVariableType(variable->getType());
if (variable->getAsSymbolNode() == nullptr ||
!variable->getAsSymbolNode()->getSymbol().empty())
variable->getAsSymbolNode()->variable().symbolType() != SymbolType::Empty)
{
out << " ";
}
......@@ -1128,19 +1113,22 @@ TString TOutputGLSLBase::getTypeName(const TType &type)
return GetTypeName(type, mHashFunction, &mNameMap);
}
TString TOutputGLSLBase::hashName(const TName &name)
TString TOutputGLSLBase::hashName(const TSymbol *symbol)
{
return HashName(name, mHashFunction, &mNameMap);
return HashName(symbol, mHashFunction, &mNameMap);
}
TString TOutputGLSLBase::hashVariableName(const TName &name)
TString TOutputGLSLBase::hashFieldName(const TSymbol *containingStruct, const TString &fieldName)
{
if (mSymbolTable->findBuiltIn(name.getString(), mShaderVersion) != nullptr ||
name.getString().substr(0, 3) == "gl_")
if (containingStruct->symbolType() == SymbolType::UserDefined ||
containingStruct->symbolType() == SymbolType::Empty)
{
return HashName(fieldName, mHashFunction, &mNameMap);
}
else
{
return name.getString();
return fieldName;
}
return hashName(name);
}
TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunction *func)
......@@ -1151,7 +1139,7 @@ TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunction *func)
}
else
{
return hashName(TName(func));
return hashName(func);
}
}
......@@ -1174,7 +1162,7 @@ void TOutputGLSLBase::declareStruct(const TStructure *structure)
if (structure->symbolType() != SymbolType::Empty)
{
out << hashName(TName(structure->name())) << " ";
out << hashName(structure) << " ";
}
out << "{\n";
const TFieldList &fields = structure->fields();
......@@ -1183,7 +1171,7 @@ void TOutputGLSLBase::declareStruct(const TStructure *structure)
const TField *field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
out << getTypeName(*field->type()) << " " << hashName(TName(field->name()));
out << getTypeName(*field->type()) << " " << hashFieldName(structure, field->name());
if (field->type()->isArray())
out << ArrayString(*field->type());
out << ";\n";
......@@ -1235,7 +1223,7 @@ void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBloc
{
TInfoSinkBase &out = objSink();
out << hashName(TName(interfaceBlock->name())) << "{\n";
out << hashName(interfaceBlock) << "{\n";
const TFieldList &fields = interfaceBlock->fields();
for (const TField *field : fields)
{
......@@ -1263,7 +1251,7 @@ void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBloc
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
out << getTypeName(*field->type()) << " " << hashName(TName(field->name()));
out << getTypeName(*field->type()) << " " << hashFieldName(interfaceBlock, field->name());
if (field->type()->isArray())
out << ArrayString(*field->type());
out << ";\n";
......
......@@ -32,9 +32,9 @@ class TOutputGLSLBase : public TIntermTraverser
ShShaderOutput getShaderOutput() const { return mOutput; }
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name. Has special handling for internal names, which are not
// hashed.
TString hashName(const TName &name);
// otherwise return the hashed name. Has special handling for internal names and built-ins,
// which are not hashed.
TString hashName(const TSymbol *symbol);
protected:
TInfoSinkBase &objSink() { return mObjSink; }
......@@ -69,9 +69,8 @@ class TOutputGLSLBase : public TIntermTraverser
void visitCodeBlock(TIntermBlock *node);
// Same as hashName(), but without hashing built-in variables.
TString hashVariableName(const TName &name);
// Same as hashName(), but without hashing internal functions or "main".
TString hashFieldName(const TSymbol *containingStruct, const TString &fieldName);
// Same as hashName(), but without hashing "main".
TString hashFunctionNameIfNeeded(const TFunction *func);
// Used to translate function names for differences between ESSL and GLSL
virtual TString translateTextureFunction(const TString &name) { return name; }
......
......@@ -345,7 +345,6 @@ TString OutputHLSL::generateStructMapping(const std::vector<MappedStruct> &std14
{
TInterfaceBlock *interfaceBlock =
mappedStruct.blockDeclarator->getType().getInterfaceBlock();
const TName &instanceName = mappedStruct.blockDeclarator->getName();
if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
{
continue;
......@@ -364,13 +363,14 @@ TString OutputHLSL::generateStructMapping(const std::vector<MappedStruct> &std14
TString originalName;
TString mappedName("map");
if (instanceName.getString() != "")
if (mappedStruct.blockDeclarator->variable().symbolType() != SymbolType::Empty)
{
const TString &instanceName = mappedStruct.blockDeclarator->variable().name();
unsigned int instanceStringArrayIndex = GL_INVALID_INDEX;
if (isInstanceArray)
instanceStringArrayIndex = instanceArrayIndex;
TString instanceString = mUniformHLSL->UniformBlockInstanceString(
instanceName.getString(), instanceStringArrayIndex);
instanceName, instanceStringArrayIndex);
originalName += instanceString;
mappedName += instanceString;
originalName += ".";
......@@ -409,7 +409,7 @@ void OutputHLSL::header(TInfoSinkBase &out,
for (const auto &varying : mReferencedVaryings)
{
const TType &type = varying.second->variable().getType();
const TString &name = varying.second->getSymbol();
const TString &name = varying.second->getName();
// Program linking depends on this exact format
varyings += "static " + InterpolationString(type.getQualifier()) + " " + TypeString(type) +
......@@ -419,7 +419,7 @@ void OutputHLSL::header(TInfoSinkBase &out,
for (const auto &attribute : mReferencedAttributes)
{
const TType &type = attribute.second->getType();
const TString &name = attribute.second->getSymbol();
const TString &name = attribute.second->getName();
attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) +
" = " + initializer(type) + ";\n";
......@@ -491,7 +491,7 @@ void OutputHLSL::header(TInfoSinkBase &out,
{
for (const auto &outputVariable : mReferencedOutputVariables)
{
const TString &variableName = outputVariable.second->getSymbol();
const TString &variableName = outputVariable.second->getName();
const TType &variableType = outputVariable.second->getType();
out << "static " + TypeString(variableType) + " out_" + variableName +
......@@ -861,6 +861,12 @@ void OutputHLSL::header(TInfoSinkBase &out,
void OutputHLSL::visitSymbol(TIntermSymbol *node)
{
const TVariable &variable = node->variable();
// Empty symbols can only appear in declarations and function arguments, and in either of those
// cases the symbol nodes are not visited.
ASSERT(variable.symbolType() != SymbolType::Empty);
TInfoSinkBase &out = getInfoSink();
// Handle accessing std140 structs by value
......@@ -869,9 +875,8 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
out << "map";
}
TString name = node->getSymbol();
const TSymbolUniqueId &uniqueId = node->uniqueId();
const TString &name = variable.name();
const TSymbolUniqueId &uniqueId = variable.uniqueId();
if (name == "gl_DepthRange")
{
......@@ -880,14 +885,14 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
}
else
{
const TType &nodeType = node->getType();
TQualifier qualifier = node->variable().getType().getQualifier();
const TType &variableType = variable.getType();
TQualifier qualifier = variable.getType().getQualifier();
ensureStructDefined(nodeType);
ensureStructDefined(variableType);
if (qualifier == EvqUniform)
{
const TInterfaceBlock *interfaceBlock = nodeType.getInterfaceBlock();
const TInterfaceBlock *interfaceBlock = variableType.getInterfaceBlock();
if (interfaceBlock)
{
......@@ -898,7 +903,7 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mReferencedUniforms[uniqueId.get()] = node;
}
out << DecorateVariableIfNeeded(node->getName());
out << DecorateVariableIfNeeded(variable);
}
else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
{
......@@ -991,7 +996,7 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
}
else
{
out << DecorateVariableIfNeeded(node->getName());
out << DecorateVariableIfNeeded(variable);
}
}
}
......@@ -1242,8 +1247,8 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
instanceArraySymbol;
const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0);
out << mUniformHLSL->UniformBlockInstanceString(
instanceArraySymbol->getSymbol(), arrayIndex);
out << mUniformHLSL->UniformBlockInstanceString(instanceArraySymbol->getName(),
arrayIndex);
return false;
}
}
......@@ -1641,7 +1646,8 @@ TString OutputHLSL::samplerNamePrefixFromStruct(TIntermTyped *node)
{
if (node->getAsSymbolNode())
{
return node->getAsSymbolNode()->getSymbol();
ASSERT(node->getAsSymbolNode()->variable().symbolType() != SymbolType::Empty);
return node->getAsSymbolNode()->getName();
}
TIntermBinary *nodeBinary = node->getAsBinaryNode();
switch (nodeBinary->getOp())
......@@ -1788,26 +1794,27 @@ bool OutputHLSL::visitDeclaration(Visit visit, TIntermDeclaration *node)
if (visit == PreVisit)
{
TIntermSequence *sequence = node->getSequence();
TIntermTyped *variable = (*sequence)[0]->getAsTyped();
TIntermTyped *declarator = (*sequence)[0]->getAsTyped();
ASSERT(sequence->size() == 1);
ASSERT(variable);
ASSERT(declarator);
if (IsDeclarationWrittenOut(node))
{
TInfoSinkBase &out = getInfoSink();
ensureStructDefined(variable->getType());
ensureStructDefined(declarator->getType());
if (!variable->getAsSymbolNode() ||
variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
if (!declarator->getAsSymbolNode() ||
declarator->getAsSymbolNode()->variable().symbolType() !=
SymbolType::Empty) // Variable declaration
{
if (!mInsideFunction)
{
out << "static ";
}
out << TypeString(variable->getType()) + " ";
out << TypeString(declarator->getType()) + " ";
TIntermSymbol *symbol = variable->getAsSymbolNode();
TIntermSymbol *symbol = declarator->getAsSymbolNode();
if (symbol)
{
......@@ -1817,21 +1824,13 @@ bool OutputHLSL::visitDeclaration(Visit visit, TIntermDeclaration *node)
}
else
{
variable->traverse(this);
declarator->traverse(this);
}
}
else if (variable->getAsSymbolNode() &&
variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration
{
ASSERT(variable->getBasicType() == EbtStruct);
// ensureStructDefined has already been called.
}
else
UNREACHABLE();
}
else if (IsVaryingOut(variable->getQualifier()))
else if (IsVaryingOut(declarator->getQualifier()))
{
TIntermSymbol *symbol = variable->getAsSymbolNode();
TIntermSymbol *symbol = declarator->getAsSymbolNode();
ASSERT(symbol); // Varying declarations can't have initializers.
if (symbol->variable().symbolType() != SymbolType::Empty)
......@@ -1975,14 +1974,14 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
{
out << ", texture_" << sampler->getSymbol();
out << ", sampler_" << sampler->getSymbol();
out << ", texture_" << sampler->getName();
out << ", sampler_" << sampler->getName();
}
else
{
// In case of HLSL 4.1+, this symbol is the sampler index, and in case
// of D3D9, it's the sampler variable.
out << ", " + sampler->getSymbol();
out << ", " + sampler->getName();
}
}
}
......@@ -2623,16 +2622,17 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
{
TQualifier qualifier = symbol->getQualifier();
const TType &type = symbol->getType();
const TName &name = symbol->getName();
const TVariable &variable = symbol->variable();
TString nameStr;
if (name.getString().empty()) // HLSL demands named arguments, also for prototypes
if (variable.symbolType() ==
SymbolType::Empty) // HLSL demands named arguments, also for prototypes
{
nameStr = "x" + str(mUniqueIndex++);
}
else
{
nameStr = DecorateVariableIfNeeded(name);
nameStr = DecorateVariableIfNeeded(variable);
}
if (IsSampler(type.getBasicType()))
......@@ -2668,23 +2668,23 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
const TType &samplerType = sampler->getType();
if (mOutputType == SH_HLSL_4_1_OUTPUT)
{
argString << ", const uint " << sampler->getSymbol() << ArrayString(samplerType);
argString << ", const uint " << sampler->getName() << ArrayString(samplerType);
}
else if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
{
ASSERT(IsSampler(samplerType.getBasicType()));
argString << ", " << QualifierString(qualifier) << " "
<< TextureString(samplerType.getBasicType()) << " texture_"
<< sampler->getSymbol() << ArrayString(samplerType) << ", "
<< sampler->getName() << ArrayString(samplerType) << ", "
<< QualifierString(qualifier) << " "
<< SamplerString(samplerType.getBasicType()) << " sampler_"
<< sampler->getSymbol() << ArrayString(samplerType);
<< sampler->getName() << ArrayString(samplerType);
}
else
{
ASSERT(IsSampler(samplerType.getBasicType()));
argString << ", " << QualifierString(qualifier) << " " << TypeString(samplerType)
<< " " << sampler->getSymbol() << ArrayString(samplerType);
<< " " << sampler->getName() << ArrayString(samplerType);
}
}
}
......@@ -2802,7 +2802,8 @@ bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out,
TIntermSymbol *symbolNode,
TIntermTyped *expression)
{
const TIntermSymbol *symbolInInitializer = FindSymbolNode(expression, symbolNode->getSymbol());
ASSERT(symbolNode->variable().symbolType() != SymbolType::Empty);
const TIntermSymbol *symbolInInitializer = FindSymbolNode(expression, symbolNode->getName());
if (symbolInInitializer)
{
......
......@@ -81,7 +81,14 @@ void TOutputTraverser::visitSymbol(TIntermSymbol *node)
{
OutputTreeText(mOut, node, mDepth);
mOut << "'" << node->getSymbol() << "' ";
if (node->variable().symbolType() == SymbolType::Empty)
{
mOut << "''";
}
else
{
mOut << "'" << node->getName() << "' ";
}
mOut << "(symbol id " << node->uniqueId().get() << ") ";
mOut << "(" << node->getCompleteString() << ")";
mOut << "\n";
......
......@@ -65,7 +65,7 @@ void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable)
if (needsCustomLayout)
{
out << "@@ LAYOUT-" << symbol->getName().getString() << " @@";
out << "@@ LAYOUT-" << symbol->getName() << " @@";
}
if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
......
......@@ -88,7 +88,7 @@ const char *GetImageArgumentToken(TIntermTyped *imageNode)
TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
if (imageSymbol)
{
return imageSymbol->getSymbol().c_str();
return imageSymbol->getName().c_str();
}
return "image";
}
......@@ -606,7 +606,10 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn
//
if (symNode)
{
const char *symbol = symNode->getSymbol().c_str();
// Symbol inside an expression can't be nameless.
ASSERT(symNode->variable().symbolType() != SymbolType::Empty);
const char *symbol = symNode->getName().c_str();
std::stringstream reasonStream;
reasonStream << "l-value required (" << message << " \"" << symbol << "\")";
std::string reason = reasonStream.str();
......@@ -3928,7 +3931,7 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
if (baseExpression->getAsSymbolNode())
{
error(location, " left of '[' is not of type array, matrix, or vector ",
baseExpression->getAsSymbolNode()->getSymbol().c_str());
baseExpression->getAsSymbolNode()->getName().c_str());
}
else
{
......
......@@ -14,6 +14,7 @@
#include "compiler/translator/PruneNoOps.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/Symbol.h"
namespace sh
{
......@@ -66,7 +67,8 @@ bool PruneNoOpsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
{
TIntermSymbol *sym = sequence->front()->getAsSymbolNode();
// Prune declarations without a variable name, unless it's an interface block declaration.
if (sym != nullptr && sym->getSymbol() == "" && !sym->isInterfaceBlock())
if (sym != nullptr && sym->variable().symbolType() == SymbolType::Empty &&
!sym->isInterfaceBlock())
{
if (sequence->size() > 1)
{
......
......@@ -187,7 +187,8 @@ void RemoveUnreferencedVariablesTraverser::removeVariableDeclaration(TIntermDecl
// count will end up being one less than the correct refcount. But since the struct
// declaration is kept, the incorrect refcount can't cause any other problems.
if (declarator->getAsSymbolNode() && declarator->getAsSymbolNode()->getSymbol().empty())
if (declarator->getAsSymbolNode() &&
declarator->getAsSymbolNode()->variable().symbolType() == SymbolType::Empty)
{
// Already an empty declaration - nothing to do.
return;
......@@ -235,7 +236,7 @@ bool RemoveUnreferencedVariablesTraverser::visitDeclaration(Visit visit, TInterm
if (symbolNode != nullptr)
{
canRemoveVariable = (*mSymbolIdRefCounts)[symbolNode->uniqueId().get()] == 1u ||
symbolNode->getSymbol().empty();
symbolNode->variable().symbolType() == SymbolType::Empty;
}
TIntermBinary *initNode = declarator->getAsBinaryNode();
if (initNode != nullptr)
......
......@@ -36,6 +36,7 @@ TSymbol::TSymbol(TSymbolTable *symbolTable,
ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
ASSERT(mName != nullptr || mSymbolType == SymbolType::AngleInternal ||
mSymbolType == SymbolType::NotResolved || mSymbolType == SymbolType::Empty);
ASSERT(mName == nullptr || *mName != "");
}
const TString &TSymbol::name() const
......
......@@ -77,8 +77,8 @@ class DeclareDefaultUniformsTraverser : public TIntermTraverser
{
if (mInDefaultUniform)
{
const TName &name = symbol->getName();
ASSERT(name.getString().substr(0, 3) != "gl_");
const TString &name = symbol->variable().name();
ASSERT(name.substr(0, 3) != "gl_");
(*mSink) << HashName(name, mHashFunction, mNameMap);
}
}
......
......@@ -210,7 +210,7 @@ void UniformHLSL::outputHLSLSamplerUniformGroup(
for (const TIntermSymbol *uniform : group)
{
const TType &type = uniform->getType();
const TString &name = uniform->getSymbol();
const TString &name = uniform->getName();
unsigned int registerCount;
// The uniform might be just a regular sampler or one extracted from a struct.
......@@ -231,14 +231,14 @@ void UniformHLSL::outputHLSLSamplerUniformGroup(
if (type.isArray())
{
out << "static const uint " << DecorateVariableIfNeeded(uniform->getName())
out << "static const uint " << DecorateVariableIfNeeded(uniform->variable())
<< ArrayString(type) << " = ";
OutputSamplerIndexArrayInitializer(out, type, samplerArrayIndex);
out << ";\n";
}
else
{
out << "static const uint " << DecorateVariableIfNeeded(uniform->getName()) << " = "
out << "static const uint " << DecorateVariableIfNeeded(uniform->variable()) << " = "
<< samplerArrayIndex << ";\n";
}
}
......@@ -262,20 +262,20 @@ void UniformHLSL::outputHLSLSamplerUniformGroup(
void UniformHLSL::outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
const TType &type,
const TName &name,
const TVariable &variable,
const unsigned int registerIndex)
{
out << "uniform " << SamplerString(type.getBasicType()) << " sampler_"
<< DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(s"
<< DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(s"
<< str(registerIndex) << ");\n";
out << "uniform " << TextureString(type.getBasicType()) << " texture_"
<< DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(t"
<< DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(t"
<< str(registerIndex) << ");\n";
}
void UniformHLSL::outputHLSL4_1_FL11Texture(TInfoSinkBase &out,
const TType &type,
const TName &name,
const TVariable &variable,
const unsigned int registerIndex)
{
// TODO(xinghua.cao@intel.com): if image2D variable is bound on one layer of Texture3D or
......@@ -284,14 +284,14 @@ void UniformHLSL::outputHLSL4_1_FL11Texture(TInfoSinkBase &out,
// temporary Texture2D to image2D variable.
out << "uniform "
<< TextureString(type.getBasicType(), type.getLayoutQualifier().imageInternalFormat) << " "
<< DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(t"
<< DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(t"
<< str(registerIndex) << ");\n";
return;
}
void UniformHLSL::outputHLSL4_1_FL11RWTexture(TInfoSinkBase &out,
const TType &type,
const TName &name,
const TVariable &variable,
const unsigned int registerIndex)
{
// TODO(xinghua.cao@intel.com): if image2D variable is bound on one layer of Texture3D or
......@@ -302,7 +302,7 @@ void UniformHLSL::outputHLSL4_1_FL11RWTexture(TInfoSinkBase &out,
{
out << "uniform "
<< RWTextureString(type.getBasicType(), type.getLayoutQualifier().imageInternalFormat)
<< " " << DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(u"
<< " " << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(u"
<< str(registerIndex) << ");\n";
}
else
......@@ -315,7 +315,7 @@ void UniformHLSL::outputHLSL4_1_FL11RWTexture(TInfoSinkBase &out,
void UniformHLSL::outputUniform(TInfoSinkBase &out,
const TType &type,
const TName &name,
const TVariable &variable,
const unsigned int registerIndex)
{
const TStructure *structure = type.getStruct();
......@@ -333,7 +333,7 @@ void UniformHLSL::outputUniform(TInfoSinkBase &out,
out << "uniform " << typeName << " ";
out << DecorateVariableIfNeeded(name);
out << DecorateVariableIfNeeded(variable);
out << ArrayString(type) << " : " << registerString << ";\n";
}
......@@ -358,7 +358,7 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out,
// Output regular uniforms. Group sampler uniforms by type.
const TIntermSymbol &uniform = *uniformIt.second;
const TType &type = uniform.getType();
const TName &name = uniform.getName();
const TVariable &variable = uniform.variable();
if (outputType == SH_HLSL_4_1_OUTPUT && IsSampler(type.getBasicType()))
{
......@@ -367,8 +367,8 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out,
}
else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(type.getBasicType()))
{
unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr);
outputHLSL4_0_FL9_3Sampler(out, type, name, registerIndex);
unsigned int registerIndex = assignUniformRegister(type, variable.name(), nullptr);
outputHLSL4_0_FL9_3Sampler(out, type, variable, registerIndex);
}
else if (outputType == SH_HLSL_4_1_OUTPUT && IsImage(type.getBasicType()))
{
......@@ -380,12 +380,12 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out,
{
TVector<TIntermSymbol *> samplerSymbols;
TMap<TIntermSymbol *, TString> symbolsToAPINames;
type.createSamplerSymbols("angle_" + name.getString(), name.getString(),
type.createSamplerSymbols("angle_" + uniform.getName(), uniform.getName(),
&samplerSymbols, &symbolsToAPINames, symbolTable);
for (TIntermSymbol *sampler : samplerSymbols)
{
const TType &samplerType = sampler->getType();
const TName &samplerName = sampler->getName();
const TVariable &samplerVariable = sampler->variable();
if (outputType == SH_HLSL_4_1_OUTPUT)
{
......@@ -397,19 +397,20 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out,
{
unsigned int registerIndex = assignSamplerInStructUniformRegister(
samplerType, symbolsToAPINames[sampler], nullptr);
outputHLSL4_0_FL9_3Sampler(out, samplerType, samplerName, registerIndex);
outputHLSL4_0_FL9_3Sampler(out, samplerType, samplerVariable,
registerIndex);
}
else
{
ASSERT(outputType == SH_HLSL_3_0_OUTPUT);
unsigned int registerIndex = assignSamplerInStructUniformRegister(
samplerType, symbolsToAPINames[sampler], nullptr);
outputUniform(out, samplerType, samplerName, registerIndex);
outputUniform(out, samplerType, samplerVariable, registerIndex);
}
}
}
unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr);
outputUniform(out, type, name, registerIndex);
unsigned int registerIndex = assignUniformRegister(type, uniform.getName(), nullptr);
outputUniform(out, type, variable, registerIndex);
}
}
......@@ -429,15 +430,15 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out,
for (const TIntermSymbol *image : imageUniformsHLSL41Output)
{
const TType &type = image->getType();
const TName &name = image->getName();
unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr);
const TVariable &variable = image->variable();
unsigned int registerIndex = assignUniformRegister(type, image->getName(), nullptr);
if (type.getMemoryQualifier().readonly)
{
outputHLSL4_1_FL11Texture(out, type, name, registerIndex);
outputHLSL4_1_FL11Texture(out, type, variable, registerIndex);
}
else
{
outputHLSL4_1_FL11RWTexture(out, type, name, registerIndex);
outputHLSL4_1_FL11RWTexture(out, type, variable, registerIndex);
}
}
}
......@@ -472,7 +473,7 @@ TString UniformHLSL::uniformBlocksHeader(const ReferencedSymbols &referencedInte
// nodeType.isInterfaceBlock() == false means the node is a field of a uniform block which
// doesn't have instance name.
const TString &instanceName =
nodeType.isInterfaceBlock() ? interfaceBlockReference.second->getSymbol() : "";
nodeType.isInterfaceBlock() ? interfaceBlockReference.second->getName() : "";
if (instanceName != "")
{
......
......@@ -63,19 +63,19 @@ class UniformHLSL : angle::NonCopyable
void outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
const TType &type,
const TName &name,
const TVariable &variable,
const unsigned int registerIndex);
void outputHLSL4_1_FL11Texture(TInfoSinkBase &out,
const TType &type,
const TName &name,
const TVariable &variable,
const unsigned int registerIndex);
void outputHLSL4_1_FL11RWTexture(TInfoSinkBase &out,
const TType &type,
const TName &name,
const TVariable &variable,
const unsigned int registerIndex);
void outputUniform(TInfoSinkBase &out,
const TType &type,
const TName &name,
const TVariable &variable,
const unsigned int registerIndex);
// Returns the uniform's register index
......
......@@ -715,18 +715,19 @@ TString Decorate(const TString &string)
return string;
}
TString DecorateVariableIfNeeded(const TName &name)
TString DecorateVariableIfNeeded(const TVariable &variable)
{
if (name.isInternal())
if (variable.symbolType() == SymbolType::AngleInternal)
{
const TString &name = variable.name();
// The name should not have a prefix reserved for user-defined variables or functions.
ASSERT(name.getString().compare(0, 2, "f_") != 0);
ASSERT(name.getString().compare(0, 1, "_") != 0);
return name.getString();
ASSERT(name.compare(0, 2, "f_") != 0);
ASSERT(name.compare(0, 1, "_") != 0);
return name;
}
else
{
return Decorate(name.getString());
return Decorate(variable.name());
}
}
......
......@@ -16,8 +16,6 @@
#include "angle_gl.h"
class TName;
namespace sh
{
......@@ -110,7 +108,7 @@ TString SamplerString(HLSLTextureGroup type);
// Adds a prefix to user-defined names to avoid naming clashes.
TString Decorate(const TString &string);
TString DecorateVariableIfNeeded(const TName &name);
TString DecorateVariableIfNeeded(const TVariable &variable);
TString DecorateFunctionIfNeeded(const TFunction *func);
TString DecorateField(const TString &string, const TStructure &structure);
TString DecoratePrivate(const TString &privateText);
......
......@@ -119,7 +119,7 @@ void ValidateLimitationsTraverser::visitSymbol(TIntermSymbol *node)
{
error(node->getLine(),
"Loop index cannot be statically assigned to within the body of the loop",
node->getSymbol().c_str());
node->getName().c_str());
}
}
......@@ -248,7 +248,7 @@ int ValidateLimitationsTraverser::validateForLoopInit(TIntermLoop *node)
if (!isConstExpr(declInit->getRight()))
{
error(declInit->getLine(), "Loop index cannot be initialized with non-constant expression",
symbol->getSymbol().c_str());
symbol->getName().c_str());
return -1;
}
......@@ -282,7 +282,7 @@ bool ValidateLimitationsTraverser::validateForLoopCond(TIntermLoop *node, int in
}
if (symbol->uniqueId().get() != indexSymbolId)
{
error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str());
error(symbol->getLine(), "Expected loop index", symbol->getName().c_str());
return false;
}
// Relational operator is one of: > >= < <= == or !=.
......@@ -304,7 +304,7 @@ bool ValidateLimitationsTraverser::validateForLoopCond(TIntermLoop *node, int in
if (!isConstExpr(binOp->getRight()))
{
error(binOp->getLine(), "Loop index cannot be compared with non-constant expression",
symbol->getSymbol().c_str());
symbol->getName().c_str());
return false;
}
......@@ -353,7 +353,7 @@ bool ValidateLimitationsTraverser::validateForLoopExpr(TIntermLoop *node, int in
}
if (symbol->uniqueId().get() != indexSymbolId)
{
error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str());
error(symbol->getLine(), "Expected loop index", symbol->getName().c_str());
return false;
}
......@@ -381,7 +381,7 @@ bool ValidateLimitationsTraverser::validateForLoopExpr(TIntermLoop *node, int in
if (!isConstExpr(binOp->getRight()))
{
error(binOp->getLine(), "Loop index cannot be modified by non-constant expression",
symbol->getSymbol().c_str());
symbol->getName().c_str());
return false;
}
}
......
......@@ -20,9 +20,10 @@ namespace sh
namespace
{
void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
{
diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str());
diagnostics->error(symbol.getLine(), reason, symbol.getName().c_str());
}
class ValidateOutputsTraverser : public TIntermTraverser
......@@ -112,7 +113,7 @@ void ValidateOutputsTraverser::validate(TDiagnostics *diagnostics) const
{
std::stringstream strstr;
strstr << "conflicting output locations with previously defined output '"
<< validOutputs[offsetLocation]->getSymbol() << "'";
<< validOutputs[offsetLocation]->getName() << "'";
error(*symbol, strstr.str().c_str(), diagnostics);
}
else
......
......@@ -22,7 +22,7 @@ namespace
void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
{
diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str());
diagnostics->error(symbol.getLine(), reason, symbol.getName().c_str());
}
int GetLocationCount(const TIntermSymbol *varying, bool ignoreVaryingArraySize)
......@@ -84,9 +84,9 @@ void ValidateShaderInterface(TDiagnostics *diagnostics,
if (locationMap.find(offsetLocation) != locationMap.end())
{
std::stringstream strstr;
strstr << "'" << varying->getSymbol()
strstr << "'" << varying->getName()
<< "' conflicting location with previously defined '"
<< locationMap[offsetLocation]->getSymbol() << "'";
<< locationMap[offsetLocation]->getName() << "'";
error(*varying, strstr.str().c_str(), diagnostics);
}
else
......@@ -128,6 +128,11 @@ bool ValidateVaryingLocationsTraverser::visitDeclaration(Visit visit, TIntermDec
return false;
}
if (symbol->variable().symbolType() == SymbolType::Empty)
{
return false;
}
// Collect varyings that have explicit 'location' qualifiers.
const TQualifier qualifier = symbol->getQualifier();
if (symbol->getType().getLayoutQualifier().location != -1)
......
......@@ -7,6 +7,7 @@
#include "compiler/translator/VersionGLSL.h"
#include "angle_gl.h"
#include "compiler/translator/Symbol.h"
namespace sh
{
......@@ -76,7 +77,7 @@ TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutpu
void TVersionGLSL::visitSymbol(TIntermSymbol *node)
{
if (node->getSymbol() == "gl_PointCoord")
if (node->variable().symbolType() == SymbolType::BuiltIn && node->getName() == "gl_PointCoord")
{
ensureVersionIsAtLeast(GLSL_VERSION_120);
}
......
......@@ -476,7 +476,7 @@ TString ArrayString(const TType &type)
TString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
{
if (type.getBasicType() == EbtStruct)
return HashName(TName(type.getStruct()->name()), hashFunction, nameMap);
return HashName(type.getStruct(), hashFunction, nameMap);
else
return type.getBuiltInTypeNameString();
}
......
......@@ -36,7 +36,9 @@ bool AreSymbolsTheSame(const TIntermSymbol *expected, const TIntermSymbol *candi
const bool sameTypes = expectedType == candidateType &&
expectedType.getPrecision() == candidateType.getPrecision() &&
expectedType.getQualifier() == candidateType.getQualifier();
const bool sameSymbols = expected->getSymbol() == candidate->getSymbol();
const bool sameSymbols = (expected->variable().symbolType() == SymbolType::Empty &&
candidate->variable().symbolType() == SymbolType::Empty) ||
expected->getName() == candidate->getName();
return sameSymbols && sameTypes;
}
......
......@@ -76,8 +76,7 @@ class IntermNodeTest : public testing::Test
ASSERT_NE(original, copy);
ASSERT_EQ(&original->variable(), &copy->variable());
ASSERT_EQ(original->uniqueId(), copy->uniqueId());
ASSERT_EQ(original->getName().getString(), copy->getName().getString());
ASSERT_EQ(original->getName().isInternal(), copy->getName().isInternal());
ASSERT_EQ(original->getName(), copy->getName());
checkTypeEqualWithQualifiers(original->getType(), copy->getType());
ASSERT_EQ(original->getLine().first_file, copy->getLine().first_file);
ASSERT_EQ(original->getLine().first_line, copy->getLine().first_line);
......
......@@ -62,7 +62,7 @@ class SymbolOccurrenceCounterByName : public SymbolOccurrenceCounter
bool shouldCountSymbol(const TIntermSymbol *node) const override
{
return node->getName().getString() == mSymbolName;
return node->variable().symbolType() != SymbolType::Empty && node->getName() == mSymbolName;
}
private:
......@@ -79,8 +79,8 @@ class SymbolOccurrenceCounterByNameAndQualifier : public SymbolOccurrenceCounter
bool shouldCountSymbol(const TIntermSymbol *node) const override
{
return node->getName().getString() == mSymbolName &&
node->getQualifier() == mSymbolQualifier;
return node->variable().symbolType() != SymbolType::Empty &&
node->getName() == mSymbolName && node->getQualifier() == mSymbolQualifier;
}
private:
......
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