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
const TSymbolUniqueId &functionId = node->getFunction()->uniqueId();
if (mChangedFunctions.find(functionId.get()) == mChangedFunctions.end())
{
TType returnValueVariableType(node->getType());
returnValueVariableType.setQualifier(EvqOut);
TType *returnValueVariableType = new TType(node->getType());
returnValueVariableType->setQualifier(EvqOut);
ChangedFunction changedFunction;
changedFunction.returnValueVariable =
new TVariable(mSymbolTable, mReturnValueVariableName, returnValueVariableType,
......@@ -170,7 +170,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter
// type s0[size];
TIntermDeclaration *returnValueDeclaration = nullptr;
TVariable *returnValue = DeclareTempVariable(mSymbolTable, node->getType(),
TVariable *returnValue = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
EvqTemporary, &returnValueDeclaration);
replacements.push_back(returnValueDeclaration);
......
......@@ -14,6 +14,7 @@
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/ReplaceVariable.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"
......@@ -142,7 +143,7 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
TQualifier viewIDQualifier = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn;
const TString *viewIDVariableName = NewPoolTString("ViewID_OVR");
const TVariable *viewID =
new TVariable(symbolTable, viewIDVariableName, TType(EbtUInt, EbpHigh, viewIDQualifier),
new TVariable(symbolTable, viewIDVariableName, new TType(EbtUInt, EbpHigh, viewIDQualifier),
SymbolType::AngleInternal);
DeclareGlobalVariable(root, viewID);
......@@ -154,9 +155,9 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// Replacing gl_InstanceID with InstanceID should happen before adding the initializers of
// InstanceID and ViewID.
const TString *instanceIDVariableName = NewPoolTString("InstanceID");
const TVariable *instanceID =
new TVariable(symbolTable, instanceIDVariableName, TType(EbtInt, EbpHigh, EvqGlobal),
SymbolType::AngleInternal);
const TType *instanceIDVariableType = StaticType::Get<EbtInt, EbpHigh, EvqGlobal, 1, 1>();
const TVariable *instanceID = new TVariable(
symbolTable, instanceIDVariableName, instanceIDVariableType, SymbolType::AngleInternal);
DeclareGlobalVariable(root, instanceID);
ReplaceVariable(
root, static_cast<TVariable *>(symbolTable->findBuiltIn("gl_InstanceID", 300, true)),
......@@ -177,9 +178,11 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// Add a uniform to switch between side-by-side and layered rendering.
const TString *multiviewBaseViewLayerIndexVariableName =
NewPoolTString("multiviewBaseViewLayerIndex");
const TType *baseLayerIndexVariableType =
StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
const TVariable *multiviewBaseViewLayerIndex =
new TVariable(symbolTable, multiviewBaseViewLayerIndexVariableName,
TType(EbtInt, EbpHigh, EvqUniform), SymbolType::AngleInternal);
baseLayerIndexVariableType, SymbolType::AngleInternal);
DeclareGlobalVariable(root, multiviewBaseViewLayerIndex);
// Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's
......
......@@ -153,8 +153,8 @@ void DeferGlobalInitializers(TIntermBlock *root,
// Replace constant variables with non-constant global variables.
for (const TVariable *var : variablesToReplace)
{
TType replacementType(var->getType());
replacementType.setQualifier(EvqGlobal);
TType *replacementType = new TType(var->getType());
replacementType->setQualifier(EvqGlobal);
TVariable *replacement =
new TVariable(symbolTable, &var->name(), replacementType, var->symbolType());
ReplaceVariable(root, var, replacement);
......
......@@ -11,6 +11,7 @@
#include "compiler/translator/FindMain.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"
......@@ -102,8 +103,10 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
TSymbolTable *symbolTable)
{
ASSERT(initializedNode->isArray());
TVariable *indexVariable = CreateTempVariable(
symbolTable, TType(EbtInt, highPrecisionSupported ? EbpHigh : EbpMedium, EvqTemporary));
const TType *mediumpIndexType = StaticType::Get<EbtInt, EbpMedium, EvqTemporary, 1, 1>();
const TType *highpIndexType = StaticType::Get<EbtInt, EbpHigh, EvqTemporary, 1, 1>();
TVariable *indexVariable =
CreateTempVariable(symbolTable, highPrecisionSupported ? highpIndexType : mediumpIndexType);
TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexVariable);
TIntermDeclaration *indexInit =
......
......@@ -144,7 +144,7 @@ TIntermConstantUnion *CreateBoolNode(bool value)
return node;
}
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type)
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type)
{
ASSERT(symbolTable != nullptr);
// 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)
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);
if (type.getQualifier() == qualifier)
if (type->getQualifier() == qualifier)
{
return CreateTempVariable(symbolTable, type);
}
TType typeWithQualifier(type);
typeWithQualifier.setQualifier(qualifier);
TType *typeWithQualifier = new TType(*type);
typeWithQualifier->setQualifier(qualifier);
return CreateTempVariable(symbolTable, typeWithQualifier);
}
......@@ -199,7 +199,7 @@ TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTy
}
TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
const TType &type,
const TType *type,
TQualifier qualifier,
TIntermDeclaration **declarationOut)
{
......@@ -213,7 +213,8 @@ TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
TQualifier qualifier,
TIntermDeclaration **declarationOut)
{
TVariable *variable = CreateTempVariable(symbolTable, initializer->getType(), qualifier);
TVariable *variable =
CreateTempVariable(symbolTable, new TType(initializer->getType()), qualifier);
*declarationOut = CreateTempInitDeclarationNode(variable, initializer);
return variable;
}
......
......@@ -25,8 +25,8 @@ TIntermTyped *CreateZeroNode(const TType &type);
TIntermConstantUnion *CreateIndexNode(int index);
TIntermConstantUnion *CreateBoolNode(bool value);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type, TQualifier qualifier);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier);
TIntermSymbol *CreateTempSymbolNode(const TVariable *tempVariable);
TIntermDeclaration *CreateTempDeclarationNode(const TVariable *tempVariable);
......@@ -35,7 +35,7 @@ TIntermDeclaration *CreateTempInitDeclarationNode(const TVariable *tempVariable,
TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTyped *rightNode);
TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
const TType &type,
const TType *type,
TQualifier qualifier,
TIntermDeclaration **declarationOut);
TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
......
......@@ -193,7 +193,7 @@ class TParseContext : angle::NonCopyable
// is not needed in the AST.
bool executeInitializer(const TSourceLoc &line,
const TString &identifier,
TType type,
TType *type,
TIntermTyped *initializer,
TIntermBinary **initNode);
TIntermNode *addConditionInitializer(const TPublicType &pType,
......@@ -471,7 +471,7 @@ class TParseContext : angle::NonCopyable
bool declareVariable(const TSourceLoc &line,
const TString &identifier,
const TType &type,
const TType *type,
TVariable **variable);
void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
......
......@@ -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
// types are kept consistent.
TType type(declaratorSymbol->getType());
TType *type = new TType(declaratorSymbol->getType());
if (mInGlobalScope)
{
type.setQualifier(EvqGlobal);
type->setQualifier(EvqGlobal);
}
else
{
type.setQualifier(EvqTemporary);
type->setQualifier(EvqTemporary);
}
TVariable *variable = new TVariable(mSymbolTable, nullptr, type, SymbolType::Empty);
queueReplacementWithParent(node, declaratorSymbol, new TIntermSymbol(variable),
......
......@@ -14,6 +14,7 @@
#include "compiler/translator/IntermNodePatternMatcher.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
namespace sh
......@@ -58,7 +59,7 @@ std::string GetIndexFunctionName(const TType &type, bool write)
return nameSink.str();
}
TIntermSymbol *CreateBaseSymbol(const TType &type, TSymbolTable *symbolTable)
TIntermSymbol *CreateBaseSymbol(const TType *type, TSymbolTable *symbolTable)
{
TString *baseString = NewPoolTString("base");
TVariable *baseVariable =
......@@ -69,16 +70,17 @@ TIntermSymbol *CreateBaseSymbol(const TType &type, TSymbolTable *symbolTable)
TIntermSymbol *CreateIndexSymbol(TSymbolTable *symbolTable)
{
TString *indexString = NewPoolTString("index");
TVariable *indexVariable = new TVariable(
symbolTable, indexString, TType(EbtInt, EbpHigh, EvqIn), SymbolType::AngleInternal);
TVariable *indexVariable =
new TVariable(symbolTable, indexString, StaticType::Get<EbtInt, EbpHigh, EvqIn, 1, 1>(),
SymbolType::AngleInternal);
return new TIntermSymbol(indexVariable);
}
TIntermSymbol *CreateValueSymbol(const TType &type, TSymbolTable *symbolTable)
{
TString *valueString = NewPoolTString("value");
TType valueType(type);
valueType.setQualifier(EvqIn);
TType *valueType = new TType(type);
valueType->setQualifier(EvqIn);
TVariable *valueVariable =
new TVariable(symbolTable, valueString, valueType, SymbolType::AngleInternal);
return new TIntermSymbol(valueVariable);
......@@ -179,15 +181,15 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(const TType &type,
std::string functionName = GetIndexFunctionName(type, write);
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
// 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
// principle this code could be used with multiple backends.
baseType.setPrecision(EbpHigh);
baseType.setQualifier(EvqInOut);
baseType->setPrecision(EbpHigh);
baseType->setQualifier(EvqInOut);
if (!write)
baseType.setQualifier(EvqIn);
baseType->setQualifier(EvqIn);
TIntermSymbol *baseParam = CreateBaseSymbol(baseType, symbolTable);
prototypeNode->getSequence()->push_back(baseParam);
......
......@@ -203,8 +203,8 @@ void RemoveUnreferencedVariablesTraverser::removeVariableDeclaration(TIntermDecl
// Already an empty declaration - nothing to do.
return;
}
TVariable *emptyVariable =
new TVariable(mSymbolTable, nullptr, declarator->getType(), SymbolType::Empty);
TVariable *emptyVariable = new TVariable(
mSymbolTable, nullptr, new TType(declarator->getType()), SymbolType::Empty);
queueReplacementWithParent(node, declarator, new TIntermSymbol(emptyVariable),
OriginalNode::IS_DROPPED);
return;
......
......@@ -11,6 +11,7 @@
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
namespace sh
{
......@@ -71,7 +72,7 @@ class DoWhileRewriter : public TIntermTraverser
}
// Found a loop to change.
TType boolType(EbtBool);
const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
// bool temp = false;
......
......@@ -192,15 +192,15 @@ TVariable *ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
{
ASSERT(original);
TType type(original->getType());
type.setQualifier(EvqTemporary);
if (mShaderType == GL_FRAGMENT_SHADER && type.getBasicType() == EbtFloat &&
type.getPrecision() == EbpUndefined)
TType *type = new TType(original->getType());
type->setQualifier(EvqTemporary);
if (mShaderType == GL_FRAGMENT_SHADER && type->getBasicType() == EbtFloat &&
type->getPrecision() == EbpUndefined)
{
// We use the highest available precision for the temporary variable
// to avoid computing the actual precision using the rules defined
// in GLSL ES 1.0 Section 4.5.2.
type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
type->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
}
TVariable *variable = CreateTempVariable(mSymbolTable, type);
......
......@@ -13,6 +13,7 @@
#include "compiler/translator/IntermNodePatternMatcher.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
namespace sh
{
......@@ -151,7 +152,7 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
if (mFoundLoopToChange)
{
TType boolType(EbtBool, EbpUndefined, EvqTemporary);
const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
// Replace the loop condition with a boolean variable that's updated on each iteration.
......
......@@ -59,11 +59,12 @@ const TString &TSymbol::getMangledName() const
TVariable::TVariable(TSymbolTable *symbolTable,
const TString *name,
const TType &t,
const TType *type,
SymbolType symbolType,
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,
......
......@@ -71,22 +71,20 @@ class TVariable : public TSymbol
public:
TVariable(TSymbolTable *symbolTable,
const TString *name,
const TType &t,
const TType *type,
SymbolType symbolType,
TExtension ext = TExtension::UNDEFINED);
~TVariable() override {}
bool isVariable() const override { return true; }
TType &getType() { return type; }
const TType &getType() const { return type; }
void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
const TType &getType() const { return *mType; }
const TConstantUnion *getConstPointer() const { return unionArray; }
void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
private:
TType type;
const TType *mType;
const TConstantUnion *unionArray;
};
......
......@@ -14,7 +14,6 @@
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/StaticType.h"
#include <stdio.h>
#include <algorithm>
......@@ -223,24 +222,22 @@ bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *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(type->isRealized());
return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
}
TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
const TString *name,
const TType &type,
const TType *type,
SymbolType symbolType)
{
ASSERT(level > LAST_BUILTIN_LEVEL || type->isRealized());
TVariable *var = new TVariable(this, name, type, symbolType);
if (insert(level, var))
{
if (level <= LAST_BUILTIN_LEVEL)
{
var->getType().realize();
}
return var;
}
return nullptr;
......@@ -249,15 +246,13 @@ TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
TExtension ext,
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);
if (insert(level, var))
{
if (level <= LAST_BUILTIN_LEVEL)
{
var->getType().realize();
}
return var;
}
return nullptr;
......@@ -266,6 +261,7 @@ TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
{
ASSERT(variable);
ASSERT(level > LAST_BUILTIN_LEVEL || variable->getType().isRealized());
return insert(level, variable);
}
......
......@@ -38,6 +38,7 @@
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/Symbol.h"
namespace sh
......@@ -146,60 +147,23 @@ class TSymbolTable : angle::NonCopyable
// 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 /
// 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,
TExtension ext,
const char *name,
const TType &type);
const TType *type);
bool insertVariable(ESymbolLevel level, TVariable *variable);
bool insertStructType(ESymbolLevel level, TStructure *str);
bool insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock);
bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision)
{
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);
}
template <TPrecision precision>
bool insertConstInt(ESymbolLevel level, const char *name, int value);
bool insertConstIntExt(ESymbolLevel level,
TExtension ext,
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);
}
template <TPrecision precision>
bool insertConstIntExt(ESymbolLevel level, TExtension ext, const char *name, int value);
bool insertConstIvec3(ESymbolLevel level,
const char *name,
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);
}
template <TPrecision precision>
bool insertConstIvec3(ESymbolLevel level, const char *name, const std::array<int, 3> &values);
void insertBuiltIn(ESymbolLevel level,
TOperator op,
......@@ -337,7 +301,7 @@ class TSymbolTable : angle::NonCopyable
TVariable *insertVariable(ESymbolLevel level,
const TString *name,
const TType &type,
const TType *type,
SymbolType symbolType);
bool insert(ESymbolLevel level, TSymbol *symbol)
......@@ -364,6 +328,52 @@ class TSymbolTable : angle::NonCopyable
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
#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_
......@@ -781,6 +781,11 @@ void TType::realize()
getMangledName();
}
bool TType::isRealized() const
{
return mMangledName != nullptr;
}
void TType::invalidateMangledName()
{
mMangledName = nullptr;
......@@ -818,8 +823,8 @@ void TType::createSamplerSymbols(const TString &namePrefix,
}
ASSERT(IsSampler(type));
TVariable *variable = new TVariable(symbolTable, NewPoolTString(namePrefix.c_str()), *this,
SymbolType::AngleInternal);
TVariable *variable = new TVariable(symbolTable, NewPoolTString(namePrefix.c_str()),
new TType(*this), SymbolType::AngleInternal);
outputSymbols->push_back(variable);
if (outputSymbolsToAPINames)
{
......
......@@ -318,6 +318,8 @@ class TType
// Initializes all lazily-initialized members.
void realize();
bool isRealized() const;
private:
void invalidateMangledName();
const char *buildMangledName() const;
......
......@@ -14,6 +14,7 @@
#include "compiler/translator/IntermNodePatternMatcher.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
namespace sh
{
......@@ -75,14 +76,14 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
// and then further simplifies down to "bool s = x; if(!s) s = y;".
TIntermSequence insertions;
TType boolType(EbtBool, EbpUndefined, EvqTemporary);
const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
ASSERT(node->getLeft()->getType() == boolType);
ASSERT(node->getLeft()->getType() == *boolType);
insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
TIntermBlock *assignRightBlock = new TIntermBlock();
ASSERT(node->getRight()->getType() == boolType);
ASSERT(node->getRight()->getType() == *boolType);
assignRightBlock->getSequence()->push_back(
CreateTempAssignmentNode(resultVariable, node->getRight()));
......@@ -102,14 +103,14 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
// else s = false;",
// and then further simplifies down to "bool s = x; if(s) s = y;".
TIntermSequence insertions;
TType boolType(EbtBool, EbpUndefined, EvqTemporary);
const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
ASSERT(node->getLeft()->getType() == boolType);
ASSERT(node->getLeft()->getType() == *boolType);
insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
TIntermBlock *assignRightBlock = new TIntermBlock();
ASSERT(node->getRight()->getType() == boolType);
ASSERT(node->getRight()->getType() == *boolType);
assignRightBlock->getSequence()->push_back(
CreateTempAssignmentNode(resultVariable, node->getRight()));
......@@ -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;"
TIntermSequence insertions;
TIntermDeclaration *tempDeclaration = nullptr;
TVariable *resultVariable =
DeclareTempVariable(mSymbolTable, node->getType(), EvqTemporary, &tempDeclaration);
TVariable *resultVariable = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
EvqTemporary, &tempDeclaration);
insertions.push_back(tempDeclaration);
TIntermBlock *trueBlock = new TIntermBlock();
......
......@@ -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.
TSymbolTable symbolTable;
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()), type,
SymbolType::UserDefined);
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()),
new TType(type), SymbolType::UserDefined);
return new TIntermSymbol(variable);
}
ExpectedLValues CreateIndexedLValueNodeList(const TString &lValueName,
TType elementType,
const TType &elementType,
unsigned arraySize)
{
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.
TSymbolTable symbolTable;
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()),
elementType, SymbolType::UserDefined);
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()), arrayType,
SymbolType::UserDefined);
TIntermSymbol *arraySymbol = new TIntermSymbol(variable);
ExpectedLValues expected(arraySize);
......
......@@ -11,6 +11,7 @@
#include "angle_gl.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/PoolAlloc.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
#include "gtest/gtest.h"
......@@ -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
// nodes.
TSymbolTable symbolTable;
TType variableType(type);
variableType.setQualifier(EvqTemporary);
TType *variableType = new TType(type);
variableType->setQualifier(EvqTemporary);
TVariable *variable =
new TVariable(&symbolTable, symbolName, variableType, SymbolType::AngleInternal);
TIntermSymbol *node = new TIntermSymbol(variable);
......@@ -122,7 +123,7 @@ class IntermNodeTest : public testing::Test
// original.
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.
TSymbolTable symbolTable;
......
......@@ -5701,3 +5701,21 @@ TEST_F(FragmentShaderValidationTest,
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