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);
......
...@@ -757,114 +757,124 @@ void InsertBuiltInFunctions(sh::GLenum type, ...@@ -757,114 +757,124 @@ void InsertBuiltInFunctions(sh::GLenum type,
TStructure *depthRangeStruct = new TStructure( TStructure *depthRangeStruct = new TStructure(
&symbolTable, NewPoolTString("gl_DepthRangeParameters"), fields, SymbolType::BuiltIn); &symbolTable, NewPoolTString("gl_DepthRangeParameters"), fields, SymbolType::BuiltIn);
symbolTable.insertStructType(COMMON_BUILTINS, depthRangeStruct); symbolTable.insertStructType(COMMON_BUILTINS, depthRangeStruct);
TType depthRangeType(depthRangeStruct); TType *depthRangeType = new TType(depthRangeStruct);
depthRangeType.setQualifier(EvqUniform); depthRangeType->setQualifier(EvqUniform);
depthRangeType->realize();
symbolTable.insertVariable(COMMON_BUILTINS, "gl_DepthRange", depthRangeType); symbolTable.insertVariable(COMMON_BUILTINS, "gl_DepthRange", depthRangeType);
// //
// Implementation dependent built-in constants. // Implementation dependent built-in constants.
// //
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs, symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxVertexAttribs",
EbpMedium); resources.MaxVertexAttribs);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors", symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxVertexUniformVectors",
resources.MaxVertexUniformVectors, EbpMedium); resources.MaxVertexUniformVectors);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits", symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits",
resources.MaxVertexTextureImageUnits, EbpMedium); resources.MaxVertexTextureImageUnits);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits",
resources.MaxCombinedTextureImageUnits, EbpMedium); resources.MaxCombinedTextureImageUnits);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxTextureImageUnits",
resources.MaxTextureImageUnits, EbpMedium); resources.MaxTextureImageUnits);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors",
resources.MaxFragmentUniformVectors, EbpMedium); resources.MaxFragmentUniformVectors);
symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors, symbolTable.insertConstInt<EbpMedium>(ESSL1_BUILTINS, "gl_MaxVaryingVectors",
EbpMedium); resources.MaxVaryingVectors);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers, symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxDrawBuffers",
EbpMedium); resources.MaxDrawBuffers);
if (resources.EXT_blend_func_extended) if (resources.EXT_blend_func_extended)
{ {
symbolTable.insertConstIntExt(COMMON_BUILTINS, TExtension::EXT_blend_func_extended, symbolTable.insertConstIntExt<EbpMedium>(
"gl_MaxDualSourceDrawBuffersEXT", COMMON_BUILTINS, TExtension::EXT_blend_func_extended, "gl_MaxDualSourceDrawBuffersEXT",
resources.MaxDualSourceDrawBuffers, EbpMedium); resources.MaxDualSourceDrawBuffers);
} }
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors",
resources.MaxVertexOutputVectors, EbpMedium); resources.MaxVertexOutputVectors);
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors",
resources.MaxFragmentInputVectors, EbpMedium); resources.MaxFragmentInputVectors);
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MinProgramTexelOffset",
resources.MinProgramTexelOffset, EbpMedium); resources.MinProgramTexelOffset);
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset",
resources.MaxProgramTexelOffset, EbpMedium); resources.MaxProgramTexelOffset);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxImageUnits", resources.MaxImageUnits, symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxImageUnits",
EbpMedium); resources.MaxImageUnits);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexImageUniforms", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxVertexImageUniforms",
resources.MaxVertexImageUniforms, EbpMedium); resources.MaxVertexImageUniforms);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentImageUniforms", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxFragmentImageUniforms",
resources.MaxFragmentImageUniforms, EbpMedium); resources.MaxFragmentImageUniforms);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeImageUniforms", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeImageUniforms",
resources.MaxComputeImageUniforms, EbpMedium); resources.MaxComputeImageUniforms);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedImageUniforms", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedImageUniforms",
resources.MaxCombinedImageUniforms, EbpMedium); resources.MaxCombinedImageUniforms);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedShaderOutputResources", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedShaderOutputResources",
resources.MaxCombinedShaderOutputResources, EbpMedium); resources.MaxCombinedShaderOutputResources);
symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupCount", symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupCount",
resources.MaxComputeWorkGroupCount, EbpHigh); resources.MaxComputeWorkGroupCount);
symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupSize", symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupSize",
resources.MaxComputeWorkGroupSize, EbpHigh); resources.MaxComputeWorkGroupSize);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeUniformComponents", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeUniformComponents",
resources.MaxComputeUniformComponents, EbpMedium); resources.MaxComputeUniformComponents);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeTextureImageUnits", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeTextureImageUnits",
resources.MaxComputeTextureImageUnits, EbpMedium); resources.MaxComputeTextureImageUnits);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounters", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounters",
resources.MaxComputeAtomicCounters, EbpMedium); resources.MaxComputeAtomicCounters);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounterBuffers", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounterBuffers",
resources.MaxComputeAtomicCounterBuffers, EbpMedium); resources.MaxComputeAtomicCounterBuffers);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounters", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounters",
resources.MaxVertexAtomicCounters, EbpMedium); resources.MaxVertexAtomicCounters);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounters", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounters",
resources.MaxFragmentAtomicCounters, EbpMedium); resources.MaxFragmentAtomicCounters);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounters", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounters",
resources.MaxCombinedAtomicCounters, EbpMedium); resources.MaxCombinedAtomicCounters);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBindings", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBindings",
resources.MaxAtomicCounterBindings, EbpMedium); resources.MaxAtomicCounterBindings);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounterBuffers", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounterBuffers",
resources.MaxVertexAtomicCounterBuffers, EbpMedium); resources.MaxVertexAtomicCounterBuffers);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounterBuffers", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounterBuffers",
resources.MaxFragmentAtomicCounterBuffers, EbpMedium); resources.MaxFragmentAtomicCounterBuffers);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounterBuffers", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounterBuffers",
resources.MaxCombinedAtomicCounterBuffers, EbpMedium); resources.MaxCombinedAtomicCounterBuffers);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize", symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize",
resources.MaxAtomicCounterBufferSize, EbpMedium); resources.MaxAtomicCounterBufferSize);
if (resources.EXT_geometry_shader) if (resources.EXT_geometry_shader)
{ {
TExtension ext = TExtension::EXT_geometry_shader; TExtension ext = TExtension::EXT_geometry_shader;
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryInputComponents", symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
resources.MaxGeometryInputComponents, EbpMedium); "gl_MaxGeometryInputComponents",
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryOutputComponents", resources.MaxGeometryInputComponents);
resources.MaxGeometryOutputComponents, EbpMedium); symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryImageUniforms", "gl_MaxGeometryOutputComponents",
resources.MaxGeometryImageUniforms, EbpMedium); resources.MaxGeometryOutputComponents);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryTextureImageUnits", symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
resources.MaxGeometryTextureImageUnits, EbpMedium); "gl_MaxGeometryImageUniforms",
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryOutputVertices", resources.MaxGeometryImageUniforms);
resources.MaxGeometryOutputVertices, EbpMedium); symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryTotalOutputComponents", "gl_MaxGeometryTextureImageUnits",
resources.MaxGeometryTotalOutputComponents, EbpMedium); resources.MaxGeometryTextureImageUnits);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryUniformComponents", symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
resources.MaxGeometryUniformComponents, EbpMedium); "gl_MaxGeometryOutputVertices",
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryAtomicCounters", resources.MaxGeometryOutputVertices);
resources.MaxGeometryAtomicCounters, EbpMedium); symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryAtomicCounterBuffers", "gl_MaxGeometryTotalOutputComponents",
resources.MaxGeometryAtomicCounterBuffers, EbpMedium); resources.MaxGeometryTotalOutputComponents);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
"gl_MaxGeometryUniformComponents",
resources.MaxGeometryUniformComponents);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
"gl_MaxGeometryAtomicCounters",
resources.MaxGeometryAtomicCounters);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
"gl_MaxGeometryAtomicCounterBuffers",
resources.MaxGeometryAtomicCounterBuffers);
} }
} }
...@@ -880,132 +890,158 @@ void IdentifyBuiltIns(sh::GLenum type, ...@@ -880,132 +890,158 @@ void IdentifyBuiltIns(sh::GLenum type,
if (resources.OVR_multiview && type != GL_COMPUTE_SHADER) if (resources.OVR_multiview && type != GL_COMPUTE_SHADER)
{ {
const TType *viewIDType = StaticType::Get<EbtUInt, EbpHigh, EvqViewIDOVR, 1, 1>();
symbolTable.insertVariableExt(ESSL3_BUILTINS, TExtension::OVR_multiview, "gl_ViewID_OVR", symbolTable.insertVariableExt(ESSL3_BUILTINS, TExtension::OVR_multiview, "gl_ViewID_OVR",
TType(EbtUInt, EbpHigh, EvqViewIDOVR, 1)); viewIDType);
// ESSL 1.00 doesn't have unsigned integers, so gl_ViewID_OVR is a signed integer in ESSL // ESSL 1.00 doesn't have unsigned integers, so gl_ViewID_OVR is a signed integer in ESSL
// 1.00. This is specified in the WEBGL_multiview spec. // 1.00. This is specified in the WEBGL_multiview spec.
const TType *viewIDIntType = StaticType::Get<EbtInt, EbpHigh, EvqViewIDOVR, 1, 1>();
symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::OVR_multiview, "gl_ViewID_OVR", symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::OVR_multiview, "gl_ViewID_OVR",
TType(EbtInt, EbpHigh, EvqViewIDOVR, 1)); viewIDIntType);
} }
const TType *positionType = StaticType::Get<EbtFloat, EbpHigh, EvqPosition, 4, 1>();
const TType *primitiveIDType = StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>();
const TType *layerType = StaticType::Get<EbtInt, EbpHigh, EvqLayer, 1, 1>();
switch (type) switch (type)
{ {
case GL_FRAGMENT_SHADER: case GL_FRAGMENT_SHADER:
{ {
symbolTable.insertVariable(COMMON_BUILTINS, "gl_FragCoord", const TType *fragCoordType = StaticType::Get<EbtFloat, EbpMedium, EvqFragCoord, 4, 1>();
TType(EbtFloat, EbpMedium, EvqFragCoord, 4)); symbolTable.insertVariable(COMMON_BUILTINS, "gl_FragCoord", fragCoordType);
symbolTable.insertVariable(COMMON_BUILTINS, "gl_FrontFacing", const TType *frontFacingType = StaticType::GetQualified<EbtBool, EvqFrontFacing>();
TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)); symbolTable.insertVariable(COMMON_BUILTINS, "gl_FrontFacing", frontFacingType);
symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointCoord", const TType *pointCoordType =
TType(EbtFloat, EbpMedium, EvqPointCoord, 2)); StaticType::Get<EbtFloat, EbpMedium, EvqPointCoord, 2, 1>();
symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointCoord", pointCoordType);
symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragColor",
TType(EbtFloat, EbpMedium, EvqFragColor, 4)); const TType *fragColorType = StaticType::Get<EbtFloat, EbpMedium, EvqFragColor, 4, 1>();
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4); symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragColor", fragColorType);
TType *fragDataType = new TType(EbtFloat, EbpMedium, EvqFragData, 4);
if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC) if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC)
{ {
fragData.makeArray(resources.MaxDrawBuffers); fragDataType->makeArray(resources.MaxDrawBuffers);
} }
else else
{ {
fragData.makeArray(1u); fragDataType->makeArray(1u);
} }
symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragData", fragData); fragDataType->realize();
symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragData", fragDataType);
if (resources.EXT_blend_func_extended) if (resources.EXT_blend_func_extended)
{ {
symbolTable.insertVariableExt( const TType *secondaryFragColorType =
ESSL1_BUILTINS, TExtension::EXT_blend_func_extended, "gl_SecondaryFragColorEXT", StaticType::Get<EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4, 1>();
TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4)); symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1); "gl_SecondaryFragColorEXT", secondaryFragColorType);
secondaryFragData.makeArray(resources.MaxDualSourceDrawBuffers); TType *secondaryFragDataType =
new TType(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
secondaryFragDataType->makeArray(resources.MaxDualSourceDrawBuffers);
secondaryFragDataType->realize();
symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended, symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
"gl_SecondaryFragDataEXT", secondaryFragData); "gl_SecondaryFragDataEXT", secondaryFragDataType);
} }
if (resources.EXT_frag_depth) if (resources.EXT_frag_depth)
{ {
symbolTable.insertVariableExt( TType *fragDepthEXTType =
ESSL1_BUILTINS, TExtension::EXT_frag_depth, "gl_FragDepthEXT", new TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepthEXT, 1);
EvqFragDepthEXT, 1)); fragDepthEXTType->realize();
symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_frag_depth,
"gl_FragDepthEXT", fragDepthEXTType);
} }
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_FragDepth", const TType *fragDepthType = StaticType::Get<EbtFloat, EbpHigh, EvqFragDepth, 1, 1>();
TType(EbtFloat, EbpHigh, EvqFragDepth, 1)); symbolTable.insertVariable(ESSL3_BUILTINS, "gl_FragDepth", fragDepthType);
const TType *lastFragColorType =
StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>();
if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch) if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
{ {
TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1); TType *lastFragDataType = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
lastFragData.makeArray(resources.MaxDrawBuffers); lastFragDataType->makeArray(resources.MaxDrawBuffers);
lastFragDataType->realize();
if (resources.EXT_shader_framebuffer_fetch) if (resources.EXT_shader_framebuffer_fetch)
{ {
symbolTable.insertVariableExt(ESSL1_BUILTINS, symbolTable.insertVariableExt(ESSL1_BUILTINS,
TExtension::EXT_shader_framebuffer_fetch, TExtension::EXT_shader_framebuffer_fetch,
"gl_LastFragData", lastFragData); "gl_LastFragData", lastFragDataType);
} }
else if (resources.NV_shader_framebuffer_fetch) else if (resources.NV_shader_framebuffer_fetch)
{ {
symbolTable.insertVariableExt(
ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch, "gl_LastFragColor",
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4));
symbolTable.insertVariableExt(ESSL1_BUILTINS, symbolTable.insertVariableExt(ESSL1_BUILTINS,
TExtension::NV_shader_framebuffer_fetch, TExtension::NV_shader_framebuffer_fetch,
"gl_LastFragData", lastFragData); "gl_LastFragColor", lastFragColorType);
symbolTable.insertVariableExt(ESSL1_BUILTINS,
TExtension::NV_shader_framebuffer_fetch,
"gl_LastFragData", lastFragDataType);
} }
} }
else if (resources.ARM_shader_framebuffer_fetch) else if (resources.ARM_shader_framebuffer_fetch)
{ {
symbolTable.insertVariableExt( symbolTable.insertVariableExt(ESSL1_BUILTINS,
ESSL1_BUILTINS, TExtension::ARM_shader_framebuffer_fetch, "gl_LastFragColorARM", TExtension::ARM_shader_framebuffer_fetch,
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)); "gl_LastFragColorARM", lastFragColorType);
} }
if (resources.EXT_geometry_shader) if (resources.EXT_geometry_shader)
{ {
TExtension extension = TExtension::EXT_geometry_shader; TExtension extension = TExtension::EXT_geometry_shader;
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID", symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
TType(EbtInt, EbpHigh, EvqPrimitiveID, 1)); primitiveIDType);
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", layerType);
TType(EbtInt, EbpHigh, EvqLayer, 1));
} }
break; break;
} }
case GL_VERTEX_SHADER: case GL_VERTEX_SHADER:
{ {
symbolTable.insertVariable(COMMON_BUILTINS, "gl_Position", symbolTable.insertVariable(COMMON_BUILTINS, "gl_Position", positionType);
TType(EbtFloat, EbpHigh, EvqPosition, 4)); const TType *pointSizeType = StaticType::Get<EbtFloat, EbpMedium, EvqPointSize, 1, 1>();
symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointSize", symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointSize", pointSizeType);
TType(EbtFloat, EbpMedium, EvqPointSize, 1)); const TType *instanceIDType = StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>();
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_InstanceID", symbolTable.insertVariable(ESSL3_BUILTINS, "gl_InstanceID", instanceIDType);
TType(EbtInt, EbpHigh, EvqInstanceID, 1)); const TType *vertexIDType = StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>();
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID", symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID", vertexIDType);
TType(EbtInt, EbpHigh, EvqVertexID, 1));
// For internal use by ANGLE - not exposed to the parser. // For internal use by ANGLE - not exposed to the parser.
symbolTable.insertVariable(GLSL_BUILTINS, "gl_ViewportIndex", const TType *viewportIndexType =
TType(EbtInt, EbpHigh, EvqViewportIndex)); StaticType::Get<EbtInt, EbpHigh, EvqViewportIndex, 1, 1>();
symbolTable.insertVariable(GLSL_BUILTINS, "gl_ViewportIndex", viewportIndexType);
// gl_Layer exists in other shader stages in ESSL, but not in vertex shader so far. // gl_Layer exists in other shader stages in ESSL, but not in vertex shader so far.
symbolTable.insertVariable(GLSL_BUILTINS, "gl_Layer", TType(EbtInt, EbpHigh, EvqLayer)); symbolTable.insertVariable(GLSL_BUILTINS, "gl_Layer", layerType);
break; break;
} }
case GL_COMPUTE_SHADER: case GL_COMPUTE_SHADER:
{ {
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups", const TType *numWorkGroupsType =
TType(EbtUInt, EbpUndefined, EvqNumWorkGroups, 3)); StaticType::Get<EbtUInt, EbpUndefined, EvqNumWorkGroups, 3, 1>();
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupSize", symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups", numWorkGroupsType);
TType(EbtUInt, EbpUndefined, EvqWorkGroupSize, 3)); const TType *workGroupSizeType =
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupID", StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupSize, 3, 1>();
TType(EbtUInt, EbpUndefined, EvqWorkGroupID, 3)); symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupSize", workGroupSizeType);
const TType *workGroupIDType =
StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupID, 3, 1>();
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupID", workGroupIDType);
const TType *localInvocationIDType =
StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationID, 3, 1>();
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationID", symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationID",
TType(EbtUInt, EbpUndefined, EvqLocalInvocationID, 3)); localInvocationIDType);
const TType *globalInvocationIDType =
StaticType::Get<EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3, 1>();
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_GlobalInvocationID", symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_GlobalInvocationID",
TType(EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3)); globalInvocationIDType);
const TType *localInvocationIndexType =
StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1, 1>();
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationIndex", symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationIndex",
TType(EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1)); localInvocationIndexType);
break; break;
} }
...@@ -1017,8 +1053,8 @@ void IdentifyBuiltIns(sh::GLenum type, ...@@ -1017,8 +1053,8 @@ void IdentifyBuiltIns(sh::GLenum type,
// TODO(jiawei.shao@intel.com): implement GL_EXT_geometry_point_size. // TODO(jiawei.shao@intel.com): implement GL_EXT_geometry_point_size.
TFieldList *glPerVertexFieldList = new TFieldList(); TFieldList *glPerVertexFieldList = new TFieldList();
TSourceLoc zeroSourceLoc = {0, 0, 0, 0}; TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
TField *glPositionField = new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4), TField *glPositionField =
NewPoolTString("gl_Position"), zeroSourceLoc); new TField(new TType(*positionType), NewPoolTString("gl_Position"), zeroSourceLoc);
glPerVertexFieldList->push_back(glPositionField); glPerVertexFieldList->push_back(glPositionField);
const TString *glPerVertexString = NewPoolTString("gl_PerVertex"); const TString *glPerVertexString = NewPoolTString("gl_PerVertex");
...@@ -1029,26 +1065,32 @@ void IdentifyBuiltIns(sh::GLenum type, ...@@ -1029,26 +1065,32 @@ void IdentifyBuiltIns(sh::GLenum type,
// The array size of gl_in is undefined until we get a valid input primitive // The array size of gl_in is undefined until we get a valid input primitive
// declaration. // declaration.
TType glInType(glPerVertexInBlock, EvqPerVertexIn, TLayoutQualifier::Create()); TType *glInType =
glInType.makeArray(0u); new TType(glPerVertexInBlock, EvqPerVertexIn, TLayoutQualifier::Create());
glInType->makeArray(0u);
glInType->realize();
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_in", glInType); symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_in", glInType);
TInterfaceBlock *glPerVertexOutBlock = TInterfaceBlock *glPerVertexOutBlock =
new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList, new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
TLayoutQualifier::Create(), SymbolType::BuiltIn); TLayoutQualifier::Create(), SymbolType::BuiltIn);
TType glPositionType(EbtFloat, EbpHigh, EvqPosition, 4); TType *glPositionInBlockType = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
glPositionType.setInterfaceBlock(glPerVertexOutBlock); glPositionInBlockType->setInterfaceBlock(glPerVertexOutBlock);
glPositionInBlockType->realize();
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Position", symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Position",
glPositionType); glPositionInBlockType);
const TType *primitiveIDInType =
StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>();
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveIDIn", symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveIDIn",
TType(EbtInt, EbpHigh, EvqPrimitiveIDIn, 1)); primitiveIDInType);
const TType *invocationIDType =
StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>();
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_InvocationID", symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_InvocationID",
TType(EbtInt, EbpHigh, EvqInvocationID, 1)); invocationIDType);
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID", symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
TType(EbtInt, EbpHigh, EvqPrimitiveID, 1)); primitiveIDType);
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", layerType);
TType(EbtInt, EbpHigh, EvqLayer, 1));
break; break;
} }
......
...@@ -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,
......
...@@ -1109,29 +1109,29 @@ void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line, ...@@ -1109,29 +1109,29 @@ void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
// //
bool TParseContext::declareVariable(const TSourceLoc &line, bool TParseContext::declareVariable(const TSourceLoc &line,
const TString &identifier, const TString &identifier,
const TType &type, const TType *type,
TVariable **variable) TVariable **variable)
{ {
ASSERT((*variable) == nullptr); ASSERT((*variable) == nullptr);
(*variable) = new TVariable(&symbolTable, &identifier, type, SymbolType::UserDefined); (*variable) = new TVariable(&symbolTable, &identifier, type, SymbolType::UserDefined);
checkBindingIsValid(line, type); checkBindingIsValid(line, *type);
bool needsReservedCheck = true; bool needsReservedCheck = true;
// gl_LastFragData may be redeclared with a new precision qualifier // gl_LastFragData may be redeclared with a new precision qualifier
if (type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0) if (type->isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0)
{ {
const TVariable *maxDrawBuffers = static_cast<const TVariable *>( const TVariable *maxDrawBuffers = static_cast<const TVariable *>(
symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion)); symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion));
if (type.isArrayOfArrays()) if (type->isArrayOfArrays())
{ {
error(line, "redeclaration of gl_LastFragData as an array of arrays", error(line, "redeclaration of gl_LastFragData as an array of arrays",
identifier.c_str()); identifier.c_str());
return false; return false;
} }
else if (static_cast<int>(type.getOutermostArraySize()) == else if (static_cast<int>(type->getOutermostArraySize()) ==
maxDrawBuffers->getConstPointer()->getIConst()) maxDrawBuffers->getConstPointer()->getIConst())
{ {
if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion)) if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
...@@ -1156,7 +1156,7 @@ bool TParseContext::declareVariable(const TSourceLoc &line, ...@@ -1156,7 +1156,7 @@ bool TParseContext::declareVariable(const TSourceLoc &line,
return false; return false;
} }
if (!checkIsNonVoid(line, identifier, type.getBasicType())) if (!checkIsNonVoid(line, identifier, type->getBasicType()))
return false; return false;
return true; return true;
...@@ -1914,21 +1914,39 @@ TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location, ...@@ -1914,21 +1914,39 @@ TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
// Returns true on success. // Returns true on success.
bool TParseContext::executeInitializer(const TSourceLoc &line, bool TParseContext::executeInitializer(const TSourceLoc &line,
const TString &identifier, const TString &identifier,
TType type, TType *type,
TIntermTyped *initializer, TIntermTyped *initializer,
TIntermBinary **initNode) TIntermBinary **initNode)
{ {
ASSERT(initNode != nullptr); ASSERT(initNode != nullptr);
ASSERT(*initNode == nullptr); ASSERT(*initNode == nullptr);
if (type.isUnsizedArray()) if (type->isUnsizedArray())
{ {
// In case initializer is not an array or type has more dimensions than initializer, this // In case initializer is not an array or type has more dimensions than initializer, this
// will default to setting array sizes to 1. We have not checked yet whether the initializer // will default to setting array sizes to 1. We have not checked yet whether the initializer
// actually is an array or not. Having a non-array initializer for an unsized array will // actually is an array or not. Having a non-array initializer for an unsized array will
// result in an error later, so we don't generate an error message here. // result in an error later, so we don't generate an error message here.
auto *arraySizes = initializer->getType().getArraySizes(); auto *arraySizes = initializer->getType().getArraySizes();
type.sizeUnsizedArrays(arraySizes); type->sizeUnsizedArrays(arraySizes);
}
const TQualifier qualifier = type->getQualifier();
bool constError = false;
if (qualifier == EvqConst)
{
if (EvqConst != initializer->getType().getQualifier())
{
std::stringstream reasonStream;
reasonStream << "assigning non-constant to '" << type->getCompleteString() << "'";
std::string reason = reasonStream.str();
error(line, reason.c_str(), "=");
// We're still going to declare the variable to avoid extra error messages.
type->setQualifier(EvqTemporary);
constError = true;
}
} }
TVariable *variable = nullptr; TVariable *variable = nullptr;
...@@ -1937,6 +1955,11 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, ...@@ -1937,6 +1955,11 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
return false; return false;
} }
if (constError)
{
return false;
}
bool globalInitWarning = false; bool globalInitWarning = false;
if (symbolTable.atGlobalLevel() && if (symbolTable.atGlobalLevel() &&
!ValidateGlobalInitializer(initializer, mShaderVersion, &globalInitWarning)) !ValidateGlobalInitializer(initializer, mShaderVersion, &globalInitWarning))
...@@ -1955,40 +1978,26 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, ...@@ -1955,40 +1978,26 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
"="); "=");
} }
//
// identifier must be of type constant, a global, or a temporary // identifier must be of type constant, a global, or a temporary
//
TQualifier qualifier = variable->getType().getQualifier();
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst))
{ {
error(line, " cannot initialize this type of qualifier ", error(line, " cannot initialize this type of qualifier ",
variable->getType().getQualifierString()); variable->getType().getQualifierString());
return false; return false;
} }
//
// test for and propagate constant
//
if (qualifier == EvqConst) TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
intermSymbol->setLine(line);
if (!binaryOpCommonCheck(EOpInitialize, intermSymbol, initializer, line))
{ {
if (qualifier != initializer->getType().getQualifier()) assignError(line, "=", variable->getType().getCompleteString(),
{ initializer->getCompleteString());
std::stringstream reasonStream; return false;
reasonStream << "assigning non-constant to '" << variable->getType().getCompleteString() }
<< "'";
std::string reason = reasonStream.str();
error(line, reason.c_str(), "=");
variable->getType().setQualifier(EvqTemporary);
return false;
}
if (type != initializer->getType())
{
error(line, " non-matching types for const initializer ",
variable->getType().getQualifierString());
variable->getType().setQualifier(EvqTemporary);
return false;
}
if (qualifier == EvqConst)
{
// Save the constant folded value to the variable if possible. // Save the constant folded value to the variable if possible.
const TConstantUnion *constArray = initializer->getConstantValue(); const TConstantUnion *constArray = initializer->getConstantValue();
if (constArray) if (constArray)
...@@ -2002,15 +2011,8 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, ...@@ -2002,15 +2011,8 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
} }
} }
TIntermSymbol *intermSymbol = new TIntermSymbol(variable); *initNode = new TIntermBinary(EOpInitialize, intermSymbol, initializer);
intermSymbol->setLine(line); (*initNode)->setLine(line);
*initNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
if (*initNode == nullptr)
{
assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
return false;
}
return true; return true;
} }
...@@ -2021,7 +2023,7 @@ TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType, ...@@ -2021,7 +2023,7 @@ TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType,
{ {
checkIsScalarBool(loc, pType); checkIsScalarBool(loc, pType);
TIntermBinary *initNode = nullptr; TIntermBinary *initNode = nullptr;
TType type(pType); TType *type = new TType(pType);
if (executeInitializer(loc, identifier, type, initializer, &initNode)) if (executeInitializer(loc, identifier, type, initializer, &initNode))
{ {
// The initializer is valid. The init condition needs to have a node - either the // The initializer is valid. The init condition needs to have a node - either the
...@@ -2393,11 +2395,11 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2393,11 +2395,11 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
const TSourceLoc &identifierOrTypeLocation, const TSourceLoc &identifierOrTypeLocation,
const TString &identifier) const TString &identifier)
{ {
TType type(publicType); TType *type = new TType(publicType);
if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) && if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) &&
mDirectiveHandler.pragma().stdgl.invariantAll) mDirectiveHandler.pragma().stdgl.invariantAll)
{ {
TQualifier qualifier = type.getQualifier(); TQualifier qualifier = type->getQualifier();
// The directive handler has already taken care of rejecting invalid uses of this pragma // The directive handler has already taken care of rejecting invalid uses of this pragma
// (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all // (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all
...@@ -2417,11 +2419,11 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2417,11 +2419,11 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
// behavior of the #pragma when specified in ESSL 1.00 fragment shaders. // behavior of the #pragma when specified in ESSL 1.00 fragment shaders.
if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut || qualifier == EvqVaryingIn) if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut || qualifier == EvqVaryingIn)
{ {
type.setInvariant(true); type->setInvariant(true);
} }
} }
checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier.c_str(), &type); checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier.c_str(), type);
declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier, declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
identifierOrTypeLocation); identifierOrTypeLocation);
...@@ -2432,10 +2434,10 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2432,10 +2434,10 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
TIntermSymbol *symbol = nullptr; TIntermSymbol *symbol = nullptr;
if (emptyDeclaration) if (emptyDeclaration)
{ {
emptyDeclarationErrorCheck(type, identifierOrTypeLocation); emptyDeclarationErrorCheck(*type, identifierOrTypeLocation);
// In most cases we don't need to create a symbol node for an empty declaration. // In most cases we don't need to create a symbol node for an empty declaration.
// But if the empty declaration is declaring a struct type, the symbol node will store that. // But if the empty declaration is declaring a struct type, the symbol node will store that.
if (type.getBasicType() == EbtStruct) if (type->getBasicType() == EbtStruct)
{ {
TVariable *emptyVariable = TVariable *emptyVariable =
new TVariable(&symbolTable, nullptr, type, SymbolType::Empty); new TVariable(&symbolTable, nullptr, type, SymbolType::Empty);
...@@ -2450,9 +2452,9 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2450,9 +2452,9 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
{ {
nonEmptyDeclarationErrorCheck(publicType, identifierOrTypeLocation); nonEmptyDeclarationErrorCheck(publicType, identifierOrTypeLocation);
checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, &type); checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, type);
checkAtomicCounterOffsetDoesNotOverlap(false, identifierOrTypeLocation, &type); checkAtomicCounterOffsetDoesNotOverlap(false, identifierOrTypeLocation, type);
TVariable *variable = nullptr; TVariable *variable = nullptr;
if (declareVariable(identifierOrTypeLocation, identifier, type, &variable)) if (declareVariable(identifierOrTypeLocation, identifier, type, &variable))
...@@ -2487,14 +2489,14 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration( ...@@ -2487,14 +2489,14 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(
checkIsValidTypeAndQualifierForArray(indexLocation, elementType); checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
TType arrayType(elementType); TType *arrayType = new TType(elementType);
arrayType.makeArrays(arraySizes); arrayType->makeArrays(arraySizes);
checkGeometryShaderInputAndSetArraySize(indexLocation, identifier.c_str(), &arrayType); checkGeometryShaderInputAndSetArraySize(indexLocation, identifier.c_str(), arrayType);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType); checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
checkAtomicCounterOffsetDoesNotOverlap(false, identifierLocation, &arrayType); checkAtomicCounterOffsetDoesNotOverlap(false, identifierLocation, arrayType);
TIntermDeclaration *declaration = new TIntermDeclaration(); TIntermDeclaration *declaration = new TIntermDeclaration();
declaration->setLine(identifierLocation); declaration->setLine(identifierLocation);
...@@ -2527,7 +2529,7 @@ TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType ...@@ -2527,7 +2529,7 @@ TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType
declaration->setLine(identifierLocation); declaration->setLine(identifierLocation);
TIntermBinary *initNode = nullptr; TIntermBinary *initNode = nullptr;
TType type(publicType); TType *type = new TType(publicType);
if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode)) if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
{ {
if (initNode) if (initNode)
...@@ -2556,8 +2558,8 @@ TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration( ...@@ -2556,8 +2558,8 @@ TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
checkIsValidTypeAndQualifierForArray(indexLocation, elementType); checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
TType arrayType(elementType); TType *arrayType = new TType(elementType);
arrayType.makeArrays(arraySizes); arrayType->makeArrays(arraySizes);
TIntermDeclaration *declaration = new TIntermDeclaration(); TIntermDeclaration *declaration = new TIntermDeclaration();
declaration->setLine(identifierLocation); declaration->setLine(identifierLocation);
...@@ -2646,13 +2648,13 @@ void TParseContext::parseDeclarator(TPublicType &publicType, ...@@ -2646,13 +2648,13 @@ void TParseContext::parseDeclarator(TPublicType &publicType,
checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType); checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
TType type(publicType); TType *type = new TType(publicType);
checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &type); checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), type);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &type); checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, type);
checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, &type); checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, type);
TVariable *variable = nullptr; TVariable *variable = nullptr;
if (declareVariable(identifierLocation, identifier, type, &variable)) if (declareVariable(identifierLocation, identifier, type, &variable))
...@@ -2682,14 +2684,14 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType, ...@@ -2682,14 +2684,14 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType,
if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType)) if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType))
{ {
TType arrayType(elementType); TType *arrayType = new TType(elementType);
arrayType.makeArrays(arraySizes); arrayType->makeArrays(arraySizes);
checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &arrayType); checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), arrayType);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType); checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, &arrayType); checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, arrayType);
TVariable *variable = nullptr; TVariable *variable = nullptr;
if (declareVariable(identifierLocation, identifier, arrayType, &variable)) if (declareVariable(identifierLocation, identifier, arrayType, &variable))
...@@ -2719,7 +2721,7 @@ void TParseContext::parseInitDeclarator(const TPublicType &publicType, ...@@ -2719,7 +2721,7 @@ void TParseContext::parseInitDeclarator(const TPublicType &publicType,
checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType); checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
TIntermBinary *initNode = nullptr; TIntermBinary *initNode = nullptr;
TType type(publicType); TType *type = new TType(publicType);
if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode)) if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
{ {
// //
...@@ -2753,8 +2755,8 @@ void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType, ...@@ -2753,8 +2755,8 @@ void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
checkIsValidTypeAndQualifierForArray(indexLocation, elementType); checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
TType arrayType(elementType); TType *arrayType = new TType(elementType);
arrayType.makeArrays(arraySizes); arrayType->makeArrays(arraySizes);
// initNode will correspond to the whole of "b[n] = initializer". // initNode will correspond to the whole of "b[n] = initializer".
TIntermBinary *initNode = nullptr; TIntermBinary *initNode = nullptr;
...@@ -2838,8 +2840,8 @@ void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize, ...@@ -2838,8 +2840,8 @@ void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
{ {
TSymbol *glPerVertex = symbolTable.findBuiltIn("gl_PerVertex", 310); TSymbol *glPerVertex = symbolTable.findBuiltIn("gl_PerVertex", 310);
TInterfaceBlock *glPerVertexBlock = static_cast<TInterfaceBlock *>(glPerVertex); TInterfaceBlock *glPerVertexBlock = static_cast<TInterfaceBlock *>(glPerVertex);
TType glInType(glPerVertexBlock, EvqPerVertexIn, TLayoutQualifier::Create()); TType *glInType = new TType(glPerVertexBlock, EvqPerVertexIn, TLayoutQualifier::Create());
glInType.makeArray(inputArraySize); glInType->makeArray(inputArraySize);
mGlInVariableWithArraySize = mGlInVariableWithArraySize =
new TVariable(&symbolTable, NewPoolTString("gl_in"), glInType, SymbolType::BuiltIn, new TVariable(&symbolTable, NewPoolTString("gl_in"), glInType, SymbolType::BuiltIn,
TExtension::EXT_geometry_shader); TExtension::EXT_geometry_shader);
...@@ -3168,7 +3170,7 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction( ...@@ -3168,7 +3170,7 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
if (param.name != nullptr) if (param.name != nullptr)
{ {
TVariable *variable = TVariable *variable =
new TVariable(&symbolTable, param.name, *param.type, SymbolType::UserDefined); new TVariable(&symbolTable, param.name, param.type, SymbolType::UserDefined);
symbol = new TIntermSymbol(variable); symbol = new TIntermSymbol(variable);
// Insert the parameter in the symbol table. // Insert the parameter in the symbol table.
if (insertParametersToSymbolTable) if (insertParametersToSymbolTable)
...@@ -3195,7 +3197,7 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction( ...@@ -3195,7 +3197,7 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
// The parameter had no name or declaring the symbol failed - either way, add a nameless // The parameter had no name or declaring the symbol failed - either way, add a nameless
// symbol. // symbol.
TVariable *emptyVariable = TVariable *emptyVariable =
new TVariable(&symbolTable, nullptr, *param.type, SymbolType::Empty); new TVariable(&symbolTable, nullptr, param.type, SymbolType::Empty);
symbol = new TIntermSymbol(emptyVariable); symbol = new TIntermSymbol(emptyVariable);
} }
symbol->setLine(location); symbol->setLine(location);
...@@ -3797,10 +3799,11 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -3797,10 +3799,11 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
error(nameLine, "redefinition of an interface block name", blockName.c_str()); error(nameLine, "redefinition of an interface block name", blockName.c_str());
} }
TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier); TType *interfaceBlockType =
new TType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier);
if (arrayIndex != nullptr) if (arrayIndex != nullptr)
{ {
interfaceBlockType.makeArray(arraySize); interfaceBlockType->makeArray(arraySize);
} }
// The instance variable gets created to refer to the interface block type from the AST // The instance variable gets created to refer to the interface block type from the AST
...@@ -3816,18 +3819,16 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -3816,18 +3819,16 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
{ {
TField *field = (*fieldList)[memberIndex]; TField *field = (*fieldList)[memberIndex];
TType *fieldType = field->type(); TType *fieldType = new TType(*field->type());
// set parent pointer of the field variable // set parent pointer of the field variable
fieldType->setInterfaceBlock(interfaceBlock); fieldType->setInterfaceBlock(interfaceBlock);
fieldType->setQualifier(typeQualifier.qualifier);
TVariable *fieldVariable = TVariable *fieldVariable =
new TVariable(&symbolTable, &field->name(), *fieldType, SymbolType::UserDefined); new TVariable(&symbolTable, &field->name(), fieldType, SymbolType::UserDefined);
if (symbolTable.declareVariable(fieldVariable)) if (!symbolTable.declareVariable(fieldVariable))
{
fieldVariable->setQualifier(typeQualifier.qualifier);
}
else
{ {
error(field->line(), "redefinition of an interface block member name", error(field->line(), "redefinition of an interface block member name",
field->name().c_str()); field->name().c_str());
......
...@@ -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