Commit b60d30f7 by Olli Etuaho Committed by Commit Bot

Make TVariable type immutable

This enables using constexpr types for built-in variables and some of the variables created in AST transformations. BUG=angleproject:2267 TEST=angle_unittests Change-Id: Ie85b3c9872a071a7c023ced013b14ad91cff7cee Reviewed-on: https://chromium-review.googlesource.com/868134 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent fa886975
...@@ -122,8 +122,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(Visit visit ...@@ -122,8 +122,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(Visit visit
const TSymbolUniqueId &functionId = node->getFunction()->uniqueId(); const TSymbolUniqueId &functionId = node->getFunction()->uniqueId();
if (mChangedFunctions.find(functionId.get()) == mChangedFunctions.end()) if (mChangedFunctions.find(functionId.get()) == mChangedFunctions.end())
{ {
TType returnValueVariableType(node->getType()); TType *returnValueVariableType = new TType(node->getType());
returnValueVariableType.setQualifier(EvqOut); returnValueVariableType->setQualifier(EvqOut);
ChangedFunction changedFunction; ChangedFunction changedFunction;
changedFunction.returnValueVariable = changedFunction.returnValueVariable =
new TVariable(mSymbolTable, mReturnValueVariableName, returnValueVariableType, new TVariable(mSymbolTable, mReturnValueVariableName, returnValueVariableType,
...@@ -170,7 +170,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter ...@@ -170,7 +170,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter
// type s0[size]; // type s0[size];
TIntermDeclaration *returnValueDeclaration = nullptr; TIntermDeclaration *returnValueDeclaration = nullptr;
TVariable *returnValue = DeclareTempVariable(mSymbolTable, node->getType(), TVariable *returnValue = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
EvqTemporary, &returnValueDeclaration); EvqTemporary, &returnValueDeclaration);
replacements.push_back(returnValueDeclaration); replacements.push_back(returnValueDeclaration);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#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/ReplaceVariable.h" #include "compiler/translator/ReplaceVariable.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h" #include "compiler/translator/util.h"
...@@ -142,7 +143,7 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root, ...@@ -142,7 +143,7 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
TQualifier viewIDQualifier = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn; TQualifier viewIDQualifier = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn;
const TString *viewIDVariableName = NewPoolTString("ViewID_OVR"); const TString *viewIDVariableName = NewPoolTString("ViewID_OVR");
const TVariable *viewID = const TVariable *viewID =
new TVariable(symbolTable, viewIDVariableName, TType(EbtUInt, EbpHigh, viewIDQualifier), new TVariable(symbolTable, viewIDVariableName, new TType(EbtUInt, EbpHigh, viewIDQualifier),
SymbolType::AngleInternal); SymbolType::AngleInternal);
DeclareGlobalVariable(root, viewID); DeclareGlobalVariable(root, viewID);
...@@ -154,9 +155,9 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root, ...@@ -154,9 +155,9 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// Replacing gl_InstanceID with InstanceID should happen before adding the initializers of // Replacing gl_InstanceID with InstanceID should happen before adding the initializers of
// InstanceID and ViewID. // InstanceID and ViewID.
const TString *instanceIDVariableName = NewPoolTString("InstanceID"); const TString *instanceIDVariableName = NewPoolTString("InstanceID");
const TVariable *instanceID = const TType *instanceIDVariableType = StaticType::Get<EbtInt, EbpHigh, EvqGlobal, 1, 1>();
new TVariable(symbolTable, instanceIDVariableName, TType(EbtInt, EbpHigh, EvqGlobal), const TVariable *instanceID = new TVariable(
SymbolType::AngleInternal); symbolTable, instanceIDVariableName, instanceIDVariableType, SymbolType::AngleInternal);
DeclareGlobalVariable(root, instanceID); DeclareGlobalVariable(root, instanceID);
ReplaceVariable( ReplaceVariable(
root, static_cast<TVariable *>(symbolTable->findBuiltIn("gl_InstanceID", 300, true)), root, static_cast<TVariable *>(symbolTable->findBuiltIn("gl_InstanceID", 300, true)),
...@@ -177,9 +178,11 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root, ...@@ -177,9 +178,11 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// Add a uniform to switch between side-by-side and layered rendering. // Add a uniform to switch between side-by-side and layered rendering.
const TString *multiviewBaseViewLayerIndexVariableName = const TString *multiviewBaseViewLayerIndexVariableName =
NewPoolTString("multiviewBaseViewLayerIndex"); NewPoolTString("multiviewBaseViewLayerIndex");
const TType *baseLayerIndexVariableType =
StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
const TVariable *multiviewBaseViewLayerIndex = const TVariable *multiviewBaseViewLayerIndex =
new TVariable(symbolTable, multiviewBaseViewLayerIndexVariableName, new TVariable(symbolTable, multiviewBaseViewLayerIndexVariableName,
TType(EbtInt, EbpHigh, EvqUniform), SymbolType::AngleInternal); baseLayerIndexVariableType, SymbolType::AngleInternal);
DeclareGlobalVariable(root, multiviewBaseViewLayerIndex); DeclareGlobalVariable(root, multiviewBaseViewLayerIndex);
// Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's // Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's
......
...@@ -153,8 +153,8 @@ void DeferGlobalInitializers(TIntermBlock *root, ...@@ -153,8 +153,8 @@ void DeferGlobalInitializers(TIntermBlock *root,
// Replace constant variables with non-constant global variables. // Replace constant variables with non-constant global variables.
for (const TVariable *var : variablesToReplace) for (const TVariable *var : variablesToReplace)
{ {
TType replacementType(var->getType()); TType *replacementType = new TType(var->getType());
replacementType.setQualifier(EvqGlobal); replacementType->setQualifier(EvqGlobal);
TVariable *replacement = TVariable *replacement =
new TVariable(symbolTable, &var->name(), replacementType, var->symbolType()); new TVariable(symbolTable, &var->name(), replacementType, var->symbolType());
ReplaceVariable(root, var, replacement); ReplaceVariable(root, var, replacement);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,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/StaticType.h"
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h" #include "compiler/translator/util.h"
...@@ -102,8 +103,10 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode, ...@@ -102,8 +103,10 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
TSymbolTable *symbolTable) TSymbolTable *symbolTable)
{ {
ASSERT(initializedNode->isArray()); ASSERT(initializedNode->isArray());
TVariable *indexVariable = CreateTempVariable( const TType *mediumpIndexType = StaticType::Get<EbtInt, EbpMedium, EvqTemporary, 1, 1>();
symbolTable, TType(EbtInt, highPrecisionSupported ? EbpHigh : EbpMedium, EvqTemporary)); const TType *highpIndexType = StaticType::Get<EbtInt, EbpHigh, EvqTemporary, 1, 1>();
TVariable *indexVariable =
CreateTempVariable(symbolTable, highPrecisionSupported ? highpIndexType : mediumpIndexType);
TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexVariable); TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexVariable);
TIntermDeclaration *indexInit = TIntermDeclaration *indexInit =
......
...@@ -144,7 +144,7 @@ TIntermConstantUnion *CreateBoolNode(bool value) ...@@ -144,7 +144,7 @@ TIntermConstantUnion *CreateBoolNode(bool value)
return node; return node;
} }
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type) TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type)
{ {
ASSERT(symbolTable != nullptr); ASSERT(symbolTable != nullptr);
// TODO(oetuaho): Might be useful to sanitize layout qualifier etc. on the type of the created // TODO(oetuaho): Might be useful to sanitize layout qualifier etc. on the type of the created
...@@ -152,15 +152,15 @@ TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type) ...@@ -152,15 +152,15 @@ TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type)
return new TVariable(symbolTable, nullptr, type, SymbolType::AngleInternal); return new TVariable(symbolTable, nullptr, type, SymbolType::AngleInternal);
} }
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type, TQualifier qualifier) TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier)
{ {
ASSERT(symbolTable != nullptr); ASSERT(symbolTable != nullptr);
if (type.getQualifier() == qualifier) if (type->getQualifier() == qualifier)
{ {
return CreateTempVariable(symbolTable, type); return CreateTempVariable(symbolTable, type);
} }
TType typeWithQualifier(type); TType *typeWithQualifier = new TType(*type);
typeWithQualifier.setQualifier(qualifier); typeWithQualifier->setQualifier(qualifier);
return CreateTempVariable(symbolTable, typeWithQualifier); return CreateTempVariable(symbolTable, typeWithQualifier);
} }
...@@ -199,7 +199,7 @@ TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTy ...@@ -199,7 +199,7 @@ TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTy
} }
TVariable *DeclareTempVariable(TSymbolTable *symbolTable, TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
const TType &type, const TType *type,
TQualifier qualifier, TQualifier qualifier,
TIntermDeclaration **declarationOut) TIntermDeclaration **declarationOut)
{ {
...@@ -213,7 +213,8 @@ TVariable *DeclareTempVariable(TSymbolTable *symbolTable, ...@@ -213,7 +213,8 @@ TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
TQualifier qualifier, TQualifier qualifier,
TIntermDeclaration **declarationOut) TIntermDeclaration **declarationOut)
{ {
TVariable *variable = CreateTempVariable(symbolTable, initializer->getType(), qualifier); TVariable *variable =
CreateTempVariable(symbolTable, new TType(initializer->getType()), qualifier);
*declarationOut = CreateTempInitDeclarationNode(variable, initializer); *declarationOut = CreateTempInitDeclarationNode(variable, initializer);
return variable; return variable;
} }
......
...@@ -25,8 +25,8 @@ TIntermTyped *CreateZeroNode(const TType &type); ...@@ -25,8 +25,8 @@ TIntermTyped *CreateZeroNode(const TType &type);
TIntermConstantUnion *CreateIndexNode(int index); TIntermConstantUnion *CreateIndexNode(int index);
TIntermConstantUnion *CreateBoolNode(bool value); TIntermConstantUnion *CreateBoolNode(bool value);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type); TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type, TQualifier qualifier); TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier);
TIntermSymbol *CreateTempSymbolNode(const TVariable *tempVariable); TIntermSymbol *CreateTempSymbolNode(const TVariable *tempVariable);
TIntermDeclaration *CreateTempDeclarationNode(const TVariable *tempVariable); TIntermDeclaration *CreateTempDeclarationNode(const TVariable *tempVariable);
...@@ -35,7 +35,7 @@ TIntermDeclaration *CreateTempInitDeclarationNode(const TVariable *tempVariable, ...@@ -35,7 +35,7 @@ TIntermDeclaration *CreateTempInitDeclarationNode(const TVariable *tempVariable,
TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTyped *rightNode); TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTyped *rightNode);
TVariable *DeclareTempVariable(TSymbolTable *symbolTable, TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
const TType &type, const TType *type,
TQualifier qualifier, TQualifier qualifier,
TIntermDeclaration **declarationOut); TIntermDeclaration **declarationOut);
TVariable *DeclareTempVariable(TSymbolTable *symbolTable, TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
......
...@@ -193,7 +193,7 @@ class TParseContext : angle::NonCopyable ...@@ -193,7 +193,7 @@ class TParseContext : angle::NonCopyable
// is not needed in the AST. // is not needed in the AST.
bool executeInitializer(const TSourceLoc &line, bool executeInitializer(const TSourceLoc &line,
const TString &identifier, const TString &identifier,
TType type, TType *type,
TIntermTyped *initializer, TIntermTyped *initializer,
TIntermBinary **initNode); TIntermBinary **initNode);
TIntermNode *addConditionInitializer(const TPublicType &pType, TIntermNode *addConditionInitializer(const TPublicType &pType,
...@@ -471,7 +471,7 @@ class TParseContext : angle::NonCopyable ...@@ -471,7 +471,7 @@ class TParseContext : angle::NonCopyable
bool declareVariable(const TSourceLoc &line, bool declareVariable(const TSourceLoc &line,
const TString &identifier, const TString &identifier,
const TType &type, const TType *type,
TVariable **variable); TVariable **variable);
void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line, void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
......
...@@ -105,14 +105,14 @@ bool PruneNoOpsTraverser::visitDeclaration(Visit, TIntermDeclaration *node) ...@@ -105,14 +105,14 @@ bool PruneNoOpsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
// Create a new variable to use in the declarator so that the variable and node // Create a new variable to use in the declarator so that the variable and node
// types are kept consistent. // types are kept consistent.
TType type(declaratorSymbol->getType()); TType *type = new TType(declaratorSymbol->getType());
if (mInGlobalScope) if (mInGlobalScope)
{ {
type.setQualifier(EvqGlobal); type->setQualifier(EvqGlobal);
} }
else else
{ {
type.setQualifier(EvqTemporary); type->setQualifier(EvqTemporary);
} }
TVariable *variable = new TVariable(mSymbolTable, nullptr, type, SymbolType::Empty); TVariable *variable = new TVariable(mSymbolTable, nullptr, type, SymbolType::Empty);
queueReplacementWithParent(node, declaratorSymbol, new TIntermSymbol(variable), queueReplacementWithParent(node, declaratorSymbol, new TIntermSymbol(variable),
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "compiler/translator/IntermNodePatternMatcher.h" #include "compiler/translator/IntermNodePatternMatcher.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/StaticType.h"
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
namespace sh namespace sh
...@@ -58,7 +59,7 @@ std::string GetIndexFunctionName(const TType &type, bool write) ...@@ -58,7 +59,7 @@ std::string GetIndexFunctionName(const TType &type, bool write)
return nameSink.str(); return nameSink.str();
} }
TIntermSymbol *CreateBaseSymbol(const TType &type, TSymbolTable *symbolTable) TIntermSymbol *CreateBaseSymbol(const TType *type, TSymbolTable *symbolTable)
{ {
TString *baseString = NewPoolTString("base"); TString *baseString = NewPoolTString("base");
TVariable *baseVariable = TVariable *baseVariable =
...@@ -69,16 +70,17 @@ TIntermSymbol *CreateBaseSymbol(const TType &type, TSymbolTable *symbolTable) ...@@ -69,16 +70,17 @@ TIntermSymbol *CreateBaseSymbol(const TType &type, TSymbolTable *symbolTable)
TIntermSymbol *CreateIndexSymbol(TSymbolTable *symbolTable) TIntermSymbol *CreateIndexSymbol(TSymbolTable *symbolTable)
{ {
TString *indexString = NewPoolTString("index"); TString *indexString = NewPoolTString("index");
TVariable *indexVariable = new TVariable( TVariable *indexVariable =
symbolTable, indexString, TType(EbtInt, EbpHigh, EvqIn), SymbolType::AngleInternal); new TVariable(symbolTable, indexString, StaticType::Get<EbtInt, EbpHigh, EvqIn, 1, 1>(),
SymbolType::AngleInternal);
return new TIntermSymbol(indexVariable); return new TIntermSymbol(indexVariable);
} }
TIntermSymbol *CreateValueSymbol(const TType &type, TSymbolTable *symbolTable) TIntermSymbol *CreateValueSymbol(const TType &type, TSymbolTable *symbolTable)
{ {
TString *valueString = NewPoolTString("value"); TString *valueString = NewPoolTString("value");
TType valueType(type); TType *valueType = new TType(type);
valueType.setQualifier(EvqIn); valueType->setQualifier(EvqIn);
TVariable *valueVariable = TVariable *valueVariable =
new TVariable(symbolTable, valueString, valueType, SymbolType::AngleInternal); new TVariable(symbolTable, valueString, valueType, SymbolType::AngleInternal);
return new TIntermSymbol(valueVariable); return new TIntermSymbol(valueVariable);
...@@ -179,15 +181,15 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(const TType &type, ...@@ -179,15 +181,15 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(const TType &type,
std::string functionName = GetIndexFunctionName(type, write); std::string functionName = GetIndexFunctionName(type, write);
TIntermFunctionPrototype *prototypeNode = CreateInternalFunctionPrototypeNode(func); TIntermFunctionPrototype *prototypeNode = CreateInternalFunctionPrototypeNode(func);
TType baseType(type); TType *baseType = new TType(type);
// Conservatively use highp here, even if the indexed type is not highp. That way the code can't // Conservatively use highp here, even if the indexed type is not highp. That way the code can't
// end up using mediump version of an indexing function for a highp value, if both mediump and // end up using mediump version of an indexing function for a highp value, if both mediump and
// highp values are being indexed in the shader. For HLSL precision doesn't matter, but in // highp values are being indexed in the shader. For HLSL precision doesn't matter, but in
// principle this code could be used with multiple backends. // principle this code could be used with multiple backends.
baseType.setPrecision(EbpHigh); baseType->setPrecision(EbpHigh);
baseType.setQualifier(EvqInOut); baseType->setQualifier(EvqInOut);
if (!write) if (!write)
baseType.setQualifier(EvqIn); baseType->setQualifier(EvqIn);
TIntermSymbol *baseParam = CreateBaseSymbol(baseType, symbolTable); TIntermSymbol *baseParam = CreateBaseSymbol(baseType, symbolTable);
prototypeNode->getSequence()->push_back(baseParam); prototypeNode->getSequence()->push_back(baseParam);
......
...@@ -203,8 +203,8 @@ void RemoveUnreferencedVariablesTraverser::removeVariableDeclaration(TIntermDecl ...@@ -203,8 +203,8 @@ void RemoveUnreferencedVariablesTraverser::removeVariableDeclaration(TIntermDecl
// Already an empty declaration - nothing to do. // Already an empty declaration - nothing to do.
return; return;
} }
TVariable *emptyVariable = TVariable *emptyVariable = new TVariable(
new TVariable(mSymbolTable, nullptr, declarator->getType(), SymbolType::Empty); mSymbolTable, nullptr, new TType(declarator->getType()), SymbolType::Empty);
queueReplacementWithParent(node, declarator, new TIntermSymbol(emptyVariable), queueReplacementWithParent(node, declarator, new TIntermSymbol(emptyVariable),
OriginalNode::IS_DROPPED); OriginalNode::IS_DROPPED);
return; return;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#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/StaticType.h"
namespace sh namespace sh
{ {
...@@ -71,7 +72,7 @@ class DoWhileRewriter : public TIntermTraverser ...@@ -71,7 +72,7 @@ class DoWhileRewriter : public TIntermTraverser
} }
// Found a loop to change. // Found a loop to change.
TType boolType(EbtBool); const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType); TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
// bool temp = false; // bool temp = false;
......
...@@ -192,15 +192,15 @@ TVariable *ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original) ...@@ -192,15 +192,15 @@ TVariable *ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
{ {
ASSERT(original); ASSERT(original);
TType type(original->getType()); TType *type = new TType(original->getType());
type.setQualifier(EvqTemporary); type->setQualifier(EvqTemporary);
if (mShaderType == GL_FRAGMENT_SHADER && type.getBasicType() == EbtFloat && if (mShaderType == GL_FRAGMENT_SHADER && type->getBasicType() == EbtFloat &&
type.getPrecision() == EbpUndefined) type->getPrecision() == EbpUndefined)
{ {
// We use the highest available precision for the temporary variable // We use the highest available precision for the temporary variable
// to avoid computing the actual precision using the rules defined // to avoid computing the actual precision using the rules defined
// in GLSL ES 1.0 Section 4.5.2. // in GLSL ES 1.0 Section 4.5.2.
type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium); type->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
} }
TVariable *variable = CreateTempVariable(mSymbolTable, type); TVariable *variable = CreateTempVariable(mSymbolTable, type);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "compiler/translator/IntermNodePatternMatcher.h" #include "compiler/translator/IntermNodePatternMatcher.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/StaticType.h"
namespace sh namespace sh
{ {
...@@ -151,7 +152,7 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node) ...@@ -151,7 +152,7 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
if (mFoundLoopToChange) if (mFoundLoopToChange)
{ {
TType boolType(EbtBool, EbpUndefined, EvqTemporary); const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType); TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
// Replace the loop condition with a boolean variable that's updated on each iteration. // Replace the loop condition with a boolean variable that's updated on each iteration.
......
...@@ -59,11 +59,12 @@ const TString &TSymbol::getMangledName() const ...@@ -59,11 +59,12 @@ const TString &TSymbol::getMangledName() const
TVariable::TVariable(TSymbolTable *symbolTable, TVariable::TVariable(TSymbolTable *symbolTable,
const TString *name, const TString *name,
const TType &t, const TType *type,
SymbolType symbolType, SymbolType symbolType,
TExtension extension) TExtension extension)
: TSymbol(symbolTable, name, symbolType, extension), type(t), unionArray(nullptr) : TSymbol(symbolTable, name, symbolType, extension), mType(type), unionArray(nullptr)
{ {
ASSERT(mType);
} }
TStructure::TStructure(TSymbolTable *symbolTable, TStructure::TStructure(TSymbolTable *symbolTable,
......
...@@ -71,22 +71,20 @@ class TVariable : public TSymbol ...@@ -71,22 +71,20 @@ class TVariable : public TSymbol
public: public:
TVariable(TSymbolTable *symbolTable, TVariable(TSymbolTable *symbolTable,
const TString *name, const TString *name,
const TType &t, const TType *type,
SymbolType symbolType, SymbolType symbolType,
TExtension ext = TExtension::UNDEFINED); TExtension ext = TExtension::UNDEFINED);
~TVariable() override {} ~TVariable() override {}
bool isVariable() const override { return true; } bool isVariable() const override { return true; }
TType &getType() { return type; } const TType &getType() const { return *mType; }
const TType &getType() const { return type; }
void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
const TConstantUnion *getConstPointer() const { return unionArray; } const TConstantUnion *getConstPointer() const { return unionArray; }
void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; } void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
private: private:
TType type; const TType *mType;
const TConstantUnion *unionArray; const TConstantUnion *unionArray;
}; };
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
#include "compiler/translator/StaticType.h"
#include <stdio.h> #include <stdio.h>
#include <algorithm> #include <algorithm>
...@@ -223,24 +222,22 @@ bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock) ...@@ -223,24 +222,22 @@ bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
return insert(currentLevel(), interfaceBlock); return insert(currentLevel(), interfaceBlock);
} }
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type) TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType *type)
{ {
ASSERT(level <= LAST_BUILTIN_LEVEL); ASSERT(level <= LAST_BUILTIN_LEVEL);
ASSERT(type->isRealized());
return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn); return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
} }
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
const TString *name, const TString *name,
const TType &type, const TType *type,
SymbolType symbolType) SymbolType symbolType)
{ {
ASSERT(level > LAST_BUILTIN_LEVEL || type->isRealized());
TVariable *var = new TVariable(this, name, type, symbolType); TVariable *var = new TVariable(this, name, type, symbolType);
if (insert(level, var)) if (insert(level, var))
{ {
if (level <= LAST_BUILTIN_LEVEL)
{
var->getType().realize();
}
return var; return var;
} }
return nullptr; return nullptr;
...@@ -249,15 +246,13 @@ TVariable *TSymbolTable::insertVariable(ESymbolLevel level, ...@@ -249,15 +246,13 @@ TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level, TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
TExtension ext, TExtension ext,
const char *name, const char *name,
const TType &type) const TType *type)
{ {
ASSERT(level <= LAST_BUILTIN_LEVEL);
ASSERT(type->isRealized());
TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext); TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
if (insert(level, var)) if (insert(level, var))
{ {
if (level <= LAST_BUILTIN_LEVEL)
{
var->getType().realize();
}
return var; return var;
} }
return nullptr; return nullptr;
...@@ -266,6 +261,7 @@ TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level, ...@@ -266,6 +261,7 @@ TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable) bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
{ {
ASSERT(variable); ASSERT(variable);
ASSERT(level > LAST_BUILTIN_LEVEL || variable->getType().isRealized());
return insert(level, variable); return insert(level, variable);
} }
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#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/StaticType.h"
#include "compiler/translator/Symbol.h" #include "compiler/translator/Symbol.h"
namespace sh namespace sh
...@@ -146,60 +147,23 @@ class TSymbolTable : angle::NonCopyable ...@@ -146,60 +147,23 @@ class TSymbolTable : angle::NonCopyable
// The insert* entry points are used when initializing the symbol table with built-ins. // The insert* entry points are used when initializing the symbol table with built-ins.
// They return the created symbol / true in case the declaration was successful, and nullptr / // They return the created symbol / true in case the declaration was successful, and nullptr /
// false if the declaration failed due to redefinition. // false if the declaration failed due to redefinition.
TVariable *insertVariable(ESymbolLevel level, const char *name, const TType &type); TVariable *insertVariable(ESymbolLevel level, const char *name, const TType *type);
TVariable *insertVariableExt(ESymbolLevel level, TVariable *insertVariableExt(ESymbolLevel level,
TExtension ext, TExtension ext,
const char *name, const char *name,
const TType &type); const TType *type);
bool insertVariable(ESymbolLevel level, TVariable *variable); bool insertVariable(ESymbolLevel level, TVariable *variable);
bool insertStructType(ESymbolLevel level, TStructure *str); bool insertStructType(ESymbolLevel level, TStructure *str);
bool insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock); bool insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock);
bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision) template <TPrecision precision>
{ bool insertConstInt(ESymbolLevel level, const char *name, int value);
TVariable *constant = new TVariable(
this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1), SymbolType::BuiltIn);
constant->getType().realize();
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, constant);
}
bool insertConstIntExt(ESymbolLevel level, template <TPrecision precision>
TExtension ext, bool insertConstIntExt(ESymbolLevel level, TExtension ext, const char *name, int value);
const char *name,
int value,
TPrecision precision)
{
TVariable *constant =
new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1),
SymbolType::BuiltIn, ext);
constant->getType().realize();
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, constant);
}
bool insertConstIvec3(ESymbolLevel level, template <TPrecision precision>
const char *name, bool insertConstIvec3(ESymbolLevel level, const char *name, const std::array<int, 3> &values);
const std::array<int, 3> &values,
TPrecision precision)
{
TVariable *constantIvec3 = new TVariable(
this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 3), SymbolType::BuiltIn);
constantIvec3->getType().realize();
TConstantUnion *unionArray = new TConstantUnion[3];
for (size_t index = 0u; index < 3u; ++index)
{
unionArray[index].setIConst(values[index]);
}
constantIvec3->shareConstPointer(unionArray);
return insert(level, constantIvec3);
}
void insertBuiltIn(ESymbolLevel level, void insertBuiltIn(ESymbolLevel level,
TOperator op, TOperator op,
...@@ -337,7 +301,7 @@ class TSymbolTable : angle::NonCopyable ...@@ -337,7 +301,7 @@ class TSymbolTable : angle::NonCopyable
TVariable *insertVariable(ESymbolLevel level, TVariable *insertVariable(ESymbolLevel level,
const TString *name, const TString *name,
const TType &type, const TType *type,
SymbolType symbolType); SymbolType symbolType);
bool insert(ESymbolLevel level, TSymbol *symbol) bool insert(ESymbolLevel level, TSymbol *symbol)
...@@ -364,6 +328,52 @@ class TSymbolTable : angle::NonCopyable ...@@ -364,6 +328,52 @@ class TSymbolTable : angle::NonCopyable
int mUserDefinedUniqueIdsStart; int mUserDefinedUniqueIdsStart;
}; };
template <TPrecision precision>
bool TSymbolTable::insertConstInt(ESymbolLevel level, const char *name, int value)
{
TVariable *constant =
new TVariable(this, NewPoolTString(name),
StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn);
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, constant);
}
template <TPrecision precision>
bool TSymbolTable::insertConstIntExt(ESymbolLevel level,
TExtension ext,
const char *name,
int value)
{
TVariable *constant = new TVariable(this, NewPoolTString(name),
StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(),
SymbolType::BuiltIn, ext);
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, constant);
}
template <TPrecision precision>
bool TSymbolTable::insertConstIvec3(ESymbolLevel level,
const char *name,
const std::array<int, 3> &values)
{
TVariable *constantIvec3 =
new TVariable(this, NewPoolTString(name),
StaticType::Get<EbtInt, precision, EvqConst, 3, 1>(), SymbolType::BuiltIn);
TConstantUnion *unionArray = new TConstantUnion[3];
for (size_t index = 0u; index < 3u; ++index)
{
unionArray[index].setIConst(values[index]);
}
constantIvec3->shareConstPointer(unionArray);
return insert(level, constantIvec3);
}
} // namespace sh } // namespace sh
#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_ #endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_
...@@ -781,6 +781,11 @@ void TType::realize() ...@@ -781,6 +781,11 @@ void TType::realize()
getMangledName(); getMangledName();
} }
bool TType::isRealized() const
{
return mMangledName != nullptr;
}
void TType::invalidateMangledName() void TType::invalidateMangledName()
{ {
mMangledName = nullptr; mMangledName = nullptr;
...@@ -818,8 +823,8 @@ void TType::createSamplerSymbols(const TString &namePrefix, ...@@ -818,8 +823,8 @@ void TType::createSamplerSymbols(const TString &namePrefix,
} }
ASSERT(IsSampler(type)); ASSERT(IsSampler(type));
TVariable *variable = new TVariable(symbolTable, NewPoolTString(namePrefix.c_str()), *this, TVariable *variable = new TVariable(symbolTable, NewPoolTString(namePrefix.c_str()),
SymbolType::AngleInternal); new TType(*this), SymbolType::AngleInternal);
outputSymbols->push_back(variable); outputSymbols->push_back(variable);
if (outputSymbolsToAPINames) if (outputSymbolsToAPINames)
{ {
......
...@@ -318,6 +318,8 @@ class TType ...@@ -318,6 +318,8 @@ class TType
// Initializes all lazily-initialized members. // Initializes all lazily-initialized members.
void realize(); void realize();
bool isRealized() const;
private: private:
void invalidateMangledName(); void invalidateMangledName();
const char *buildMangledName() const; const char *buildMangledName() const;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "compiler/translator/IntermNodePatternMatcher.h" #include "compiler/translator/IntermNodePatternMatcher.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/StaticType.h"
namespace sh namespace sh
{ {
...@@ -75,14 +76,14 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) ...@@ -75,14 +76,14 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
// and then further simplifies down to "bool s = x; if(!s) s = y;". // and then further simplifies down to "bool s = x; if(!s) s = y;".
TIntermSequence insertions; TIntermSequence insertions;
TType boolType(EbtBool, EbpUndefined, EvqTemporary); const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType); TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
ASSERT(node->getLeft()->getType() == boolType); ASSERT(node->getLeft()->getType() == *boolType);
insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft())); insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
TIntermBlock *assignRightBlock = new TIntermBlock(); TIntermBlock *assignRightBlock = new TIntermBlock();
ASSERT(node->getRight()->getType() == boolType); ASSERT(node->getRight()->getType() == *boolType);
assignRightBlock->getSequence()->push_back( assignRightBlock->getSequence()->push_back(
CreateTempAssignmentNode(resultVariable, node->getRight())); CreateTempAssignmentNode(resultVariable, node->getRight()));
...@@ -102,14 +103,14 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) ...@@ -102,14 +103,14 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
// else s = false;", // else s = false;",
// and then further simplifies down to "bool s = x; if(s) s = y;". // and then further simplifies down to "bool s = x; if(s) s = y;".
TIntermSequence insertions; TIntermSequence insertions;
TType boolType(EbtBool, EbpUndefined, EvqTemporary); const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType); TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
ASSERT(node->getLeft()->getType() == boolType); ASSERT(node->getLeft()->getType() == *boolType);
insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft())); insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
TIntermBlock *assignRightBlock = new TIntermBlock(); TIntermBlock *assignRightBlock = new TIntermBlock();
ASSERT(node->getRight()->getType() == boolType); ASSERT(node->getRight()->getType() == *boolType);
assignRightBlock->getSequence()->push_back( assignRightBlock->getSequence()->push_back(
CreateTempAssignmentNode(resultVariable, node->getRight())); CreateTempAssignmentNode(resultVariable, node->getRight()));
...@@ -144,8 +145,8 @@ bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node ...@@ -144,8 +145,8 @@ bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node
// Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;" // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
TIntermSequence insertions; TIntermSequence insertions;
TIntermDeclaration *tempDeclaration = nullptr; TIntermDeclaration *tempDeclaration = nullptr;
TVariable *resultVariable = TVariable *resultVariable = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
DeclareTempVariable(mSymbolTable, node->getType(), EvqTemporary, &tempDeclaration); EvqTemporary, &tempDeclaration);
insertions.push_back(tempDeclaration); insertions.push_back(tempDeclaration);
TIntermBlock *trueBlock = new TIntermBlock(); TIntermBlock *trueBlock = new TIntermBlock();
......
...@@ -68,22 +68,23 @@ TIntermTyped *CreateLValueNode(const TString &lValueName, const TType &type) ...@@ -68,22 +68,23 @@ TIntermTyped *CreateLValueNode(const TString &lValueName, const TType &type)
{ {
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes. // We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
TSymbolTable symbolTable; TSymbolTable symbolTable;
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()), type, TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()),
SymbolType::UserDefined); new TType(type), SymbolType::UserDefined);
return new TIntermSymbol(variable); return new TIntermSymbol(variable);
} }
ExpectedLValues CreateIndexedLValueNodeList(const TString &lValueName, ExpectedLValues CreateIndexedLValueNodeList(const TString &lValueName,
TType elementType, const TType &elementType,
unsigned arraySize) unsigned arraySize)
{ {
ASSERT(elementType.isArray() == false); ASSERT(elementType.isArray() == false);
elementType.makeArray(arraySize); TType *arrayType = new TType(elementType);
arrayType->makeArray(arraySize);
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes. // We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
TSymbolTable symbolTable; TSymbolTable symbolTable;
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()), TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()), arrayType,
elementType, SymbolType::UserDefined); SymbolType::UserDefined);
TIntermSymbol *arraySymbol = new TIntermSymbol(variable); TIntermSymbol *arraySymbol = new TIntermSymbol(variable);
ExpectedLValues expected(arraySize); ExpectedLValues expected(arraySize);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "angle_gl.h" #include "angle_gl.h"
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/PoolAlloc.h" #include "compiler/translator/PoolAlloc.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
...@@ -44,8 +45,8 @@ class IntermNodeTest : public testing::Test ...@@ -44,8 +45,8 @@ class IntermNodeTest : public testing::Test
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these // We're using a dummy symbol table here, don't need to assign proper symbol ids to these
// nodes. // nodes.
TSymbolTable symbolTable; TSymbolTable symbolTable;
TType variableType(type); TType *variableType = new TType(type);
variableType.setQualifier(EvqTemporary); variableType->setQualifier(EvqTemporary);
TVariable *variable = TVariable *variable =
new TVariable(&symbolTable, symbolName, variableType, SymbolType::AngleInternal); new TVariable(&symbolTable, symbolName, variableType, SymbolType::AngleInternal);
TIntermSymbol *node = new TIntermSymbol(variable); TIntermSymbol *node = new TIntermSymbol(variable);
...@@ -122,7 +123,7 @@ class IntermNodeTest : public testing::Test ...@@ -122,7 +123,7 @@ class IntermNodeTest : public testing::Test
// original. // original.
TEST_F(IntermNodeTest, DeepCopySymbolNode) TEST_F(IntermNodeTest, DeepCopySymbolNode)
{ {
TType type(EbtInt, EbpHigh); const TType *type = StaticType::Get<EbtInt, EbpHigh, EvqTemporary, 1, 1>();
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes. // We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
TSymbolTable symbolTable; TSymbolTable symbolTable;
......
...@@ -5701,3 +5701,21 @@ TEST_F(FragmentShaderValidationTest, ...@@ -5701,3 +5701,21 @@ TEST_F(FragmentShaderValidationTest,
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
} }
} }
// Test that the type of an initializer of a constant variable needs to match.
TEST_F(FragmentShaderValidationTest, ConstantInitializerTypeMismatch)
{
const std::string &shaderString =
R"(
precision mediump float;
const float f = 0;
void main()
{
gl_FragColor = vec4(f);
})";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
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