Commit b60d30f7 by Olli Etuaho Committed by Commit Bot

Make TVariable type immutable

This enables using constexpr types for built-in variables and some of the variables created in AST transformations. BUG=angleproject:2267 TEST=angle_unittests Change-Id: Ie85b3c9872a071a7c023ced013b14ad91cff7cee Reviewed-on: https://chromium-review.googlesource.com/868134 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent fa886975
......@@ -122,8 +122,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(Visit visit
const TSymbolUniqueId &functionId = node->getFunction()->uniqueId();
if (mChangedFunctions.find(functionId.get()) == mChangedFunctions.end())
{
TType returnValueVariableType(node->getType());
returnValueVariableType.setQualifier(EvqOut);
TType *returnValueVariableType = new TType(node->getType());
returnValueVariableType->setQualifier(EvqOut);
ChangedFunction changedFunction;
changedFunction.returnValueVariable =
new TVariable(mSymbolTable, mReturnValueVariableName, returnValueVariableType,
......@@ -170,7 +170,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter
// type s0[size];
TIntermDeclaration *returnValueDeclaration = nullptr;
TVariable *returnValue = DeclareTempVariable(mSymbolTable, node->getType(),
TVariable *returnValue = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
EvqTemporary, &returnValueDeclaration);
replacements.push_back(returnValueDeclaration);
......
......@@ -14,6 +14,7 @@
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/ReplaceVariable.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"
......@@ -142,7 +143,7 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
TQualifier viewIDQualifier = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn;
const TString *viewIDVariableName = NewPoolTString("ViewID_OVR");
const TVariable *viewID =
new TVariable(symbolTable, viewIDVariableName, TType(EbtUInt, EbpHigh, viewIDQualifier),
new TVariable(symbolTable, viewIDVariableName, new TType(EbtUInt, EbpHigh, viewIDQualifier),
SymbolType::AngleInternal);
DeclareGlobalVariable(root, viewID);
......@@ -154,9 +155,9 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// Replacing gl_InstanceID with InstanceID should happen before adding the initializers of
// InstanceID and ViewID.
const TString *instanceIDVariableName = NewPoolTString("InstanceID");
const TVariable *instanceID =
new TVariable(symbolTable, instanceIDVariableName, TType(EbtInt, EbpHigh, EvqGlobal),
SymbolType::AngleInternal);
const TType *instanceIDVariableType = StaticType::Get<EbtInt, EbpHigh, EvqGlobal, 1, 1>();
const TVariable *instanceID = new TVariable(
symbolTable, instanceIDVariableName, instanceIDVariableType, SymbolType::AngleInternal);
DeclareGlobalVariable(root, instanceID);
ReplaceVariable(
root, static_cast<TVariable *>(symbolTable->findBuiltIn("gl_InstanceID", 300, true)),
......@@ -177,9 +178,11 @@ void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root,
// Add a uniform to switch between side-by-side and layered rendering.
const TString *multiviewBaseViewLayerIndexVariableName =
NewPoolTString("multiviewBaseViewLayerIndex");
const TType *baseLayerIndexVariableType =
StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
const TVariable *multiviewBaseViewLayerIndex =
new TVariable(symbolTable, multiviewBaseViewLayerIndexVariableName,
TType(EbtInt, EbpHigh, EvqUniform), SymbolType::AngleInternal);
baseLayerIndexVariableType, SymbolType::AngleInternal);
DeclareGlobalVariable(root, multiviewBaseViewLayerIndex);
// Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's
......
......@@ -153,8 +153,8 @@ void DeferGlobalInitializers(TIntermBlock *root,
// Replace constant variables with non-constant global variables.
for (const TVariable *var : variablesToReplace)
{
TType replacementType(var->getType());
replacementType.setQualifier(EvqGlobal);
TType *replacementType = new TType(var->getType());
replacementType->setQualifier(EvqGlobal);
TVariable *replacement =
new TVariable(symbolTable, &var->name(), replacementType, var->symbolType());
ReplaceVariable(root, var, replacement);
......
......@@ -757,114 +757,124 @@ void InsertBuiltInFunctions(sh::GLenum type,
TStructure *depthRangeStruct = new TStructure(
&symbolTable, NewPoolTString("gl_DepthRangeParameters"), fields, SymbolType::BuiltIn);
symbolTable.insertStructType(COMMON_BUILTINS, depthRangeStruct);
TType depthRangeType(depthRangeStruct);
depthRangeType.setQualifier(EvqUniform);
TType *depthRangeType = new TType(depthRangeStruct);
depthRangeType->setQualifier(EvqUniform);
depthRangeType->realize();
symbolTable.insertVariable(COMMON_BUILTINS, "gl_DepthRange", depthRangeType);
//
// Implementation dependent built-in constants.
//
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs,
EbpMedium);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors",
resources.MaxVertexUniformVectors, EbpMedium);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits",
resources.MaxVertexTextureImageUnits, EbpMedium);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits",
resources.MaxCombinedTextureImageUnits, EbpMedium);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits",
resources.MaxTextureImageUnits, EbpMedium);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors",
resources.MaxFragmentUniformVectors, EbpMedium);
symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors,
EbpMedium);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers,
EbpMedium);
symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxVertexAttribs",
resources.MaxVertexAttribs);
symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxVertexUniformVectors",
resources.MaxVertexUniformVectors);
symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits",
resources.MaxVertexTextureImageUnits);
symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits",
resources.MaxCombinedTextureImageUnits);
symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxTextureImageUnits",
resources.MaxTextureImageUnits);
symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors",
resources.MaxFragmentUniformVectors);
symbolTable.insertConstInt<EbpMedium>(ESSL1_BUILTINS, "gl_MaxVaryingVectors",
resources.MaxVaryingVectors);
symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, "gl_MaxDrawBuffers",
resources.MaxDrawBuffers);
if (resources.EXT_blend_func_extended)
{
symbolTable.insertConstIntExt(COMMON_BUILTINS, TExtension::EXT_blend_func_extended,
"gl_MaxDualSourceDrawBuffersEXT",
resources.MaxDualSourceDrawBuffers, EbpMedium);
symbolTable.insertConstIntExt<EbpMedium>(
COMMON_BUILTINS, TExtension::EXT_blend_func_extended, "gl_MaxDualSourceDrawBuffersEXT",
resources.MaxDualSourceDrawBuffers);
}
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors",
resources.MaxVertexOutputVectors, EbpMedium);
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors",
resources.MaxFragmentInputVectors, EbpMedium);
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset",
resources.MinProgramTexelOffset, EbpMedium);
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset",
resources.MaxProgramTexelOffset, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxImageUnits", resources.MaxImageUnits,
EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexImageUniforms",
resources.MaxVertexImageUniforms, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentImageUniforms",
resources.MaxFragmentImageUniforms, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeImageUniforms",
resources.MaxComputeImageUniforms, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedImageUniforms",
resources.MaxCombinedImageUniforms, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedShaderOutputResources",
resources.MaxCombinedShaderOutputResources, EbpMedium);
symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupCount",
resources.MaxComputeWorkGroupCount, EbpHigh);
symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupSize",
resources.MaxComputeWorkGroupSize, EbpHigh);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeUniformComponents",
resources.MaxComputeUniformComponents, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeTextureImageUnits",
resources.MaxComputeTextureImageUnits, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounters",
resources.MaxComputeAtomicCounters, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounterBuffers",
resources.MaxComputeAtomicCounterBuffers, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounters",
resources.MaxVertexAtomicCounters, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounters",
resources.MaxFragmentAtomicCounters, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounters",
resources.MaxCombinedAtomicCounters, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBindings",
resources.MaxAtomicCounterBindings, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounterBuffers",
resources.MaxVertexAtomicCounterBuffers, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounterBuffers",
resources.MaxFragmentAtomicCounterBuffers, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounterBuffers",
resources.MaxCombinedAtomicCounterBuffers, EbpMedium);
symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize",
resources.MaxAtomicCounterBufferSize, EbpMedium);
symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors",
resources.MaxVertexOutputVectors);
symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors",
resources.MaxFragmentInputVectors);
symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MinProgramTexelOffset",
resources.MinProgramTexelOffset);
symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset",
resources.MaxProgramTexelOffset);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxImageUnits",
resources.MaxImageUnits);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxVertexImageUniforms",
resources.MaxVertexImageUniforms);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxFragmentImageUniforms",
resources.MaxFragmentImageUniforms);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeImageUniforms",
resources.MaxComputeImageUniforms);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedImageUniforms",
resources.MaxCombinedImageUniforms);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedShaderOutputResources",
resources.MaxCombinedShaderOutputResources);
symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupCount",
resources.MaxComputeWorkGroupCount);
symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupSize",
resources.MaxComputeWorkGroupSize);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeUniformComponents",
resources.MaxComputeUniformComponents);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeTextureImageUnits",
resources.MaxComputeTextureImageUnits);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounters",
resources.MaxComputeAtomicCounters);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounterBuffers",
resources.MaxComputeAtomicCounterBuffers);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounters",
resources.MaxVertexAtomicCounters);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounters",
resources.MaxFragmentAtomicCounters);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounters",
resources.MaxCombinedAtomicCounters);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBindings",
resources.MaxAtomicCounterBindings);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounterBuffers",
resources.MaxVertexAtomicCounterBuffers);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounterBuffers",
resources.MaxFragmentAtomicCounterBuffers);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounterBuffers",
resources.MaxCombinedAtomicCounterBuffers);
symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize",
resources.MaxAtomicCounterBufferSize);
if (resources.EXT_geometry_shader)
{
TExtension ext = TExtension::EXT_geometry_shader;
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryInputComponents",
resources.MaxGeometryInputComponents, EbpMedium);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryOutputComponents",
resources.MaxGeometryOutputComponents, EbpMedium);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryImageUniforms",
resources.MaxGeometryImageUniforms, EbpMedium);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryTextureImageUnits",
resources.MaxGeometryTextureImageUnits, EbpMedium);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryOutputVertices",
resources.MaxGeometryOutputVertices, EbpMedium);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryTotalOutputComponents",
resources.MaxGeometryTotalOutputComponents, EbpMedium);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryUniformComponents",
resources.MaxGeometryUniformComponents, EbpMedium);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryAtomicCounters",
resources.MaxGeometryAtomicCounters, EbpMedium);
symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryAtomicCounterBuffers",
resources.MaxGeometryAtomicCounterBuffers, EbpMedium);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
"gl_MaxGeometryInputComponents",
resources.MaxGeometryInputComponents);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
"gl_MaxGeometryOutputComponents",
resources.MaxGeometryOutputComponents);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
"gl_MaxGeometryImageUniforms",
resources.MaxGeometryImageUniforms);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
"gl_MaxGeometryTextureImageUnits",
resources.MaxGeometryTextureImageUnits);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
"gl_MaxGeometryOutputVertices",
resources.MaxGeometryOutputVertices);
symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
"gl_MaxGeometryTotalOutputComponents",
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,
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",
TType(EbtUInt, EbpHigh, EvqViewIDOVR, 1));
viewIDType);
// 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.
const TType *viewIDIntType = StaticType::Get<EbtInt, EbpHigh, EvqViewIDOVR, 1, 1>();
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)
{
case GL_FRAGMENT_SHADER:
{
symbolTable.insertVariable(COMMON_BUILTINS, "gl_FragCoord",
TType(EbtFloat, EbpMedium, EvqFragCoord, 4));
symbolTable.insertVariable(COMMON_BUILTINS, "gl_FrontFacing",
TType(EbtBool, EbpUndefined, EvqFrontFacing, 1));
symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointCoord",
TType(EbtFloat, EbpMedium, EvqPointCoord, 2));
symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragColor",
TType(EbtFloat, EbpMedium, EvqFragColor, 4));
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4);
const TType *fragCoordType = StaticType::Get<EbtFloat, EbpMedium, EvqFragCoord, 4, 1>();
symbolTable.insertVariable(COMMON_BUILTINS, "gl_FragCoord", fragCoordType);
const TType *frontFacingType = StaticType::GetQualified<EbtBool, EvqFrontFacing>();
symbolTable.insertVariable(COMMON_BUILTINS, "gl_FrontFacing", frontFacingType);
const TType *pointCoordType =
StaticType::Get<EbtFloat, EbpMedium, EvqPointCoord, 2, 1>();
symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointCoord", pointCoordType);
const TType *fragColorType = StaticType::Get<EbtFloat, EbpMedium, EvqFragColor, 4, 1>();
symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragColor", fragColorType);
TType *fragDataType = new TType(EbtFloat, EbpMedium, EvqFragData, 4);
if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC)
{
fragData.makeArray(resources.MaxDrawBuffers);
fragDataType->makeArray(resources.MaxDrawBuffers);
}
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)
{
symbolTable.insertVariableExt(
ESSL1_BUILTINS, TExtension::EXT_blend_func_extended, "gl_SecondaryFragColorEXT",
TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4));
TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
secondaryFragData.makeArray(resources.MaxDualSourceDrawBuffers);
const TType *secondaryFragColorType =
StaticType::Get<EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4, 1>();
symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
"gl_SecondaryFragColorEXT", secondaryFragColorType);
TType *secondaryFragDataType =
new TType(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
secondaryFragDataType->makeArray(resources.MaxDualSourceDrawBuffers);
secondaryFragDataType->realize();
symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
"gl_SecondaryFragDataEXT", secondaryFragData);
"gl_SecondaryFragDataEXT", secondaryFragDataType);
}
if (resources.EXT_frag_depth)
{
symbolTable.insertVariableExt(
ESSL1_BUILTINS, TExtension::EXT_frag_depth, "gl_FragDepthEXT",
TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
EvqFragDepthEXT, 1));
TType *fragDepthEXTType =
new TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
EvqFragDepthEXT, 1);
fragDepthEXTType->realize();
symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_frag_depth,
"gl_FragDepthEXT", fragDepthEXTType);
}
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_FragDepth",
TType(EbtFloat, EbpHigh, EvqFragDepth, 1));
const TType *fragDepthType = StaticType::Get<EbtFloat, EbpHigh, EvqFragDepth, 1, 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)
{
TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
lastFragData.makeArray(resources.MaxDrawBuffers);
TType *lastFragDataType = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
lastFragDataType->makeArray(resources.MaxDrawBuffers);
lastFragDataType->realize();
if (resources.EXT_shader_framebuffer_fetch)
{
symbolTable.insertVariableExt(ESSL1_BUILTINS,
TExtension::EXT_shader_framebuffer_fetch,
"gl_LastFragData", lastFragData);
"gl_LastFragData", lastFragDataType);
}
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,
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)
{
symbolTable.insertVariableExt(
ESSL1_BUILTINS, TExtension::ARM_shader_framebuffer_fetch, "gl_LastFragColorARM",
TType(EbtFloat, EbpMedium, EvqLastFragColor, 4));
symbolTable.insertVariableExt(ESSL1_BUILTINS,
TExtension::ARM_shader_framebuffer_fetch,
"gl_LastFragColorARM", lastFragColorType);
}
if (resources.EXT_geometry_shader)
{
TExtension extension = TExtension::EXT_geometry_shader;
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
TType(EbtInt, EbpHigh, EvqPrimitiveID, 1));
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer",
TType(EbtInt, EbpHigh, EvqLayer, 1));
primitiveIDType);
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", layerType);
}
break;
}
case GL_VERTEX_SHADER:
{
symbolTable.insertVariable(COMMON_BUILTINS, "gl_Position",
TType(EbtFloat, EbpHigh, EvqPosition, 4));
symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointSize",
TType(EbtFloat, EbpMedium, EvqPointSize, 1));
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_InstanceID",
TType(EbtInt, EbpHigh, EvqInstanceID, 1));
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID",
TType(EbtInt, EbpHigh, EvqVertexID, 1));
symbolTable.insertVariable(COMMON_BUILTINS, "gl_Position", positionType);
const TType *pointSizeType = StaticType::Get<EbtFloat, EbpMedium, EvqPointSize, 1, 1>();
symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointSize", pointSizeType);
const TType *instanceIDType = StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>();
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_InstanceID", instanceIDType);
const TType *vertexIDType = StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>();
symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID", vertexIDType);
// For internal use by ANGLE - not exposed to the parser.
symbolTable.insertVariable(GLSL_BUILTINS, "gl_ViewportIndex",
TType(EbtInt, EbpHigh, EvqViewportIndex));
const TType *viewportIndexType =
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.
symbolTable.insertVariable(GLSL_BUILTINS, "gl_Layer", TType(EbtInt, EbpHigh, EvqLayer));
symbolTable.insertVariable(GLSL_BUILTINS, "gl_Layer", layerType);
break;
}
case GL_COMPUTE_SHADER:
{
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups",
TType(EbtUInt, EbpUndefined, EvqNumWorkGroups, 3));
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupSize",
TType(EbtUInt, EbpUndefined, EvqWorkGroupSize, 3));
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupID",
TType(EbtUInt, EbpUndefined, EvqWorkGroupID, 3));
const TType *numWorkGroupsType =
StaticType::Get<EbtUInt, EbpUndefined, EvqNumWorkGroups, 3, 1>();
symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups", numWorkGroupsType);
const TType *workGroupSizeType =
StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupSize, 3, 1>();
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",
TType(EbtUInt, EbpUndefined, EvqLocalInvocationID, 3));
localInvocationIDType);
const TType *globalInvocationIDType =
StaticType::Get<EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3, 1>();
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",
TType(EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1));
localInvocationIndexType);
break;
}
......@@ -1017,8 +1053,8 @@ void IdentifyBuiltIns(sh::GLenum type,
// TODO(jiawei.shao@intel.com): implement GL_EXT_geometry_point_size.
TFieldList *glPerVertexFieldList = new TFieldList();
TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
TField *glPositionField = new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4),
NewPoolTString("gl_Position"), zeroSourceLoc);
TField *glPositionField =
new TField(new TType(*positionType), NewPoolTString("gl_Position"), zeroSourceLoc);
glPerVertexFieldList->push_back(glPositionField);
const TString *glPerVertexString = NewPoolTString("gl_PerVertex");
......@@ -1029,26 +1065,32 @@ void IdentifyBuiltIns(sh::GLenum type,
// The array size of gl_in is undefined until we get a valid input primitive
// declaration.
TType glInType(glPerVertexInBlock, EvqPerVertexIn, TLayoutQualifier::Create());
glInType.makeArray(0u);
TType *glInType =
new TType(glPerVertexInBlock, EvqPerVertexIn, TLayoutQualifier::Create());
glInType->makeArray(0u);
glInType->realize();
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_in", glInType);
TInterfaceBlock *glPerVertexOutBlock =
new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
TLayoutQualifier::Create(), SymbolType::BuiltIn);
TType glPositionType(EbtFloat, EbpHigh, EvqPosition, 4);
glPositionType.setInterfaceBlock(glPerVertexOutBlock);
TType *glPositionInBlockType = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
glPositionInBlockType->setInterfaceBlock(glPerVertexOutBlock);
glPositionInBlockType->realize();
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",
TType(EbtInt, EbpHigh, EvqPrimitiveIDIn, 1));
primitiveIDInType);
const TType *invocationIDType =
StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>();
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_InvocationID",
TType(EbtInt, EbpHigh, EvqInvocationID, 1));
invocationIDType);
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID",
TType(EbtInt, EbpHigh, EvqPrimitiveID, 1));
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer",
TType(EbtInt, EbpHigh, EvqLayer, 1));
primitiveIDType);
symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", layerType);
break;
}
......
......@@ -11,6 +11,7 @@
#include "compiler/translator/FindMain.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"
......@@ -102,8 +103,10 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
TSymbolTable *symbolTable)
{
ASSERT(initializedNode->isArray());
TVariable *indexVariable = CreateTempVariable(
symbolTable, TType(EbtInt, highPrecisionSupported ? EbpHigh : EbpMedium, EvqTemporary));
const TType *mediumpIndexType = StaticType::Get<EbtInt, EbpMedium, EvqTemporary, 1, 1>();
const TType *highpIndexType = StaticType::Get<EbtInt, EbpHigh, EvqTemporary, 1, 1>();
TVariable *indexVariable =
CreateTempVariable(symbolTable, highPrecisionSupported ? highpIndexType : mediumpIndexType);
TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexVariable);
TIntermDeclaration *indexInit =
......
......@@ -144,7 +144,7 @@ TIntermConstantUnion *CreateBoolNode(bool value)
return node;
}
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type)
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type)
{
ASSERT(symbolTable != nullptr);
// TODO(oetuaho): Might be useful to sanitize layout qualifier etc. on the type of the created
......@@ -152,15 +152,15 @@ TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type)
return new TVariable(symbolTable, nullptr, type, SymbolType::AngleInternal);
}
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type, TQualifier qualifier)
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier)
{
ASSERT(symbolTable != nullptr);
if (type.getQualifier() == qualifier)
if (type->getQualifier() == qualifier)
{
return CreateTempVariable(symbolTable, type);
}
TType typeWithQualifier(type);
typeWithQualifier.setQualifier(qualifier);
TType *typeWithQualifier = new TType(*type);
typeWithQualifier->setQualifier(qualifier);
return CreateTempVariable(symbolTable, typeWithQualifier);
}
......@@ -199,7 +199,7 @@ TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTy
}
TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
const TType &type,
const TType *type,
TQualifier qualifier,
TIntermDeclaration **declarationOut)
{
......@@ -213,7 +213,8 @@ TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
TQualifier qualifier,
TIntermDeclaration **declarationOut)
{
TVariable *variable = CreateTempVariable(symbolTable, initializer->getType(), qualifier);
TVariable *variable =
CreateTempVariable(symbolTable, new TType(initializer->getType()), qualifier);
*declarationOut = CreateTempInitDeclarationNode(variable, initializer);
return variable;
}
......
......@@ -25,8 +25,8 @@ TIntermTyped *CreateZeroNode(const TType &type);
TIntermConstantUnion *CreateIndexNode(int index);
TIntermConstantUnion *CreateBoolNode(bool value);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType &type, TQualifier qualifier);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type);
TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier);
TIntermSymbol *CreateTempSymbolNode(const TVariable *tempVariable);
TIntermDeclaration *CreateTempDeclarationNode(const TVariable *tempVariable);
......@@ -35,7 +35,7 @@ TIntermDeclaration *CreateTempInitDeclarationNode(const TVariable *tempVariable,
TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTyped *rightNode);
TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
const TType &type,
const TType *type,
TQualifier qualifier,
TIntermDeclaration **declarationOut);
TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
......
......@@ -1109,29 +1109,29 @@ void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
//
bool TParseContext::declareVariable(const TSourceLoc &line,
const TString &identifier,
const TType &type,
const TType *type,
TVariable **variable)
{
ASSERT((*variable) == nullptr);
(*variable) = new TVariable(&symbolTable, &identifier, type, SymbolType::UserDefined);
checkBindingIsValid(line, type);
checkBindingIsValid(line, *type);
bool needsReservedCheck = true;
// 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 *>(
symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion));
if (type.isArrayOfArrays())
if (type->isArrayOfArrays())
{
error(line, "redeclaration of gl_LastFragData as an array of arrays",
identifier.c_str());
return false;
}
else if (static_cast<int>(type.getOutermostArraySize()) ==
else if (static_cast<int>(type->getOutermostArraySize()) ==
maxDrawBuffers->getConstPointer()->getIConst())
{
if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
......@@ -1156,7 +1156,7 @@ bool TParseContext::declareVariable(const TSourceLoc &line,
return false;
}
if (!checkIsNonVoid(line, identifier, type.getBasicType()))
if (!checkIsNonVoid(line, identifier, type->getBasicType()))
return false;
return true;
......@@ -1914,21 +1914,39 @@ TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
// Returns true on success.
bool TParseContext::executeInitializer(const TSourceLoc &line,
const TString &identifier,
TType type,
TType *type,
TIntermTyped *initializer,
TIntermBinary **initNode)
{
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
// 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
// result in an error later, so we don't generate an error message here.
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;
......@@ -1937,6 +1955,11 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
return false;
}
if (constError)
{
return false;
}
bool globalInitWarning = false;
if (symbolTable.atGlobalLevel() &&
!ValidateGlobalInitializer(initializer, mShaderVersion, &globalInitWarning))
......@@ -1955,40 +1978,26 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
"=");
}
//
// identifier must be of type constant, a global, or a temporary
//
TQualifier qualifier = variable->getType().getQualifier();
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst))
{
error(line, " cannot initialize this type of qualifier ",
variable->getType().getQualifierString());
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())
{
std::stringstream reasonStream;
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;
}
assignError(line, "=", variable->getType().getCompleteString(),
initializer->getCompleteString());
return false;
}
if (qualifier == EvqConst)
{
// Save the constant folded value to the variable if possible.
const TConstantUnion *constArray = initializer->getConstantValue();
if (constArray)
......@@ -2002,15 +2011,8 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
}
}
TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
intermSymbol->setLine(line);
*initNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
if (*initNode == nullptr)
{
assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
return false;
}
*initNode = new TIntermBinary(EOpInitialize, intermSymbol, initializer);
(*initNode)->setLine(line);
return true;
}
......@@ -2021,7 +2023,7 @@ TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType,
{
checkIsScalarBool(loc, pType);
TIntermBinary *initNode = nullptr;
TType type(pType);
TType *type = new TType(pType);
if (executeInitializer(loc, identifier, type, initializer, &initNode))
{
// The initializer is valid. The init condition needs to have a node - either the
......@@ -2393,11 +2395,11 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
const TSourceLoc &identifierOrTypeLocation,
const TString &identifier)
{
TType type(publicType);
TType *type = new TType(publicType);
if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) &&
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
// (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all
......@@ -2417,11 +2419,11 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
// behavior of the #pragma when specified in ESSL 1.00 fragment shaders.
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,
identifierOrTypeLocation);
......@@ -2432,10 +2434,10 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
TIntermSymbol *symbol = nullptr;
if (emptyDeclaration)
{
emptyDeclarationErrorCheck(type, identifierOrTypeLocation);
emptyDeclarationErrorCheck(*type, identifierOrTypeLocation);
// 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.
if (type.getBasicType() == EbtStruct)
if (type->getBasicType() == EbtStruct)
{
TVariable *emptyVariable =
new TVariable(&symbolTable, nullptr, type, SymbolType::Empty);
......@@ -2450,9 +2452,9 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
{
nonEmptyDeclarationErrorCheck(publicType, identifierOrTypeLocation);
checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, &type);
checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, type);
checkAtomicCounterOffsetDoesNotOverlap(false, identifierOrTypeLocation, &type);
checkAtomicCounterOffsetDoesNotOverlap(false, identifierOrTypeLocation, type);
TVariable *variable = nullptr;
if (declareVariable(identifierOrTypeLocation, identifier, type, &variable))
......@@ -2487,14 +2489,14 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(
checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
TType arrayType(elementType);
arrayType.makeArrays(arraySizes);
TType *arrayType = new TType(elementType);
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();
declaration->setLine(identifierLocation);
......@@ -2527,7 +2529,7 @@ TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType
declaration->setLine(identifierLocation);
TIntermBinary *initNode = nullptr;
TType type(publicType);
TType *type = new TType(publicType);
if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
{
if (initNode)
......@@ -2556,8 +2558,8 @@ TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
TType arrayType(elementType);
arrayType.makeArrays(arraySizes);
TType *arrayType = new TType(elementType);
arrayType->makeArrays(arraySizes);
TIntermDeclaration *declaration = new TIntermDeclaration();
declaration->setLine(identifierLocation);
......@@ -2646,13 +2648,13 @@ void TParseContext::parseDeclarator(TPublicType &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;
if (declareVariable(identifierLocation, identifier, type, &variable))
......@@ -2682,14 +2684,14 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType,
if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType))
{
TType arrayType(elementType);
arrayType.makeArrays(arraySizes);
TType *arrayType = new TType(elementType);
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;
if (declareVariable(identifierLocation, identifier, arrayType, &variable))
......@@ -2719,7 +2721,7 @@ void TParseContext::parseInitDeclarator(const TPublicType &publicType,
checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
TIntermBinary *initNode = nullptr;
TType type(publicType);
TType *type = new TType(publicType);
if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
{
//
......@@ -2753,8 +2755,8 @@ void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
TType arrayType(elementType);
arrayType.makeArrays(arraySizes);
TType *arrayType = new TType(elementType);
arrayType->makeArrays(arraySizes);
// initNode will correspond to the whole of "b[n] = initializer".
TIntermBinary *initNode = nullptr;
......@@ -2838,8 +2840,8 @@ void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
{
TSymbol *glPerVertex = symbolTable.findBuiltIn("gl_PerVertex", 310);
TInterfaceBlock *glPerVertexBlock = static_cast<TInterfaceBlock *>(glPerVertex);
TType glInType(glPerVertexBlock, EvqPerVertexIn, TLayoutQualifier::Create());
glInType.makeArray(inputArraySize);
TType *glInType = new TType(glPerVertexBlock, EvqPerVertexIn, TLayoutQualifier::Create());
glInType->makeArray(inputArraySize);
mGlInVariableWithArraySize =
new TVariable(&symbolTable, NewPoolTString("gl_in"), glInType, SymbolType::BuiltIn,
TExtension::EXT_geometry_shader);
......@@ -3168,7 +3170,7 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
if (param.name != nullptr)
{
TVariable *variable =
new TVariable(&symbolTable, param.name, *param.type, SymbolType::UserDefined);
new TVariable(&symbolTable, param.name, param.type, SymbolType::UserDefined);
symbol = new TIntermSymbol(variable);
// Insert the parameter in the symbol table.
if (insertParametersToSymbolTable)
......@@ -3195,7 +3197,7 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
// The parameter had no name or declaring the symbol failed - either way, add a nameless
// symbol.
TVariable *emptyVariable =
new TVariable(&symbolTable, nullptr, *param.type, SymbolType::Empty);
new TVariable(&symbolTable, nullptr, param.type, SymbolType::Empty);
symbol = new TIntermSymbol(emptyVariable);
}
symbol->setLine(location);
......@@ -3797,10 +3799,11 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
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)
{
interfaceBlockType.makeArray(arraySize);
interfaceBlockType->makeArray(arraySize);
}
// The instance variable gets created to refer to the interface block type from the AST
......@@ -3816,18 +3819,16 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
{
TField *field = (*fieldList)[memberIndex];
TType *fieldType = field->type();
TType *fieldType = new TType(*field->type());
// set parent pointer of the field variable
fieldType->setInterfaceBlock(interfaceBlock);
fieldType->setQualifier(typeQualifier.qualifier);
TVariable *fieldVariable =
new TVariable(&symbolTable, &field->name(), *fieldType, SymbolType::UserDefined);
if (symbolTable.declareVariable(fieldVariable))
{
fieldVariable->setQualifier(typeQualifier.qualifier);
}
else
new TVariable(&symbolTable, &field->name(), fieldType, SymbolType::UserDefined);
if (!symbolTable.declareVariable(fieldVariable))
{
error(field->line(), "redefinition of an interface block member name",
field->name().c_str());
......
......@@ -193,7 +193,7 @@ class TParseContext : angle::NonCopyable
// is not needed in the AST.
bool executeInitializer(const TSourceLoc &line,
const TString &identifier,
TType type,
TType *type,
TIntermTyped *initializer,
TIntermBinary **initNode);
TIntermNode *addConditionInitializer(const TPublicType &pType,
......@@ -471,7 +471,7 @@ class TParseContext : angle::NonCopyable
bool declareVariable(const TSourceLoc &line,
const TString &identifier,
const TType &type,
const TType *type,
TVariable **variable);
void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
......
......@@ -105,14 +105,14 @@ bool PruneNoOpsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
// Create a new variable to use in the declarator so that the variable and node
// types are kept consistent.
TType type(declaratorSymbol->getType());
TType *type = new TType(declaratorSymbol->getType());
if (mInGlobalScope)
{
type.setQualifier(EvqGlobal);
type->setQualifier(EvqGlobal);
}
else
{
type.setQualifier(EvqTemporary);
type->setQualifier(EvqTemporary);
}
TVariable *variable = new TVariable(mSymbolTable, nullptr, type, SymbolType::Empty);
queueReplacementWithParent(node, declaratorSymbol, new TIntermSymbol(variable),
......
......@@ -14,6 +14,7 @@
#include "compiler/translator/IntermNodePatternMatcher.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
namespace sh
......@@ -58,7 +59,7 @@ std::string GetIndexFunctionName(const TType &type, bool write)
return nameSink.str();
}
TIntermSymbol *CreateBaseSymbol(const TType &type, TSymbolTable *symbolTable)
TIntermSymbol *CreateBaseSymbol(const TType *type, TSymbolTable *symbolTable)
{
TString *baseString = NewPoolTString("base");
TVariable *baseVariable =
......@@ -69,16 +70,17 @@ TIntermSymbol *CreateBaseSymbol(const TType &type, TSymbolTable *symbolTable)
TIntermSymbol *CreateIndexSymbol(TSymbolTable *symbolTable)
{
TString *indexString = NewPoolTString("index");
TVariable *indexVariable = new TVariable(
symbolTable, indexString, TType(EbtInt, EbpHigh, EvqIn), SymbolType::AngleInternal);
TVariable *indexVariable =
new TVariable(symbolTable, indexString, StaticType::Get<EbtInt, EbpHigh, EvqIn, 1, 1>(),
SymbolType::AngleInternal);
return new TIntermSymbol(indexVariable);
}
TIntermSymbol *CreateValueSymbol(const TType &type, TSymbolTable *symbolTable)
{
TString *valueString = NewPoolTString("value");
TType valueType(type);
valueType.setQualifier(EvqIn);
TType *valueType = new TType(type);
valueType->setQualifier(EvqIn);
TVariable *valueVariable =
new TVariable(symbolTable, valueString, valueType, SymbolType::AngleInternal);
return new TIntermSymbol(valueVariable);
......@@ -179,15 +181,15 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(const TType &type,
std::string functionName = GetIndexFunctionName(type, write);
TIntermFunctionPrototype *prototypeNode = CreateInternalFunctionPrototypeNode(func);
TType baseType(type);
TType *baseType = new TType(type);
// Conservatively use highp here, even if the indexed type is not highp. That way the code can't
// end up using mediump version of an indexing function for a highp value, if both mediump and
// highp values are being indexed in the shader. For HLSL precision doesn't matter, but in
// principle this code could be used with multiple backends.
baseType.setPrecision(EbpHigh);
baseType.setQualifier(EvqInOut);
baseType->setPrecision(EbpHigh);
baseType->setQualifier(EvqInOut);
if (!write)
baseType.setQualifier(EvqIn);
baseType->setQualifier(EvqIn);
TIntermSymbol *baseParam = CreateBaseSymbol(baseType, symbolTable);
prototypeNode->getSequence()->push_back(baseParam);
......
......@@ -203,8 +203,8 @@ void RemoveUnreferencedVariablesTraverser::removeVariableDeclaration(TIntermDecl
// Already an empty declaration - nothing to do.
return;
}
TVariable *emptyVariable =
new TVariable(mSymbolTable, nullptr, declarator->getType(), SymbolType::Empty);
TVariable *emptyVariable = new TVariable(
mSymbolTable, nullptr, new TType(declarator->getType()), SymbolType::Empty);
queueReplacementWithParent(node, declarator, new TIntermSymbol(emptyVariable),
OriginalNode::IS_DROPPED);
return;
......
......@@ -11,6 +11,7 @@
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
namespace sh
{
......@@ -71,7 +72,7 @@ class DoWhileRewriter : public TIntermTraverser
}
// Found a loop to change.
TType boolType(EbtBool);
const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
// bool temp = false;
......
......@@ -192,15 +192,15 @@ TVariable *ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
{
ASSERT(original);
TType type(original->getType());
type.setQualifier(EvqTemporary);
if (mShaderType == GL_FRAGMENT_SHADER && type.getBasicType() == EbtFloat &&
type.getPrecision() == EbpUndefined)
TType *type = new TType(original->getType());
type->setQualifier(EvqTemporary);
if (mShaderType == GL_FRAGMENT_SHADER && type->getBasicType() == EbtFloat &&
type->getPrecision() == EbpUndefined)
{
// We use the highest available precision for the temporary variable
// to avoid computing the actual precision using the rules defined
// in GLSL ES 1.0 Section 4.5.2.
type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
type->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
}
TVariable *variable = CreateTempVariable(mSymbolTable, type);
......
......@@ -13,6 +13,7 @@
#include "compiler/translator/IntermNodePatternMatcher.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
namespace sh
{
......@@ -151,7 +152,7 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
if (mFoundLoopToChange)
{
TType boolType(EbtBool, EbpUndefined, EvqTemporary);
const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
// Replace the loop condition with a boolean variable that's updated on each iteration.
......
......@@ -59,11 +59,12 @@ const TString &TSymbol::getMangledName() const
TVariable::TVariable(TSymbolTable *symbolTable,
const TString *name,
const TType &t,
const TType *type,
SymbolType symbolType,
TExtension extension)
: TSymbol(symbolTable, name, symbolType, extension), type(t), unionArray(nullptr)
: TSymbol(symbolTable, name, symbolType, extension), mType(type), unionArray(nullptr)
{
ASSERT(mType);
}
TStructure::TStructure(TSymbolTable *symbolTable,
......
......@@ -71,22 +71,20 @@ class TVariable : public TSymbol
public:
TVariable(TSymbolTable *symbolTable,
const TString *name,
const TType &t,
const TType *type,
SymbolType symbolType,
TExtension ext = TExtension::UNDEFINED);
~TVariable() override {}
bool isVariable() const override { return true; }
TType &getType() { return type; }
const TType &getType() const { return type; }
void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
const TType &getType() const { return *mType; }
const TConstantUnion *getConstPointer() const { return unionArray; }
void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
private:
TType type;
const TType *mType;
const TConstantUnion *unionArray;
};
......
......@@ -14,7 +14,6 @@
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/StaticType.h"
#include <stdio.h>
#include <algorithm>
......@@ -223,24 +222,22 @@ bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
return insert(currentLevel(), interfaceBlock);
}
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType *type)
{
ASSERT(level <= LAST_BUILTIN_LEVEL);
ASSERT(type->isRealized());
return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
}
TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
const TString *name,
const TType &type,
const TType *type,
SymbolType symbolType)
{
ASSERT(level > LAST_BUILTIN_LEVEL || type->isRealized());
TVariable *var = new TVariable(this, name, type, symbolType);
if (insert(level, var))
{
if (level <= LAST_BUILTIN_LEVEL)
{
var->getType().realize();
}
return var;
}
return nullptr;
......@@ -249,15 +246,13 @@ TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
TExtension ext,
const char *name,
const TType &type)
const TType *type)
{
ASSERT(level <= LAST_BUILTIN_LEVEL);
ASSERT(type->isRealized());
TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
if (insert(level, var))
{
if (level <= LAST_BUILTIN_LEVEL)
{
var->getType().realize();
}
return var;
}
return nullptr;
......@@ -266,6 +261,7 @@ TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
{
ASSERT(variable);
ASSERT(level > LAST_BUILTIN_LEVEL || variable->getType().isRealized());
return insert(level, variable);
}
......
......@@ -38,6 +38,7 @@
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/Symbol.h"
namespace sh
......@@ -146,60 +147,23 @@ class TSymbolTable : angle::NonCopyable
// The insert* entry points are used when initializing the symbol table with built-ins.
// They return the created symbol / true in case the declaration was successful, and nullptr /
// false if the declaration failed due to redefinition.
TVariable *insertVariable(ESymbolLevel level, const char *name, const TType &type);
TVariable *insertVariable(ESymbolLevel level, const char *name, const TType *type);
TVariable *insertVariableExt(ESymbolLevel level,
TExtension ext,
const char *name,
const TType &type);
const TType *type);
bool insertVariable(ESymbolLevel level, TVariable *variable);
bool insertStructType(ESymbolLevel level, TStructure *str);
bool insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock);
bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision)
{
TVariable *constant = new TVariable(
this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1), SymbolType::BuiltIn);
constant->getType().realize();
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, constant);
}
template <TPrecision precision>
bool insertConstInt(ESymbolLevel level, const char *name, int value);
bool insertConstIntExt(ESymbolLevel level,
TExtension ext,
const char *name,
int value,
TPrecision precision)
{
TVariable *constant =
new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1),
SymbolType::BuiltIn, ext);
constant->getType().realize();
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, constant);
}
template <TPrecision precision>
bool insertConstIntExt(ESymbolLevel level, TExtension ext, const char *name, int value);
bool insertConstIvec3(ESymbolLevel level,
const char *name,
const std::array<int, 3> &values,
TPrecision precision)
{
TVariable *constantIvec3 = new TVariable(
this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 3), SymbolType::BuiltIn);
constantIvec3->getType().realize();
TConstantUnion *unionArray = new TConstantUnion[3];
for (size_t index = 0u; index < 3u; ++index)
{
unionArray[index].setIConst(values[index]);
}
constantIvec3->shareConstPointer(unionArray);
return insert(level, constantIvec3);
}
template <TPrecision precision>
bool insertConstIvec3(ESymbolLevel level, const char *name, const std::array<int, 3> &values);
void insertBuiltIn(ESymbolLevel level,
TOperator op,
......@@ -337,7 +301,7 @@ class TSymbolTable : angle::NonCopyable
TVariable *insertVariable(ESymbolLevel level,
const TString *name,
const TType &type,
const TType *type,
SymbolType symbolType);
bool insert(ESymbolLevel level, TSymbol *symbol)
......@@ -364,6 +328,52 @@ class TSymbolTable : angle::NonCopyable
int mUserDefinedUniqueIdsStart;
};
template <TPrecision precision>
bool TSymbolTable::insertConstInt(ESymbolLevel level, const char *name, int value)
{
TVariable *constant =
new TVariable(this, NewPoolTString(name),
StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn);
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, constant);
}
template <TPrecision precision>
bool TSymbolTable::insertConstIntExt(ESymbolLevel level,
TExtension ext,
const char *name,
int value)
{
TVariable *constant = new TVariable(this, NewPoolTString(name),
StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(),
SymbolType::BuiltIn, ext);
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, constant);
}
template <TPrecision precision>
bool TSymbolTable::insertConstIvec3(ESymbolLevel level,
const char *name,
const std::array<int, 3> &values)
{
TVariable *constantIvec3 =
new TVariable(this, NewPoolTString(name),
StaticType::Get<EbtInt, precision, EvqConst, 3, 1>(), SymbolType::BuiltIn);
TConstantUnion *unionArray = new TConstantUnion[3];
for (size_t index = 0u; index < 3u; ++index)
{
unionArray[index].setIConst(values[index]);
}
constantIvec3->shareConstPointer(unionArray);
return insert(level, constantIvec3);
}
} // namespace sh
#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_
......@@ -781,6 +781,11 @@ void TType::realize()
getMangledName();
}
bool TType::isRealized() const
{
return mMangledName != nullptr;
}
void TType::invalidateMangledName()
{
mMangledName = nullptr;
......@@ -818,8 +823,8 @@ void TType::createSamplerSymbols(const TString &namePrefix,
}
ASSERT(IsSampler(type));
TVariable *variable = new TVariable(symbolTable, NewPoolTString(namePrefix.c_str()), *this,
SymbolType::AngleInternal);
TVariable *variable = new TVariable(symbolTable, NewPoolTString(namePrefix.c_str()),
new TType(*this), SymbolType::AngleInternal);
outputSymbols->push_back(variable);
if (outputSymbolsToAPINames)
{
......
......@@ -318,6 +318,8 @@ class TType
// Initializes all lazily-initialized members.
void realize();
bool isRealized() const;
private:
void invalidateMangledName();
const char *buildMangledName() const;
......
......@@ -14,6 +14,7 @@
#include "compiler/translator/IntermNodePatternMatcher.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/StaticType.h"
namespace sh
{
......@@ -75,14 +76,14 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
// and then further simplifies down to "bool s = x; if(!s) s = y;".
TIntermSequence insertions;
TType boolType(EbtBool, EbpUndefined, EvqTemporary);
const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
ASSERT(node->getLeft()->getType() == boolType);
ASSERT(node->getLeft()->getType() == *boolType);
insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
TIntermBlock *assignRightBlock = new TIntermBlock();
ASSERT(node->getRight()->getType() == boolType);
ASSERT(node->getRight()->getType() == *boolType);
assignRightBlock->getSequence()->push_back(
CreateTempAssignmentNode(resultVariable, node->getRight()));
......@@ -102,14 +103,14 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
// else s = false;",
// and then further simplifies down to "bool s = x; if(s) s = y;".
TIntermSequence insertions;
TType boolType(EbtBool, EbpUndefined, EvqTemporary);
const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
ASSERT(node->getLeft()->getType() == boolType);
ASSERT(node->getLeft()->getType() == *boolType);
insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
TIntermBlock *assignRightBlock = new TIntermBlock();
ASSERT(node->getRight()->getType() == boolType);
ASSERT(node->getRight()->getType() == *boolType);
assignRightBlock->getSequence()->push_back(
CreateTempAssignmentNode(resultVariable, node->getRight()));
......@@ -144,8 +145,8 @@ bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node
// Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
TIntermSequence insertions;
TIntermDeclaration *tempDeclaration = nullptr;
TVariable *resultVariable =
DeclareTempVariable(mSymbolTable, node->getType(), EvqTemporary, &tempDeclaration);
TVariable *resultVariable = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
EvqTemporary, &tempDeclaration);
insertions.push_back(tempDeclaration);
TIntermBlock *trueBlock = new TIntermBlock();
......
......@@ -68,22 +68,23 @@ TIntermTyped *CreateLValueNode(const TString &lValueName, const TType &type)
{
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
TSymbolTable symbolTable;
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()), type,
SymbolType::UserDefined);
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()),
new TType(type), SymbolType::UserDefined);
return new TIntermSymbol(variable);
}
ExpectedLValues CreateIndexedLValueNodeList(const TString &lValueName,
TType elementType,
const TType &elementType,
unsigned arraySize)
{
ASSERT(elementType.isArray() == false);
elementType.makeArray(arraySize);
TType *arrayType = new TType(elementType);
arrayType->makeArray(arraySize);
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
TSymbolTable symbolTable;
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()),
elementType, SymbolType::UserDefined);
TVariable *variable = new TVariable(&symbolTable, NewPoolTString(lValueName.c_str()), arrayType,
SymbolType::UserDefined);
TIntermSymbol *arraySymbol = new TIntermSymbol(variable);
ExpectedLValues expected(arraySize);
......
......@@ -11,6 +11,7 @@
#include "angle_gl.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/PoolAlloc.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
#include "gtest/gtest.h"
......@@ -44,8 +45,8 @@ class IntermNodeTest : public testing::Test
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these
// nodes.
TSymbolTable symbolTable;
TType variableType(type);
variableType.setQualifier(EvqTemporary);
TType *variableType = new TType(type);
variableType->setQualifier(EvqTemporary);
TVariable *variable =
new TVariable(&symbolTable, symbolName, variableType, SymbolType::AngleInternal);
TIntermSymbol *node = new TIntermSymbol(variable);
......@@ -122,7 +123,7 @@ class IntermNodeTest : public testing::Test
// original.
TEST_F(IntermNodeTest, DeepCopySymbolNode)
{
TType type(EbtInt, EbpHigh);
const TType *type = StaticType::Get<EbtInt, EbpHigh, EvqTemporary, 1, 1>();
// We're using a dummy symbol table here, don't need to assign proper symbol ids to these nodes.
TSymbolTable symbolTable;
......
......@@ -5701,3 +5701,21 @@ TEST_F(FragmentShaderValidationTest,
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test that the type of an initializer of a constant variable needs to match.
TEST_F(FragmentShaderValidationTest, ConstantInitializerTypeMismatch)
{
const std::string &shaderString =
R"(
precision mediump float;
const float f = 0;
void main()
{
gl_FragColor = vec4(f);
})";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment