summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/compiler/translator
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-08-05 11:35:53 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-08-05 11:35:53 +0200
commit6bd66b1728eeddb058066edda740aaeb2ceaec23 (patch)
tree985faf01c526763515731569fa01a99f4dbef36e /gfx/angle/src/compiler/translator
parente0a8dcfed131ffa58a5e2cb1d30fe48c745c2fdc (diff)
parent559824514dc95e02fbe81f1786e6ac13ee8e9d55 (diff)
downloadUXP-6bd66b1728eeddb058066edda740aaeb2ceaec23.tar
UXP-6bd66b1728eeddb058066edda740aaeb2ceaec23.tar.gz
UXP-6bd66b1728eeddb058066edda740aaeb2ceaec23.tar.lz
UXP-6bd66b1728eeddb058066edda740aaeb2ceaec23.tar.xz
UXP-6bd66b1728eeddb058066edda740aaeb2ceaec23.zip
Merge branch 'master' into js-modules
Diffstat (limited to 'gfx/angle/src/compiler/translator')
-rwxr-xr-xgfx/angle/src/compiler/translator/64bit-lexer-safety.patch118
-rwxr-xr-xgfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp33
-rwxr-xr-xgfx/angle/src/compiler/translator/ASTMetadataHLSL.h11
-rw-r--r--gfx/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp59
-rw-r--r--gfx/angle/src/compiler/translator/AddAndTrueToLoopCondition.h20
-rwxr-xr-xgfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp56
-rwxr-xr-xgfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp92
-rwxr-xr-xgfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h3
-rwxr-xr-xgfx/angle/src/compiler/translator/BaseTypes.h299
-rw-r--r--gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp106
-rw-r--r--gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h23
-rwxr-xr-xgfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp5
-rwxr-xr-xgfx/angle/src/compiler/translator/BuiltInFunctionEmulator.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp80
-rwxr-xr-xgfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h14
-rwxr-xr-xgfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp58
-rwxr-xr-xgfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h11
-rwxr-xr-xgfx/angle/src/compiler/translator/Cache.cpp6
-rwxr-xr-xgfx/angle/src/compiler/translator/Cache.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/CallDAG.cpp185
-rwxr-xr-xgfx/angle/src/compiler/translator/CallDAG.h8
-rwxr-xr-xgfx/angle/src/compiler/translator/CodeGen.cpp90
-rwxr-xr-xgfx/angle/src/compiler/translator/Common.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/Compiler.cpp504
-rwxr-xr-xgfx/angle/src/compiler/translator/Compiler.h76
-rw-r--r--gfx/angle/src/compiler/translator/ConstantUnion.cpp642
-rwxr-xr-xgfx/angle/src/compiler/translator/ConstantUnion.h373
-rwxr-xr-xgfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp74
-rwxr-xr-xgfx/angle/src/compiler/translator/DeferGlobalInitializers.h7
-rwxr-xr-xgfx/angle/src/compiler/translator/Diagnostics.cpp5
-rwxr-xr-xgfx/angle/src/compiler/translator/Diagnostics.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/DirectiveHandler.cpp5
-rwxr-xr-xgfx/angle/src/compiler/translator/DirectiveHandler.h4
-rwxr-xr-xgfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp103
-rwxr-xr-xgfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/EmulatePrecision.cpp71
-rwxr-xr-xgfx/angle/src/compiler/translator/EmulatePrecision.h8
-rwxr-xr-xgfx/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp11
-rwxr-xr-xgfx/angle/src/compiler/translator/ExtensionGLSL.cpp5
-rwxr-xr-xgfx/angle/src/compiler/translator/ExtensionGLSL.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/ForLoopUnroll.cpp7
-rwxr-xr-xgfx/angle/src/compiler/translator/ForLoopUnroll.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/InfoSink.cpp5
-rwxr-xr-xgfx/angle/src/compiler/translator/InfoSink.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/Initialize.cpp187
-rwxr-xr-xgfx/angle/src/compiler/translator/Initialize.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/InitializeDll.cpp5
-rwxr-xr-xgfx/angle/src/compiler/translator/InitializeDll.h3
-rwxr-xr-xgfx/angle/src/compiler/translator/InitializeParseContext.cpp4
-rwxr-xr-xgfx/angle/src/compiler/translator/InitializeParseContext.h4
-rwxr-xr-xgfx/angle/src/compiler/translator/InitializeVariables.cpp183
-rwxr-xr-xgfx/angle/src/compiler/translator/InitializeVariables.h15
-rwxr-xr-xgfx/angle/src/compiler/translator/IntermNode.cpp2054
-rwxr-xr-xgfx/angle/src/compiler/translator/IntermNode.h403
-rwxr-xr-xgfx/angle/src/compiler/translator/IntermNodePatternMatcher.cpp23
-rwxr-xr-xgfx/angle/src/compiler/translator/IntermNodePatternMatcher.h9
-rwxr-xr-xgfx/angle/src/compiler/translator/IntermTraverse.cpp271
-rwxr-xr-xgfx/angle/src/compiler/translator/Intermediate.cpp222
-rwxr-xr-xgfx/angle/src/compiler/translator/Intermediate.h52
-rwxr-xr-xgfx/angle/src/compiler/translator/LoopInfo.cpp7
-rwxr-xr-xgfx/angle/src/compiler/translator/LoopInfo.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/Operator.cpp2
-rwxr-xr-xgfx/angle/src/compiler/translator/Operator.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/OutputESSL.cpp13
-rwxr-xr-xgfx/angle/src/compiler/translator/OutputESSL.h23
-rwxr-xr-xgfx/angle/src/compiler/translator/OutputGLSL.cpp27
-rwxr-xr-xgfx/angle/src/compiler/translator/OutputGLSL.h15
-rwxr-xr-xgfx/angle/src/compiler/translator/OutputGLSLBase.cpp891
-rwxr-xr-xgfx/angle/src/compiler/translator/OutputGLSLBase.h31
-rwxr-xr-xgfx/angle/src/compiler/translator/OutputHLSL.cpp854
-rwxr-xr-xgfx/angle/src/compiler/translator/OutputHLSL.h25
-rwxr-xr-xgfx/angle/src/compiler/translator/ParseContext.cpp1775
-rwxr-xr-xgfx/angle/src/compiler/translator/ParseContext.h292
-rwxr-xr-xgfx/angle/src/compiler/translator/PoolAlloc.cpp94
-rwxr-xr-xgfx/angle/src/compiler/translator/PoolAlloc.h18
-rwxr-xr-xgfx/angle/src/compiler/translator/PruneEmptyDeclarations.cpp105
-rwxr-xr-xgfx/angle/src/compiler/translator/PruneEmptyDeclarations.h3
-rw-r--r--gfx/angle/src/compiler/translator/QualifierTypes.cpp727
-rw-r--r--gfx/angle/src/compiler/translator/QualifierTypes.h191
-rwxr-xr-xgfx/angle/src/compiler/translator/RecordConstantPrecision.cpp10
-rwxr-xr-xgfx/angle/src/compiler/translator/RecordConstantPrecision.h3
-rwxr-xr-xgfx/angle/src/compiler/translator/RegenerateStructNames.cpp30
-rwxr-xr-xgfx/angle/src/compiler/translator/RegenerateStructNames.h7
-rwxr-xr-xgfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp73
-rwxr-xr-xgfx/angle/src/compiler/translator/RemoveDynamicIndexing.h5
-rw-r--r--gfx/angle/src/compiler/translator/RemoveInvariantDeclaration.cpp47
-rw-r--r--gfx/angle/src/compiler/translator/RemoveInvariantDeclaration.h18
-rwxr-xr-xgfx/angle/src/compiler/translator/RemovePow.cpp13
-rwxr-xr-xgfx/angle/src/compiler/translator/RemovePow.h3
-rwxr-xr-xgfx/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp31
-rwxr-xr-xgfx/angle/src/compiler/translator/RemoveSwitchFallThrough.h21
-rw-r--r--gfx/angle/src/compiler/translator/RenameFunction.h36
-rwxr-xr-xgfx/angle/src/compiler/translator/RewriteDoWhile.cpp44
-rwxr-xr-xgfx/angle/src/compiler/translator/RewriteDoWhile.h3
-rwxr-xr-xgfx/angle/src/compiler/translator/RewriteElseBlocks.cpp87
-rwxr-xr-xgfx/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp54
-rwxr-xr-xgfx/angle/src/compiler/translator/RewriteTexelFetchOffset.h1
-rw-r--r--gfx/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp112
-rw-r--r--gfx/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h20
-rwxr-xr-xgfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp187
-rwxr-xr-xgfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h46
-rwxr-xr-xgfx/angle/src/compiler/translator/SeparateArrayInitialization.cpp59
-rwxr-xr-xgfx/angle/src/compiler/translator/SeparateArrayInitialization.h3
-rwxr-xr-xgfx/angle/src/compiler/translator/SeparateDeclarations.cpp43
-rwxr-xr-xgfx/angle/src/compiler/translator/SeparateDeclarations.h3
-rwxr-xr-xgfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp14
-rwxr-xr-xgfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.h3
-rwxr-xr-xgfx/angle/src/compiler/translator/ShaderLang.cpp173
-rwxr-xr-xgfx/angle/src/compiler/translator/SimplifyLoopConditions.cpp32
-rwxr-xr-xgfx/angle/src/compiler/translator/SimplifyLoopConditions.h3
-rwxr-xr-xgfx/angle/src/compiler/translator/SplitSequenceOperator.cpp34
-rwxr-xr-xgfx/angle/src/compiler/translator/SplitSequenceOperator.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/SymbolTable.cpp72
-rwxr-xr-xgfx/angle/src/compiler/translator/SymbolTable.h33
-rwxr-xr-xgfx/angle/src/compiler/translator/TextureFunctionHLSL.cpp55
-rwxr-xr-xgfx/angle/src/compiler/translator/TranslatorESSL.cpp19
-rwxr-xr-xgfx/angle/src/compiler/translator/TranslatorESSL.h9
-rwxr-xr-xgfx/angle/src/compiler/translator/TranslatorGLSL.cpp43
-rwxr-xr-xgfx/angle/src/compiler/translator/TranslatorGLSL.h11
-rwxr-xr-xgfx/angle/src/compiler/translator/TranslatorHLSL.cpp24
-rwxr-xr-xgfx/angle/src/compiler/translator/TranslatorHLSL.h9
-rwxr-xr-xgfx/angle/src/compiler/translator/Types.cpp157
-rwxr-xr-xgfx/angle/src/compiler/translator/Types.h232
-rwxr-xr-xgfx/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp17
-rwxr-xr-xgfx/angle/src/compiler/translator/UnfoldShortCircuitAST.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp40
-rwxr-xr-xgfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.h3
-rw-r--r--gfx/angle/src/compiler/translator/UseInterfaceBlockFields.cpp163
-rw-r--r--gfx/angle/src/compiler/translator/UseInterfaceBlockFields.h30
-rwxr-xr-xgfx/angle/src/compiler/translator/UtilsHLSL.cpp2
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateGlobalInitializer.cpp4
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateGlobalInitializer.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateLimitations.cpp11
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateLimitations.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateMaxParameters.cpp5
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateMaxParameters.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateOutputs.cpp5
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateOutputs.h5
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateSwitch.cpp21
-rwxr-xr-xgfx/angle/src/compiler/translator/ValidateSwitch.h13
-rwxr-xr-xgfx/angle/src/compiler/translator/VariableInfo.cpp71
-rwxr-xr-xgfx/angle/src/compiler/translator/VariableInfo.h2
-rwxr-xr-xgfx/angle/src/compiler/translator/VersionGLSL.cpp27
-rwxr-xr-xgfx/angle/src/compiler/translator/VersionGLSL.h6
-rwxr-xr-xgfx/angle/src/compiler/translator/blocklayout.h6
-rwxr-xr-xgfx/angle/src/compiler/translator/blocklayoutHLSL.h7
-rw-r--r--gfx/angle/src/compiler/translator/depgraph/DependencyGraph.cpp95
-rw-r--r--gfx/angle/src/compiler/translator/depgraph/DependencyGraph.h199
-rw-r--r--gfx/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp255
-rw-r--r--gfx/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h199
-rw-r--r--gfx/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp64
-rw-r--r--gfx/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h31
-rw-r--r--gfx/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp69
-rwxr-xr-xgfx/angle/src/compiler/translator/glslang.h14
-rwxr-xr-xgfx/angle/src/compiler/translator/glslang.l75
-rwxr-xr-xgfx/angle/src/compiler/translator/glslang.y544
-rwxr-xr-xgfx/angle/src/compiler/translator/glslang_lex.cpp195
-rwxr-xr-xgfx/angle/src/compiler/translator/glslang_tab.cpp2467
-rwxr-xr-xgfx/angle/src/compiler/translator/glslang_tab.h294
-rwxr-xr-xgfx/angle/src/compiler/translator/intermOut.cpp426
-rwxr-xr-xgfx/angle/src/compiler/translator/length_limits.h5
-rw-r--r--gfx/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp130
-rw-r--r--gfx/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h39
-rw-r--r--gfx/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp17
-rw-r--r--gfx/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h32
-rwxr-xr-xgfx/angle/src/compiler/translator/util.cpp84
-rwxr-xr-xgfx/angle/src/compiler/translator/util.h13
167 files changed, 8003 insertions, 11349 deletions
diff --git a/gfx/angle/src/compiler/translator/64bit-lexer-safety.patch b/gfx/angle/src/compiler/translator/64bit-lexer-safety.patch
index e7e403771..db3b2fab5 100755
--- a/gfx/angle/src/compiler/translator/64bit-lexer-safety.patch
+++ b/gfx/angle/src/compiler/translator/64bit-lexer-safety.patch
@@ -1,13 +1,6 @@
-diff --git a/src/compiler/translator/glslang_lex.cpp b/src/compiler/translator/glslang_lex.cpp
-index 1ba63df..2a206ab 100644
---- a/src/compiler/translator/glslang_lex.cpp
-+++ b/src/compiler/translator/glslang_lex.cpp
-@@ -1,4 +1,3 @@
--#line 17 "./glslang.l"
- //
- // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
-@@ -149,6 +148,7 @@ typedef int16_t flex_int16_t;
+--- a/src/compiler/glslang_lex.cpp
++++ b/src/compiler/glslang_lex.cpp
+@@ -68,6 +68,7 @@ typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
@@ -15,10 +8,10 @@ index 1ba63df..2a206ab 100644
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
-@@ -335,6 +335,11 @@ typedef size_t yy_size_t;
-
-
-
+@@ -191,6 +192,11 @@ typedef void* yyscan_t;
+ typedef struct yy_buffer_state *YY_BUFFER_STATE;
+ #endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
@@ -27,96 +20,21 @@ index 1ba63df..2a206ab 100644
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
-@@ -351,8 +356,8 @@ typedef size_t yy_size_t;
+@@ -204,7 +210,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
*/
#define YY_LESS_LINENO(n) \
do { \
- int yyl;\
-- for ( yyl = n; yyl < yyleng; ++yyl )\
+ yy_size_t yyl;\
-+ for ( yyl = n; yyl < static_cast<yy_site_t>(yyleng); ++yyl )\
+ for ( yyl = n; yyl < yyleng; ++yyl )\
if ( yytext[yyl] == '\n' )\
--yylineno;\
- }while(0)
-@@ -1692,7 +1697,7 @@ yy_find_action:
- if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
- {
- yy_size_t yyl;
-- for ( yyl = 0; yyl < yyleng; ++yyl )
-+ for ( yyl = 0; yyl < static_cast<yy_size_t>(yyleng); ++yyl )
- if ( yytext[yyl] == '\n' )
-
- do{ yylineno++;
-@@ -2655,7 +2660,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
- else
- {
- int num_to_read =
-- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - static_cast<int>(number_to_move) - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-@@ -2690,7 +2695,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
- yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-- number_to_move - 1;
-+ static_cast<int>(number_to_move) - 1;
-
- }
-
-@@ -2698,8 +2703,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
-+ size_t result = 0;
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-- yyg->yy_n_chars, num_to_read );
-+ result, num_to_read );
-+ yyg->yy_n_chars = static_cast<int>(result);
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-@@ -2725,13 +2732,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
-
- if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
- /* Extend the array by 50%, plus the number we really need. */
-- int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
-+ int new_size = yyg->yy_n_chars + static_cast<int>(number_to_move) + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
- }
-
-- yyg->yy_n_chars += number_to_move;
-+ yyg->yy_n_chars += static_cast<int>(number_to_move);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
-@@ -3158,7 +3165,7 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
- /* Increase the buffer to prepare for a possible push. */
- yy_size_t grow_size = 8 /* arbitrary grow size */;
-
-- num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
-+ num_to_alloc = static_cast<int>(yyg->yy_buffer_stack_max + grow_size);
- yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
- (yyg->yy_buffer_stack,
- num_to_alloc * sizeof(struct yy_buffer_state*)
-@@ -3196,7 +3203,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
-- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
-+ b->yy_buf_size = static_cast<int>(size) - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = NULL;
-@@ -3251,7 +3258,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yysc
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
-- for ( i = 0; i < _yybytes_len; ++i )
-+ for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+@@ -378,7 +379,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+ */
+ #define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+- yyleng = (size_t) (yy_cp - yy_bp); \
++ yyleng = (yy_size_t) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
diff --git a/gfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp b/gfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp
index ba991b709..31bfae996 100755
--- a/gfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/ASTMetadataHLSL.cpp
@@ -11,9 +11,6 @@
#include "compiler/translator/CallDAG.h"
#include "compiler/translator/SymbolTable.h"
-namespace sh
-{
-
namespace
{
@@ -34,7 +31,7 @@ class PullGradient : public TIntermTraverser
ASSERT(index < metadataList->size());
}
- void traverse(TIntermFunctionDefinition *node)
+ void traverse(TIntermAggregate *node)
{
node->traverse(this);
ASSERT(mParents.empty());
@@ -75,9 +72,9 @@ class PullGradient : public TIntermTraverser
return true;
}
- bool visitIfElse(Visit visit, TIntermIfElse *ifElse) override
+ bool visitSelection(Visit visit, TIntermSelection *selection) override
{
- visitControlFlow(visit, ifElse);
+ visitControlFlow(visit, selection);
return true;
}
@@ -106,8 +103,9 @@ class PullGradient : public TIntermTraverser
{
if (node->isUserDefined())
{
- size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
+ size_t calleeIndex = mDag.findIndex(node);
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
+ UNUSED_ASSERTION_VARIABLE(mIndex);
if ((*mMetadataList)[calleeIndex].mUsesGradient) {
onGradient();
@@ -115,8 +113,7 @@ class PullGradient : public TIntermTraverser
}
else
{
- TString name =
- TFunction::unmangleName(node->getFunctionSymbolInfo()->getName());
+ TString name = TFunction::unmangleName(node->getName());
if (name == "texture2D" ||
name == "texture2DProj" ||
@@ -160,7 +157,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
{
}
- void traverse(TIntermFunctionDefinition *node)
+ void traverse(TIntermAggregate *node)
{
node->traverse(this);
ASSERT(mLoopsAndSwitches.empty());
@@ -199,7 +196,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
return true;
}
- bool visitIfElse(Visit visit, TIntermIfElse *node) override
+ bool visitSelection(Visit visit, TIntermSelection *node) override
{
if (visit == PreVisit)
{
@@ -278,8 +275,9 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
{
if (node->isUserDefined())
{
- size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
+ size_t calleeIndex = mDag.findIndex(node);
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
+ UNUSED_ASSERTION_VARIABLE(mIndex);
if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
{
@@ -312,7 +310,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
const CallDAG &mDag;
std::vector<TIntermNode*> mLoopsAndSwitches;
- std::vector<TIntermIfElse *> mIfs;
+ std::vector<TIntermSelection*> mIfs;
};
// Tags all the functions called in a discontinuous loop
@@ -329,7 +327,7 @@ class PushDiscontinuousLoops : public TIntermTraverser
{
}
- void traverse(TIntermFunctionDefinition *node)
+ void traverse(TIntermAggregate *node)
{
node->traverse(this);
ASSERT(mNestedDiscont == (mMetadata->mCalledInDiscontinuousLoop ? 1 : 0));
@@ -358,8 +356,9 @@ class PushDiscontinuousLoops : public TIntermTraverser
case EOpFunctionCall:
if (visit == PreVisit && node->isUserDefined() && mNestedDiscont > 0)
{
- size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
+ size_t calleeIndex = mDag.findIndex(node);
ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
+ UNUSED_ASSERTION_VARIABLE(mIndex);
(*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
}
@@ -386,7 +385,7 @@ bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node)
return mControlFlowsContainingGradient.count(node) > 0;
}
-bool ASTMetadataHLSL::hasGradientLoop(TIntermIfElse *node)
+bool ASTMetadataHLSL::hasGradientLoop(TIntermSelection *node)
{
return mIfsContainingGradientLoop.count(node) > 0;
}
@@ -450,5 +449,3 @@ MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
return metadataList;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ASTMetadataHLSL.h b/gfx/angle/src/compiler/translator/ASTMetadataHLSL.h
index f8ed5af4a..39e671e3e 100755
--- a/gfx/angle/src/compiler/translator/ASTMetadataHLSL.h
+++ b/gfx/angle/src/compiler/translator/ASTMetadataHLSL.h
@@ -12,12 +12,9 @@
#include <set>
#include <vector>
-namespace sh
-{
-
class CallDAG;
class TIntermNode;
-class TIntermIfElse;
+class TIntermSelection;
class TIntermLoop;
struct ASTMetadataHLSL
@@ -33,7 +30,7 @@ struct ASTMetadataHLSL
// Here "something uses a gradient" means here that it either contains a
// gradient operation, or a call to a function that uses a gradient.
bool hasGradientInCallGraph(TIntermLoop *node);
- bool hasGradientLoop(TIntermIfElse *node);
+ bool hasGradientLoop(TIntermSelection *node);
// Does the function use a gradient.
bool mUsesGradient;
@@ -47,7 +44,7 @@ struct ASTMetadataHLSL
bool mCalledInDiscontinuousLoop;
bool mHasGradientLoopInCallGraph;
std::set<TIntermLoop*> mDiscontinuousLoops;
- std::set<TIntermIfElse *> mIfsContainingGradientLoop;
+ std::set<TIntermSelection *> mIfsContainingGradientLoop;
// Will we need to generate a Lod0 version of the function.
bool mNeedsLod0;
@@ -58,6 +55,4 @@ typedef std::vector<ASTMetadataHLSL> MetadataList;
// Return the AST analysis result, in the order defined by the call DAG
MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag);
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
diff --git a/gfx/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp b/gfx/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp
deleted file mode 100644
index 0177fea96..000000000
--- a/gfx/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "compiler/translator/AddAndTrueToLoopCondition.h"
-
-#include "compiler/translator/IntermNode.h"
-
-namespace sh
-{
-
-namespace
-{
-
-// An AST traverser that rewrites for and while loops by replacing "condition" with
-// "condition && true" to work around condition bug on Intel Mac.
-class AddAndTrueToLoopConditionTraverser : public TIntermTraverser
-{
- public:
- AddAndTrueToLoopConditionTraverser() : TIntermTraverser(true, false, false) {}
-
- bool visitLoop(Visit, TIntermLoop *loop) override
- {
- // do-while loop doesn't have this bug.
- if (loop->getType() != ELoopFor && loop->getType() != ELoopWhile)
- {
- return true;
- }
-
- // For loop may not have a condition.
- if (loop->getCondition() == nullptr)
- {
- return true;
- }
-
- // Constant true.
- TConstantUnion *trueConstant = new TConstantUnion();
- trueConstant->setBConst(true);
- TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, TType(EbtBool));
-
- // CONDITION && true.
- TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue);
- loop->setCondition(andOp);
-
- return true;
- }
-};
-
-} // anonymous namespace
-
-void AddAndTrueToLoopCondition(TIntermNode *root)
-{
- AddAndTrueToLoopConditionTraverser traverser;
- root->traverse(&traverser);
-}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/AddAndTrueToLoopCondition.h b/gfx/angle/src/compiler/translator/AddAndTrueToLoopCondition.h
deleted file mode 100644
index 34debe0ed..000000000
--- a/gfx/angle/src/compiler/translator/AddAndTrueToLoopCondition.h
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// Rewrite condition in for and while loops to work around driver bug on Intel Mac.
-
-#ifndef COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
-#define COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
-
-class TIntermNode;
-namespace sh
-{
-
-void AddAndTrueToLoopCondition(TIntermNode *root);
-
-} // namespace sh
-
-#endif // COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_
diff --git a/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp b/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp
index 5767aea2b..97111d1a1 100755
--- a/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp
+++ b/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp
@@ -31,16 +31,21 @@ class AddDefaultReturnStatementsTraverser : private TIntermTraverser
private:
AddDefaultReturnStatementsTraverser() : TIntermTraverser(true, false, false) {}
- static bool IsFunctionWithoutReturnStatement(TIntermFunctionDefinition *node, TType *returnType)
+ static bool IsFunctionWithoutReturnStatement(TIntermAggregate *node, TType *returnType)
{
*returnType = node->getType();
- if (node->getType().getBasicType() == EbtVoid)
+ if (node->getOp() != EOpFunction || node->getType().getBasicType() == EbtVoid)
{
return false;
}
- TIntermBlock *bodyNode = node->getBody();
- TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
+ TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
+ if (lastNode == nullptr)
+ {
+ return true;
+ }
+
+ TIntermBranch *returnNode = lastNode->getSequence()->front()->getAsBranchNode();
if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
{
return false;
@@ -49,16 +54,51 @@ class AddDefaultReturnStatementsTraverser : private TIntermTraverser
return true;
}
- bool visitFunctionDefinition(Visit, TIntermFunctionDefinition *node) override
+ static TIntermTyped *GenerateTypeConstructor(const TType &returnType)
+ {
+ // Base case, constructing a single element
+ if (!returnType.isArray())
+ {
+ size_t objectSize = returnType.getObjectSize();
+ TConstantUnion *constantUnion = new TConstantUnion[objectSize];
+ for (size_t constantIdx = 0; constantIdx < objectSize; constantIdx++)
+ {
+ constantUnion[constantIdx].setFConst(0.0f);
+ }
+
+ TIntermConstantUnion *intermConstantUnion =
+ new TIntermConstantUnion(constantUnion, returnType);
+ return intermConstantUnion;
+ }
+
+ // Recursive case, construct an array of single elements
+ TIntermAggregate *constructorAggrigate =
+ new TIntermAggregate(TypeToConstructorOperator(returnType));
+ constructorAggrigate->setType(returnType);
+
+ size_t arraySize = returnType.getArraySize();
+ for (size_t arrayIdx = 0; arrayIdx < arraySize; arrayIdx++)
+ {
+ TType arrayElementType(returnType);
+ arrayElementType.clearArrayness();
+
+ constructorAggrigate->getSequence()->push_back(
+ GenerateTypeConstructor(arrayElementType));
+ }
+
+ return constructorAggrigate;
+ }
+
+ bool visitAggregate(Visit, TIntermAggregate *node) override
{
TType returnType;
if (IsFunctionWithoutReturnStatement(node, &returnType))
{
TIntermBranch *branch =
- new TIntermBranch(EOpReturn, TIntermTyped::CreateZero(returnType));
+ new TIntermBranch(EOpReturn, GenerateTypeConstructor(returnType));
- TIntermBlock *bodyNode = node->getBody();
- bodyNode->getSequence()->push_back(branch);
+ TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
+ lastNode->getSequence()->push_back(branch);
return false;
}
diff --git a/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp b/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
index 766f700ee..af5bb9ce3 100755
--- a/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ b/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
@@ -10,9 +10,6 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
namespace
{
@@ -44,7 +41,8 @@ TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall, TIntermT
TIntermAggregate *replacementCall = new TIntermAggregate(EOpFunctionCall);
replacementCall->setType(TType(EbtVoid));
replacementCall->setUserDefined();
- *replacementCall->getFunctionSymbolInfo() = *originalCall->getFunctionSymbolInfo();
+ replacementCall->setNameObj(originalCall->getNameObj());
+ replacementCall->setFunctionId(originalCall->getFunctionId());
replacementCall->setLine(originalCall->getLine());
TIntermSequence *replacementParameters = replacementCall->getSequence();
TIntermSequence *originalParameters = originalCall->getSequence();
@@ -63,7 +61,6 @@ class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser
private:
ArrayReturnValueToOutParameterTraverser();
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
bool visitBranch(Visit visit, TIntermBranch *node) override;
bool visitBinary(Visit visit, TIntermBinary *node) override;
@@ -85,47 +82,35 @@ ArrayReturnValueToOutParameterTraverser::ArrayReturnValueToOutParameterTraverser
{
}
-bool ArrayReturnValueToOutParameterTraverser::visitFunctionDefinition(
- Visit visit,
- TIntermFunctionDefinition *node)
+bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
{
- if (node->isArray() && visit == PreVisit)
+ if (visit == PreVisit)
{
- // Replace the parameters child node of the function definition with another node
- // that has the out parameter added.
- // Also set the function to return void.
-
- TIntermAggregate *params = node->getFunctionParameters();
- ASSERT(params != nullptr && params->getOp() == EOpParameters);
+ if (node->isArray())
+ {
+ if (node->getOp() == EOpFunction)
+ {
+ // Replace the parameters child node of the function definition with another node
+ // that has the out parameter added.
+ // Also set the function to return void.
- TIntermAggregate *replacementParams = new TIntermAggregate;
- replacementParams->setOp(EOpParameters);
- CopyAggregateChildren(params, replacementParams);
- replacementParams->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
- replacementParams->setLine(params->getLine());
+ TIntermAggregate *params = node->getSequence()->front()->getAsAggregate();
+ ASSERT(params != nullptr && params->getOp() == EOpParameters);
- queueReplacementWithParent(node, params, replacementParams, OriginalNode::IS_DROPPED);
+ TIntermAggregate *replacementParams = new TIntermAggregate;
+ replacementParams->setOp(EOpParameters);
+ CopyAggregateChildren(params, replacementParams);
+ replacementParams->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
+ replacementParams->setLine(params->getLine());
- node->setType(TType(EbtVoid));
+ queueReplacementWithParent(node, params, replacementParams,
+ OriginalNode::IS_DROPPED);
- mInFunctionWithArrayReturnValue = true;
- }
- if (visit == PostVisit)
- {
- // This isn't conditional on node->isArray() since the type has already been changed on
- // PreVisit.
- mInFunctionWithArrayReturnValue = false;
- }
- return true;
-}
+ node->setType(TType(EbtVoid));
-bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
-{
- if (visit == PreVisit)
- {
- if (node->isArray())
- {
- if (node->getOp() == EOpPrototype)
+ mInFunctionWithArrayReturnValue = true;
+ }
+ else if (node->getOp() == EOpPrototype)
{
// Replace the whole prototype node with another node that has the out parameter added.
TIntermAggregate *replacement = new TIntermAggregate;
@@ -133,7 +118,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter
CopyAggregateChildren(node, replacement);
replacement->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
replacement->setUserDefined();
- *replacement->getFunctionSymbolInfo() = *node->getFunctionSymbolInfo();
+ replacement->setNameObj(node->getNameObj());
+ replacement->setFunctionId(node->getFunctionId());
replacement->setLine(node->getLine());
replacement->setType(TType(EbtVoid));
@@ -150,21 +136,27 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter
// Cases 2 to 4 are already converted to simpler cases by SeparateExpressionsReturningArrays, so we
// only need to worry about the case where a function call returning an array forms an expression by
// itself.
- TIntermBlock *parentBlock = getParentNode()->getAsBlock();
- if (parentBlock)
+ TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
+ if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence)
{
nextTemporaryIndex();
TIntermSequence replacements;
replacements.push_back(createTempDeclaration(node->getType()));
TIntermSymbol *returnSymbol = createTempSymbol(node->getType());
replacements.push_back(CreateReplacementCall(node, returnSymbol));
- mMultiReplacements.push_back(
- NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
+ mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements));
}
return false;
}
}
}
+ else if (visit == PostVisit)
+ {
+ if (node->getOp() == EOpFunction)
+ {
+ mInFunctionWithArrayReturnValue = false;
+ }
+ }
return true;
}
@@ -175,11 +167,12 @@ bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBr
// Instead of returning a value, assign to the out parameter and then return.
TIntermSequence replacements;
+ TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign);
TIntermTyped *expression = node->getExpression();
ASSERT(expression != nullptr);
- TIntermSymbol *returnValueSymbol = CreateReturnValueSymbol(expression->getType());
- TIntermBinary *replacementAssignment =
- new TIntermBinary(EOpAssign, returnValueSymbol, expression);
+ replacementAssignment->setLeft(CreateReturnValueSymbol(expression->getType()));
+ replacementAssignment->setRight(node->getExpression());
+ replacementAssignment->setType(expression->getType());
replacementAssignment->setLine(expression->getLine());
replacements.push_back(replacementAssignment);
@@ -187,8 +180,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBr
replacementBranch->setLine(node->getLine());
replacements.push_back(replacementBranch);
- mMultiReplacements.push_back(
- NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, replacements));
+ mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsAggregate(), node, replacements));
}
return false;
}
@@ -213,5 +205,3 @@ void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIn
{
ArrayReturnValueToOutParameterTraverser::apply(root, temporaryIndex);
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h b/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h
index e030f6ffe..983e203e6 100755
--- a/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h
+++ b/gfx/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h
@@ -9,11 +9,8 @@
#ifndef COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
#define COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
-namespace sh
-{
class TIntermNode;
void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_
diff --git a/gfx/angle/src/compiler/translator/BaseTypes.h b/gfx/angle/src/compiler/translator/BaseTypes.h
index e050c88da..72ecb50f4 100755
--- a/gfx/angle/src/compiler/translator/BaseTypes.h
+++ b/gfx/angle/src/compiler/translator/BaseTypes.h
@@ -13,9 +13,6 @@
#include "common/debug.h"
#include "GLSLANG/ShaderLang.h"
-namespace sh
-{
-
//
// Precision qualifiers
//
@@ -35,10 +32,10 @@ inline const char* getPrecisionString(TPrecision p)
{
switch(p)
{
- case EbpHigh: return "highp";
- case EbpMedium: return "mediump";
- case EbpLow: return "lowp";
- default: return "mediump"; // Safest fallback
+ case EbpHigh: return "highp"; break;
+ case EbpMedium: return "mediump"; break;
+ case EbpLow: return "lowp"; break;
+ default: return "mediump"; break; // Safest fallback
}
}
@@ -79,98 +76,19 @@ enum TBasicType
EbtSampler2DShadow,
EbtSamplerCubeShadow,
EbtSampler2DArrayShadow,
- EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
- EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
- EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
- EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
- EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and
- // usampler2DArray
-
- // images
- EbtGuardImageBegin,
- EbtImage2D,
- EbtIImage2D,
- EbtUImage2D,
- EbtImage3D,
- EbtIImage3D,
- EbtUImage3D,
- EbtImage2DArray,
- EbtIImage2DArray,
- EbtUImage2DArray,
- EbtImageCube,
- EbtIImageCube,
- EbtUImageCube,
- EbtGuardImageEnd,
-
- EbtGuardGImageBegin,
- EbtGImage2D, // non type: represents image2D, uimage2D, iimage2D
- EbtGImage3D, // non type: represents image3D, uimage3D, iimage3D
- EbtGImage2DArray, // non type: represents image2DArray, uimage2DArray, iimage2DArray
- EbtGImageCube, // non type: represents imageCube, uimageCube, iimageCube
- EbtGuardGImageEnd,
-
+ EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
+ EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
+ EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
+ EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
+ EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
EbtStruct,
EbtInterfaceBlock,
- EbtAddress, // should be deprecated??
+ EbtAddress, // should be deprecated??
// end of list
EbtLast
};
-inline TBasicType convertGImageToFloatImage(TBasicType type)
-{
- switch (type)
- {
- case EbtGImage2D:
- return EbtImage2D;
- case EbtGImage3D:
- return EbtImage3D;
- case EbtGImage2DArray:
- return EbtImage2DArray;
- case EbtGImageCube:
- return EbtImageCube;
- default:
- UNREACHABLE();
- }
- return EbtLast;
-}
-
-inline TBasicType convertGImageToIntImage(TBasicType type)
-{
- switch (type)
- {
- case EbtGImage2D:
- return EbtIImage2D;
- case EbtGImage3D:
- return EbtIImage3D;
- case EbtGImage2DArray:
- return EbtIImage2DArray;
- case EbtGImageCube:
- return EbtIImageCube;
- default:
- UNREACHABLE();
- }
- return EbtLast;
-}
-
-inline TBasicType convertGImageToUnsignedImage(TBasicType type)
-{
- switch (type)
- {
- case EbtGImage2D:
- return EbtUImage2D;
- case EbtGImage3D:
- return EbtUImage3D;
- case EbtGImage2DArray:
- return EbtUImage2DArray;
- case EbtGImageCube:
- return EbtUImageCube;
- default:
- UNREACHABLE();
- }
- return EbtLast;
-}
-
const char* getBasicString(TBasicType t);
inline bool IsSampler(TBasicType type)
@@ -178,22 +96,6 @@ inline bool IsSampler(TBasicType type)
return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
}
-inline bool IsImage(TBasicType type)
-{
- return type > EbtGuardImageBegin && type < EbtGuardImageEnd;
-}
-
-inline bool IsGImage(TBasicType type)
-{
- return type > EbtGuardGImageBegin && type < EbtGuardGImageEnd;
-}
-
-inline bool IsOpaqueType(TBasicType type)
-{
- // TODO (mradev): add atomic types as opaque.
- return IsSampler(type) || IsImage(type);
-}
-
inline bool IsIntegerSampler(TBasicType type)
{
switch (type)
@@ -224,56 +126,6 @@ inline bool IsIntegerSampler(TBasicType type)
return false;
}
-inline bool IsFloatImage(TBasicType type)
-{
- switch (type)
- {
- case EbtImage2D:
- case EbtImage3D:
- case EbtImage2DArray:
- case EbtImageCube:
- return true;
- default:
- break;
- }
-
- return false;
-}
-
-inline bool IsIntegerImage(TBasicType type)
-{
-
- switch (type)
- {
- case EbtIImage2D:
- case EbtIImage3D:
- case EbtIImage2DArray:
- case EbtIImageCube:
- return true;
- default:
- break;
- }
-
- return false;
-}
-
-inline bool IsUnsignedImage(TBasicType type)
-{
-
- switch (type)
- {
- case EbtUImage2D:
- case EbtUImage3D:
- case EbtUImage2DArray:
- case EbtUImageCube:
- return true;
- default:
- break;
- }
-
- return false;
-}
-
inline bool IsSampler2D(TBasicType type)
{
switch (type)
@@ -431,7 +283,7 @@ inline bool IsInteger(TBasicType type)
inline bool SupportsPrecision(TBasicType type)
{
- return type == EbtFloat || type == EbtInt || type == EbtUInt || IsOpaqueType(type);
+ return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type);
}
//
@@ -489,11 +341,10 @@ enum TQualifier
EvqLastFragData,
// GLSL ES 3.0 vertex output and fragment input
- EvqSmooth, // Incomplete qualifier, smooth is the default
- EvqFlat, // Incomplete qualifier
- EvqCentroid, // Incomplete qualifier
- EvqSmoothOut,
- EvqFlatOut,
+ EvqSmooth, // Incomplete qualifier, smooth is the default
+ EvqFlat, // Incomplete qualifier
+ EvqSmoothOut = EvqSmooth,
+ EvqFlatOut = EvqFlat,
EvqCentroidOut, // Implies smooth
EvqSmoothIn,
EvqFlatIn,
@@ -508,40 +359,10 @@ enum TQualifier
EvqGlobalInvocationID,
EvqLocalInvocationIndex,
- // GLSL ES 3.1 memory qualifiers
- EvqReadOnly,
- EvqWriteOnly,
- EvqCoherent,
- EvqRestrict,
- EvqVolatile,
-
// end of list
EvqLast
};
-inline bool IsQualifierUnspecified(TQualifier qualifier)
-{
- return (qualifier == EvqTemporary || qualifier == EvqGlobal);
-}
-
-enum TLayoutImageInternalFormat
-{
- EiifUnspecified,
- EiifRGBA32F,
- EiifRGBA16F,
- EiifR32F,
- EiifRGBA32UI,
- EiifRGBA16UI,
- EiifRGBA8UI,
- EiifR32UI,
- EiifRGBA32I,
- EiifRGBA16I,
- EiifRGBA8I,
- EiifR32I,
- EiifRGBA8,
- EiifRGBA8_SNORM
-};
-
enum TLayoutMatrixPacking
{
EmpUnspecified,
@@ -560,44 +381,36 @@ enum TLayoutBlockStorage
struct TLayoutQualifier
{
int location;
- unsigned int locationsSpecified;
TLayoutMatrixPacking matrixPacking;
TLayoutBlockStorage blockStorage;
// Compute shader layout qualifiers.
sh::WorkGroupSize localSize;
- // Image format layout qualifier
- TLayoutImageInternalFormat imageInternalFormat;
-
static TLayoutQualifier create()
{
TLayoutQualifier layoutQualifier;
layoutQualifier.location = -1;
- layoutQualifier.locationsSpecified = 0;
layoutQualifier.matrixPacking = EmpUnspecified;
layoutQualifier.blockStorage = EbsUnspecified;
layoutQualifier.localSize.fill(-1);
- layoutQualifier.imageInternalFormat = EiifUnspecified;
return layoutQualifier;
}
bool isEmpty() const
{
return location == -1 && matrixPacking == EmpUnspecified &&
- blockStorage == EbsUnspecified && !localSize.isAnyValueSet() &&
- imageInternalFormat == EiifUnspecified;
+ blockStorage == EbsUnspecified && !localSize.isAnyValueSet();
}
bool isCombinationValid() const
{
bool workSizeSpecified = localSize.isAnyValueSet();
bool otherLayoutQualifiersSpecified =
- (location != -1 || matrixPacking != EmpUnspecified || blockStorage != EbsUnspecified ||
- imageInternalFormat != EiifUnspecified);
+ (location != -1 || matrixPacking != EmpUnspecified || blockStorage != EbsUnspecified);
// we can have either the work group size specified, or the other layout qualifiers
return !(workSizeSpecified && otherLayoutQualifiersSpecified);
@@ -609,37 +422,6 @@ struct TLayoutQualifier
}
};
-struct TMemoryQualifier
-{
- // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
- // An image can be qualified as both readonly and writeonly. It still can be can be used with
- // imageSize().
- bool readonly;
- bool writeonly;
- bool coherent;
-
- // restrict and volatile are reserved keywords in C/C++
- bool restrictQualifier;
- bool volatileQualifier;
- static TMemoryQualifier create()
- {
- TMemoryQualifier memoryQualifier;
-
- memoryQualifier.readonly = false;
- memoryQualifier.writeonly = false;
- memoryQualifier.coherent = false;
- memoryQualifier.restrictQualifier = false;
- memoryQualifier.volatileQualifier = false;
-
- return memoryQualifier;
- }
-
- bool isEmpty()
- {
- return !readonly && !writeonly && !coherent && !restrictQualifier && !volatileQualifier;
- }
-};
-
inline const char *getWorkGroupSizeString(size_t dimension)
{
switch (dimension)
@@ -700,9 +482,6 @@ inline const char* getQualifierString(TQualifier q)
case EvqSmoothIn: return "smooth in";
case EvqFlatIn: return "flat in";
case EvqCentroidIn: return "smooth centroid in";
- case EvqCentroid: return "centroid";
- case EvqFlat: return "flat";
- case EvqSmooth: return "smooth";
case EvqComputeIn: return "in";
case EvqNumWorkGroups: return "NumWorkGroups";
case EvqWorkGroupSize: return "WorkGroupSize";
@@ -710,8 +489,6 @@ inline const char* getQualifierString(TQualifier q)
case EvqLocalInvocationID: return "LocalInvocationID";
case EvqGlobalInvocationID: return "GlobalInvocationID";
case EvqLocalInvocationIndex: return "LocalInvocationIndex";
- case EvqReadOnly: return "readonly";
- case EvqWriteOnly: return "writeonly";
default: UNREACHABLE(); return "unknown qualifier";
}
// clang-format on
@@ -740,42 +517,18 @@ inline const char* getBlockStorageString(TLayoutBlockStorage bsq)
}
}
-inline const char *getImageInternalFormatString(TLayoutImageInternalFormat iifq)
+inline const char* getInterpolationString(TQualifier q)
{
- switch (iifq)
+ switch(q)
{
- case EiifRGBA32F:
- return "rgba32f";
- case EiifRGBA16F:
- return "rgba16f";
- case EiifR32F:
- return "r32f";
- case EiifRGBA32UI:
- return "rgba32ui";
- case EiifRGBA16UI:
- return "rgba16ui";
- case EiifRGBA8UI:
- return "rgba8ui";
- case EiifR32UI:
- return "r32ui";
- case EiifRGBA32I:
- return "rgba32i";
- case EiifRGBA16I:
- return "rgba16i";
- case EiifRGBA8I:
- return "rgba8i";
- case EiifR32I:
- return "r32i";
- case EiifRGBA8:
- return "rgba8";
- case EiifRGBA8_SNORM:
- return "rgba8_snorm";
- default:
- UNREACHABLE();
- return "unknown internal image format";
+ case EvqSmoothOut: return "smooth"; break;
+ case EvqCentroidOut: return "smooth centroid"; break;
+ case EvqFlatOut: return "flat"; break;
+ case EvqSmoothIn: return "smooth"; break;
+ case EvqCentroidIn: return "smooth centroid"; break;
+ case EvqFlatIn: return "flat"; break;
+ default: UNREACHABLE(); return "unknown interpolation";
}
}
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_BASETYPES_H_
diff --git a/gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp b/gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp
deleted file mode 100644
index 018e72cd1..000000000
--- a/gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend
-// may record a variable as aliasing another. Sometimes the alias information gets garbled
-// so we work around this issue by breaking the aliasing chain in inner loops.
-
-#include "BreakVariableAliasingInInnerLoops.h"
-
-#include "compiler/translator/IntermNode.h"
-
-// A HLSL compiler developer gave us more details on the root cause and the workaround needed:
-// The root problem is that if the HLSL compiler is applying aliasing information even on
-// incomplete simulations (in this case, a single pass). The bug is triggered by an assignment
-// that comes from a series of assignments, possibly with swizzled or ternary operators with
-// known conditionals, where the source is before the loop.
-// So, a workaround is to add a +0 term to variables the first time they are assigned to in
-// an inner loop (if they are declared in an outside scope, otherwise there is no need).
-// This will break the aliasing chain.
-
-// For simplicity here we add a +0 to any assignment that is in at least two nested loops. Because
-// the bug only shows up with swizzles, and ternary assignment, whole array or whole structure
-// assignment don't need a workaround.
-
-namespace sh
-{
-
-namespace
-{
-
-class AliasingBreaker : public TIntermTraverser
-{
- public:
- AliasingBreaker() : TIntermTraverser(true, false, true) {}
-
- protected:
- bool visitBinary(Visit visit, TIntermBinary *binary)
- {
- if (visit != PreVisit)
- {
- return false;
- }
-
- if (mLoopLevel < 2 || !binary->isAssignment())
- {
- return true;
- }
-
- TIntermTyped *B = binary->getRight();
- TType type = B->getType();
-
- if (!type.isScalar() && !type.isVector() && !type.isMatrix())
- {
- return true;
- }
-
- if (type.isArray() || IsSampler(type.getBasicType()))
- {
- return true;
- }
-
- // We have a scalar / vector / matrix assignment with loop depth 2.
- // Transform it from
- // A = B
- // to
- // A = (B + typeof<B>(0));
-
- TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, TIntermTyped::CreateZero(type));
- bPlusZero->setLine(B->getLine());
-
- binary->replaceChildNode(B, bPlusZero);
-
- return true;
- }
-
- bool visitLoop(Visit visit, TIntermLoop *loop)
- {
- if (visit == PreVisit)
- {
- mLoopLevel++;
- }
- else
- {
- ASSERT(mLoopLevel > 0);
- mLoopLevel--;
- }
-
- return true;
- }
-
- private:
- int mLoopLevel = 0;
-};
-
-} // anonymous namespace
-
-void BreakVariableAliasingInInnerLoops(TIntermNode *root)
-{
- AliasingBreaker breaker;
- root->traverse(&breaker);
-}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h b/gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h
deleted file mode 100644
index b1d906f91..000000000
--- a/gfx/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend
-// may record a variable as aliasing another. Sometimes the alias information gets garbled
-// so we work around this issue by breaking the aliasing chain in inner loops.
-
-#ifndef COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
-#define COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
-
-class TIntermNode;
-
-namespace sh
-{
-
-void BreakVariableAliasingInInnerLoops(TIntermNode *root);
-
-} // namespace sh
-
-#endif // COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_
diff --git a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
index 152251fde..483fb4467 100755
--- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
+++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
@@ -9,9 +9,6 @@
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/Cache.h"
-namespace sh
-{
-
class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
{
public:
@@ -245,5 +242,3 @@ BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::FunctionId::getCopy
{
return FunctionId(mOp, new TType(*mParam1), new TType(*mParam2), new TType(*mParam3));
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.h b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.h
index db5c202d2..6976edfd5 100755
--- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.h
+++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.h
@@ -10,9 +10,6 @@
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
//
// This class decides which built-in functions need to be replaced with the
// emulated ones.
@@ -85,6 +82,4 @@ class BuiltInFunctionEmulator
std::vector<FunctionId> mFunctions;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
diff --git a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
index 74397fb7f..075a55361 100755
--- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
@@ -11,68 +11,32 @@
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/VersionGLSL.h"
-namespace sh
+void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType)
{
-
-void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
- sh::GLenum shaderType)
-{
- if (shaderType == GL_VERTEX_SHADER)
- {
- const TType *int1 = TCache::getType(EbtInt);
- emu->addEmulatedFunction(EOpAbs, int1, "int webgl_abs_emu(int x) { return x * sign(x); }");
- }
-}
-
-void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
- int targetGLSLVersion)
-{
- // isnan() is supported since GLSL 1.3.
- if (targetGLSLVersion < GLSL_VERSION_130)
- return;
+ // we use macros here instead of function definitions to work around more GLSL
+ // compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are
+ // problematic because if the argument has side-effects they will be repeatedly
+ // evaluated. This is unlikely to show up in real shaders, but is something to
+ // consider.
const TType *float1 = TCache::getType(EbtFloat);
const TType *float2 = TCache::getType(EbtFloat, 2);
const TType *float3 = TCache::getType(EbtFloat, 3);
const TType *float4 = TCache::getType(EbtFloat, 4);
- // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
- emu->addEmulatedFunction(
- EOpIsNan, float1,
- "bool webgl_isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
- emu->addEmulatedFunction(
- EOpIsNan, float2,
- "bvec2 webgl_isnan_emu(vec2 x)\n"
- "{\n"
- " bvec2 isnan;\n"
- " for (int i = 0; i < 2; i++)\n"
- " {\n"
- " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
- " }\n"
- " return isnan;\n"
- "}\n");
- emu->addEmulatedFunction(
- EOpIsNan, float3,
- "bvec3 webgl_isnan_emu(vec3 x)\n"
- "{\n"
- " bvec3 isnan;\n"
- " for (int i = 0; i < 3; i++)\n"
- " {\n"
- " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
- " }\n"
- " return isnan;\n"
- "}\n");
- emu->addEmulatedFunction(
- EOpIsNan, float4,
- "bvec4 webgl_isnan_emu(vec4 x)\n"
- "{\n"
- " bvec4 isnan;\n"
- " for (int i = 0; i < 4; i++)\n"
- " {\n"
- " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
- " }\n"
- " return isnan;\n"
- "}\n");
+ if (shaderType == GL_FRAGMENT_SHADER)
+ {
+ emu->addEmulatedFunction(EOpCos, float1, "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }");
+ emu->addEmulatedFunction(EOpCos, float2, "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }");
+ emu->addEmulatedFunction(EOpCos, float3, "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }");
+ emu->addEmulatedFunction(EOpCos, float4, "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }");
+ }
+ emu->addEmulatedFunction(EOpDistance, float1, float1, "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))");
+ emu->addEmulatedFunction(EOpDot, float1, float1, "#define webgl_dot_emu(x, y) ((x) * (y))");
+ emu->addEmulatedFunction(EOpLength, float1, "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))");
+ emu->addEmulatedFunction(EOpNormalize, float1, "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))");
+ emu->addEmulatedFunction(EOpReflect, float1, float1, "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))");
+ emu->addEmulatedFunction(EOpFaceForward, float1, float1, float1, "#define webgl_faceforward_emu(N, I, Nref) (((Nref) * (I) < 0.0) ? (N) : -(N))");
}
// Emulate built-in functions missing from GLSL 1.30 and higher
@@ -217,9 +181,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
" float scale;\n"
" if(exponent < 0)\n"
" {\n"
- " // The negative unary operator is buggy on OSX.\n"
- " // Work around this by using abs instead.\n"
- " scale = 1.0 / (1 << abs(exponent));\n"
+ " scale = 1.0 / (1 << -exponent);\n"
" }\n"
" else\n"
" {\n"
@@ -251,5 +213,3 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
// clang-format on
}
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
index 09fc85b0d..56242598a 100755
--- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
+++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
@@ -9,27 +9,17 @@
#include "GLSLANG/ShaderLang.h"
-namespace sh
-{
class BuiltInFunctionEmulator;
//
-// This works around bug in Intel Mac drivers.
+// This is only a workaround for OpenGL driver bugs, and isn't needed in general.
//
-void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
- sh::GLenum shaderType);
-
-//
-// This works around isnan() bug in Intel Mac drivers
-//
-void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
- int targetGLSLVersion);
+void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType);
//
// This function is emulating built-in functions missing from GLSL 1.30 and higher.
//
void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType,
int targetGLSLVersion);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
diff --git a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
index c51062e1e..50e15cbc2 100755
--- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
@@ -8,62 +8,6 @@
#include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
#include "compiler/translator/SymbolTable.h"
-#include "compiler/translator/VersionGLSL.h"
-
-namespace sh
-{
-
-void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
- int targetGLSLVersion)
-{
- if (targetGLSLVersion < GLSL_VERSION_130)
- return;
-
- TType *float1 = new TType(EbtFloat);
- TType *float2 = new TType(EbtFloat, 2);
- TType *float3 = new TType(EbtFloat, 3);
- TType *float4 = new TType(EbtFloat, 4);
-
- emu->addEmulatedFunction(EOpIsNan, float1,
- "bool webgl_isnan_emu(float x)\n"
- "{\n"
- " return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n"
- "}\n"
- "\n");
-
- emu->addEmulatedFunction(EOpIsNan, float2,
- "bool2 webgl_isnan_emu(float2 x)\n"
- "{\n"
- " bool2 isnan;\n"
- " for (int i = 0; i < 2; i++)\n"
- " {\n"
- " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
- " }\n"
- " return isnan;\n"
- "}\n");
-
- emu->addEmulatedFunction(EOpIsNan, float3,
- "bool3 webgl_isnan_emu(float3 x)\n"
- "{\n"
- " bool3 isnan;\n"
- " for (int i = 0; i < 3; i++)\n"
- " {\n"
- " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
- " }\n"
- " return isnan;\n"
- "}\n");
-
- emu->addEmulatedFunction(EOpIsNan, float4,
- "bool4 webgl_isnan_emu(float4 x)\n"
- "{\n"
- " bool4 isnan;\n"
- " for (int i = 0; i < 4; i++)\n"
- " {\n"
- " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n"
- " }\n"
- " return isnan;\n"
- "}\n");
-}
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
{
@@ -495,5 +439,3 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
"}\n");
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
index 48da73f58..4c45a93dc 100755
--- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
+++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
@@ -9,19 +9,8 @@
#include "GLSLANG/ShaderLang.h"
-namespace sh
-{
-
class BuiltInFunctionEmulator;
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu);
-//
-// This works around isnan() bug on some Intel drivers.
-//
-void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
- int targetGLSLVersion);
-
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
diff --git a/gfx/angle/src/compiler/translator/Cache.cpp b/gfx/angle/src/compiler/translator/Cache.cpp
index 094e3ff57..57a43700c 100755
--- a/gfx/angle/src/compiler/translator/Cache.cpp
+++ b/gfx/angle/src/compiler/translator/Cache.cpp
@@ -12,9 +12,6 @@
#include "common/debug.h"
#include "compiler/translator/Cache.h"
-namespace sh
-{
-
namespace
{
@@ -47,6 +44,7 @@ TCache::TypeKey::TypeKey(TBasicType basicType,
"TypeKey::value is too small");
const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max();
+ UNUSED_ASSERTION_VARIABLE(MaxEnumValue);
// TODO: change to static_assert() once we deprecate MSVC 2013 support
ASSERT(MaxEnumValue >= EbtLast &&
@@ -100,5 +98,3 @@ const TType *TCache::getType(TBasicType basicType,
return type;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/Cache.h b/gfx/angle/src/compiler/translator/Cache.h
index 9a5607f24..1d2abb77e 100755
--- a/gfx/angle/src/compiler/translator/Cache.h
+++ b/gfx/angle/src/compiler/translator/Cache.h
@@ -16,9 +16,6 @@
#include "compiler/translator/Types.h"
#include "compiler/translator/PoolAlloc.h"
-namespace sh
-{
-
class TCache
{
public:
@@ -90,6 +87,4 @@ class TCache
static TCache *sCache;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_CACHE_H_
diff --git a/gfx/angle/src/compiler/translator/CallDAG.cpp b/gfx/angle/src/compiler/translator/CallDAG.cpp
index 00aa833b8..10f0eb937 100755
--- a/gfx/angle/src/compiler/translator/CallDAG.cpp
+++ b/gfx/angle/src/compiler/translator/CallDAG.cpp
@@ -11,9 +11,6 @@
#include "compiler/translator/CallDAG.h"
#include "compiler/translator/InfoSink.h"
-namespace sh
-{
-
// The CallDAGCreator does all the processing required to create the CallDAG
// structure so that the latter contains only the necessary variables.
class CallDAG::CallDAGCreator : public TIntermTraverser
@@ -47,7 +44,6 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
skipped++;
}
}
-
ASSERT(mFunctions.size() == mCurrentIndex + skipped);
return INITDAG_SUCCESS;
}
@@ -79,8 +75,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
record.callees.push_back(static_cast<int>(callee->index));
}
- (*idToIndex)[data.node->getFunctionSymbolInfo()->getId()] =
- static_cast<int>(data.index);
+ (*idToIndex)[data.node->getFunctionId()] = static_cast<int>(data.index);
}
}
@@ -97,39 +92,13 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
}
std::set<CreatorFunctionData*> callees;
- TIntermFunctionDefinition *node;
+ TIntermAggregate *node;
TString name;
size_t index;
bool indexAssigned;
bool visiting;
};
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
- {
- // Create the record if need be and remember the node.
- if (visit == PreVisit)
- {
- auto it = mFunctions.find(node->getFunctionSymbolInfo()->getName());
-
- if (it == mFunctions.end())
- {
- mCurrentFunction = &mFunctions[node->getFunctionSymbolInfo()->getName()];
- }
- else
- {
- mCurrentFunction = &it->second;
- }
-
- mCurrentFunction->node = node;
- mCurrentFunction->name = node->getFunctionSymbolInfo()->getName();
- }
- else if (visit == PostVisit)
- {
- mCurrentFunction = nullptr;
- }
- return true;
- }
-
// Aggregates the AST node for each function as well as the name of the functions called by it
bool visitAggregate(Visit visit, TIntermAggregate *node) override
{
@@ -139,10 +108,36 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
if (visit == PreVisit)
{
// Function declaration, create an empty record.
- auto &record = mFunctions[node->getFunctionSymbolInfo()->getName()];
- record.name = node->getFunctionSymbolInfo()->getName();
+ auto& record = mFunctions[node->getName()];
+ record.name = node->getName();
}
break;
+ case EOpFunction:
+ {
+ // Function definition, create the record if need be and remember the node.
+ if (visit == PreVisit)
+ {
+ auto it = mFunctions.find(node->getName());
+
+ if (it == mFunctions.end())
+ {
+ mCurrentFunction = &mFunctions[node->getName()];
+ }
+ else
+ {
+ mCurrentFunction = &it->second;
+ }
+
+ mCurrentFunction->node = node;
+ mCurrentFunction->name = node->getName();
+
+ }
+ else if (visit == PostVisit)
+ {
+ mCurrentFunction = nullptr;
+ }
+ break;
+ }
case EOpFunctionCall:
{
// Function call, add the callees
@@ -151,7 +146,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
// Do not handle calls to builtin functions
if (node->isUserDefined())
{
- auto it = mFunctions.find(node->getFunctionSymbolInfo()->getName());
+ auto it = mFunctions.find(node->getName());
ASSERT(it != mFunctions.end());
// We might be in a top-level function call to set a global variable
@@ -170,102 +165,52 @@ class CallDAG::CallDAGCreator : public TIntermTraverser
}
// Recursively assigns indices to a sub DAG
- InitResult assignIndicesInternal(CreatorFunctionData *root)
+ InitResult assignIndicesInternal(CreatorFunctionData *function)
{
- // Iterative implementation of the index assignment algorithm. A recursive version
- // would be prettier but since the CallDAG creation runs before the limiting of the
- // call depth, we might get stack overflows (computation of the call depth uses the
- // CallDAG).
+ ASSERT(function);
- ASSERT(root);
+ if (!function->node)
+ {
+ *mCreationInfo << "Undefined function '" << function->name
+ << ")' used in the following call chain:";
+ return INITDAG_UNDEFINED;
+ }
- if (root->indexAssigned)
+ if (function->indexAssigned)
{
return INITDAG_SUCCESS;
}
- // If we didn't have to detect recursion, functionsToProcess could be a simple queue
- // in which we add the function being processed's callees. However in order to detect
- // recursion we need to know which functions we are currently visiting. For that reason
- // functionsToProcess will look like a concatenation of segments of the form
- // [F visiting = true, subset of F callees with visiting = false] and the following
- // segment (if any) will be start with a callee of F.
- // This way we can remember when we started visiting a function, to put visiting back
- // to false.
- TVector<CreatorFunctionData *> functionsToProcess;
- functionsToProcess.push_back(root);
-
- InitResult result = INITDAG_SUCCESS;
-
- while (!functionsToProcess.empty())
+ if (function->visiting)
{
- CreatorFunctionData *function = functionsToProcess.back();
-
- if (function->visiting)
- {
- function->visiting = false;
- function->index = mCurrentIndex++;
- function->indexAssigned = true;
-
- functionsToProcess.pop_back();
- continue;
- }
-
- if (!function->node)
- {
- *mCreationInfo << "Undefined function '" << function->name
- << ")' used in the following call chain:";
- result = INITDAG_UNDEFINED;
- break;
- }
-
- if (function->indexAssigned)
- {
- functionsToProcess.pop_back();
- continue;
- }
-
- function->visiting = true;
-
- for (auto callee : function->callees)
+ if (mCreationInfo)
{
- functionsToProcess.push_back(callee);
-
- // Check if the callee is already being visited after pushing it so that it appears
- // in the chain printed in the info log.
- if (callee->visiting)
- {
- *mCreationInfo << "Recursive function call in the following call chain:";
- result = INITDAG_RECURSION;
- break;
- }
- }
-
- if (result != INITDAG_SUCCESS)
- {
- break;
+ *mCreationInfo << "Recursive function call in the following call chain:" << function->name;
}
+ return INITDAG_RECURSION;
}
+ function->visiting = true;
- // The call chain is made of the function we were visiting when the error was detected.
- if (result != INITDAG_SUCCESS)
+ for (auto &callee : function->callees)
{
- bool first = true;
- for (auto function : functionsToProcess)
+ InitResult result = assignIndicesInternal(callee);
+ if (result != INITDAG_SUCCESS)
{
- if (function->visiting)
+ // We know that there is an issue with the call chain in the AST,
+ // print the link of the chain we were processing.
+ if (mCreationInfo)
{
- if (!first)
- {
- *mCreationInfo << " -> ";
- }
- *mCreationInfo << function->name << ")";
- first = false;
+ *mCreationInfo << " <- " << function->name << ")";
}
+ return result;
}
}
- return result;
+ function->index = mCurrentIndex++;
+ function->indexAssigned = true;
+
+ function->visiting = false;
+ return INITDAG_SUCCESS;
}
TInfoSinkBase *mCreationInfo;
@@ -287,9 +232,13 @@ CallDAG::~CallDAG()
const size_t CallDAG::InvalidIndex = std::numeric_limits<size_t>::max();
-size_t CallDAG::findIndex(const TFunctionSymbolInfo *functionInfo) const
+size_t CallDAG::findIndex(const TIntermAggregate *function) const
{
- auto it = mFunctionIdToIndex.find(functionInfo->getId());
+ TOperator op = function->getOp();
+ ASSERT(op == EOpPrototype || op == EOpFunction || op == EOpFunctionCall);
+ UNUSED_ASSERTION_VARIABLE(op);
+
+ auto it = mFunctionIdToIndex.find(function->getFunctionId());
if (it == mFunctionIdToIndex.end())
{
@@ -309,7 +258,7 @@ const CallDAG::Record &CallDAG::getRecordFromIndex(size_t index) const
const CallDAG::Record &CallDAG::getRecord(const TIntermAggregate *function) const
{
- size_t index = findIndex(function->getFunctionSymbolInfo());
+ size_t index = findIndex(function);
ASSERT(index != InvalidIndex && index < mRecords.size());
return mRecords[index];
}
@@ -327,8 +276,6 @@ void CallDAG::clear()
CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info)
{
- ASSERT(info);
-
CallDAGCreator creator(info);
// Creates the mapping of functions to callees
@@ -344,5 +291,3 @@ CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info)
creator.fillDataStructures(&mRecords, &mFunctionIdToIndex);
return INITDAG_SUCCESS;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/CallDAG.h b/gfx/angle/src/compiler/translator/CallDAG.h
index 90c056878..06c377db0 100755
--- a/gfx/angle/src/compiler/translator/CallDAG.h
+++ b/gfx/angle/src/compiler/translator/CallDAG.h
@@ -16,8 +16,6 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/VariableInfo.h"
-namespace sh
-{
// The translator needs to analyze the the graph of the function calls
// to run checks and analyses; since in GLSL recursion is not allowed
@@ -43,7 +41,7 @@ class CallDAG : angle::NonCopyable
struct Record
{
std::string name;
- TIntermFunctionDefinition *node;
+ TIntermAggregate *node;
std::vector<int> callees;
};
@@ -59,7 +57,7 @@ class CallDAG : angle::NonCopyable
InitResult init(TIntermNode *root, TInfoSinkBase *info);
// Returns InvalidIndex if the function wasn't found
- size_t findIndex(const TFunctionSymbolInfo *functionInfo) const;
+ size_t findIndex(const TIntermAggregate *function) const;
const Record &getRecordFromIndex(size_t index) const;
const Record &getRecord(const TIntermAggregate *function) const;
@@ -74,6 +72,4 @@ class CallDAG : angle::NonCopyable
class CallDAGCreator;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_CALLDAG_H_
diff --git a/gfx/angle/src/compiler/translator/CodeGen.cpp b/gfx/angle/src/compiler/translator/CodeGen.cpp
index 22f2afc98..f099bccf1 100755
--- a/gfx/angle/src/compiler/translator/CodeGen.cpp
+++ b/gfx/angle/src/compiler/translator/CodeGen.cpp
@@ -6,79 +6,71 @@
#ifdef ANGLE_ENABLE_ESSL
#include "compiler/translator/TranslatorESSL.h"
-#endif // ANGLE_ENABLE_ESSL
+#endif
#ifdef ANGLE_ENABLE_GLSL
#include "compiler/translator/TranslatorGLSL.h"
-#endif // ANGLE_ENABLE_GLSL
+#endif
#ifdef ANGLE_ENABLE_HLSL
#include "compiler/translator/TranslatorHLSL.h"
-#endif // ANGLE_ENABLE_HLSL
-
-namespace sh
-{
+#endif // ANGLE_ENABLE_HLSL
//
// This function must be provided to create the actual
// compile object used by higher level code. It returns
// a subclass of TCompiler.
//
-TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+TCompiler* ConstructCompiler(
+ sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
{
- switch (output)
- {
- case SH_ESSL_OUTPUT:
+ switch (output) {
+ case SH_ESSL_OUTPUT:
#ifdef ANGLE_ENABLE_ESSL
- return new TranslatorESSL(type, spec);
+ return new TranslatorESSL(type, spec);
#else
- // This compiler is not supported in this configuration. Return NULL per the
- // sh::ConstructCompiler API.
- return nullptr;
-#endif // ANGLE_ENABLE_ESSL
-
- case SH_GLSL_130_OUTPUT:
- case SH_GLSL_140_OUTPUT:
- case SH_GLSL_150_CORE_OUTPUT:
- case SH_GLSL_330_CORE_OUTPUT:
- case SH_GLSL_400_CORE_OUTPUT:
- case SH_GLSL_410_CORE_OUTPUT:
- case SH_GLSL_420_CORE_OUTPUT:
- case SH_GLSL_430_CORE_OUTPUT:
- case SH_GLSL_440_CORE_OUTPUT:
- case SH_GLSL_450_CORE_OUTPUT:
- case SH_GLSL_COMPATIBILITY_OUTPUT:
+ // This compiler is not supported in this
+ // configuration. Return NULL per the ShConstructCompiler API.
+ return nullptr;
+#endif // ANGLE_ENABLE_ESSL
+ case SH_GLSL_130_OUTPUT:
+ case SH_GLSL_140_OUTPUT:
+ case SH_GLSL_150_CORE_OUTPUT:
+ case SH_GLSL_330_CORE_OUTPUT:
+ case SH_GLSL_400_CORE_OUTPUT:
+ case SH_GLSL_410_CORE_OUTPUT:
+ case SH_GLSL_420_CORE_OUTPUT:
+ case SH_GLSL_430_CORE_OUTPUT:
+ case SH_GLSL_440_CORE_OUTPUT:
+ case SH_GLSL_450_CORE_OUTPUT:
+ case SH_GLSL_COMPATIBILITY_OUTPUT:
#ifdef ANGLE_ENABLE_GLSL
- return new TranslatorGLSL(type, spec, output);
+ return new TranslatorGLSL(type, spec, output);
#else
- // This compiler is not supported in this configuration. Return NULL per the
- // sh::ConstructCompiler API.
- return nullptr;
-#endif // ANGLE_ENABLE_GLSL
-
- case SH_HLSL_3_0_OUTPUT:
- case SH_HLSL_4_1_OUTPUT:
- case SH_HLSL_4_0_FL9_3_OUTPUT:
+ // This compiler is not supported in this
+ // configuration. Return NULL per the ShConstructCompiler API.
+ return nullptr;
+#endif // ANGLE_ENABLE_GLSL
+ case SH_HLSL_3_0_OUTPUT:
+ case SH_HLSL_4_1_OUTPUT:
+ case SH_HLSL_4_0_FL9_3_OUTPUT:
#ifdef ANGLE_ENABLE_HLSL
- return new TranslatorHLSL(type, spec, output);
+ return new TranslatorHLSL(type, spec, output);
#else
- // This compiler is not supported in this configuration. Return NULL per the
- // sh::ConstructCompiler API.
- return nullptr;
-#endif // ANGLE_ENABLE_HLSL
-
- default:
- // Unknown format. Return NULL per the sh::ConstructCompiler API.
- return nullptr;
+ // This compiler is not supported in this
+ // configuration. Return NULL per the ShConstructCompiler API.
+ return nullptr;
+#endif // ANGLE_ENABLE_HLSL
+ default:
+ // Unknown format. Return NULL per the ShConstructCompiler API.
+ return nullptr;
}
}
//
// Delete the compiler made by ConstructCompiler
//
-void DeleteCompiler(TCompiler *compiler)
+void DeleteCompiler(TCompiler* compiler)
{
- SafeDelete(compiler);
+ delete compiler;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/Common.h b/gfx/angle/src/compiler/translator/Common.h
index 853317891..60223232a 100755
--- a/gfx/angle/src/compiler/translator/Common.h
+++ b/gfx/angle/src/compiler/translator/Common.h
@@ -18,9 +18,6 @@
#include "common/debug.h"
#include "compiler/translator/PoolAlloc.h"
-namespace sh
-{
-
struct TSourceLoc {
int first_file;
int first_line;
@@ -95,6 +92,4 @@ inline TString str(T i)
return buffer;
}
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_COMMON_H_
diff --git a/gfx/angle/src/compiler/translator/Compiler.cpp b/gfx/angle/src/compiler/translator/Compiler.cpp
index e085ed588..0257dd3a7 100755
--- a/gfx/angle/src/compiler/translator/Compiler.cpp
+++ b/gfx/angle/src/compiler/translator/Compiler.cpp
@@ -4,18 +4,11 @@
// found in the LICENSE file.
//
-#include "compiler/translator/Compiler.h"
-
-#include <sstream>
-
-#include "angle_gl.h"
-#include "common/utilities.h"
-#include "compiler/translator/AddAndTrueToLoopCondition.h"
#include "compiler/translator/Cache.h"
+#include "compiler/translator/Compiler.h"
#include "compiler/translator/CallDAG.h"
#include "compiler/translator/DeferGlobalInitializers.h"
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
-#include "compiler/translator/EmulatePrecision.h"
#include "compiler/translator/ForLoopUnroll.h"
#include "compiler/translator/Initialize.h"
#include "compiler/translator/InitializeParseContext.h"
@@ -23,100 +16,41 @@
#include "compiler/translator/ParseContext.h"
#include "compiler/translator/PruneEmptyDeclarations.h"
#include "compiler/translator/RegenerateStructNames.h"
-#include "compiler/translator/RemoveInvariantDeclaration.h"
#include "compiler/translator/RemovePow.h"
+#include "compiler/translator/RenameFunction.h"
#include "compiler/translator/RewriteDoWhile.h"
#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
#include "compiler/translator/UnfoldShortCircuitAST.h"
-#include "compiler/translator/UseInterfaceBlockFields.h"
#include "compiler/translator/ValidateLimitations.h"
#include "compiler/translator/ValidateMaxParameters.h"
#include "compiler/translator/ValidateOutputs.h"
#include "compiler/translator/VariablePacker.h"
+#include "compiler/translator/depgraph/DependencyGraph.h"
+#include "compiler/translator/depgraph/DependencyGraphOutput.h"
+#include "compiler/translator/timing/RestrictFragmentShaderTiming.h"
+#include "compiler/translator/timing/RestrictVertexShaderTiming.h"
#include "third_party/compiler/ArrayBoundsClamper.h"
-
-namespace sh
-{
-
-namespace
-{
-
-#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT)
-void DumpFuzzerCase(char const *const *shaderStrings,
- size_t numStrings,
- uint32_t type,
- uint32_t spec,
- uint32_t output,
- uint64_t options)
-{
- static int fileIndex = 0;
-
- std::ostringstream o;
- o << "corpus/" << fileIndex++ << ".sample";
- std::string s = o.str();
-
- // Must match the input format of the fuzzer
- FILE *f = fopen(s.c_str(), "w");
- fwrite(&type, sizeof(type), 1, f);
- fwrite(&spec, sizeof(spec), 1, f);
- fwrite(&output, sizeof(output), 1, f);
- fwrite(&options, sizeof(options), 1, f);
-
- char zero[128 - 20] = {0};
- fwrite(&zero, 128 - 20, 1, f);
-
- for (size_t i = 0; i < numStrings; i++)
- {
- fwrite(shaderStrings[i], sizeof(char), strlen(shaderStrings[i]), f);
- }
- fwrite(&zero, 1, 1, f);
-
- fclose(f);
-}
-#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT)
-} // anonymous namespace
+#include "angle_gl.h"
+#include "common/utilities.h"
bool IsWebGLBasedSpec(ShShaderSpec spec)
{
- return (spec == SH_WEBGL_SPEC || spec == SH_WEBGL2_SPEC || spec == SH_WEBGL3_SPEC);
+ return (spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC || spec == SH_WEBGL2_SPEC ||
+ spec == SH_WEBGL3_SPEC);
}
bool IsGLSL130OrNewer(ShShaderOutput output)
{
- return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
- output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
- output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT ||
- output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
- output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
-}
-
-bool IsGLSL420OrNewer(ShShaderOutput output)
-{
- return (output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
- output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
-}
-
-bool IsGLSL410OrOlder(ShShaderOutput output)
-{
- return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
- output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
- output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT);
-}
-
-bool RemoveInvariant(sh::GLenum shaderType,
- int shaderVersion,
- ShShaderOutput outputType,
- ShCompileOptions compileOptions)
-{
- if ((compileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT) == 0 &&
- shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType))
- return true;
-
- if ((compileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0 &&
- shaderVersion >= 300 && shaderType == GL_VERTEX_SHADER && IsGLSL410OrOlder(outputType))
- return true;
-
- return false;
+ return (output == SH_GLSL_130_OUTPUT ||
+ output == SH_GLSL_140_OUTPUT ||
+ output == SH_GLSL_150_CORE_OUTPUT ||
+ output == SH_GLSL_330_CORE_OUTPUT ||
+ output == SH_GLSL_400_CORE_OUTPUT ||
+ output == SH_GLSL_410_CORE_OUTPUT ||
+ output == SH_GLSL_420_CORE_OUTPUT ||
+ output == SH_GLSL_430_CORE_OUTPUT ||
+ output == SH_GLSL_440_CORE_OUTPUT ||
+ output == SH_GLSL_450_CORE_OUTPUT);
}
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
@@ -125,10 +59,11 @@ size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
// size undefined. ES3 defines a max size of 1024 characters.
switch (spec)
{
- case SH_WEBGL_SPEC:
- return 256;
- default:
- return 1024;
+ case SH_WEBGL_SPEC:
+ case SH_CSS_SHADERS_SPEC:
+ return 256;
+ default:
+ return 1024;
}
}
@@ -174,18 +109,19 @@ int MapSpecToShaderVersion(ShShaderSpec spec)
{
switch (spec)
{
- case SH_GLES2_SPEC:
- case SH_WEBGL_SPEC:
- return 100;
- case SH_GLES3_SPEC:
- case SH_WEBGL2_SPEC:
- return 300;
- case SH_GLES3_1_SPEC:
- case SH_WEBGL3_SPEC:
- return 310;
- default:
- UNREACHABLE();
- return 0;
+ case SH_GLES2_SPEC:
+ case SH_WEBGL_SPEC:
+ case SH_CSS_SHADERS_SPEC:
+ return 100;
+ case SH_GLES3_SPEC:
+ case SH_WEBGL2_SPEC:
+ return 300;
+ case SH_GLES3_1_SPEC:
+ case SH_WEBGL3_SPEC:
+ return 310;
+ default:
+ UNREACHABLE();
+ return 0;
}
}
@@ -226,7 +162,7 @@ TCompiler::~TCompiler()
{
}
-bool TCompiler::shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const
+bool TCompiler::shouldRunLoopAndIndexingValidation(int compileOptions) const
{
// If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API,
// validate loop and indexing as well (to verify that the shader only uses minimal functionality
@@ -261,16 +197,15 @@ bool TCompiler::Init(const ShBuiltInResources& resources)
return true;
}
-TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[],
- size_t numStrings,
- ShCompileOptions compileOptions)
+TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[],
+ size_t numStrings, int compileOptions)
{
return compileTreeImpl(shaderStrings, numStrings, compileOptions);
}
-TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
- size_t numStrings,
- const ShCompileOptions compileOptions)
+TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
+ size_t numStrings,
+ const int compileOptions)
{
clearResults();
@@ -288,7 +223,8 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
++firstSource;
}
- TParseContext parseContext(symbolTable, extensionBehavior, shaderType, shaderSpec,
+ TIntermediate intermediate(infoSink);
+ TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec,
compileOptions, true, infoSink, getResources());
parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh);
@@ -311,7 +247,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
success = false;
}
- TIntermBlock *root = nullptr;
+ TIntermNode *root = nullptr;
if (success)
{
@@ -322,6 +258,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
root = parseContext.getTreeRoot();
+ root = intermediate.postProcess(root);
// Highp might have been auto-enabled based on shader version
fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
@@ -358,17 +295,11 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
if (success && shouldRunLoopAndIndexingValidation(compileOptions))
success = validateLimitations(root);
- // Fail compilation if precision emulation not supported.
- if (success && getResources().WEBGL_debug_shader_precision &&
- getPragma().debugShaderPrecision)
- {
- if (!EmulatePrecision::SupportedInLanguage(outputType))
- {
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "Precision emulation not supported for this output type.";
- success = false;
- }
- }
+ if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
+ success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0);
+
+ if (success && shaderSpec == SH_CSS_SHADERS_SPEC)
+ rewriteCSSShader(root);
// Unroll for-loop markup needs to happen after validateLimitations pass.
if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
@@ -410,16 +341,10 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
(outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
initializeGLPosition(root);
- if (success && RemoveInvariant(shaderType, shaderVersion, outputType, compileOptions))
- sh::RemoveInvariantDeclaration(root);
-
// This pass might emit short circuits so keep it before the short circuit unfolding
if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS))
RewriteDoWhile(root, getTemporaryIndex());
- if (success && (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION))
- sh::AddAndTrueToLoopCondition(root);
-
if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
{
UnfoldShortCircuitAST unfoldShortCircuit;
@@ -435,10 +360,6 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
if (success && shouldCollectVariables(compileOptions))
{
collectVariables(root);
- if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
- {
- useAllMembersInUnusedStandardAndSharedBlocks(root);
- }
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
{
success = enforcePackingRestrictions();
@@ -456,8 +377,9 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
{
- ScalarizeVecAndMatConstructorArgs(root, shaderType, fragmentPrecisionHigh,
- &mTemporaryIndex);
+ ScalarizeVecAndMatConstructorArgs scalarizer(
+ shaderType, fragmentPrecisionHigh);
+ root->traverse(&scalarizer);
}
if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES))
@@ -486,18 +408,12 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
return NULL;
}
-bool TCompiler::compile(const char *const shaderStrings[],
- size_t numStrings,
- ShCompileOptions compileOptionsIn)
+bool TCompiler::compile(const char *const shaderStrings[], size_t numStrings, int compileOptionsIn)
{
-#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT)
- DumpFuzzerCase(shaderStrings, numStrings, shaderType, shaderSpec, outputType, compileOptionsIn);
-#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT)
-
if (numStrings == 0)
return true;
- ShCompileOptions compileOptions = compileOptionsIn;
+ int compileOptions = compileOptionsIn;
// Apply key workarounds.
if (shouldFlattenPragmaStdglInvariantAll())
@@ -506,19 +422,8 @@ bool TCompiler::compile(const char *const shaderStrings[],
compileOptions |= SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL;
}
- ShCompileOptions unrollFlags =
- SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX | SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
- if ((compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION) != 0 &&
- (compileOptions & unrollFlags) != 0)
- {
- infoSink.info.prefix(EPrefixError);
- infoSink.info
- << "Unsupported compile flag combination: unroll & ADD_TRUE_TO_LOOP_CONDITION";
- return false;
- }
-
TScopedPoolAllocator scopedAlloc(&allocator);
- TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
+ TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
if (root)
{
@@ -547,26 +452,32 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
symbolTable.push(); // ESSL3_1_BUILTINS
TPublicType integer;
- integer.initializeBasicType(EbtInt);
+ integer.type = EbtInt;
+ integer.primarySize = 1;
+ integer.secondarySize = 1;
+ integer.array = false;
TPublicType floatingPoint;
- floatingPoint.initializeBasicType(EbtFloat);
+ floatingPoint.type = EbtFloat;
+ floatingPoint.primarySize = 1;
+ floatingPoint.secondarySize = 1;
+ floatingPoint.array = false;
- switch (shaderType)
+ switch(shaderType)
{
- case GL_FRAGMENT_SHADER:
- symbolTable.setDefaultPrecision(integer, EbpMedium);
- break;
- case GL_VERTEX_SHADER:
- symbolTable.setDefaultPrecision(integer, EbpHigh);
- symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
- break;
- case GL_COMPUTE_SHADER:
- symbolTable.setDefaultPrecision(integer, EbpHigh);
- symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
- break;
- default:
- assert(false && "Language not supported");
+ case GL_FRAGMENT_SHADER:
+ symbolTable.setDefaultPrecision(integer, EbpMedium);
+ break;
+ case GL_VERTEX_SHADER:
+ symbolTable.setDefaultPrecision(integer, EbpHigh);
+ symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
+ break;
+ case GL_COMPUTE_SHADER:
+ symbolTable.setDefaultPrecision(integer, EbpHigh);
+ symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
+ break;
+ default:
+ assert(false && "Language not supported");
}
// Set defaults for sampler types that have default precision, even those that are
// only available if an extension exists.
@@ -589,7 +500,10 @@ void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType)
{
ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
TPublicType sampler;
- sampler.initializeBasicType(samplerType);
+ sampler.primarySize = 1;
+ sampler.secondarySize = 1;
+ sampler.array = false;
+ sampler.type = samplerType;
symbolTable.setDefaultPrecision(sampler, EbpLow);
}
@@ -599,60 +513,60 @@ void TCompiler::setResourceString()
// clang-format off
strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs
- << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
- << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
- << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits
- << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits
- << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits
- << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors
- << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
- << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
- << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
- << ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3
- << ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external
- << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
- << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
- << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
- << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
- << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
- << ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters
- << ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended
- << ":EXT_frag_depth:" << compileResources.EXT_frag_depth
- << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
- << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
- << ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
- << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
- << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
- << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
- << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
- << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
- << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
- << ":NV_draw_buffers:" << compileResources.NV_draw_buffers
- << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision
- << ":MaxImageUnits:" << compileResources.MaxImageUnits
- << ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms
- << ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms
- << ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms
- << ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms
- << ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources
- << ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0]
- << ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1]
- << ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2]
- << ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0]
- << ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1]
- << ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2]
- << ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents
- << ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits
- << ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters
- << ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers
- << ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters
- << ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters
- << ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters
- << ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings
- << ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers
- << ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers
- << ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers
- << ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize;
+ << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
+ << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
+ << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits
+ << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits
+ << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits
+ << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors
+ << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
+ << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
+ << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
+ << ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3
+ << ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external
+ << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
+ << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
+ << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
+ << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
+ << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
+ << ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters
+ << ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended
+ << ":EXT_frag_depth:" << compileResources.EXT_frag_depth
+ << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
+ << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
+ << ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
+ << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
+ << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
+ << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
+ << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
+ << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
+ << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
+ << ":NV_draw_buffers:" << compileResources.NV_draw_buffers
+ << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision
+ << ":MaxImageUnits:" << compileResources.MaxImageUnits
+ << ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms
+ << ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms
+ << ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms
+ << ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms
+ << ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources
+ << ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0]
+ << ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1]
+ << ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2]
+ << ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0]
+ << ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1]
+ << ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2]
+ << ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents
+ << ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits
+ << ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters
+ << ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers
+ << ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters
+ << ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters
+ << ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters
+ << ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings
+ << ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers
+ << ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers
+ << ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers
+ << ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize;
// clang-format on
builtInResourcesString = strstream.str();
@@ -687,16 +601,16 @@ bool TCompiler::initCallDag(TIntermNode *root)
switch (mCallDag.init(root, &infoSink.info))
{
- case CallDAG::INITDAG_SUCCESS:
- return true;
- case CallDAG::INITDAG_RECURSION:
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "Function recursion detected";
- return false;
- case CallDAG::INITDAG_UNDEFINED:
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "Unimplemented function detected";
- return false;
+ case CallDAG::INITDAG_SUCCESS:
+ return true;
+ case CallDAG::INITDAG_RECURSION:
+ infoSink.info.prefix(EPrefixError);
+ infoSink.info << "Function recursion detected";
+ return false;
+ case CallDAG::INITDAG_UNDEFINED:
+ infoSink.info.prefix(EPrefixError);
+ infoSink.info << "Unimplemented function detected";
+ return false;
}
UNREACHABLE();
@@ -790,38 +704,30 @@ class TCompiler::UnusedPredicate
{
public:
UnusedPredicate(const CallDAG *callDag, const std::vector<FunctionMetadata> *metadatas)
- : mCallDag(callDag), mMetadatas(metadatas)
+ : mCallDag(callDag),
+ mMetadatas(metadatas)
{
}
bool operator ()(TIntermNode *node)
{
const TIntermAggregate *asAggregate = node->getAsAggregate();
- const TIntermFunctionDefinition *asFunction = node->getAsFunctionDefinition();
-
- const TFunctionSymbolInfo *functionInfo = nullptr;
- if (asFunction)
+ if (asAggregate == nullptr)
{
- functionInfo = asFunction->getFunctionSymbolInfo();
- }
- else if (asAggregate)
- {
- if (asAggregate->getOp() == EOpPrototype)
- {
- functionInfo = asAggregate->getFunctionSymbolInfo();
- }
+ return false;
}
- if (functionInfo == nullptr)
+
+ if (!(asAggregate->getOp() == EOpFunction || asAggregate->getOp() == EOpPrototype))
{
return false;
}
- size_t callDagIndex = mCallDag->findIndex(functionInfo);
+ size_t callDagIndex = mCallDag->findIndex(asAggregate);
if (callDagIndex == CallDAG::InvalidIndex)
{
// This happens only for unimplemented prototypes which are thus unused
- ASSERT(asAggregate && asAggregate->getOp() == EOpPrototype);
+ ASSERT(asAggregate->getOp() == EOpPrototype);
return true;
}
@@ -834,10 +740,13 @@ class TCompiler::UnusedPredicate
const std::vector<FunctionMetadata> *mMetadatas;
};
-bool TCompiler::pruneUnusedFunctions(TIntermBlock *root)
+bool TCompiler::pruneUnusedFunctions(TIntermNode *root)
{
+ TIntermAggregate *rootNode = root->getAsAggregate();
+ ASSERT(rootNode != nullptr);
+
UnusedPredicate isUnused(&mCallDag, &functionMetadata);
- TIntermSequence *sequence = root->getSequence();
+ TIntermSequence *sequence = rootNode->getSequence();
if (!sequence->empty())
{
@@ -854,6 +763,12 @@ bool TCompiler::validateOutputs(TIntermNode* root)
return (validateOutputs.validateAndCountErrors(infoSink.info) == 0);
}
+void TCompiler::rewriteCSSShader(TIntermNode* root)
+{
+ RenameFunction renamer("main(", "css_main(");
+ root->traverse(&renamer);
+}
+
bool TCompiler::validateLimitations(TIntermNode* root)
{
ValidateLimitations validate(shaderType, &infoSink.info);
@@ -861,9 +776,39 @@ bool TCompiler::validateLimitations(TIntermNode* root)
return validate.numErrors() == 0;
}
+bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
+{
+ if (shaderSpec != SH_WEBGL_SPEC)
+ {
+ infoSink.info << "Timing restrictions must be enforced under the WebGL spec.";
+ return false;
+ }
+
+ if (shaderType == GL_FRAGMENT_SHADER)
+ {
+ TDependencyGraph graph(root);
+
+ // Output any errors first.
+ bool success = enforceFragmentShaderTimingRestrictions(graph);
+
+ // Then, output the dependency graph.
+ if (outputGraph)
+ {
+ TDependencyGraphOutput output(infoSink.info);
+ output.outputAllSpanningTrees(graph);
+ }
+
+ return success;
+ }
+ else
+ {
+ return enforceVertexShaderTimingRestrictions(root);
+ }
+}
+
bool TCompiler::limitExpressionComplexity(TIntermNode* root)
{
- TMaxDepthTraverser traverser(maxExpressionComplexity + 1);
+ TMaxDepthTraverser traverser(maxExpressionComplexity+1);
root->traverse(&traverser);
if (traverser.getMaxDepth() > maxExpressionComplexity)
@@ -881,13 +826,26 @@ bool TCompiler::limitExpressionComplexity(TIntermNode* root)
return true;
}
+bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
+{
+ RestrictFragmentShaderTiming restrictor(infoSink.info);
+ restrictor.enforceRestrictions(graph);
+ return restrictor.numErrors() == 0;
+}
+
+bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
+{
+ RestrictVertexShaderTiming restrictor(infoSink.info);
+ restrictor.enforceRestrictions(root);
+ return restrictor.numErrors() == 0;
+}
+
void TCompiler::collectVariables(TIntermNode* root)
{
if (!variablesCollected)
{
sh::CollectVariables collect(&attributes, &outputVariables, &uniforms, &varyings,
- &interfaceBlocks, hashFunction, symbolTable,
- extensionBehavior);
+ &interfaceBlocks, hashFunction, symbolTable, extensionBehavior);
root->traverse(&collect);
// This is for enforcePackingRestriction().
@@ -896,16 +854,6 @@ void TCompiler::collectVariables(TIntermNode* root)
}
}
-bool TCompiler::shouldCollectVariables(ShCompileOptions compileOptions)
-{
- return (compileOptions & SH_VARIABLES) != 0;
-}
-
-bool TCompiler::wereVariablesCollected() const
-{
- return variablesCollected;
-}
-
bool TCompiler::enforcePackingRestrictions()
{
VariablePacker packer;
@@ -918,23 +866,7 @@ void TCompiler::initializeGLPosition(TIntermNode* root)
sh::ShaderVariable var(GL_FLOAT_VEC4, 0);
var.name = "gl_Position";
list.push_back(var);
- InitializeVariables(root, list, symbolTable);
-}
-
-void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root)
-{
- sh::InterfaceBlockList list;
-
- for (auto block : interfaceBlocks)
- {
- if (!block.staticUse &&
- (block.layout == sh::BLOCKLAYOUT_STANDARD || block.layout == sh::BLOCKLAYOUT_SHARED))
- {
- list.push_back(block);
- }
- }
-
- sh::UseInterfaceBlockFields(root, list, symbolTable);
+ InitializeVariables(root, list);
}
void TCompiler::initializeOutputVariables(TIntermNode *root)
@@ -955,7 +887,7 @@ void TCompiler::initializeOutputVariables(TIntermNode *root)
list.push_back(var);
}
}
- InitializeVariables(root, list, symbolTable);
+ InitializeVariables(root, list);
}
const TExtensionBehavior& TCompiler::getExtensionBehavior() const
@@ -988,7 +920,7 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
return builtInFunctionEmulator;
}
-void TCompiler::writePragma(ShCompileOptions compileOptions)
+void TCompiler::writePragma(int compileOptions)
{
if (!(compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL))
{
@@ -1011,5 +943,3 @@ bool TCompiler::isVaryingDefined(const char *varyingName)
return false;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/Compiler.h b/gfx/angle/src/compiler/translator/Compiler.h
index 42b4f8f06..6b682374b 100755
--- a/gfx/angle/src/compiler/translator/Compiler.h
+++ b/gfx/angle/src/compiler/translator/Compiler.h
@@ -24,16 +24,15 @@
#include "compiler/translator/VariableInfo.h"
#include "third_party/compiler/ArrayBoundsClamper.h"
-namespace sh
-{
-
class TCompiler;
+class TDependencyGraph;
#ifdef ANGLE_ENABLE_HLSL
class TranslatorHLSL;
#endif // ANGLE_ENABLE_HLSL
//
-// Helper function to identify specs that are based on the WebGL spec.
+// Helper function to identify specs that are based on the WebGL spec,
+// like the CSS Shaders spec.
//
bool IsWebGLBasedSpec(ShShaderSpec spec);
@@ -41,16 +40,6 @@ bool IsWebGLBasedSpec(ShShaderSpec spec);
// Helper function to check if the shader type is GLSL.
//
bool IsGLSL130OrNewer(ShShaderOutput output);
-bool IsGLSL420OrNewer(ShShaderOutput output);
-bool IsGLSL410OrOlder(ShShaderOutput output);
-
-//
-// Helper function to check if the invariant qualifier can be removed.
-//
-bool RemoveInvariant(sh::GLenum shaderType,
- int shaderVersion,
- ShShaderOutput outputType,
- ShCompileOptions compileOptions);
//
// The base class used to back handles returned to the driver.
@@ -85,14 +74,12 @@ class TCompiler : public TShHandleBase
// compileTreeForTesting should be used only when tests require access to
// the AST. Users of this function need to manually manage the global pool
- // allocator. Returns nullptr whenever there are compilation errors.
- TIntermBlock *compileTreeForTesting(const char *const shaderStrings[],
- size_t numStrings,
- ShCompileOptions compileOptions);
+ // allocator. Returns NULL whenever there are compilation errors.
+ TIntermNode *compileTreeForTesting(const char* const shaderStrings[],
+ size_t numStrings, int compileOptions);
- bool compile(const char *const shaderStrings[],
- size_t numStrings,
- ShCompileOptions compileOptions);
+ bool compile(const char* const shaderStrings[],
+ size_t numStrings, int compileOptions);
// Get results of the last compilation.
int getShaderVersion() const { return shaderVersion; }
@@ -117,7 +104,7 @@ class TCompiler : public TShHandleBase
ShShaderOutput getOutputType() const { return outputType; }
const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
- bool shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const;
+ bool shouldRunLoopAndIndexingValidation(int compileOptions) const;
// Get the resources set by InitBuiltInSymbolTable
const ShBuiltInResources& getResources() const;
@@ -132,21 +119,20 @@ class TCompiler : public TShHandleBase
bool checkCallDepth();
// Returns true if a program has no conflicting or missing fragment outputs
bool validateOutputs(TIntermNode* root);
+ // Rewrites a shader's intermediate tree according to the CSS Shaders spec.
+ void rewriteCSSShader(TIntermNode* root);
// Returns true if the given shader does not exceed the minimum
// functionality mandated in GLSL 1.0 spec Appendix A.
bool validateLimitations(TIntermNode* root);
+ // Collect info for all attribs, uniforms, varyings.
+ void collectVariables(TIntermNode* root);
// Add emulated functions to the built-in function emulator.
- virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
- ShCompileOptions compileOptions){};
+ virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) {};
// Translate to object code.
- virtual void translate(TIntermNode *root, ShCompileOptions compileOptions) = 0;
+ virtual void translate(TIntermNode *root, int compileOptions) = 0;
// Returns true if, after applying the packing rules in the GLSL 1.017 spec
// Appendix A, section 7, the shader does not use too many uniforms.
bool enforcePackingRestrictions();
- // Insert statements to reference all members in unused uniform blocks with standard and shared
- // layout. This is to work around a Mac driver that treats unused standard/shared
- // uniform blocks as inactive.
- void useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root);
// Insert statements to initialize output variables in the beginning of main().
// This is to avoid undefined behaviors.
void initializeOutputVariables(TIntermNode *root);
@@ -155,13 +141,20 @@ class TCompiler : public TShHandleBase
// while spec says it is allowed.
// This function should only be applied to vertex shaders.
void initializeGLPosition(TIntermNode* root);
+ // Returns true if the shader passes the restrictions that aim to prevent timing attacks.
+ bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph);
+ // Returns true if the shader does not use samplers.
+ bool enforceVertexShaderTimingRestrictions(TIntermNode* root);
+ // Returns true if the shader does not use sampler dependent values to affect control
+ // flow or in operations whose time can depend on the input values.
+ bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph);
// Return true if the maximum expression complexity is below the limit.
bool limitExpressionComplexity(TIntermNode* root);
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
const char *getSourcePath() const;
const TPragma& getPragma() const { return mPragma; }
- void writePragma(ShCompileOptions compileOptions);
+ void writePragma(int compileOptions);
unsigned int *getTemporaryIndex() { return &mTemporaryIndex; }
// Relies on collectVariables having been called.
bool isVaryingDefined(const char *varyingName);
@@ -170,16 +163,20 @@ class TCompiler : public TShHandleBase
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
+ virtual bool shouldCollectVariables(int compileOptions)
+ {
+ return (compileOptions & SH_VARIABLES) != 0;
+ }
+
virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
- virtual bool shouldCollectVariables(ShCompileOptions compileOptions);
- bool wereVariablesCollected() const;
std::vector<sh::Attribute> attributes;
std::vector<sh::OutputVariable> outputVariables;
std::vector<sh::Uniform> uniforms;
std::vector<sh::ShaderVariable> expandedUniforms;
std::vector<sh::Varying> varyings;
std::vector<sh::InterfaceBlock> interfaceBlocks;
+ bool variablesCollected;
private:
// Creates the function call DAG for further analysis, returning false if there is a recursion
@@ -190,18 +187,13 @@ class TCompiler : public TShHandleBase
void initSamplerDefaultPrecision(TBasicType samplerType);
- // Collect info for all attribs, uniforms, varyings.
- void collectVariables(TIntermNode *root);
-
- bool variablesCollected;
-
// Removes unused function declarations and prototypes from the AST
class UnusedPredicate;
- bool pruneUnusedFunctions(TIntermBlock *root);
+ bool pruneUnusedFunctions(TIntermNode *root);
- TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
- size_t numStrings,
- const ShCompileOptions compileOptions);
+ TIntermNode *compileTreeImpl(const char *const shaderStrings[],
+ size_t numStrings,
+ const int compileOptions);
sh::GLenum shaderType;
ShShaderSpec shaderSpec;
@@ -269,6 +261,4 @@ TCompiler* ConstructCompiler(
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
void DeleteCompiler(TCompiler*);
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_COMPILER_H_
diff --git a/gfx/angle/src/compiler/translator/ConstantUnion.cpp b/gfx/angle/src/compiler/translator/ConstantUnion.cpp
deleted file mode 100644
index 66f444b0b..000000000
--- a/gfx/angle/src/compiler/translator/ConstantUnion.cpp
+++ /dev/null
@@ -1,642 +0,0 @@
-//
-// Copyright 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// ConstantUnion: Constant folding helper class.
-
-#include "compiler/translator/ConstantUnion.h"
-
-#include "base/numerics/safe_math.h"
-#include "common/mathutil.h"
-#include "compiler/translator/Diagnostics.h"
-
-namespace sh
-{
-
-namespace
-{
-
-template <typename T>
-T CheckedSum(base::CheckedNumeric<T> lhs,
- base::CheckedNumeric<T> rhs,
- TDiagnostics *diag,
- const TSourceLoc &line)
-{
- ASSERT(lhs.IsValid() && rhs.IsValid());
- auto result = lhs + rhs;
- if (!result.IsValid())
- {
- diag->error(line, "Addition out of range", "*", "");
- return 0;
- }
- return result.ValueOrDefault(0);
-}
-
-template <typename T>
-T CheckedDiff(base::CheckedNumeric<T> lhs,
- base::CheckedNumeric<T> rhs,
- TDiagnostics *diag,
- const TSourceLoc &line)
-{
- ASSERT(lhs.IsValid() && rhs.IsValid());
- auto result = lhs - rhs;
- if (!result.IsValid())
- {
- diag->error(line, "Difference out of range", "*", "");
- return 0;
- }
- return result.ValueOrDefault(0);
-}
-
-template <typename T>
-T CheckedMul(base::CheckedNumeric<T> lhs,
- base::CheckedNumeric<T> rhs,
- TDiagnostics *diag,
- const TSourceLoc &line)
-{
- ASSERT(lhs.IsValid() && rhs.IsValid());
- auto result = lhs * rhs;
- if (!result.IsValid())
- {
- diag->error(line, "Multiplication out of range", "*", "");
- return 0;
- }
- return result.ValueOrDefault(0);
-}
-
-} // anonymous namespace
-
-TConstantUnion::TConstantUnion()
-{
- iConst = 0;
- type = EbtVoid;
-}
-
-bool TConstantUnion::cast(TBasicType newType, const TConstantUnion &constant)
-{
- switch (newType)
- {
- case EbtFloat:
- switch (constant.type)
- {
- case EbtInt:
- setFConst(static_cast<float>(constant.getIConst()));
- break;
- case EbtUInt:
- setFConst(static_cast<float>(constant.getUConst()));
- break;
- case EbtBool:
- setFConst(static_cast<float>(constant.getBConst()));
- break;
- case EbtFloat:
- setFConst(static_cast<float>(constant.getFConst()));
- break;
- default:
- return false;
- }
- break;
- case EbtInt:
- switch (constant.type)
- {
- case EbtInt:
- setIConst(static_cast<int>(constant.getIConst()));
- break;
- case EbtUInt:
- setIConst(static_cast<int>(constant.getUConst()));
- break;
- case EbtBool:
- setIConst(static_cast<int>(constant.getBConst()));
- break;
- case EbtFloat:
- setIConst(static_cast<int>(constant.getFConst()));
- break;
- default:
- return false;
- }
- break;
- case EbtUInt:
- switch (constant.type)
- {
- case EbtInt:
- setUConst(static_cast<unsigned int>(constant.getIConst()));
- break;
- case EbtUInt:
- setUConst(static_cast<unsigned int>(constant.getUConst()));
- break;
- case EbtBool:
- setUConst(static_cast<unsigned int>(constant.getBConst()));
- break;
- case EbtFloat:
- setUConst(static_cast<unsigned int>(constant.getFConst()));
- break;
- default:
- return false;
- }
- break;
- case EbtBool:
- switch (constant.type)
- {
- case EbtInt:
- setBConst(constant.getIConst() != 0);
- break;
- case EbtUInt:
- setBConst(constant.getUConst() != 0);
- break;
- case EbtBool:
- setBConst(constant.getBConst());
- break;
- case EbtFloat:
- setBConst(constant.getFConst() != 0.0f);
- break;
- default:
- return false;
- }
- break;
- case EbtStruct: // Struct fields don't get cast
- switch (constant.type)
- {
- case EbtInt:
- setIConst(constant.getIConst());
- break;
- case EbtUInt:
- setUConst(constant.getUConst());
- break;
- case EbtBool:
- setBConst(constant.getBConst());
- break;
- case EbtFloat:
- setFConst(constant.getFConst());
- break;
- default:
- return false;
- }
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-bool TConstantUnion::operator==(const int i) const
-{
- return i == iConst;
-}
-
-bool TConstantUnion::operator==(const unsigned int u) const
-{
- return u == uConst;
-}
-
-bool TConstantUnion::operator==(const float f) const
-{
- return f == fConst;
-}
-
-bool TConstantUnion::operator==(const bool b) const
-{
- return b == bConst;
-}
-
-bool TConstantUnion::operator==(const TConstantUnion &constant) const
-{
- if (constant.type != type)
- return false;
-
- switch (type)
- {
- case EbtInt:
- return constant.iConst == iConst;
- case EbtUInt:
- return constant.uConst == uConst;
- case EbtFloat:
- return constant.fConst == fConst;
- case EbtBool:
- return constant.bConst == bConst;
- default:
- return false;
- }
-}
-
-bool TConstantUnion::operator!=(const int i) const
-{
- return !operator==(i);
-}
-
-bool TConstantUnion::operator!=(const unsigned int u) const
-{
- return !operator==(u);
-}
-
-bool TConstantUnion::operator!=(const float f) const
-{
- return !operator==(f);
-}
-
-bool TConstantUnion::operator!=(const bool b) const
-{
- return !operator==(b);
-}
-
-bool TConstantUnion::operator!=(const TConstantUnion &constant) const
-{
- return !operator==(constant);
-}
-
-bool TConstantUnion::operator>(const TConstantUnion &constant) const
-{
- ASSERT(type == constant.type);
- switch (type)
- {
- case EbtInt:
- return iConst > constant.iConst;
- case EbtUInt:
- return uConst > constant.uConst;
- case EbtFloat:
- return fConst > constant.fConst;
- default:
- return false; // Invalid operation, handled at semantic analysis
- }
-}
-
-bool TConstantUnion::operator<(const TConstantUnion &constant) const
-{
- ASSERT(type == constant.type);
- switch (type)
- {
- case EbtInt:
- return iConst < constant.iConst;
- case EbtUInt:
- return uConst < constant.uConst;
- case EbtFloat:
- return fConst < constant.fConst;
- default:
- return false; // Invalid operation, handled at semantic analysis
- }
-}
-
-// static
-TConstantUnion TConstantUnion::add(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line)
-{
- TConstantUnion returnValue;
- ASSERT(lhs.type == rhs.type);
- switch (lhs.type)
- {
- case EbtInt:
- returnValue.setIConst(gl::WrappingSum<int>(lhs.iConst, rhs.iConst));
- break;
- case EbtUInt:
- returnValue.setUConst(gl::WrappingSum<unsigned int>(lhs.uConst, rhs.uConst));
- break;
- case EbtFloat:
- returnValue.setFConst(CheckedSum<float>(lhs.fConst, rhs.fConst, diag, line));
- break;
- default:
- UNREACHABLE();
- }
-
- return returnValue;
-}
-
-// static
-TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line)
-{
- TConstantUnion returnValue;
- ASSERT(lhs.type == rhs.type);
- switch (lhs.type)
- {
- case EbtInt:
- returnValue.setIConst(gl::WrappingDiff<int>(lhs.iConst, rhs.iConst));
- break;
- case EbtUInt:
- returnValue.setUConst(gl::WrappingDiff<unsigned int>(lhs.uConst, rhs.uConst));
- break;
- case EbtFloat:
- returnValue.setFConst(CheckedDiff<float>(lhs.fConst, rhs.fConst, diag, line));
- break;
- default:
- UNREACHABLE();
- }
-
- return returnValue;
-}
-
-// static
-TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line)
-{
- TConstantUnion returnValue;
- ASSERT(lhs.type == rhs.type);
- switch (lhs.type)
- {
- case EbtInt:
- returnValue.setIConst(gl::WrappingMul(lhs.iConst, rhs.iConst));
- break;
- case EbtUInt:
- // Unsigned integer math in C++ is defined to be done in modulo 2^n, so we rely on that
- // to implement wrapping multiplication.
- returnValue.setUConst(lhs.uConst * rhs.uConst);
- break;
- case EbtFloat:
- returnValue.setFConst(CheckedMul<float>(lhs.fConst, rhs.fConst, diag, line));
- break;
- default:
- UNREACHABLE();
- }
-
- return returnValue;
-}
-
-TConstantUnion TConstantUnion::operator%(const TConstantUnion &constant) const
-{
- TConstantUnion returnValue;
- ASSERT(type == constant.type);
- switch (type)
- {
- case EbtInt:
- returnValue.setIConst(iConst % constant.iConst);
- break;
- case EbtUInt:
- returnValue.setUConst(uConst % constant.uConst);
- break;
- default:
- UNREACHABLE();
- }
-
- return returnValue;
-}
-
-// static
-TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line)
-{
- TConstantUnion returnValue;
- ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
- ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
- if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
- (rhs.type == EbtUInt && rhs.uConst > 31u))
- {
- diag->error(line, "Undefined shift (operand out of range)", ">>", "");
- switch (lhs.type)
- {
- case EbtInt:
- returnValue.setIConst(0);
- break;
- case EbtUInt:
- returnValue.setUConst(0u);
- break;
- default:
- UNREACHABLE();
- }
- return returnValue;
- }
-
- switch (lhs.type)
- {
- case EbtInt:
- {
- unsigned int shiftOffset = 0;
- switch (rhs.type)
- {
- case EbtInt:
- shiftOffset = static_cast<unsigned int>(rhs.iConst);
- break;
- case EbtUInt:
- shiftOffset = rhs.uConst;
- break;
- default:
- UNREACHABLE();
- }
- if (shiftOffset > 0)
- {
- // ESSL 3.00.6 section 5.9: "If E1 is a signed integer, the right-shift will extend
- // the sign bit." In C++ shifting negative integers is undefined, so we implement
- // extending the sign bit manually.
- int lhsSafe = lhs.iConst;
- if (lhsSafe == std::numeric_limits<int>::min())
- {
- // The min integer needs special treatment because only bit it has set is the
- // sign bit, which we clear later to implement safe right shift of negative
- // numbers.
- lhsSafe = -0x40000000;
- --shiftOffset;
- }
- if (shiftOffset > 0)
- {
- bool extendSignBit = false;
- if (lhsSafe < 0)
- {
- extendSignBit = true;
- // Clear the sign bit so that bitshift right is defined in C++.
- lhsSafe &= 0x7fffffff;
- ASSERT(lhsSafe > 0);
- }
- returnValue.setIConst(lhsSafe >> shiftOffset);
-
- // Manually fill in the extended sign bit if necessary.
- if (extendSignBit)
- {
- int extendedSignBit = static_cast<int>(0xffffffffu << (31 - shiftOffset));
- returnValue.setIConst(returnValue.getIConst() | extendedSignBit);
- }
- }
- else
- {
- returnValue.setIConst(lhsSafe);
- }
- }
- else
- {
- returnValue.setIConst(lhs.iConst);
- }
- break;
- }
- case EbtUInt:
- switch (rhs.type)
- {
- case EbtInt:
- returnValue.setUConst(lhs.uConst >> rhs.iConst);
- break;
- case EbtUInt:
- returnValue.setUConst(lhs.uConst >> rhs.uConst);
- break;
- default:
- UNREACHABLE();
- }
- break;
-
- default:
- UNREACHABLE();
- }
- return returnValue;
-}
-
-// static
-TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line)
-{
- TConstantUnion returnValue;
- ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
- ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
- if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
- (rhs.type == EbtUInt && rhs.uConst > 31u))
- {
- diag->error(line, "Undefined shift (operand out of range)", "<<", "");
- switch (lhs.type)
- {
- case EbtInt:
- returnValue.setIConst(0);
- break;
- case EbtUInt:
- returnValue.setUConst(0u);
- break;
- default:
- UNREACHABLE();
- }
- return returnValue;
- }
-
- switch (lhs.type)
- {
- case EbtInt:
- switch (rhs.type)
- {
- // Cast to unsigned integer before shifting, since ESSL 3.00.6 section 5.9 says that
- // lhs is "interpreted as a bit pattern". This also avoids the possibility of signed
- // integer overflow or undefined shift of a negative integer.
- case EbtInt:
- returnValue.setIConst(
- static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.iConst));
- break;
- case EbtUInt:
- returnValue.setIConst(
- static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.uConst));
- break;
- default:
- UNREACHABLE();
- }
- break;
-
- case EbtUInt:
- switch (rhs.type)
- {
- case EbtInt:
- returnValue.setUConst(lhs.uConst << rhs.iConst);
- break;
- case EbtUInt:
- returnValue.setUConst(lhs.uConst << rhs.uConst);
- break;
- default:
- UNREACHABLE();
- }
- break;
-
- default:
- UNREACHABLE();
- }
- return returnValue;
-}
-
-TConstantUnion TConstantUnion::operator&(const TConstantUnion &constant) const
-{
- TConstantUnion returnValue;
- ASSERT(constant.type == EbtInt || constant.type == EbtUInt);
- switch (type)
- {
- case EbtInt:
- returnValue.setIConst(iConst & constant.iConst);
- break;
- case EbtUInt:
- returnValue.setUConst(uConst & constant.uConst);
- break;
- default:
- UNREACHABLE();
- }
-
- return returnValue;
-}
-
-TConstantUnion TConstantUnion::operator|(const TConstantUnion &constant) const
-{
- TConstantUnion returnValue;
- ASSERT(type == constant.type);
- switch (type)
- {
- case EbtInt:
- returnValue.setIConst(iConst | constant.iConst);
- break;
- case EbtUInt:
- returnValue.setUConst(uConst | constant.uConst);
- break;
- default:
- UNREACHABLE();
- }
-
- return returnValue;
-}
-
-TConstantUnion TConstantUnion::operator^(const TConstantUnion &constant) const
-{
- TConstantUnion returnValue;
- ASSERT(type == constant.type);
- switch (type)
- {
- case EbtInt:
- returnValue.setIConst(iConst ^ constant.iConst);
- break;
- case EbtUInt:
- returnValue.setUConst(uConst ^ constant.uConst);
- break;
- default:
- UNREACHABLE();
- }
-
- return returnValue;
-}
-
-TConstantUnion TConstantUnion::operator&&(const TConstantUnion &constant) const
-{
- TConstantUnion returnValue;
- ASSERT(type == constant.type);
- switch (type)
- {
- case EbtBool:
- returnValue.setBConst(bConst && constant.bConst);
- break;
- default:
- UNREACHABLE();
- }
-
- return returnValue;
-}
-
-TConstantUnion TConstantUnion::operator||(const TConstantUnion &constant) const
-{
- TConstantUnion returnValue;
- ASSERT(type == constant.type);
- switch (type)
- {
- case EbtBool:
- returnValue.setBConst(bConst || constant.bConst);
- break;
- default:
- UNREACHABLE();
- }
-
- return returnValue;
-}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ConstantUnion.h b/gfx/angle/src/compiler/translator/ConstantUnion.h
index f6222ce5a..a86d27f3f 100755
--- a/gfx/angle/src/compiler/translator/ConstantUnion.h
+++ b/gfx/angle/src/compiler/translator/ConstantUnion.h
@@ -9,21 +9,77 @@
#include <assert.h>
-#include "compiler/translator/Common.h"
#include "compiler/translator/BaseTypes.h"
-namespace sh
-{
-
-class TDiagnostics;
-
-class TConstantUnion
-{
- public:
+class TConstantUnion {
+public:
POOL_ALLOCATOR_NEW_DELETE();
- TConstantUnion();
+ TConstantUnion()
+ {
+ iConst = 0;
+ type = EbtVoid;
+ }
+
+ bool cast(TBasicType newType, const TConstantUnion &constant)
+ {
+ switch (newType)
+ {
+ case EbtFloat:
+ switch (constant.type)
+ {
+ case EbtInt: setFConst(static_cast<float>(constant.getIConst())); break;
+ case EbtUInt: setFConst(static_cast<float>(constant.getUConst())); break;
+ case EbtBool: setFConst(static_cast<float>(constant.getBConst())); break;
+ case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break;
+ default: return false;
+ }
+ break;
+ case EbtInt:
+ switch (constant.type)
+ {
+ case EbtInt: setIConst(static_cast<int>(constant.getIConst())); break;
+ case EbtUInt: setIConst(static_cast<int>(constant.getUConst())); break;
+ case EbtBool: setIConst(static_cast<int>(constant.getBConst())); break;
+ case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break;
+ default: return false;
+ }
+ break;
+ case EbtUInt:
+ switch (constant.type)
+ {
+ case EbtInt: setUConst(static_cast<unsigned int>(constant.getIConst())); break;
+ case EbtUInt: setUConst(static_cast<unsigned int>(constant.getUConst())); break;
+ case EbtBool: setUConst(static_cast<unsigned int>(constant.getBConst())); break;
+ case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break;
+ default: return false;
+ }
+ break;
+ case EbtBool:
+ switch (constant.type)
+ {
+ case EbtInt: setBConst(constant.getIConst() != 0); break;
+ case EbtUInt: setBConst(constant.getUConst() != 0); break;
+ case EbtBool: setBConst(constant.getBConst()); break;
+ case EbtFloat: setBConst(constant.getFConst() != 0.0f); break;
+ default: return false;
+ }
+ break;
+ case EbtStruct: // Struct fields don't get cast
+ switch (constant.type)
+ {
+ case EbtInt: setIConst(constant.getIConst()); break;
+ case EbtUInt: setUConst(constant.getUConst()); break;
+ case EbtBool: setBConst(constant.getBConst()); break;
+ case EbtFloat: setFConst(constant.getFConst()); break;
+ default: return false;
+ }
+ break;
+ default:
+ return false;
+ }
- bool cast(TBasicType newType, const TConstantUnion &constant);
+ return true;
+ }
void setIConst(int i) {iConst = i; type = EbtInt; }
void setUConst(unsigned int u) { uConst = u; type = EbtUInt; }
@@ -35,57 +91,258 @@ class TConstantUnion
float getFConst() const { return fConst; }
bool getBConst() const { return bConst; }
- bool operator==(const int i) const;
- bool operator==(const unsigned int u) const;
- bool operator==(const float f) const;
- bool operator==(const bool b) const;
- bool operator==(const TConstantUnion &constant) const;
- bool operator!=(const int i) const;
- bool operator!=(const unsigned int u) const;
- bool operator!=(const float f) const;
- bool operator!=(const bool b) const;
- bool operator!=(const TConstantUnion &constant) const;
- bool operator>(const TConstantUnion &constant) const;
- bool operator<(const TConstantUnion &constant) const;
- static TConstantUnion add(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line);
- static TConstantUnion sub(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line);
- static TConstantUnion mul(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line);
- TConstantUnion operator%(const TConstantUnion &constant) const;
- static TConstantUnion rshift(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line);
- static TConstantUnion lshift(const TConstantUnion &lhs,
- const TConstantUnion &rhs,
- TDiagnostics *diag,
- const TSourceLoc &line);
- TConstantUnion operator&(const TConstantUnion &constant) const;
- TConstantUnion operator|(const TConstantUnion &constant) const;
- TConstantUnion operator^(const TConstantUnion &constant) const;
- TConstantUnion operator&&(const TConstantUnion &constant) const;
- TConstantUnion operator||(const TConstantUnion &constant) const;
+ bool operator==(const int i) const
+ {
+ return i == iConst;
+ }
+
+ bool operator==(const unsigned int u) const
+ {
+ return u == uConst;
+ }
+
+ bool operator==(const float f) const
+ {
+ return f == fConst;
+ }
+
+ bool operator==(const bool b) const
+ {
+ return b == bConst;
+ }
+
+ bool operator==(const TConstantUnion& constant) const
+ {
+ if (constant.type != type)
+ return false;
+
+ switch (type) {
+ case EbtInt:
+ return constant.iConst == iConst;
+ case EbtUInt:
+ return constant.uConst == uConst;
+ case EbtFloat:
+ return constant.fConst == fConst;
+ case EbtBool:
+ return constant.bConst == bConst;
+ default:
+ return false;
+ }
+ }
+
+ bool operator!=(const int i) const
+ {
+ return !operator==(i);
+ }
+
+ bool operator!=(const unsigned int u) const
+ {
+ return !operator==(u);
+ }
+
+ bool operator!=(const float f) const
+ {
+ return !operator==(f);
+ }
+
+ bool operator!=(const bool b) const
+ {
+ return !operator==(b);
+ }
+
+ bool operator!=(const TConstantUnion& constant) const
+ {
+ return !operator==(constant);
+ }
+
+ bool operator>(const TConstantUnion& constant) const
+ {
+ assert(type == constant.type);
+ switch (type) {
+ case EbtInt:
+ return iConst > constant.iConst;
+ case EbtUInt:
+ return uConst > constant.uConst;
+ case EbtFloat:
+ return fConst > constant.fConst;
+ default:
+ return false; // Invalid operation, handled at semantic analysis
+ }
+ }
+
+ bool operator<(const TConstantUnion& constant) const
+ {
+ assert(type == constant.type);
+ switch (type) {
+ case EbtInt:
+ return iConst < constant.iConst;
+ case EbtUInt:
+ return uConst < constant.uConst;
+ case EbtFloat:
+ return fConst < constant.fConst;
+ default:
+ return false; // Invalid operation, handled at semantic analysis
+ }
+ }
+
+ TConstantUnion operator+(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(type == constant.type);
+ switch (type) {
+ case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
+ case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break;
+ case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator-(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(type == constant.type);
+ switch (type) {
+ case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
+ case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break;
+ case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator*(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(type == constant.type);
+ switch (type) {
+ case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
+ case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break;
+ case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator%(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(type == constant.type);
+ switch (type) {
+ case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
+ case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator>>(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(type == constant.type);
+ switch (type) {
+ case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
+ case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator<<(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ // The signedness of the second parameter might be different, but we
+ // don't care, since the result is undefined if the second parameter is
+ // negative, and aliasing should not be a problem with unions.
+ assert(constant.type == EbtInt || constant.type == EbtUInt);
+ switch (type) {
+ case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
+ case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator&(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(constant.type == EbtInt || constant.type == EbtUInt);
+ switch (type) {
+ case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
+ case EbtUInt: returnValue.setUConst(uConst & constant.uConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator|(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(type == constant.type);
+ switch (type) {
+ case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
+ case EbtUInt: returnValue.setUConst(uConst | constant.uConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator^(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(type == constant.type);
+ switch (type) {
+ case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
+ case EbtUInt: returnValue.setUConst(uConst ^ constant.uConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator&&(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(type == constant.type);
+ switch (type) {
+ case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
+
+ TConstantUnion operator||(const TConstantUnion& constant) const
+ {
+ TConstantUnion returnValue;
+ assert(type == constant.type);
+ switch (type) {
+ case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
+ default: assert(false && "Default missing");
+ }
+
+ return returnValue;
+ }
TBasicType getType() const { return type; }
- private:
- union {
- int iConst; // used for ivec, scalar ints
- unsigned int uConst; // used for uvec, scalar uints
- bool bConst; // used for bvec, scalar bools
- float fConst; // used for vec, mat, scalar floats
- };
+private:
+
+ union {
+ int iConst; // used for ivec, scalar ints
+ unsigned int uConst; // used for uvec, scalar uints
+ bool bConst; // used for bvec, scalar bools
+ float fConst; // used for vec, mat, scalar floats
+ } ;
TBasicType type;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_
diff --git a/gfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp b/gfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp
index 1c58562fc..76addf293 100755
--- a/gfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp
+++ b/gfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -15,43 +15,42 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
-namespace sh
-{
-
namespace
{
-void SetInternalFunctionName(TFunctionSymbolInfo *functionInfo, const char *name)
+void SetInternalFunctionName(TIntermAggregate *functionNode, const char *name)
{
TString nameStr(name);
nameStr = TFunction::mangleName(nameStr);
TName nameObj(nameStr);
nameObj.setInternal(true);
- functionInfo->setNameObj(nameObj);
+ functionNode->setNameObj(nameObj);
}
TIntermAggregate *CreateFunctionPrototypeNode(const char *name, const int functionId)
{
TIntermAggregate *functionNode = new TIntermAggregate(EOpPrototype);
- SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
+ SetInternalFunctionName(functionNode, name);
TType returnType(EbtVoid);
functionNode->setType(returnType);
- functionNode->getFunctionSymbolInfo()->setId(functionId);
+ functionNode->setFunctionId(functionId);
return functionNode;
}
-TIntermFunctionDefinition *CreateFunctionDefinitionNode(const char *name,
- TIntermBlock *functionBody,
- const int functionId)
+TIntermAggregate *CreateFunctionDefinitionNode(const char *name,
+ TIntermAggregate *functionBody,
+ const int functionId)
{
- TType returnType(EbtVoid);
+ TIntermAggregate *functionNode = new TIntermAggregate(EOpFunction);
TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters);
- TIntermFunctionDefinition *functionNode =
- new TIntermFunctionDefinition(returnType, paramsNode, functionBody);
+ functionNode->getSequence()->push_back(paramsNode);
+ functionNode->getSequence()->push_back(functionBody);
- SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
- functionNode->getFunctionSymbolInfo()->setId(functionId);
+ SetInternalFunctionName(functionNode, name);
+ TType returnType(EbtVoid);
+ functionNode->setType(returnType);
+ functionNode->setFunctionId(functionId);
return functionNode;
}
@@ -60,10 +59,10 @@ TIntermAggregate *CreateFunctionCallNode(const char *name, const int functionId)
TIntermAggregate *functionNode = new TIntermAggregate(EOpFunctionCall);
functionNode->setUserDefined();
- SetInternalFunctionName(functionNode->getFunctionSymbolInfo(), name);
+ SetInternalFunctionName(functionNode, name);
TType returnType(EbtVoid);
functionNode->setType(returnType);
- functionNode->getFunctionSymbolInfo()->setId(functionId);
+ functionNode->setFunctionId(functionId);
return functionNode;
}
@@ -74,7 +73,7 @@ class DeferGlobalInitializersTraverser : public TIntermTraverser
bool visitBinary(Visit visit, TIntermBinary *node) override;
- void insertInitFunction(TIntermBlock *root);
+ void insertInitFunction(TIntermNode *root);
private:
TIntermSequence mDeferredInitializers;
@@ -102,8 +101,10 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n
// Deferral is done also in any cases where the variable has not been constant folded,
// since otherwise there's a chance that HLSL output will generate extra statements
// from the initializer expression.
- TIntermBinary *deferredInit =
- new TIntermBinary(EOpAssign, symbolNode->deepCopy(), node->getRight());
+ TIntermBinary *deferredInit = new TIntermBinary(EOpAssign);
+ deferredInit->setLeft(symbolNode->deepCopy());
+ deferredInit->setRight(node->getRight());
+ deferredInit->setType(node->getType());
mDeferredInitializers.push_back(deferredInit);
// Change const global to a regular global if its initialization is deferred.
@@ -114,7 +115,7 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n
if (symbolNode->getQualifier() == EvqConst)
{
// All of the siblings in the same declaration need to have consistent qualifiers.
- auto *siblings = getParentNode()->getAsDeclarationNode()->getSequence();
+ auto *siblings = getParentNode()->getAsAggregate()->getSequence();
for (TIntermNode *siblingNode : *siblings)
{
TIntermBinary *siblingBinary = siblingNode->getAsBinaryNode();
@@ -135,51 +136,56 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n
return false;
}
-void DeferGlobalInitializersTraverser::insertInitFunction(TIntermBlock *root)
+void DeferGlobalInitializersTraverser::insertInitFunction(TIntermNode *root)
{
if (mDeferredInitializers.empty())
{
return;
}
const int initFunctionId = TSymbolTable::nextUniqueId();
+ TIntermAggregate *rootAgg = root->getAsAggregate();
+ ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence);
const char *functionName = "initializeDeferredGlobals";
// Add function prototype to the beginning of the shader
TIntermAggregate *functionPrototypeNode =
CreateFunctionPrototypeNode(functionName, initFunctionId);
- root->getSequence()->insert(root->getSequence()->begin(), functionPrototypeNode);
+ rootAgg->getSequence()->insert(rootAgg->getSequence()->begin(), functionPrototypeNode);
// Add function definition to the end of the shader
- TIntermBlock *functionBodyNode = new TIntermBlock();
+ TIntermAggregate *functionBodyNode = new TIntermAggregate(EOpSequence);
TIntermSequence *functionBody = functionBodyNode->getSequence();
for (const auto &deferredInit : mDeferredInitializers)
{
functionBody->push_back(deferredInit);
}
- TIntermFunctionDefinition *functionDefinition =
+ TIntermAggregate *functionDefinition =
CreateFunctionDefinitionNode(functionName, functionBodyNode, initFunctionId);
- root->getSequence()->push_back(functionDefinition);
+ rootAgg->getSequence()->push_back(functionDefinition);
// Insert call into main function
- for (TIntermNode *node : *root->getSequence())
+ for (TIntermNode *node : *rootAgg->getSequence())
{
- TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
- if (nodeFunction != nullptr && nodeFunction->getFunctionSymbolInfo()->isMain())
+ TIntermAggregate *nodeAgg = node->getAsAggregate();
+ if (nodeAgg != nullptr && nodeAgg->getOp() == EOpFunction &&
+ TFunction::unmangleName(nodeAgg->getName()) == "main")
{
TIntermAggregate *functionCallNode =
CreateFunctionCallNode(functionName, initFunctionId);
- TIntermBlock *mainBody = nodeFunction->getBody();
- ASSERT(mainBody != nullptr);
- mainBody->getSequence()->insert(mainBody->getSequence()->begin(), functionCallNode);
+ TIntermNode *mainBody = nodeAgg->getSequence()->back();
+ TIntermAggregate *mainBodyAgg = mainBody->getAsAggregate();
+ ASSERT(mainBodyAgg != nullptr && mainBodyAgg->getOp() == EOpSequence);
+ mainBodyAgg->getSequence()->insert(mainBodyAgg->getSequence()->begin(),
+ functionCallNode);
}
}
}
} // namespace
-void DeferGlobalInitializers(TIntermBlock *root)
+void DeferGlobalInitializers(TIntermNode *root)
{
DeferGlobalInitializersTraverser traverser;
root->traverse(&traverser);
@@ -190,5 +196,3 @@ void DeferGlobalInitializers(TIntermBlock *root)
// Add the function with initialization and the call to that.
traverser.insertInitFunction(root);
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/DeferGlobalInitializers.h b/gfx/angle/src/compiler/translator/DeferGlobalInitializers.h
index 261ec9001..14f25539c 100755
--- a/gfx/angle/src/compiler/translator/DeferGlobalInitializers.h
+++ b/gfx/angle/src/compiler/translator/DeferGlobalInitializers.h
@@ -13,11 +13,8 @@
#ifndef COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
-class TIntermBlock;
+class TIntermNode;
-namespace sh
-{
-void DeferGlobalInitializers(TIntermBlock *root);
-} // namespace sh
+void DeferGlobalInitializers(TIntermNode *root);
#endif // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
diff --git a/gfx/angle/src/compiler/translator/Diagnostics.cpp b/gfx/angle/src/compiler/translator/Diagnostics.cpp
index 3b4168617..6ba4679c4 100755
--- a/gfx/angle/src/compiler/translator/Diagnostics.cpp
+++ b/gfx/angle/src/compiler/translator/Diagnostics.cpp
@@ -11,9 +11,6 @@
#include "compiler/translator/Common.h"
#include "compiler/translator/InfoSink.h"
-namespace sh
-{
-
TDiagnostics::TDiagnostics(TInfoSink& infoSink) :
mInfoSink(infoSink),
mNumErrors(0),
@@ -82,5 +79,3 @@ void TDiagnostics::print(ID id,
{
writeInfo(severity(id), loc, message(id), text, "");
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/Diagnostics.h b/gfx/angle/src/compiler/translator/Diagnostics.h
index 25a8a3a57..bb521da1a 100755
--- a/gfx/angle/src/compiler/translator/Diagnostics.h
+++ b/gfx/angle/src/compiler/translator/Diagnostics.h
@@ -10,9 +10,6 @@
#include "common/angleutils.h"
#include "compiler/preprocessor/DiagnosticsBase.h"
-namespace sh
-{
-
class TInfoSink;
struct TSourceLoc;
@@ -48,6 +45,4 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable
int mNumWarnings;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
diff --git a/gfx/angle/src/compiler/translator/DirectiveHandler.cpp b/gfx/angle/src/compiler/translator/DirectiveHandler.cpp
index 073994d3c..f8081ecd6 100755
--- a/gfx/angle/src/compiler/translator/DirectiveHandler.cpp
+++ b/gfx/angle/src/compiler/translator/DirectiveHandler.cpp
@@ -12,9 +12,6 @@
#include "common/debug.h"
#include "compiler/translator/Diagnostics.h"
-namespace sh
-{
-
static TBehavior getBehavior(const std::string& str)
{
const char kRequire[] = "require";
@@ -198,5 +195,3 @@ void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
"version number", str, "not supported");
}
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/DirectiveHandler.h b/gfx/angle/src/compiler/translator/DirectiveHandler.h
index a50b08219..00eb49114 100755
--- a/gfx/angle/src/compiler/translator/DirectiveHandler.h
+++ b/gfx/angle/src/compiler/translator/DirectiveHandler.h
@@ -13,8 +13,6 @@
#include "compiler/preprocessor/DirectiveHandlerBase.h"
#include "GLSLANG/ShaderLang.h"
-namespace sh
-{
class TDiagnostics;
class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
@@ -52,6 +50,4 @@ class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
bool mDebugShaderPrecisionSupported;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
diff --git a/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp b/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
index a4eeb9b7e..a664d9e2f 100755
--- a/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
+++ b/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
@@ -14,60 +14,59 @@
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
#include "compiler/translator/IntermNode.h"
-namespace sh
+namespace
{
-namespace
+TIntermConstantUnion *constructIndexNode(int index)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setIConst(index);
+
+ TType type(EbtInt, EbpUndefined, EvqConst, 1);
+ TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+ return node;
+}
+
+TIntermBinary *constructGLFragDataNode(int index)
{
+ TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
+ TIntermSymbol *symbol = new TIntermSymbol(0, "gl_FragData", TType(EbtFloat, 4));
+ indexDirect->setLeft(symbol);
+ TIntermConstantUnion *indexNode = constructIndexNode(index);
+ indexDirect->setRight(indexNode);
+ return indexDirect;
+}
+
+TIntermBinary *constructGLFragDataAssignNode(int index)
+{
+ TIntermBinary *assign = new TIntermBinary(EOpAssign);
+ assign->setLeft(constructGLFragDataNode(index));
+ assign->setRight(constructGLFragDataNode(0));
+ assign->setType(TType(EbtFloat, 4));
+ return assign;
+}
class GLFragColorBroadcastTraverser : public TIntermTraverser
{
public:
- GLFragColorBroadcastTraverser(int maxDrawBuffers)
- : TIntermTraverser(true, false, false),
- mMainSequence(nullptr),
- mGLFragColorUsed(false),
- mMaxDrawBuffers(maxDrawBuffers)
+ GLFragColorBroadcastTraverser()
+ : TIntermTraverser(true, false, false), mMainSequence(nullptr), mGLFragColorUsed(false)
{
}
- void broadcastGLFragColor();
+ void broadcastGLFragColor(int maxDrawBuffers);
bool isGLFragColorUsed() const { return mGLFragColorUsed; }
protected:
void visitSymbol(TIntermSymbol *node) override;
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
-
- TIntermBinary *constructGLFragDataNode(int index) const;
- TIntermBinary *constructGLFragDataAssignNode(int index) const;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
private:
TIntermSequence *mMainSequence;
bool mGLFragColorUsed;
- int mMaxDrawBuffers;
};
-TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const
-{
- TType gl_FragDataType = TType(EbtFloat, EbpMedium, EvqFragData, 4);
- gl_FragDataType.setArraySize(mMaxDrawBuffers);
-
- TIntermSymbol *symbol = new TIntermSymbol(0, "gl_FragData", gl_FragDataType);
- TIntermTyped *indexNode = TIntermTyped::CreateIndexNode(index);
-
- TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode);
- return binary;
-}
-
-TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataAssignNode(int index) const
-{
- TIntermTyped *fragDataIndex = constructGLFragDataNode(index);
- TIntermTyped *fragDataZero = constructGLFragDataNode(0);
-
- return new TIntermBinary(EOpAssign, fragDataIndex, fragDataZero);
-}
-
void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
{
if (node->getSymbol() == "gl_FragColor")
@@ -77,22 +76,34 @@ void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
}
}
-bool GLFragColorBroadcastTraverser::visitFunctionDefinition(Visit visit,
- TIntermFunctionDefinition *node)
+bool GLFragColorBroadcastTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
{
- ASSERT(visit == PreVisit);
- if (node->getFunctionSymbolInfo()->isMain())
+ switch (node->getOp())
{
- TIntermBlock *body = node->getBody();
- ASSERT(body);
- mMainSequence = body->getSequence();
+ case EOpFunction:
+ // Function definition.
+ ASSERT(visit == PreVisit);
+ if (node->getName() == "main(")
+ {
+ TIntermSequence *sequence = node->getSequence();
+ ASSERT((sequence->size() == 1) || (sequence->size() == 2));
+ if (sequence->size() == 2)
+ {
+ TIntermAggregate *body = (*sequence)[1]->getAsAggregate();
+ ASSERT(body);
+ mMainSequence = body->getSequence();
+ }
+ }
+ break;
+ default:
+ break;
}
return true;
}
-void GLFragColorBroadcastTraverser::broadcastGLFragColor()
+void GLFragColorBroadcastTraverser::broadcastGLFragColor(int maxDrawBuffers)
{
- ASSERT(mMaxDrawBuffers > 1);
+ ASSERT(maxDrawBuffers > 1);
if (!mGLFragColorUsed)
{
return;
@@ -102,7 +113,7 @@ void GLFragColorBroadcastTraverser::broadcastGLFragColor()
// gl_FragData[1] = gl_FragData[0];
// ...
// gl_FragData[maxDrawBuffers - 1] = gl_FragData[0];
- for (int colorIndex = 1; colorIndex < mMaxDrawBuffers; ++colorIndex)
+ for (int colorIndex = 1; colorIndex < maxDrawBuffers; ++colorIndex)
{
mMainSequence->insert(mMainSequence->end(), constructGLFragDataAssignNode(colorIndex));
}
@@ -115,12 +126,12 @@ void EmulateGLFragColorBroadcast(TIntermNode *root,
std::vector<sh::OutputVariable> *outputVariables)
{
ASSERT(maxDrawBuffers > 1);
- GLFragColorBroadcastTraverser traverser(maxDrawBuffers);
+ GLFragColorBroadcastTraverser traverser;
root->traverse(&traverser);
if (traverser.isGLFragColorUsed())
{
traverser.updateTree();
- traverser.broadcastGLFragColor();
+ traverser.broadcastGLFragColor(maxDrawBuffers);
for (auto &var : *outputVariables)
{
if (var.name == "gl_FragColor")
@@ -133,5 +144,3 @@ void EmulateGLFragColorBroadcast(TIntermNode *root,
}
}
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h b/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h
index 09e8dae6d..627c4c67f 100755
--- a/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h
+++ b/gfx/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h
@@ -15,6 +15,8 @@
namespace sh
{
struct OutputVariable;
+}
+
class TIntermNode;
// Replace all gl_FragColor with gl_FragData[0], and in the end of main() function,
@@ -22,7 +24,6 @@ class TIntermNode;
// If gl_FragColor is in outputVariables, it is replaced by gl_FragData.
void EmulateGLFragColorBroadcast(TIntermNode *root,
int maxDrawBuffers,
- std::vector<OutputVariable> *outputVariables);
-}
+ std::vector<sh::OutputVariable> *outputVariables);
#endif // COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_
diff --git a/gfx/angle/src/compiler/translator/EmulatePrecision.cpp b/gfx/angle/src/compiler/translator/EmulatePrecision.cpp
index c3c49021c..5f1454b57 100755
--- a/gfx/angle/src/compiler/translator/EmulatePrecision.cpp
+++ b/gfx/angle/src/compiler/translator/EmulatePrecision.cpp
@@ -8,9 +8,6 @@
#include <memory>
-namespace sh
-{
-
namespace
{
@@ -94,7 +91,6 @@ class RoundingHelperWriterHLSL : public RoundingHelperWriter
RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
{
- ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage));
switch (outputLanguage)
{
case SH_HLSL_4_1_OUTPUT:
@@ -102,6 +98,9 @@ RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOut
case SH_ESSL_OUTPUT:
return new RoundingHelperWriterESSL(outputLanguage);
default:
+ // Other languages not yet supported
+ ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
+ IsGLSL130OrNewer(outputLanguage));
return new RoundingHelperWriterGLSL(outputLanguage);
}
}
@@ -433,7 +432,7 @@ TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *chil
callNode->setOp(EOpFunctionCall);
TName nameObj(TFunction::mangleName(name));
nameObj.setInternal(true);
- callNode->getFunctionSymbolInfo()->setNameObj(nameObj);
+ callNode->setNameObj(nameObj);
callNode->getSequence()->push_back(child);
return callNode;
}
@@ -470,16 +469,15 @@ bool parentUsesResult(TIntermNode* parent, TIntermNode* node)
return false;
}
- TIntermBlock *blockParent = parent->getAsBlock();
- // If the parent is a block, the result is not assigned anywhere,
+ TIntermAggregate *aggParent = parent->getAsAggregate();
+ // If the parent's op is EOpSequence, the result is not assigned anywhere,
// so rounding it is not needed. In particular, this can avoid a lot of
// unnecessary rounding of unused return values of assignment.
- if (blockParent)
+ if (aggParent && aggParent->getOp() == EOpSequence)
{
return false;
}
- TIntermBinary *binaryParent = parent->getAsBinaryNode();
- if (binaryParent && binaryParent->getOp() == EOpComma && (binaryParent->getRight() != node))
+ if (aggParent && aggParent->getOp() == EOpComma && (aggParent->getSequence()->back() != node))
{
return false;
}
@@ -513,7 +511,7 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
if (op == EOpInitialize && visit == InVisit)
mDeclaringVariables = false;
- if ((op == EOpIndexDirectStruct) && visit == InVisit)
+ if ((op == EOpIndexDirectStruct || op == EOpVectorSwizzle) && visit == InVisit)
visitChildren = false;
if (visit != PreVisit)
@@ -601,30 +599,14 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
return visitChildren;
}
-bool EmulatePrecision::visitDeclaration(Visit visit, TIntermDeclaration *node)
-{
- // Variable or interface block declaration.
- if (visit == PreVisit)
- {
- mDeclaringVariables = true;
- }
- else if (visit == InVisit)
- {
- mDeclaringVariables = true;
- }
- else
- {
- mDeclaringVariables = false;
- }
- return true;
-}
-
bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
{
bool visitChildren = true;
switch (node->getOp())
{
+ case EOpSequence:
case EOpConstructStruct:
+ case EOpFunction:
break;
case EOpPrototype:
visitChildren = false;
@@ -635,6 +617,21 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpInvariantDeclaration:
visitChildren = false;
break;
+ case EOpDeclaration:
+ // Variable declaration.
+ if (visit == PreVisit)
+ {
+ mDeclaringVariables = true;
+ }
+ else if (visit == InVisit)
+ {
+ mDeclaringVariables = true;
+ }
+ else
+ {
+ mDeclaringVariables = false;
+ }
+ break;
case EOpFunctionCall:
{
// Function call.
@@ -708,19 +705,3 @@ void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase &sink,
roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul");
}
-// static
-bool EmulatePrecision::SupportedInLanguage(const ShShaderOutput outputLanguage)
-{
- switch (outputLanguage)
- {
- case SH_HLSL_4_1_OUTPUT:
- case SH_ESSL_OUTPUT:
- return true;
- default:
- // Other languages not yet supported
- return (outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
- sh::IsGLSL130OrNewer(outputLanguage));
- }
-}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/EmulatePrecision.h b/gfx/angle/src/compiler/translator/EmulatePrecision.h
index deb49cd2c..c2b9857bb 100755
--- a/gfx/angle/src/compiler/translator/EmulatePrecision.h
+++ b/gfx/angle/src/compiler/translator/EmulatePrecision.h
@@ -18,9 +18,6 @@
// need to write a huge number of variations of the emulated compound assignment
// to every translated shader with emulation enabled.
-namespace sh
-{
-
class EmulatePrecision : public TLValueTrackingTraverser
{
public:
@@ -30,14 +27,11 @@ class EmulatePrecision : public TLValueTrackingTraverser
bool visitBinary(Visit visit, TIntermBinary *node) override;
bool visitUnary(Visit visit, TIntermUnary *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
- bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
void writeEmulationHelpers(TInfoSinkBase &sink,
const int shaderVersion,
const ShShaderOutput outputLanguage);
- static bool SupportedInLanguage(const ShShaderOutput outputLanguage);
-
private:
struct TypePair
{
@@ -67,6 +61,4 @@ class EmulatePrecision : public TLValueTrackingTraverser
bool mDeclaringVariables;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
diff --git a/gfx/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp b/gfx/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp
index c5ff7b36b..b78c2059e 100755
--- a/gfx/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp
+++ b/gfx/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp
@@ -116,7 +116,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
TIntermTyped *lhs = sequence->at(0)->getAsTyped();
ASSERT(lhs);
- TIntermDeclaration *init = createTempInitDeclaration(lhs);
+ TIntermAggregate *init = createTempInitDeclaration(lhs);
TIntermTyped *current = createTempSymbol(lhs->getType());
insertStatementInParentBlock(init);
@@ -124,7 +124,10 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
// Create a chain of n-1 multiples.
for (int i = 1; i < n; ++i)
{
- TIntermBinary *mul = new TIntermBinary(EOpMul, current, createTempSymbol(lhs->getType()));
+ TIntermBinary *mul = new TIntermBinary(EOpMul);
+ mul->setLeft(current);
+ mul->setRight(createTempSymbol(lhs->getType()));
+ mul->setType(node->getType());
mul->setLine(node->getLine());
current = mul;
}
@@ -135,7 +138,9 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
TConstantUnion *oneVal = new TConstantUnion();
oneVal->setFConst(1.0f);
TIntermConstantUnion *oneNode = new TIntermConstantUnion(oneVal, node->getType());
- TIntermBinary *div = new TIntermBinary(EOpDiv, oneNode, current);
+ TIntermBinary *div = new TIntermBinary(EOpDiv);
+ div->setLeft(oneNode);
+ div->setRight(current);
current = div;
}
diff --git a/gfx/angle/src/compiler/translator/ExtensionGLSL.cpp b/gfx/angle/src/compiler/translator/ExtensionGLSL.cpp
index 5b5dc580e..d7f45f7ee 100755
--- a/gfx/angle/src/compiler/translator/ExtensionGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/ExtensionGLSL.cpp
@@ -10,9 +10,6 @@
#include "compiler/translator/VersionGLSL.h"
-namespace sh
-{
-
TExtensionGLSL::TExtensionGLSL(ShShaderOutput output)
: TIntermTraverser(true, false, false), mTargetVersion(ShaderOutputTypeToGLSLVersion(output))
{
@@ -101,5 +98,3 @@ void TExtensionGLSL::checkOperator(TIntermOperator *node)
break;
}
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ExtensionGLSL.h b/gfx/angle/src/compiler/translator/ExtensionGLSL.h
index 3c2dbe074..6bb84d612 100755
--- a/gfx/angle/src/compiler/translator/ExtensionGLSL.h
+++ b/gfx/angle/src/compiler/translator/ExtensionGLSL.h
@@ -14,9 +14,6 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
// Traverses the intermediate tree to determine which GLSL extensions are required
// to support the shader.
class TExtensionGLSL : public TIntermTraverser
@@ -39,6 +36,4 @@ class TExtensionGLSL : public TIntermTraverser
std::set<std::string> mRequiredExtensions;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
diff --git a/gfx/angle/src/compiler/translator/ForLoopUnroll.cpp b/gfx/angle/src/compiler/translator/ForLoopUnroll.cpp
index 58cce845f..4cc1c26a1 100755
--- a/gfx/angle/src/compiler/translator/ForLoopUnroll.cpp
+++ b/gfx/angle/src/compiler/translator/ForLoopUnroll.cpp
@@ -9,9 +9,6 @@
#include "compiler/translator/ValidateLimitations.h"
#include "angle_gl.h"
-namespace sh
-{
-
bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node)
{
if (mUnrollCondition != kSamplerArrayIndex)
@@ -54,7 +51,7 @@ bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node)
// Check if loop index type is integer.
// This is called after ValidateLimitations pass, so the loop has the limited form specified
// in ESSL 1.00 appendix A.
- TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
+ TIntermSequence *declSeq = node->getInit()->getAsAggregate()->getSequence();
TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
if (symbol->getBasicType() == EbtInt)
node->setUnrollFlag(true);
@@ -98,5 +95,3 @@ void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol)
}
}
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ForLoopUnroll.h b/gfx/angle/src/compiler/translator/ForLoopUnroll.h
index cda89b29f..9c49ecad3 100755
--- a/gfx/angle/src/compiler/translator/ForLoopUnroll.h
+++ b/gfx/angle/src/compiler/translator/ForLoopUnroll.h
@@ -9,9 +9,6 @@
#include "compiler/translator/LoopInfo.h"
-namespace sh
-{
-
// This class detects for-loops that needs to be unrolled.
// Currently we support two unroll conditions:
// 1) kForLoopWithIntegerIndex: unroll if the index type is integer.
@@ -53,6 +50,4 @@ class ForLoopUnrollMarker : public TIntermTraverser
bool mHasRunLoopValidation;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
diff --git a/gfx/angle/src/compiler/translator/InfoSink.cpp b/gfx/angle/src/compiler/translator/InfoSink.cpp
index e71fe51d3..cd59658ff 100755
--- a/gfx/angle/src/compiler/translator/InfoSink.cpp
+++ b/gfx/angle/src/compiler/translator/InfoSink.cpp
@@ -6,9 +6,6 @@
#include "compiler/translator/InfoSink.h"
-namespace sh
-{
-
void TInfoSinkBase::prefix(TPrefixType p) {
switch(p) {
case EPrefixNone:
@@ -55,5 +52,3 @@ void TInfoSinkBase::message(TPrefixType p, const TSourceLoc& loc, const char* m)
sink.append(m);
sink.append("\n");
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/InfoSink.h b/gfx/angle/src/compiler/translator/InfoSink.h
index b18e5861b..f47fafa8e 100755
--- a/gfx/angle/src/compiler/translator/InfoSink.h
+++ b/gfx/angle/src/compiler/translator/InfoSink.h
@@ -11,9 +11,6 @@
#include <stdlib.h>
#include "compiler/translator/Common.h"
-namespace sh
-{
-
// Returns the fractional part of the given floating-point number.
inline float fractionalPart(float f) {
float intPart = 0.0f;
@@ -116,6 +113,4 @@ public:
TInfoSinkBase obj;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_INFOSINK_H_
diff --git a/gfx/angle/src/compiler/translator/Initialize.cpp b/gfx/angle/src/compiler/translator/Initialize.cpp
index a0b35f636..0bf6ac45b 100755
--- a/gfx/angle/src/compiler/translator/Initialize.cpp
+++ b/gfx/angle/src/compiler/translator/Initialize.cpp
@@ -16,12 +16,8 @@
#include "compiler/translator/IntermNode.h"
#include "angle_gl.h"
-namespace sh
-{
-
void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable)
{
- const TType *voidType = TCache::getType(EbtVoid);
const TType *float1 = TCache::getType(EbtFloat);
const TType *float2 = TCache::getType(EbtFloat, 2);
const TType *float3 = TCache::getType(EbtFloat, 3);
@@ -473,26 +469,6 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, float3, float3, int3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, float4, float2, float2, int2);
- const TType *gimage2D = TCache::getType(EbtGImage2D);
- const TType *gimage3D = TCache::getType(EbtGImage3D);
- const TType *gimage2DArray = TCache::getType(EbtGImage2DArray);
- const TType *gimageCube = TCache::getType(EbtGImageCube);
-
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2D, int2, gvec4);
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage3D, int3, gvec4);
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2DArray, int3, gvec4);
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimageCube, int3, gvec4);
-
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2D, int2);
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage3D, int3);
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2DArray, int3);
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimageCube, int3);
-
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimage2D);
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage3D);
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage2DArray);
- symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimageCube);
-
//
// Depth range in window coordinates
//
@@ -535,13 +511,16 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors,
EbpMedium);
- symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers,
- EbpMedium);
- if (resources.EXT_blend_func_extended)
+ if (spec != SH_CSS_SHADERS_SPEC)
{
- symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended",
- "gl_MaxDualSourceDrawBuffersEXT",
- resources.MaxDualSourceDrawBuffers);
+ symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers,
+ EbpMedium);
+ if (resources.EXT_blend_func_extended)
+ {
+ symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended",
+ "gl_MaxDualSourceDrawBuffersEXT",
+ resources.MaxDualSourceDrawBuffers);
+ }
}
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors",
@@ -611,73 +590,85 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
switch (type)
{
case GL_FRAGMENT_SHADER:
- {
- symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"),
- TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
- symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"),
- TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
- symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"),
- TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
-
- symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"),
- TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
- TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
- fragData.setArraySize(resources.MaxDrawBuffers);
- symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
-
- if (resources.EXT_blend_func_extended)
- {
- symbolTable.insert(
- ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
- new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"),
- TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4)));
- TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true);
- secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers);
- symbolTable.insert(
- ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
- new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData));
- }
-
- if (resources.EXT_frag_depth)
- {
- symbolTable.insert(
- ESSL1_BUILTINS, "GL_EXT_frag_depth",
- new TVariable(
- NewPoolTString("gl_FragDepthEXT"),
- TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
- EvqFragDepthEXT, 1)));
- }
-
- symbolTable.insert(ESSL3_BUILTINS,
- new TVariable(NewPoolTString("gl_FragDepth"),
- TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
-
- if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
- {
- TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
- lastFragData.setArraySize(resources.MaxDrawBuffers);
-
- if (resources.EXT_shader_framebuffer_fetch)
- {
- symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch",
- new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
- }
- else if (resources.NV_shader_framebuffer_fetch)
- {
- symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
- new TVariable(NewPoolTString("gl_LastFragColor"),
- TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
- symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
- new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
- }
- }
- else if (resources.ARM_shader_framebuffer_fetch)
- {
- symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch",
- new TVariable(NewPoolTString("gl_LastFragColorARM"),
- TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
- }
- }
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"),
+ TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"),
+ TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"),
+ TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
+
+ //
+ // In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available.
+ // Instead, css_MixColor and css_ColorMatrix are available.
+ //
+ if (spec != SH_CSS_SHADERS_SPEC)
+ {
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"),
+ TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
+ TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
+ fragData.setArraySize(resources.MaxDrawBuffers);
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
+
+ if (resources.EXT_blend_func_extended)
+ {
+ symbolTable.insert(
+ ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
+ new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"),
+ TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4)));
+ TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true);
+ secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers);
+ symbolTable.insert(
+ ESSL1_BUILTINS, "GL_EXT_blend_func_extended",
+ new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData));
+ }
+
+ if (resources.EXT_frag_depth)
+ {
+ symbolTable.insert(
+ ESSL1_BUILTINS, "GL_EXT_frag_depth",
+ new TVariable(
+ NewPoolTString("gl_FragDepthEXT"),
+ TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
+ EvqFragDepthEXT, 1)));
+ }
+
+ symbolTable.insert(ESSL3_BUILTINS,
+ new TVariable(NewPoolTString("gl_FragDepth"),
+ TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
+
+ if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
+ {
+ TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
+ lastFragData.setArraySize(resources.MaxDrawBuffers);
+
+ if (resources.EXT_shader_framebuffer_fetch)
+ {
+ symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch",
+ new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
+ }
+ else if (resources.NV_shader_framebuffer_fetch)
+ {
+ symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
+ new TVariable(NewPoolTString("gl_LastFragColor"),
+ TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
+ symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
+ new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
+ }
+ }
+ else if (resources.ARM_shader_framebuffer_fetch)
+ {
+ symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch",
+ new TVariable(NewPoolTString("gl_LastFragColorARM"),
+ TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
+ }
+ }
+ else
+ {
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"),
+ TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"),
+ TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4)));
+ }
break;
@@ -758,5 +749,3 @@ void ResetExtensionBehavior(TExtensionBehavior &extBehavior)
ext_iter->second = EBhUndefined;
}
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/Initialize.h b/gfx/angle/src/compiler/translator/Initialize.h
index 0f1b60ba3..c43ce3417 100755
--- a/gfx/angle/src/compiler/translator/Initialize.h
+++ b/gfx/angle/src/compiler/translator/Initialize.h
@@ -11,9 +11,6 @@
#include "compiler/translator/Compiler.h"
#include "compiler/translator/SymbolTable.h"
-namespace sh
-{
-
void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table);
void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
@@ -29,6 +26,4 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
// extensions will remain unsupported.
void ResetExtensionBehavior(TExtensionBehavior &extensionBehavior);
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_INITIALIZE_H_
diff --git a/gfx/angle/src/compiler/translator/InitializeDll.cpp b/gfx/angle/src/compiler/translator/InitializeDll.cpp
index 89901935c..713965389 100755
--- a/gfx/angle/src/compiler/translator/InitializeDll.cpp
+++ b/gfx/angle/src/compiler/translator/InitializeDll.cpp
@@ -13,9 +13,6 @@
#include <assert.h>
-namespace sh
-{
-
bool InitProcess()
{
if (!InitializePoolIndex()) {
@@ -39,5 +36,3 @@ void DetachProcess()
FreePoolIndex();
TCache::destroy();
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/InitializeDll.h b/gfx/angle/src/compiler/translator/InitializeDll.h
index b2c787a8c..4c400760f 100755
--- a/gfx/angle/src/compiler/translator/InitializeDll.h
+++ b/gfx/angle/src/compiler/translator/InitializeDll.h
@@ -6,11 +6,8 @@
#ifndef COMPILER_TRANSLATOR_INITIALIZEDLL_H_
#define COMPILER_TRANSLATOR_INITIALIZEDLL_H_
-namespace sh
-{
bool InitProcess();
void DetachProcess();
-} // namespace sh
#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_
diff --git a/gfx/angle/src/compiler/translator/InitializeParseContext.cpp b/gfx/angle/src/compiler/translator/InitializeParseContext.cpp
index 67a248b60..c35cedb34 100755
--- a/gfx/angle/src/compiler/translator/InitializeParseContext.cpp
+++ b/gfx/angle/src/compiler/translator/InitializeParseContext.cpp
@@ -10,9 +10,6 @@
#include <assert.h>
-namespace sh
-{
-
TLSIndex GlobalParseContextIndex = TLS_INVALID_INDEX;
bool InitializeParseContextIndex()
@@ -43,4 +40,3 @@ TParseContext* GetGlobalParseContext()
return static_cast<TParseContext*>(GetTLSValue(GlobalParseContextIndex));
}
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/InitializeParseContext.h b/gfx/angle/src/compiler/translator/InitializeParseContext.h
index 9c315be3f..70dac702e 100755
--- a/gfx/angle/src/compiler/translator/InitializeParseContext.h
+++ b/gfx/angle/src/compiler/translator/InitializeParseContext.h
@@ -7,15 +7,11 @@
#ifndef COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
#define COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
-namespace sh
-{
-
bool InitializeParseContextIndex();
void FreeParseContextIndex();
class TParseContext;
extern void SetGlobalParseContext(TParseContext* context);
extern TParseContext* GetGlobalParseContext();
-} // namespace sh
#endif // COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
diff --git a/gfx/angle/src/compiler/translator/InitializeVariables.cpp b/gfx/angle/src/compiler/translator/InitializeVariables.cpp
index dafea1bd6..21f00936e 100755
--- a/gfx/angle/src/compiler/translator/InitializeVariables.cpp
+++ b/gfx/angle/src/compiler/translator/InitializeVariables.cpp
@@ -9,122 +9,191 @@
#include "angle_gl.h"
#include "common/debug.h"
#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"
-namespace sh
+namespace
{
-namespace
+TIntermConstantUnion *constructConstUnionNode(const TType &type)
+{
+ TType myType = type;
+ myType.clearArrayness();
+ myType.setQualifier(EvqConst);
+ size_t size = myType.getObjectSize();
+ TConstantUnion *u = new TConstantUnion[size];
+ for (size_t ii = 0; ii < size; ++ii)
+ {
+ switch (type.getBasicType())
+ {
+ case EbtFloat:
+ u[ii].setFConst(0.0f);
+ break;
+ case EbtInt:
+ u[ii].setIConst(0);
+ break;
+ case EbtUInt:
+ u[ii].setUConst(0u);
+ break;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ }
+
+ TIntermConstantUnion *node = new TIntermConstantUnion(u, myType);
+ return node;
+}
+
+TIntermConstantUnion *constructIndexNode(int index)
{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setIConst(index);
+
+ TType type(EbtInt, EbpUndefined, EvqConst, 1);
+ TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+ return node;
+}
class VariableInitializer : public TIntermTraverser
{
public:
- VariableInitializer(const InitVariableList &vars, const TSymbolTable &symbolTable)
- : TIntermTraverser(true, false, false),
- mVariables(vars),
- mSymbolTable(symbolTable),
- mCodeInserted(false)
+ VariableInitializer(const InitVariableList &vars)
+ : TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false)
{
- ASSERT(mSymbolTable.atGlobalLevel());
}
protected:
bool visitBinary(Visit, TIntermBinary *node) override { return false; }
bool visitUnary(Visit, TIntermUnary *node) override { return false; }
- bool visitIfElse(Visit, TIntermIfElse *node) override { return false; }
+ bool visitSelection(Visit, TIntermSelection *node) override { return false; }
bool visitLoop(Visit, TIntermLoop *node) override { return false; }
bool visitBranch(Visit, TIntermBranch *node) override { return false; }
- bool visitAggregate(Visit, TIntermAggregate *node) override { return false; }
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
private:
void insertInitCode(TIntermSequence *sequence);
const InitVariableList &mVariables;
- const TSymbolTable &mSymbolTable;
bool mCodeInserted;
};
// VariableInitializer implementation.
-bool VariableInitializer::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+bool VariableInitializer::visitAggregate(Visit visit, TIntermAggregate *node)
{
- // Function definition.
- ASSERT(visit == PreVisit);
- if (node->getFunctionSymbolInfo()->isMain())
+ bool visitChildren = !mCodeInserted;
+ switch (node->getOp())
{
- TIntermBlock *body = node->getBody();
- insertInitCode(body->getSequence());
- mCodeInserted = true;
+ case EOpSequence:
+ break;
+ case EOpFunction:
+ {
+ // Function definition.
+ ASSERT(visit == PreVisit);
+ if (node->getName() == "main(")
+ {
+ TIntermSequence *sequence = node->getSequence();
+ ASSERT((sequence->size() == 1) || (sequence->size() == 2));
+ TIntermAggregate *body = NULL;
+ if (sequence->size() == 1)
+ {
+ body = new TIntermAggregate(EOpSequence);
+ sequence->push_back(body);
+ }
+ else
+ {
+ body = (*sequence)[1]->getAsAggregate();
+ }
+ ASSERT(body);
+ insertInitCode(body->getSequence());
+ mCodeInserted = true;
+ }
+ break;
+ }
+ default:
+ visitChildren = false;
+ break;
}
- return false;
+ return visitChildren;
}
void VariableInitializer::insertInitCode(TIntermSequence *sequence)
{
- for (const auto &var : mVariables)
+ for (size_t ii = 0; ii < mVariables.size(); ++ii)
{
+ const sh::ShaderVariable &var = mVariables[ii];
TString name = TString(var.name.c_str());
-
if (var.isArray())
{
- // Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which
- // doesn't have array assignment.
+ TType type = sh::ConvertShaderVariableTypeToTType(var.type);
size_t pos = name.find_last_of('[');
if (pos != TString::npos)
- {
name = name.substr(0, pos);
- }
- TType elementType = sh::GetShaderVariableBasicType(var);
- TType arrayType = elementType;
- arrayType.setArraySize(var.elementCount());
-
- for (unsigned int i = 0; i < var.arraySize; ++i)
+ for (int index = static_cast<int>(var.arraySize) - 1; index >= 0; --index)
{
- TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, arrayType);
- TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol,
- TIntermTyped::CreateIndexNode(i));
+ TIntermBinary *assign = new TIntermBinary(EOpAssign);
+ sequence->insert(sequence->begin(), assign);
+
+ TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
+ TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
+ indexDirect->setLeft(symbol);
+ TIntermConstantUnion *indexNode = constructIndexNode(index);
+ indexDirect->setRight(indexNode);
- TIntermTyped *zero = TIntermTyped::CreateZero(elementType);
- TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero);
+ assign->setLeft(indexDirect);
- sequence->insert(sequence->begin(), assignment);
+ TIntermConstantUnion *zeroConst = constructConstUnionNode(type);
+ assign->setRight(zeroConst);
}
}
else if (var.isStruct())
{
- TVariable *structInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
- ASSERT(structInfo);
-
- TIntermSymbol *symbol = new TIntermSymbol(0, name, structInfo->getType());
- TIntermTyped *zero = TIntermTyped::CreateZero(structInfo->getType());
-
- TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
- sequence->insert(sequence->begin(), assign);
+ TFieldList *fields = new TFieldList;
+ TSourceLoc loc;
+ for (auto field : var.fields)
+ {
+ fields->push_back(new TField(nullptr, new TString(field.name.c_str()), loc));
+ }
+ TStructure *structure = new TStructure(new TString(var.structName.c_str()), fields);
+ TType type;
+ type.setStruct(structure);
+ for (int fieldIndex = 0; fieldIndex < static_cast<int>(var.fields.size()); ++fieldIndex)
+ {
+ TIntermBinary *assign = new TIntermBinary(EOpAssign);
+ sequence->insert(sequence->begin(), assign);
+
+ TIntermBinary *indexDirectStruct = new TIntermBinary(EOpIndexDirectStruct);
+ TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
+ indexDirectStruct->setLeft(symbol);
+ TIntermConstantUnion *indexNode = constructIndexNode(fieldIndex);
+ indexDirectStruct->setRight(indexNode);
+ assign->setLeft(indexDirectStruct);
+
+ const sh::ShaderVariable &field = var.fields[fieldIndex];
+ TType fieldType = sh::ConvertShaderVariableTypeToTType(field.type);
+ TIntermConstantUnion *zeroConst = constructConstUnionNode(fieldType);
+ assign->setRight(zeroConst);
+ }
}
else
{
- TType type = sh::GetShaderVariableBasicType(var);
- TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
- TIntermTyped *zero = TIntermTyped::CreateZero(type);
-
- TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
+ TType type = sh::ConvertShaderVariableTypeToTType(var.type);
+ TIntermBinary *assign = new TIntermBinary(EOpAssign);
sequence->insert(sequence->begin(), assign);
+ TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
+ assign->setLeft(symbol);
+ TIntermConstantUnion *zeroConst = constructConstUnionNode(type);
+ assign->setRight(zeroConst);
}
+
}
}
} // namespace anonymous
-void InitializeVariables(TIntermNode *root,
- const InitVariableList &vars,
- const TSymbolTable &symbolTable)
+void InitializeVariables(TIntermNode *root, const InitVariableList &vars)
{
- VariableInitializer initializer(vars, symbolTable);
+ VariableInitializer initializer(vars);
root->traverse(&initializer);
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/InitializeVariables.h b/gfx/angle/src/compiler/translator/InitializeVariables.h
index 9a34245a5..f826032d3 100755
--- a/gfx/angle/src/compiler/translator/InitializeVariables.h
+++ b/gfx/angle/src/compiler/translator/InitializeVariables.h
@@ -9,23 +9,10 @@
#include <GLSLANG/ShaderLang.h>
-namespace sh
-{
class TIntermNode;
-class TSymbolTable;
typedef std::vector<sh::ShaderVariable> InitVariableList;
-// Currently this function is only capable of initializing variables of basic types,
-// array of basic types, or struct of basic types.
-// For now it is used for the following two scenarios:
-// 1. initializing gl_Position;
-// 2. initializing ESSL 3.00 shaders' output variables (which might be structs).
-// Specifically, it's not feasible to make it work for local variables because if their
-// types are structs, we can't look into TSymbolTable to find the TType data.
-void InitializeVariables(TIntermNode *root,
- const InitVariableList &vars,
- const TSymbolTable &symbolTable);
-} // namespace sh
+void InitializeVariables(TIntermNode *root, const InitVariableList &vars);
#endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
diff --git a/gfx/angle/src/compiler/translator/IntermNode.cpp b/gfx/angle/src/compiler/translator/IntermNode.cpp
index b91b43ecf..dcf47879a 100755
--- a/gfx/angle/src/compiler/translator/IntermNode.cpp
+++ b/gfx/angle/src/compiler/translator/IntermNode.cpp
@@ -21,10 +21,6 @@
#include "compiler/translator/HashNames.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
-#include "compiler/translator/util.h"
-
-namespace sh
-{
namespace
{
@@ -47,14 +43,13 @@ TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size)
return constUnion;
}
-void UndefinedConstantFoldingError(const TSourceLoc &loc,
- TOperator op,
- TBasicType basicType,
- TDiagnostics *diagnostics,
- TConstantUnion *result)
+void UndefinedConstantFoldingError(const TSourceLoc &loc, TOperator op, TBasicType basicType,
+ TInfoSink &infoSink, TConstantUnion *result)
{
- diagnostics->warning(loc, "operation result is undefined for the values passed in",
- GetOperatorString(op), "");
+ std::stringstream constantFoldingErrorStream;
+ constantFoldingErrorStream << "'" << GetOperatorString(op)
+ << "' operation result is undefined for the values passed in";
+ infoSink.info.message(EPrefixWarning, loc, constantFoldingErrorStream.str().c_str());
switch (basicType)
{
@@ -96,7 +91,7 @@ float VectorDotProduct(const TConstantUnion *paramArray1,
return result;
}
-TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray,
+TIntermTyped *CreateFoldedNode(TConstantUnion *constArray,
const TIntermTyped *originalNode,
TQualifier qualifier)
{
@@ -173,7 +168,7 @@ bool TIntermLoop::replaceChildNode(
REPLACE_IF_IS(mInit, TIntermNode, original, replacement);
REPLACE_IF_IS(mCond, TIntermTyped, original, replacement);
REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement);
- REPLACE_IF_IS(mBody, TIntermBlock, original, replacement);
+ REPLACE_IF_IS(mBody, TIntermAggregate, original, replacement);
return false;
}
@@ -184,13 +179,6 @@ bool TIntermBranch::replaceChildNode(
return false;
}
-bool TIntermSwizzle::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
-{
- ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
- REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
- return false;
-}
-
bool TIntermBinary::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -202,67 +190,42 @@ bool TIntermBinary::replaceChildNode(
bool TIntermUnary::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
- ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
return false;
}
-bool TIntermFunctionDefinition::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
-{
- REPLACE_IF_IS(mParameters, TIntermAggregate, original, replacement);
- REPLACE_IF_IS(mBody, TIntermBlock, original, replacement);
- return false;
-}
-
bool TIntermAggregate::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
- return replaceChildNodeInternal(original, replacement);
-}
-
-bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
-{
- return replaceChildNodeInternal(original, replacement);
-}
-
-bool TIntermDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
-{
- return replaceChildNodeInternal(original, replacement);
-}
-
-bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement)
-{
- for (size_t ii = 0; ii < getSequence()->size(); ++ii)
+ for (size_t ii = 0; ii < mSequence.size(); ++ii)
{
- REPLACE_IF_IS((*getSequence())[ii], TIntermNode, original, replacement);
+ REPLACE_IF_IS(mSequence[ii], TIntermNode, original, replacement);
}
return false;
}
-bool TIntermAggregateBase::replaceChildNodeWithMultiple(TIntermNode *original,
- const TIntermSequence &replacements)
+bool TIntermAggregate::replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements)
{
- for (auto it = getSequence()->begin(); it < getSequence()->end(); ++it)
+ for (auto it = mSequence.begin(); it < mSequence.end(); ++it)
{
if (*it == original)
{
- it = getSequence()->erase(it);
- getSequence()->insert(it, replacements.begin(), replacements.end());
+ it = mSequence.erase(it);
+ mSequence.insert(it, replacements.begin(), replacements.end());
return true;
}
}
return false;
}
-bool TIntermAggregateBase::insertChildNodes(TIntermSequence::size_type position,
- const TIntermSequence &insertions)
+bool TIntermAggregate::insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions)
{
- if (position > getSequence()->size())
+ if (position > mSequence.size())
{
return false;
}
- auto it = getSequence()->begin() + position;
- getSequence()->insert(it, insertions.begin(), insertions.end());
+ auto it = mSequence.begin() + position;
+ mSequence.insert(it, insertions.begin(), insertions.end());
return true;
}
@@ -320,47 +283,18 @@ void TIntermAggregate::setBuiltInFunctionPrecision()
}
// ESSL 3.0 spec section 8: textureSize always gets highp precision.
// All other functions that take a sampler are assumed to be texture functions.
- if (mFunctionInfo.getName().find("textureSize") == 0)
+ if (mName.getString().find("textureSize") == 0)
mType.setPrecision(EbpHigh);
else
mType.setPrecision(precision);
}
-void TIntermBlock::appendStatement(TIntermNode *statement)
-{
- // Declaration nodes with no children can appear if all the declarators just added constants to
- // the symbol table instead of generating code. They're no-ops so they aren't added to blocks.
- if (statement != nullptr && (statement->getAsDeclarationNode() == nullptr ||
- !statement->getAsDeclarationNode()->getSequence()->empty()))
- {
- mStatements.push_back(statement);
- }
-}
-
-void TIntermDeclaration::appendDeclarator(TIntermTyped *declarator)
-{
- ASSERT(declarator != nullptr);
- ASSERT(declarator->getAsSymbolNode() != nullptr ||
- (declarator->getAsBinaryNode() != nullptr &&
- declarator->getAsBinaryNode()->getOp() == EOpInitialize));
- ASSERT(mDeclarators.empty() ||
- declarator->getType().sameElementType(mDeclarators.back()->getAsTyped()->getType()));
- mDeclarators.push_back(declarator);
-}
-
-bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
-{
- REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
- REPLACE_IF_IS(mTrueExpression, TIntermTyped, original, replacement);
- REPLACE_IF_IS(mFalseExpression, TIntermTyped, original, replacement);
- return false;
-}
-
-bool TIntermIfElse::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+bool TIntermSelection::replaceChildNode(
+ TIntermNode *original, TIntermNode *replacement)
{
REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
- REPLACE_IF_IS(mTrueBlock, TIntermBlock, original, replacement);
- REPLACE_IF_IS(mFalseBlock, TIntermBlock, original, replacement);
+ REPLACE_IF_IS(mTrueBlock, TIntermNode, original, replacement);
+ REPLACE_IF_IS(mFalseBlock, TIntermNode, original, replacement);
return false;
}
@@ -368,7 +302,7 @@ bool TIntermSwitch::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
REPLACE_IF_IS(mInit, TIntermTyped, original, replacement);
- REPLACE_IF_IS(mStatementList, TIntermBlock, original, replacement);
+ REPLACE_IF_IS(mStatementList, TIntermAggregate, original, replacement);
return false;
}
@@ -402,100 +336,18 @@ bool TIntermTyped::isConstructorWithOnlyConstantUnionParameters()
return true;
}
-// static
-TIntermTyped *TIntermTyped::CreateIndexNode(int index)
-{
- TConstantUnion *u = new TConstantUnion[1];
- u[0].setIConst(index);
-
- TType type(EbtInt, EbpUndefined, EvqConst, 1);
- TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
- return node;
-}
-
-// static
-TIntermTyped *TIntermTyped::CreateZero(const TType &type)
-{
- TType constType(type);
- constType.setQualifier(EvqConst);
-
- if (!type.isArray() && type.getBasicType() != EbtStruct)
- {
- ASSERT(type.isScalar() || type.isVector() || type.isMatrix());
-
- size_t size = constType.getObjectSize();
- TConstantUnion *u = new TConstantUnion[size];
- for (size_t i = 0; i < size; ++i)
- {
- switch (type.getBasicType())
- {
- case EbtFloat:
- u[i].setFConst(0.0f);
- break;
- case EbtInt:
- u[i].setIConst(0);
- break;
- case EbtUInt:
- u[i].setUConst(0u);
- break;
- case EbtBool:
- u[i].setBConst(false);
- break;
- default:
- UNREACHABLE();
- return nullptr;
- }
- }
-
- TIntermConstantUnion *node = new TIntermConstantUnion(u, constType);
- return node;
- }
-
- TIntermAggregate *constructor = new TIntermAggregate(sh::TypeToConstructorOperator(type));
- constructor->setType(constType);
-
- if (type.isArray())
- {
- TType elementType(type);
- elementType.clearArrayness();
-
- size_t arraySize = type.getArraySize();
- for (size_t i = 0; i < arraySize; ++i)
- {
- constructor->getSequence()->push_back(CreateZero(elementType));
- }
- }
- else
- {
- ASSERT(type.getBasicType() == EbtStruct);
-
- TStructure *structure = type.getStruct();
- for (const auto &field : structure->fields())
- {
- constructor->getSequence()->push_back(CreateZero(*field->type()));
- }
- }
-
- return constructor;
-}
-
TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node)
{
mUnionArrayPointer = node.mUnionArrayPointer;
}
-void TFunctionSymbolInfo::setFromFunction(const TFunction &function)
-{
- setName(function.getMangledName());
- setId(function.getUniqueId());
-}
-
TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
: TIntermOperator(node),
+ mName(node.mName),
mUserDefined(node.mUserDefined),
+ mFunctionId(node.mFunctionId),
mUseEmulatedFunction(node.mUseEmulatedFunction),
- mGotPrecisionFromChildren(node.mGotPrecisionFromChildren),
- mFunctionInfo(node.mFunctionInfo)
+ mGotPrecisionFromChildren(node.mGotPrecisionFromChildren)
{
for (TIntermNode *child : node.mSequence)
{
@@ -506,13 +358,6 @@ TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
}
}
-TIntermSwizzle::TIntermSwizzle(const TIntermSwizzle &node) : TIntermTyped(node)
-{
- TIntermTyped *operandCopy = node.mOperand->deepCopy();
- ASSERT(operandCopy != nullptr);
- mOperand = operandCopy;
-}
-
TIntermBinary::TIntermBinary(const TIntermBinary &node)
: TIntermOperator(node), mAddIndexClamp(node.mAddIndexClamp)
{
@@ -531,15 +376,20 @@ TIntermUnary::TIntermUnary(const TIntermUnary &node)
mOperand = operandCopy;
}
-TIntermTernary::TIntermTernary(const TIntermTernary &node) : TIntermTyped(node)
+TIntermSelection::TIntermSelection(const TIntermSelection &node) : TIntermTyped(node)
{
+ // Only supported for ternary nodes, not if statements.
+ TIntermTyped *trueTyped = node.mTrueBlock->getAsTyped();
+ TIntermTyped *falseTyped = node.mFalseBlock->getAsTyped();
+ ASSERT(trueTyped != nullptr);
+ ASSERT(falseTyped != nullptr);
TIntermTyped *conditionCopy = node.mCondition->deepCopy();
- TIntermTyped *trueCopy = node.mTrueExpression->deepCopy();
- TIntermTyped *falseCopy = node.mFalseExpression->deepCopy();
+ TIntermTyped *trueCopy = trueTyped->deepCopy();
+ TIntermTyped *falseCopy = falseTyped->deepCopy();
ASSERT(conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr);
- mCondition = conditionCopy;
- mTrueExpression = trueCopy;
- mFalseExpression = falseCopy;
+ mCondition = conditionCopy;
+ mTrueBlock = trueCopy;
+ mFalseBlock = falseCopy;
}
bool TIntermOperator::isAssignment() const
@@ -694,187 +544,77 @@ TOperator TIntermBinary::GetMulAssignOpBasedOnOperands(const TType &left, const
// Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type.
//
-void TIntermUnary::promote()
+void TIntermUnary::promote(const TType *funcReturnType)
{
- TQualifier resultQualifier = EvqTemporary;
- if (mOperand->getQualifier() == EvqConst)
- resultQualifier = EvqConst;
-
- unsigned char operandPrimarySize =
- static_cast<unsigned char>(mOperand->getType().getNominalSize());
switch (mOp)
{
- case EOpFloatBitsToInt:
- setType(TType(EbtInt, EbpHigh, resultQualifier, operandPrimarySize));
- break;
- case EOpFloatBitsToUint:
- setType(TType(EbtUInt, EbpHigh, resultQualifier, operandPrimarySize));
- break;
- case EOpIntBitsToFloat:
- case EOpUintBitsToFloat:
- setType(TType(EbtFloat, EbpHigh, resultQualifier, operandPrimarySize));
- break;
- case EOpPackSnorm2x16:
- case EOpPackUnorm2x16:
- case EOpPackHalf2x16:
- setType(TType(EbtUInt, EbpHigh, resultQualifier));
- break;
- case EOpUnpackSnorm2x16:
- case EOpUnpackUnorm2x16:
- setType(TType(EbtFloat, EbpHigh, resultQualifier, 2));
- break;
- case EOpUnpackHalf2x16:
- setType(TType(EbtFloat, EbpMedium, resultQualifier, 2));
- break;
- case EOpAny:
- case EOpAll:
- setType(TType(EbtBool, EbpUndefined, resultQualifier));
- break;
- case EOpLength:
- case EOpDeterminant:
- setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier));
- break;
- case EOpTranspose:
- setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier,
- static_cast<unsigned char>(mOperand->getType().getRows()),
- static_cast<unsigned char>(mOperand->getType().getCols())));
- break;
- case EOpIsInf:
- case EOpIsNan:
- setType(TType(EbtBool, EbpUndefined, resultQualifier, operandPrimarySize));
- break;
- default:
- setType(mOperand->getType());
- mType.setQualifier(resultQualifier);
- break;
- }
-}
-
-TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets)
- : TIntermTyped(TType(EbtFloat, EbpUndefined)),
- mOperand(operand),
- mSwizzleOffsets(swizzleOffsets)
-{
- ASSERT(mSwizzleOffsets.size() <= 4);
- promote();
-}
-
-TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand)
- : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false)
-{
- promote();
-}
-
-TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
- : TIntermOperator(op), mLeft(left), mRight(right), mAddIndexClamp(false)
-{
- promote();
-}
-
-TIntermTernary::TIntermTernary(TIntermTyped *cond,
- TIntermTyped *trueExpression,
- TIntermTyped *falseExpression)
- : TIntermTyped(trueExpression->getType()),
- mCondition(cond),
- mTrueExpression(trueExpression),
- mFalseExpression(falseExpression)
-{
- getTypePointer()->setQualifier(
- TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression));
-}
-
-// static
-TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond,
- TIntermTyped *trueExpression,
- TIntermTyped *falseExpression)
-{
- if (cond->getQualifier() == EvqConst && trueExpression->getQualifier() == EvqConst &&
- falseExpression->getQualifier() == EvqConst)
- {
- return EvqConst;
+ case EOpFloatBitsToInt:
+ case EOpFloatBitsToUint:
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ mType.setPrecision(EbpHigh);
+ break;
+ case EOpUnpackHalf2x16:
+ mType.setPrecision(EbpMedium);
+ break;
+ default:
+ setType(mOperand->getType());
}
- return EvqTemporary;
-}
-void TIntermSwizzle::promote()
-{
- TQualifier resultQualifier = EvqTemporary;
- if (mOperand->getQualifier() == EvqConst)
- resultQualifier = EvqConst;
-
- auto numFields = mSwizzleOffsets.size();
- setType(TType(mOperand->getBasicType(), mOperand->getPrecision(), resultQualifier,
- static_cast<unsigned char>(numFields)));
-}
-
-bool TIntermSwizzle::hasDuplicateOffsets() const
-{
- int offsetCount[4] = {0u, 0u, 0u, 0u};
- for (const auto offset : mSwizzleOffsets)
+ if (funcReturnType != nullptr)
{
- offsetCount[offset]++;
- if (offsetCount[offset] > 1)
+ if (funcReturnType->getBasicType() == EbtBool)
{
- return true;
+ // Bool types should not have precision.
+ setType(*funcReturnType);
}
- }
- return false;
-}
-
-void TIntermSwizzle::writeOffsetsAsXYZW(TInfoSinkBase *out) const
-{
- for (const int offset : mSwizzleOffsets)
- {
- switch (offset)
+ else
{
- case 0:
- *out << "x";
- break;
- case 1:
- *out << "y";
- break;
- case 2:
- *out << "z";
- break;
- case 3:
- *out << "w";
- break;
- default:
- UNREACHABLE();
+ // Precision of the node has been set based on the operand.
+ setTypePreservePrecision(*funcReturnType);
}
}
+
+ if (mOperand->getQualifier() == EvqConst)
+ mType.setQualifier(EvqConst);
+ else
+ mType.setQualifier(EvqTemporary);
}
-TQualifier TIntermBinary::GetCommaQualifier(int shaderVersion,
- const TIntermTyped *left,
- const TIntermTyped *right)
+TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
+ : TIntermOperator(op), mLeft(left), mRight(right), mAddIndexClamp(false)
{
- // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression.
- if (shaderVersion >= 300 || left->getQualifier() != EvqConst ||
- right->getQualifier() != EvqConst)
- {
- return EvqTemporary;
- }
- return EvqConst;
+ promote();
}
-// Establishes the type of the result of the binary operation.
+//
+// Establishes the type of the resultant operation, as well as
+// makes the operator the correct one for the operands.
+//
+// For lots of operations it should already be established that the operand
+// combination is valid, but returns false if operator can't work on operands.
+//
void TIntermBinary::promote()
{
+ ASSERT(mLeft->isArray() == mRight->isArray());
+
ASSERT(!isMultiplication() ||
mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType()));
- // Comma is handled as a special case.
- if (mOp == EOpComma)
- {
- setType(mRight->getType());
- return;
- }
-
// Base assumption: just make the type the same as the left
// operand. Then only deviations from this need be coded.
setType(mLeft->getType());
+ // The result gets promoted to the highest precision.
+ TPrecision higherPrecision = GetHigherPrecision(
+ mLeft->getPrecision(), mRight->getPrecision());
+ getTypePointer()->setPrecision(higherPrecision);
+
TQualifier resultQualifier = EvqConst;
// Binary operations results in temporary variables unless both
// operands are const.
@@ -884,55 +624,6 @@ void TIntermBinary::promote()
getTypePointer()->setQualifier(EvqTemporary);
}
- // Handle indexing ops.
- switch (mOp)
- {
- case EOpIndexDirect:
- case EOpIndexIndirect:
- if (mLeft->isArray())
- {
- mType.clearArrayness();
- }
- else if (mLeft->isMatrix())
- {
- setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier,
- static_cast<unsigned char>(mLeft->getRows())));
- }
- else if (mLeft->isVector())
- {
- setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier));
- }
- else
- {
- UNREACHABLE();
- }
- return;
- case EOpIndexDirectStruct:
- {
- const TFieldList &fields = mLeft->getType().getStruct()->fields();
- const int i = mRight->getAsConstantUnion()->getIConst(0);
- setType(*fields[i]->type());
- getTypePointer()->setQualifier(resultQualifier);
- return;
- }
- case EOpIndexDirectInterfaceBlock:
- {
- const TFieldList &fields = mLeft->getType().getInterfaceBlock()->fields();
- const int i = mRight->getAsConstantUnion()->getIConst(0);
- setType(*fields[i]->type());
- getTypePointer()->setQualifier(resultQualifier);
- return;
- }
- default:
- break;
- }
-
- ASSERT(mLeft->isArray() == mRight->isArray());
-
- // The result gets promoted to the highest precision.
- TPrecision higherPrecision = GetHigherPrecision(mLeft->getPrecision(), mRight->getPrecision());
- getTypePointer()->setPrecision(higherPrecision);
-
const int nominalSize =
std::max(mLeft->getNominalSize(), mRight->getNominalSize());
@@ -952,8 +643,8 @@ void TIntermBinary::promote()
case EOpGreaterThan:
case EOpLessThanEqual:
case EOpGreaterThanEqual:
- setType(TType(EbtBool, EbpUndefined, resultQualifier));
- break;
+ setType(TType(EbtBool, EbpUndefined));
+ break;
//
// And and Or operate on conditionals
@@ -962,7 +653,7 @@ void TIntermBinary::promote()
case EOpLogicalXor:
case EOpLogicalOr:
ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool);
- setType(TType(EbtBool, EbpUndefined, resultQualifier));
+ setType(TType(EbtBool, EbpUndefined));
break;
default:
@@ -1058,7 +749,8 @@ void TIntermBinary::promote()
case EOpIndexIndirect:
case EOpIndexDirectInterfaceBlock:
case EOpIndexDirectStruct:
- // These ops should be already fully handled.
+ // TODO (oetuaho): These ops could be handled here as well (should be done closer to the
+ // top of the function).
UNREACHABLE();
break;
default:
@@ -1067,105 +759,26 @@ void TIntermBinary::promote()
}
}
-const TConstantUnion *TIntermConstantUnion::foldIndexing(int index)
-{
- if (isArray())
- {
- ASSERT(index < static_cast<int>(getType().getArraySize()));
- TType arrayElementType = getType();
- arrayElementType.clearArrayness();
- size_t arrayElementSize = arrayElementType.getObjectSize();
- return &mUnionArrayPointer[arrayElementSize * index];
- }
- else if (isMatrix())
- {
- ASSERT(index < getType().getCols());
- int size = getType().getRows();
- return &mUnionArrayPointer[size * index];
- }
- else if (isVector())
- {
- ASSERT(index < getType().getNominalSize());
- return &mUnionArrayPointer[index];
- }
- else
- {
- UNREACHABLE();
- return nullptr;
- }
-}
-
-TIntermTyped *TIntermSwizzle::fold()
+TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
{
- TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
- if (operandConstant == nullptr)
+ TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion();
+ TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion();
+ if (leftConstant == nullptr || rightConstant == nullptr)
{
return nullptr;
}
+ TConstantUnion *constArray = leftConstant->foldBinary(mOp, rightConstant, diagnostics);
- TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()];
- for (size_t i = 0; i < mSwizzleOffsets.size(); ++i)
- {
- constArray[i] = *operandConstant->foldIndexing(mSwizzleOffsets.at(i));
- }
- return CreateFoldedNode(constArray, this, mType.getQualifier());
-}
-
-TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
-{
- TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion();
- TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion();
- switch (mOp)
+ // Nodes may be constant folded without being qualified as constant.
+ TQualifier resultQualifier = EvqConst;
+ if (mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst)
{
- case EOpIndexDirect:
- {
- if (leftConstant == nullptr || rightConstant == nullptr)
- {
- return nullptr;
- }
- int index = rightConstant->getIConst(0);
-
- const TConstantUnion *constArray = leftConstant->foldIndexing(index);
- return CreateFoldedNode(constArray, this, mType.getQualifier());
- }
- case EOpIndexDirectStruct:
- {
- if (leftConstant == nullptr || rightConstant == nullptr)
- {
- return nullptr;
- }
- const TFieldList &fields = mLeft->getType().getStruct()->fields();
- size_t index = static_cast<size_t>(rightConstant->getIConst(0));
-
- size_t previousFieldsSize = 0;
- for (size_t i = 0; i < index; ++i)
- {
- previousFieldsSize += fields[i]->type()->getObjectSize();
- }
-
- const TConstantUnion *constArray = leftConstant->getUnionArrayPointer();
- return CreateFoldedNode(constArray + previousFieldsSize, this, mType.getQualifier());
- }
- case EOpIndexIndirect:
- case EOpIndexDirectInterfaceBlock:
- // Can never be constant folded.
- return nullptr;
- default:
- {
- if (leftConstant == nullptr || rightConstant == nullptr)
- {
- return nullptr;
- }
- TConstantUnion *constArray =
- leftConstant->foldBinary(mOp, rightConstant, diagnostics, mLeft->getLine());
-
- // Nodes may be constant folded without being qualified as constant.
- return CreateFoldedNode(constArray, this, mType.getQualifier());
- }
+ resultQualifier = EvqTemporary;
}
+ return CreateFoldedNode(constArray, this, resultQualifier);
}
-TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
+TIntermTyped *TIntermUnary::fold(TInfoSink &infoSink)
{
TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
if (operandConstant == nullptr)
@@ -1188,18 +801,19 @@ TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
case EOpUnpackUnorm2x16:
case EOpPackHalf2x16:
case EOpUnpackHalf2x16:
- constArray = operandConstant->foldUnaryNonComponentWise(mOp);
- break;
+ constArray = operandConstant->foldUnaryWithDifferentReturnType(mOp, infoSink);
+ break;
default:
- constArray = operandConstant->foldUnaryComponentWise(mOp, diagnostics);
- break;
+ constArray = operandConstant->foldUnaryWithSameReturnType(mOp, infoSink);
+ break;
}
// Nodes may be constant folded without being qualified as constant.
- return CreateFoldedNode(constArray, this, mType.getQualifier());
+ TQualifier resultQualifier = mOperand->getQualifier() == EvqConst ? EvqConst : EvqTemporary;
+ return CreateFoldedNode(constArray, this, resultQualifier);
}
-TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics)
+TIntermTyped *TIntermAggregate::fold(TInfoSink &infoSink)
{
// Make sure that all params are constant before actual constant folding.
for (auto *param : *getSequence())
@@ -1211,9 +825,9 @@ TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics)
}
TConstantUnion *constArray = nullptr;
if (isConstructor())
- constArray = TIntermConstantUnion::FoldAggregateConstructor(this);
+ constArray = TIntermConstantUnion::FoldAggregateConstructor(this, infoSink);
else
- constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics);
+ constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, infoSink);
// Nodes may be constant folded without being qualified as constant.
TQualifier resultQualifier = areChildrenConstQualified() ? EvqConst : EvqTemporary;
@@ -1228,13 +842,15 @@ TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics)
//
TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
TIntermConstantUnion *rightNode,
- TDiagnostics *diagnostics,
- const TSourceLoc &line)
+ TDiagnostics *diagnostics)
{
const TConstantUnion *leftArray = getUnionArrayPointer();
const TConstantUnion *rightArray = rightNode->getUnionArrayPointer();
- ASSERT(leftArray && rightArray);
+ if (!leftArray)
+ return nullptr;
+ if (!rightArray)
+ return nullptr;
size_t objectSize = getType().getObjectSize();
@@ -1257,12 +873,12 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
case EOpAdd:
resultArray = new TConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
- resultArray[i] = TConstantUnion::add(leftArray[i], rightArray[i], diagnostics, line);
+ resultArray[i] = leftArray[i] + rightArray[i];
break;
case EOpSub:
resultArray = new TConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
- resultArray[i] = TConstantUnion::sub(leftArray[i], rightArray[i], diagnostics, line);
+ resultArray[i] = leftArray[i] - rightArray[i];
break;
case EOpMul:
@@ -1270,12 +886,11 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
case EOpMatrixTimesScalar:
resultArray = new TConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
- resultArray[i] = TConstantUnion::mul(leftArray[i], rightArray[i], diagnostics, line);
+ resultArray[i] = leftArray[i] * rightArray[i];
break;
case EOpMatrixTimesMatrix:
{
- // TODO(jmadll): This code should check for overflows.
ASSERT(getType().getBasicType() == EbtFloat && rightNode->getBasicType() == EbtFloat);
const int leftCols = getCols();
@@ -1334,42 +949,14 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
}
else
{
- int lhs = leftArray[i].getIConst();
- int divisor = rightArray[i].getIConst();
if (op == EOpDiv)
{
- // Check for the special case where the minimum representable number is
- // divided by -1. If left alone this leads to integer overflow in C++.
- // ESSL 3.00.6 section 4.1.3 Integers:
- // "However, for the case where the minimum representable value is
- // divided by -1, it is allowed to return either the minimum
- // representable value or the maximum representable value."
- if (lhs == -0x7fffffff - 1 && divisor == -1)
- {
- resultArray[i].setIConst(0x7fffffff);
- }
- else
- {
- resultArray[i].setIConst(lhs / divisor);
- }
+ resultArray[i].setIConst(leftArray[i].getIConst() / rightArray[i].getIConst());
}
else
{
ASSERT(op == EOpIMod);
- if (lhs < 0 || divisor < 0)
- {
- // ESSL 3.00.6 section 5.9: Results of modulus are undefined when
- // either one of the operands is negative.
- diagnostics->warning(getLine(),
- "Negative modulus operator operand "
- "encountered during constant folding",
- "%", "");
- resultArray[i].setIConst(0);
- }
- else
- {
- resultArray[i].setIConst(lhs % divisor);
- }
+ resultArray[i].setIConst(leftArray[i].getIConst() % rightArray[i].getIConst());
}
}
break;
@@ -1405,7 +992,6 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
case EOpMatrixTimesVector:
{
- // TODO(jmadll): This code should check for overflows.
ASSERT(rightNode->getBasicType() == EbtFloat);
const int matrixCols = getCols();
@@ -1428,7 +1014,6 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
case EOpVectorTimesMatrix:
{
- // TODO(jmadll): This code should check for overflows.
ASSERT(getType().getBasicType() == EbtFloat);
const int matrixCols = rightNode->getType().getCols();
@@ -1498,12 +1083,12 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
case EOpBitShiftLeft:
resultArray = new TConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
- resultArray[i] = TConstantUnion::lshift(leftArray[i], rightArray[i], diagnostics, line);
+ resultArray[i] = leftArray[i] << rightArray[i];
break;
case EOpBitShiftRight:
resultArray = new TConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
- resultArray[i] = TConstantUnion::rshift(leftArray[i], rightArray[i], diagnostics, line);
+ resultArray[i] = leftArray[i] >> rightArray[i];
break;
case EOpLessThan:
@@ -1561,22 +1146,29 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
return resultArray;
}
-// The fold functions do operations on a constant at GLSL compile time, without generating run-time
-// code. Returns the constant value to keep using. Nullptr should not be returned.
-TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op)
+//
+// The fold functions see if an operation on a constant can be done in place,
+// without generating run-time code.
+//
+// Returns the constant value to keep using or nullptr.
+//
+TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink)
{
- // Do operations where the return type may have a different number of components compared to the
- // operand type.
+ //
+ // Do operations where the return type has a different number of components compared to the operand type.
+ //
const TConstantUnion *operandArray = getUnionArrayPointer();
- ASSERT(operandArray);
+ if (!operandArray)
+ return nullptr;
size_t objectSize = getType().getObjectSize();
TConstantUnion *resultArray = nullptr;
switch (op)
{
- case EOpAny:
- ASSERT(getType().getBasicType() == EbtBool);
+ case EOpAny:
+ if (getType().getBasicType() == EbtBool)
+ {
resultArray = new TConstantUnion();
resultArray->setBConst(false);
for (size_t i = 0; i < objectSize; i++)
@@ -1588,9 +1180,16 @@ TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op)
}
}
break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpAll:
- ASSERT(getType().getBasicType() == EbtBool);
+ case EOpAll:
+ if (getType().getBasicType() == EbtBool)
+ {
resultArray = new TConstantUnion();
resultArray->setBConst(true);
for (size_t i = 0; i < objectSize; i++)
@@ -1602,55 +1201,89 @@ TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op)
}
}
break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpLength:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpLength:
+ if (getType().getBasicType() == EbtFloat)
+ {
resultArray = new TConstantUnion();
resultArray->setFConst(VectorLength(operandArray, objectSize));
break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpTranspose:
+ case EOpTranspose:
+ if (getType().getBasicType() == EbtFloat)
{
- ASSERT(getType().getBasicType() == EbtFloat);
resultArray = new TConstantUnion[objectSize];
angle::Matrix<float> result =
GetMatrix(operandArray, getType().getRows(), getType().getCols()).transpose();
SetUnionArrayFromMatrix(result, resultArray);
break;
}
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpDeterminant:
+ case EOpDeterminant:
+ if (getType().getBasicType() == EbtFloat)
{
- ASSERT(getType().getBasicType() == EbtFloat);
unsigned int size = getType().getNominalSize();
ASSERT(size >= 2 && size <= 4);
resultArray = new TConstantUnion();
resultArray->setFConst(GetMatrix(operandArray, size).determinant());
break;
}
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpInverse:
+ case EOpInverse:
+ if (getType().getBasicType() == EbtFloat)
{
- ASSERT(getType().getBasicType() == EbtFloat);
unsigned int size = getType().getNominalSize();
ASSERT(size >= 2 && size <= 4);
- resultArray = new TConstantUnion[objectSize];
+ resultArray = new TConstantUnion[objectSize];
angle::Matrix<float> result = GetMatrix(operandArray, size).inverse();
SetUnionArrayFromMatrix(result, resultArray);
break;
}
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpPackSnorm2x16:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpPackSnorm2x16:
+ if (getType().getBasicType() == EbtFloat)
+ {
ASSERT(getType().getNominalSize() == 2);
resultArray = new TConstantUnion();
- resultArray->setUConst(
- gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ resultArray->setUConst(gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpUnpackSnorm2x16:
+ case EOpUnpackSnorm2x16:
+ if (getType().getBasicType() == EbtUInt)
{
- ASSERT(getType().getBasicType() == EbtUInt);
resultArray = new TConstantUnion[2];
float f1, f2;
gl::unpackSnorm2x16(operandArray[0].getUConst(), &f1, &f2);
@@ -1658,18 +1291,29 @@ TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op)
resultArray[1].setFConst(f2);
break;
}
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpPackUnorm2x16:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpPackUnorm2x16:
+ if (getType().getBasicType() == EbtFloat)
+ {
ASSERT(getType().getNominalSize() == 2);
resultArray = new TConstantUnion();
- resultArray->setUConst(
- gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ resultArray->setUConst(gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpUnpackUnorm2x16:
+ case EOpUnpackUnorm2x16:
+ if (getType().getBasicType() == EbtUInt)
{
- ASSERT(getType().getBasicType() == EbtUInt);
resultArray = new TConstantUnion[2];
float f1, f2;
gl::unpackUnorm2x16(operandArray[0].getUConst(), &f1, &f2);
@@ -1677,18 +1321,29 @@ TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op)
resultArray[1].setFConst(f2);
break;
}
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpPackHalf2x16:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpPackHalf2x16:
+ if (getType().getBasicType() == EbtFloat)
+ {
ASSERT(getType().getNominalSize() == 2);
resultArray = new TConstantUnion();
- resultArray->setUConst(
- gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ resultArray->setUConst(gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
- case EOpUnpackHalf2x16:
+ case EOpUnpackHalf2x16:
+ if (getType().getBasicType() == EbtUInt)
{
- ASSERT(getType().getBasicType() == EbtUInt);
resultArray = new TConstantUnion[2];
float f1, f2;
gl::unpackHalf2x16(operandArray[0].getUConst(), &f1, &f2);
@@ -1696,24 +1351,29 @@ TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op)
resultArray[1].setFConst(f2);
break;
}
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
+ break;
- default:
- UNREACHABLE();
- break;
+ default:
+ break;
}
return resultArray;
}
-TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op,
- TDiagnostics *diagnostics)
+TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink)
{
- // Do unary operations where each component of the result is computed based on the corresponding
- // component of the operand. Also folds normalize, though the divisor in that case takes all
- // components into account.
+ //
+ // Do unary operations where the return type is the same as operand type.
+ //
const TConstantUnion *operandArray = getUnionArrayPointer();
- ASSERT(operandArray);
+ if (!operandArray)
+ return nullptr;
size_t objectSize = getType().getObjectSize();
@@ -1722,232 +1382,243 @@ TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op,
{
switch(op)
{
- case EOpNegative:
- switch (getType().getBasicType())
- {
- case EbtFloat:
- resultArray[i].setFConst(-operandArray[i].getFConst());
- break;
- case EbtInt:
- if (operandArray[i] == std::numeric_limits<int>::min())
- {
- // The minimum representable integer doesn't have a positive
- // counterpart, rather the negation overflows and in ESSL is supposed to
- // wrap back to the minimum representable integer. Make sure that we
- // don't actually let the negation overflow, which has undefined
- // behavior in C++.
- resultArray[i].setIConst(std::numeric_limits<int>::min());
- }
- else
- {
- resultArray[i].setIConst(-operandArray[i].getIConst());
- }
- break;
- case EbtUInt:
- if (operandArray[i] == 0x80000000u)
- {
- resultArray[i].setUConst(0x80000000u);
- }
- else
- {
- resultArray[i].setUConst(static_cast<unsigned int>(
- -static_cast<int>(operandArray[i].getUConst())));
- }
- break;
- default:
- UNREACHABLE();
- return nullptr;
- }
+ case EOpNegative:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ resultArray[i].setFConst(-operandArray[i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setIConst(-operandArray[i].getIConst());
break;
+ case EbtUInt:
+ resultArray[i].setUConst(static_cast<unsigned int>(
+ -static_cast<int>(operandArray[i].getUConst())));
+ break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
+ }
+ break;
- case EOpPositive:
- switch (getType().getBasicType())
- {
- case EbtFloat:
- resultArray[i].setFConst(operandArray[i].getFConst());
- break;
- case EbtInt:
- resultArray[i].setIConst(operandArray[i].getIConst());
- break;
- case EbtUInt:
- resultArray[i].setUConst(static_cast<unsigned int>(
- static_cast<int>(operandArray[i].getUConst())));
- break;
- default:
- UNREACHABLE();
- return nullptr;
- }
+ case EOpPositive:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ resultArray[i].setFConst(operandArray[i].getFConst());
break;
+ case EbtInt:
+ resultArray[i].setIConst(operandArray[i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setUConst(static_cast<unsigned int>(
+ static_cast<int>(operandArray[i].getUConst())));
+ break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
+ }
+ break;
- case EOpLogicalNot:
- switch (getType().getBasicType())
- {
- case EbtBool:
- resultArray[i].setBConst(!operandArray[i].getBConst());
- break;
- default:
- UNREACHABLE();
- return nullptr;
- }
+ case EOpLogicalNot:
+ // this code is written for possible future use,
+ // will not get executed currently
+ switch (getType().getBasicType())
+ {
+ case EbtBool:
+ resultArray[i].setBConst(!operandArray[i].getBConst());
break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
+ }
+ break;
- case EOpBitwiseNot:
- switch (getType().getBasicType())
- {
- case EbtInt:
- resultArray[i].setIConst(~operandArray[i].getIConst());
- break;
- case EbtUInt:
- resultArray[i].setUConst(~operandArray[i].getUConst());
- break;
- default:
- UNREACHABLE();
- return nullptr;
- }
+ case EOpBitwiseNot:
+ switch (getType().getBasicType())
+ {
+ case EbtInt:
+ resultArray[i].setIConst(~operandArray[i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setUConst(~operandArray[i].getUConst());
break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
+ }
+ break;
- case EOpRadians:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpRadians:
+ if (getType().getBasicType() == EbtFloat)
+ {
resultArray[i].setFConst(kDegreesToRadiansMultiplier * operandArray[i].getFConst());
break;
+ }
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
- case EOpDegrees:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpDegrees:
+ if (getType().getBasicType() == EbtFloat)
+ {
resultArray[i].setFConst(kRadiansToDegreesMultiplier * operandArray[i].getFConst());
break;
+ }
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
- case EOpSin:
- foldFloatTypeUnary(operandArray[i], &sinf, &resultArray[i]);
- break;
+ case EOpSin:
+ if (!foldFloatTypeUnary(operandArray[i], &sinf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpCos:
- foldFloatTypeUnary(operandArray[i], &cosf, &resultArray[i]);
- break;
+ case EOpCos:
+ if (!foldFloatTypeUnary(operandArray[i], &cosf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpTan:
- foldFloatTypeUnary(operandArray[i], &tanf, &resultArray[i]);
- break;
+ case EOpTan:
+ if (!foldFloatTypeUnary(operandArray[i], &tanf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpAsin:
- // For asin(x), results are undefined if |x| > 1, we are choosing to set result to
- // 0.
- if (fabsf(operandArray[i].getFConst()) > 1.0f)
- UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
- diagnostics, &resultArray[i]);
- else
- foldFloatTypeUnary(operandArray[i], &asinf, &resultArray[i]);
- break;
+ case EOpAsin:
+ // For asin(x), results are undefined if |x| > 1, we are choosing to set result to 0.
+ if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f)
+ UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
+ else if (!foldFloatTypeUnary(operandArray[i], &asinf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpAcos:
- // For acos(x), results are undefined if |x| > 1, we are choosing to set result to
- // 0.
- if (fabsf(operandArray[i].getFConst()) > 1.0f)
- UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
- diagnostics, &resultArray[i]);
- else
- foldFloatTypeUnary(operandArray[i], &acosf, &resultArray[i]);
- break;
+ case EOpAcos:
+ // For acos(x), results are undefined if |x| > 1, we are choosing to set result to 0.
+ if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f)
+ UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
+ else if (!foldFloatTypeUnary(operandArray[i], &acosf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpAtan:
- foldFloatTypeUnary(operandArray[i], &atanf, &resultArray[i]);
- break;
+ case EOpAtan:
+ if (!foldFloatTypeUnary(operandArray[i], &atanf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpSinh:
- foldFloatTypeUnary(operandArray[i], &sinhf, &resultArray[i]);
- break;
+ case EOpSinh:
+ if (!foldFloatTypeUnary(operandArray[i], &sinhf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpCosh:
- foldFloatTypeUnary(operandArray[i], &coshf, &resultArray[i]);
- break;
+ case EOpCosh:
+ if (!foldFloatTypeUnary(operandArray[i], &coshf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpTanh:
- foldFloatTypeUnary(operandArray[i], &tanhf, &resultArray[i]);
- break;
+ case EOpTanh:
+ if (!foldFloatTypeUnary(operandArray[i], &tanhf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpAsinh:
- foldFloatTypeUnary(operandArray[i], &asinhf, &resultArray[i]);
- break;
+ case EOpAsinh:
+ if (!foldFloatTypeUnary(operandArray[i], &asinhf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpAcosh:
- // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0.
- if (operandArray[i].getFConst() < 1.0f)
- UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
- diagnostics, &resultArray[i]);
- else
- foldFloatTypeUnary(operandArray[i], &acoshf, &resultArray[i]);
- break;
+ case EOpAcosh:
+ // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0.
+ if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 1.0f)
+ UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
+ else if (!foldFloatTypeUnary(operandArray[i], &acoshf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpAtanh:
- // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to
- // 0.
- if (fabsf(operandArray[i].getFConst()) >= 1.0f)
- UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
- diagnostics, &resultArray[i]);
- else
- foldFloatTypeUnary(operandArray[i], &atanhf, &resultArray[i]);
+ case EOpAtanh:
+ // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to 0.
+ if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) >= 1.0f)
+ UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
+ else if (!foldFloatTypeUnary(operandArray[i], &atanhf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
+
+ case EOpAbs:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ resultArray[i].setFConst(fabsf(operandArray[i].getFConst()));
+ break;
+ case EbtInt:
+ resultArray[i].setIConst(abs(operandArray[i].getIConst()));
break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
+ }
+ break;
- case EOpAbs:
- switch (getType().getBasicType())
+ case EOpSign:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
{
- case EbtFloat:
- resultArray[i].setFConst(fabsf(operandArray[i].getFConst()));
- break;
- case EbtInt:
- resultArray[i].setIConst(abs(operandArray[i].getIConst()));
- break;
- default:
- UNREACHABLE();
- return nullptr;
+ float fConst = operandArray[i].getFConst();
+ float fResult = 0.0f;
+ if (fConst > 0.0f)
+ fResult = 1.0f;
+ else if (fConst < 0.0f)
+ fResult = -1.0f;
+ resultArray[i].setFConst(fResult);
}
break;
-
- case EOpSign:
- switch (getType().getBasicType())
+ case EbtInt:
{
- case EbtFloat:
- {
- float fConst = operandArray[i].getFConst();
- float fResult = 0.0f;
- if (fConst > 0.0f)
- fResult = 1.0f;
- else if (fConst < 0.0f)
- fResult = -1.0f;
- resultArray[i].setFConst(fResult);
- break;
- }
- case EbtInt:
- {
- int iConst = operandArray[i].getIConst();
- int iResult = 0;
- if (iConst > 0)
- iResult = 1;
- else if (iConst < 0)
- iResult = -1;
- resultArray[i].setIConst(iResult);
- break;
- }
- default:
- UNREACHABLE();
- return nullptr;
+ int iConst = operandArray[i].getIConst();
+ int iResult = 0;
+ if (iConst > 0)
+ iResult = 1;
+ else if (iConst < 0)
+ iResult = -1;
+ resultArray[i].setIConst(iResult);
}
break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
+ }
+ break;
- case EOpFloor:
- foldFloatTypeUnary(operandArray[i], &floorf, &resultArray[i]);
- break;
+ case EOpFloor:
+ if (!foldFloatTypeUnary(operandArray[i], &floorf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpTrunc:
- foldFloatTypeUnary(operandArray[i], &truncf, &resultArray[i]);
- break;
+ case EOpTrunc:
+ if (!foldFloatTypeUnary(operandArray[i], &truncf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpRound:
- foldFloatTypeUnary(operandArray[i], &roundf, &resultArray[i]);
- break;
+ case EOpRound:
+ if (!foldFloatTypeUnary(operandArray[i], &roundf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpRoundEven:
+ case EOpRoundEven:
+ if (getType().getBasicType() == EbtFloat)
{
- ASSERT(getType().getBasicType() == EbtFloat);
float x = operandArray[i].getFConst();
float result;
float fractPart = modff(x, &result);
@@ -1958,151 +1629,197 @@ TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op,
resultArray[i].setFConst(result);
break;
}
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
- case EOpCeil:
- foldFloatTypeUnary(operandArray[i], &ceilf, &resultArray[i]);
- break;
+ case EOpCeil:
+ if (!foldFloatTypeUnary(operandArray[i], &ceilf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpFract:
+ case EOpFract:
+ if (getType().getBasicType() == EbtFloat)
{
- ASSERT(getType().getBasicType() == EbtFloat);
float x = operandArray[i].getFConst();
resultArray[i].setFConst(x - floorf(x));
break;
}
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
- case EOpIsNan:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpIsNan:
+ if (getType().getBasicType() == EbtFloat)
+ {
resultArray[i].setBConst(gl::isNaN(operandArray[0].getFConst()));
break;
+ }
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
- case EOpIsInf:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpIsInf:
+ if (getType().getBasicType() == EbtFloat)
+ {
resultArray[i].setBConst(gl::isInf(operandArray[0].getFConst()));
break;
+ }
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
- case EOpFloatBitsToInt:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpFloatBitsToInt:
+ if (getType().getBasicType() == EbtFloat)
+ {
resultArray[i].setIConst(gl::bitCast<int32_t>(operandArray[0].getFConst()));
break;
+ }
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
- case EOpFloatBitsToUint:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpFloatBitsToUint:
+ if (getType().getBasicType() == EbtFloat)
+ {
resultArray[i].setUConst(gl::bitCast<uint32_t>(operandArray[0].getFConst()));
break;
+ }
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
- case EOpIntBitsToFloat:
- ASSERT(getType().getBasicType() == EbtInt);
+ case EOpIntBitsToFloat:
+ if (getType().getBasicType() == EbtInt)
+ {
resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getIConst()));
break;
+ }
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
- case EOpUintBitsToFloat:
- ASSERT(getType().getBasicType() == EbtUInt);
+ case EOpUintBitsToFloat:
+ if (getType().getBasicType() == EbtUInt)
+ {
resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getUConst()));
break;
+ }
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
- case EOpExp:
- foldFloatTypeUnary(operandArray[i], &expf, &resultArray[i]);
- break;
+ case EOpExp:
+ if (!foldFloatTypeUnary(operandArray[i], &expf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpLog:
- // For log(x), results are undefined if x <= 0, we are choosing to set result to 0.
- if (operandArray[i].getFConst() <= 0.0f)
- UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
- diagnostics, &resultArray[i]);
- else
- foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]);
- break;
+ case EOpLog:
+ // For log(x), results are undefined if x <= 0, we are choosing to set result to 0.
+ if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f)
+ UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
+ else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpExp2:
- foldFloatTypeUnary(operandArray[i], &exp2f, &resultArray[i]);
- break;
+ case EOpExp2:
+ if (!foldFloatTypeUnary(operandArray[i], &exp2f, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpLog2:
- // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0.
- // And log2f is not available on some plarforms like old android, so just using
- // log(x)/log(2) here.
- if (operandArray[i].getFConst() <= 0.0f)
- UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
- diagnostics, &resultArray[i]);
- else
- {
- foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]);
- resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f));
- }
- break;
+ case EOpLog2:
+ // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0.
+ // And log2f is not available on some plarforms like old android, so just using log(x)/log(2) here.
+ if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f)
+ UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
+ else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i]))
+ return nullptr;
+ else
+ resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f));
+ break;
- case EOpSqrt:
- // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0.
- if (operandArray[i].getFConst() < 0.0f)
- UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
- diagnostics, &resultArray[i]);
- else
- foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
- break;
+ case EOpSqrt:
+ // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0.
+ if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 0.0f)
+ UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
+ else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i]))
+ return nullptr;
+ break;
- case EOpInverseSqrt:
- // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(),
- // so getting the square root first using builtin function sqrt() and then taking
- // its inverse.
- // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set
- // result to 0.
- if (operandArray[i].getFConst() <= 0.0f)
- UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
- diagnostics, &resultArray[i]);
- else
- {
- foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
- resultArray[i].setFConst(1.0f / resultArray[i].getFConst());
- }
- break;
+ case EOpInverseSqrt:
+ // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(),
+ // so getting the square root first using builtin function sqrt() and then taking its inverse.
+ // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set result to 0.
+ if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f)
+ UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
+ else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i]))
+ return nullptr;
+ else
+ resultArray[i].setFConst(1.0f / resultArray[i].getFConst());
+ break;
- case EOpVectorLogicalNot:
- ASSERT(getType().getBasicType() == EbtBool);
+ case EOpVectorLogicalNot:
+ if (getType().getBasicType() == EbtBool)
+ {
resultArray[i].setBConst(!operandArray[i].getBConst());
break;
+ }
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return nullptr;
- case EOpNormalize:
+ case EOpNormalize:
+ if (getType().getBasicType() == EbtFloat)
{
- ASSERT(getType().getBasicType() == EbtFloat);
- float x = operandArray[i].getFConst();
+ float x = operandArray[i].getFConst();
float length = VectorLength(operandArray, objectSize);
if (length)
resultArray[i].setFConst(x / length);
else
- UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(),
- diagnostics, &resultArray[i]);
+ UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink,
+ &resultArray[i]);
break;
}
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
- case EOpDFdx:
- case EOpDFdy:
- case EOpFwidth:
- ASSERT(getType().getBasicType() == EbtFloat);
+ case EOpDFdx:
+ case EOpDFdy:
+ case EOpFwidth:
+ if (getType().getBasicType() == EbtFloat)
+ {
// Derivatives of constant arguments should be 0.
resultArray[i].setFConst(0.0f);
break;
+ }
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
- default:
- return nullptr;
+ default:
+ return nullptr;
}
}
return resultArray;
}
-void TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion &parameter,
- FloatTypeUnaryFunc builtinFunc,
- TConstantUnion *result) const
+bool TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion &parameter, FloatTypeUnaryFunc builtinFunc,
+ TInfoSink &infoSink, TConstantUnion *result) const
{
ASSERT(builtinFunc);
- ASSERT(getType().getBasicType() == EbtFloat);
- result->setFConst(builtinFunc(parameter.getFConst()));
+ if (getType().getBasicType() == EbtFloat)
+ {
+ result->setFConst(builtinFunc(parameter.getFConst()));
+ return true;
+ }
+
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return false;
}
// static
-TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate *aggregate)
+TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate *aggregate,
+ TInfoSink &infoSink)
{
ASSERT(aggregate->getSequence()->size() > 0u);
size_t resultSize = aggregate->getType().getObjectSize();
@@ -2201,8 +1918,7 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate
}
// static
-TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate,
- TDiagnostics *diagnostics)
+TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink)
{
TOperator op = aggregate->getOp();
TIntermSequence *sequence = aggregate->getSequence();
@@ -2243,298 +1959,284 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
//
switch (op)
{
- case EOpAtan:
+ case EOpAtan:
{
- ASSERT(basicType == EbtFloat);
- resultArray = new TConstantUnion[maxObjectSize];
- for (size_t i = 0; i < maxObjectSize; i++)
+ if (basicType == EbtFloat)
{
- float y = unionArrays[0][i].getFConst();
- float x = unionArrays[1][i].getFConst();
- // Results are undefined if x and y are both 0.
- if (x == 0.0f && y == 0.0f)
- UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
- &resultArray[i]);
- else
- resultArray[i].setFConst(atan2f(y, x));
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float y = unionArrays[0][i].getFConst();
+ float x = unionArrays[1][i].getFConst();
+ // Results are undefined if x and y are both 0.
+ if (x == 0.0f && y == 0.0f)
+ UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]);
+ else
+ resultArray[i].setFConst(atan2f(y, x));
+ }
}
- break;
+ else
+ UNREACHABLE();
}
+ break;
- case EOpPow:
+ case EOpPow:
{
- ASSERT(basicType == EbtFloat);
- resultArray = new TConstantUnion[maxObjectSize];
- for (size_t i = 0; i < maxObjectSize; i++)
+ if (basicType == EbtFloat)
{
- float x = unionArrays[0][i].getFConst();
- float y = unionArrays[1][i].getFConst();
- // Results are undefined if x < 0.
- // Results are undefined if x = 0 and y <= 0.
- if (x < 0.0f)
- UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
- &resultArray[i]);
- else if (x == 0.0f && y <= 0.0f)
- UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
- &resultArray[i]);
- else
- resultArray[i].setFConst(powf(x, y));
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+ // Results are undefined if x < 0.
+ // Results are undefined if x = 0 and y <= 0.
+ if (x < 0.0f)
+ UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]);
+ else if (x == 0.0f && y <= 0.0f)
+ UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]);
+ else
+ resultArray[i].setFConst(powf(x, y));
+ }
}
- break;
+ else
+ UNREACHABLE();
}
+ break;
- case EOpMod:
+ case EOpMod:
{
- ASSERT(basicType == EbtFloat);
- resultArray = new TConstantUnion[maxObjectSize];
- for (size_t i = 0; i < maxObjectSize; i++)
+ if (basicType == EbtFloat)
{
- float x = unionArrays[0][i].getFConst();
- float y = unionArrays[1][i].getFConst();
- resultArray[i].setFConst(x - y * floorf(x / y));
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+ resultArray[i].setFConst(x - y * floorf(x / y));
+ }
}
- break;
+ else
+ UNREACHABLE();
}
+ break;
- case EOpMin:
+ case EOpMin:
{
resultArray = new TConstantUnion[maxObjectSize];
for (size_t i = 0; i < maxObjectSize; i++)
{
switch (basicType)
{
- case EbtFloat:
- resultArray[i].setFConst(std::min(unionArrays[0][i].getFConst(),
- unionArrays[1][i].getFConst()));
- break;
- case EbtInt:
- resultArray[i].setIConst(std::min(unionArrays[0][i].getIConst(),
- unionArrays[1][i].getIConst()));
- break;
- case EbtUInt:
- resultArray[i].setUConst(std::min(unionArrays[0][i].getUConst(),
- unionArrays[1][i].getUConst()));
- break;
- default:
- UNREACHABLE();
- break;
+ case EbtFloat:
+ resultArray[i].setFConst(std::min(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst()));
+ break;
+ case EbtInt:
+ resultArray[i].setIConst(std::min(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst()));
+ break;
+ case EbtUInt:
+ resultArray[i].setUConst(std::min(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst()));
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
- break;
}
+ break;
- case EOpMax:
+ case EOpMax:
{
resultArray = new TConstantUnion[maxObjectSize];
for (size_t i = 0; i < maxObjectSize; i++)
{
switch (basicType)
{
- case EbtFloat:
- resultArray[i].setFConst(std::max(unionArrays[0][i].getFConst(),
- unionArrays[1][i].getFConst()));
- break;
- case EbtInt:
- resultArray[i].setIConst(std::max(unionArrays[0][i].getIConst(),
- unionArrays[1][i].getIConst()));
- break;
- case EbtUInt:
- resultArray[i].setUConst(std::max(unionArrays[0][i].getUConst(),
- unionArrays[1][i].getUConst()));
- break;
- default:
- UNREACHABLE();
- break;
+ case EbtFloat:
+ resultArray[i].setFConst(std::max(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst()));
+ break;
+ case EbtInt:
+ resultArray[i].setIConst(std::max(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst()));
+ break;
+ case EbtUInt:
+ resultArray[i].setUConst(std::max(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst()));
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
- break;
}
+ break;
- case EOpStep:
+ case EOpStep:
{
- ASSERT(basicType == EbtFloat);
- resultArray = new TConstantUnion[maxObjectSize];
- for (size_t i = 0; i < maxObjectSize; i++)
- resultArray[i].setFConst(
- unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f
- : 1.0f);
- break;
+ if (basicType == EbtFloat)
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ resultArray[i].setFConst(unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f : 1.0f);
+ }
+ else
+ UNREACHABLE();
}
+ break;
- case EOpLessThan:
+ case EOpLessThan:
{
resultArray = new TConstantUnion[maxObjectSize];
for (size_t i = 0; i < maxObjectSize; i++)
{
switch (basicType)
{
- case EbtFloat:
- resultArray[i].setBConst(unionArrays[0][i].getFConst() <
- unionArrays[1][i].getFConst());
- break;
- case EbtInt:
- resultArray[i].setBConst(unionArrays[0][i].getIConst() <
- unionArrays[1][i].getIConst());
- break;
- case EbtUInt:
- resultArray[i].setBConst(unionArrays[0][i].getUConst() <
- unionArrays[1][i].getUConst());
- break;
- default:
- UNREACHABLE();
- break;
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() < unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() < unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() < unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
- break;
}
+ break;
- case EOpLessThanEqual:
+ case EOpLessThanEqual:
{
resultArray = new TConstantUnion[maxObjectSize];
for (size_t i = 0; i < maxObjectSize; i++)
{
switch (basicType)
{
- case EbtFloat:
- resultArray[i].setBConst(unionArrays[0][i].getFConst() <=
- unionArrays[1][i].getFConst());
- break;
- case EbtInt:
- resultArray[i].setBConst(unionArrays[0][i].getIConst() <=
- unionArrays[1][i].getIConst());
- break;
- case EbtUInt:
- resultArray[i].setBConst(unionArrays[0][i].getUConst() <=
- unionArrays[1][i].getUConst());
- break;
- default:
- UNREACHABLE();
- break;
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() <= unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() <= unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() <= unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
- break;
}
+ break;
- case EOpGreaterThan:
+ case EOpGreaterThan:
{
resultArray = new TConstantUnion[maxObjectSize];
for (size_t i = 0; i < maxObjectSize; i++)
{
switch (basicType)
{
- case EbtFloat:
- resultArray[i].setBConst(unionArrays[0][i].getFConst() >
- unionArrays[1][i].getFConst());
- break;
- case EbtInt:
- resultArray[i].setBConst(unionArrays[0][i].getIConst() >
- unionArrays[1][i].getIConst());
- break;
- case EbtUInt:
- resultArray[i].setBConst(unionArrays[0][i].getUConst() >
- unionArrays[1][i].getUConst());
- break;
- default:
- UNREACHABLE();
- break;
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() > unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() > unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() > unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
- break;
}
- case EOpGreaterThanEqual:
+ break;
+
+ case EOpGreaterThanEqual:
{
resultArray = new TConstantUnion[maxObjectSize];
for (size_t i = 0; i < maxObjectSize; i++)
{
switch (basicType)
{
- case EbtFloat:
- resultArray[i].setBConst(unionArrays[0][i].getFConst() >=
- unionArrays[1][i].getFConst());
- break;
- case EbtInt:
- resultArray[i].setBConst(unionArrays[0][i].getIConst() >=
- unionArrays[1][i].getIConst());
- break;
- case EbtUInt:
- resultArray[i].setBConst(unionArrays[0][i].getUConst() >=
- unionArrays[1][i].getUConst());
- break;
- default:
- UNREACHABLE();
- break;
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() >= unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() >= unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() >= unionArrays[1][i].getUConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
}
break;
- case EOpVectorEqual:
+ case EOpVectorEqual:
{
resultArray = new TConstantUnion[maxObjectSize];
for (size_t i = 0; i < maxObjectSize; i++)
{
switch (basicType)
{
- case EbtFloat:
- resultArray[i].setBConst(unionArrays[0][i].getFConst() ==
- unionArrays[1][i].getFConst());
- break;
- case EbtInt:
- resultArray[i].setBConst(unionArrays[0][i].getIConst() ==
- unionArrays[1][i].getIConst());
- break;
- case EbtUInt:
- resultArray[i].setBConst(unionArrays[0][i].getUConst() ==
- unionArrays[1][i].getUConst());
- break;
- case EbtBool:
- resultArray[i].setBConst(unionArrays[0][i].getBConst() ==
- unionArrays[1][i].getBConst());
- break;
- default:
- UNREACHABLE();
- break;
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() == unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() == unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() == unionArrays[1][i].getUConst());
+ break;
+ case EbtBool:
+ resultArray[i].setBConst(unionArrays[0][i].getBConst() == unionArrays[1][i].getBConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
- break;
}
+ break;
- case EOpVectorNotEqual:
+ case EOpVectorNotEqual:
{
resultArray = new TConstantUnion[maxObjectSize];
for (size_t i = 0; i < maxObjectSize; i++)
{
switch (basicType)
{
- case EbtFloat:
- resultArray[i].setBConst(unionArrays[0][i].getFConst() !=
- unionArrays[1][i].getFConst());
- break;
- case EbtInt:
- resultArray[i].setBConst(unionArrays[0][i].getIConst() !=
- unionArrays[1][i].getIConst());
- break;
- case EbtUInt:
- resultArray[i].setBConst(unionArrays[0][i].getUConst() !=
- unionArrays[1][i].getUConst());
- break;
- case EbtBool:
- resultArray[i].setBConst(unionArrays[0][i].getBConst() !=
- unionArrays[1][i].getBConst());
- break;
- default:
- UNREACHABLE();
- break;
+ case EbtFloat:
+ resultArray[i].setBConst(unionArrays[0][i].getFConst() != unionArrays[1][i].getFConst());
+ break;
+ case EbtInt:
+ resultArray[i].setBConst(unionArrays[0][i].getIConst() != unionArrays[1][i].getIConst());
+ break;
+ case EbtUInt:
+ resultArray[i].setBConst(unionArrays[0][i].getUConst() != unionArrays[1][i].getUConst());
+ break;
+ case EbtBool:
+ resultArray[i].setBConst(unionArrays[0][i].getBConst() != unionArrays[1][i].getBConst());
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
- break;
}
+ break;
- case EOpDistance:
+ case EOpDistance:
+ if (basicType == EbtFloat)
{
- ASSERT(basicType == EbtFloat);
TConstantUnion *distanceArray = new TConstantUnion[maxObjectSize];
- resultArray = new TConstantUnion();
+ resultArray = new TConstantUnion();
for (size_t i = 0; i < maxObjectSize; i++)
{
float x = unionArrays[0][i].getFConst();
@@ -2542,40 +2244,47 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
distanceArray[i].setFConst(x - y);
}
resultArray->setFConst(VectorLength(distanceArray, maxObjectSize));
- break;
}
+ else
+ UNREACHABLE();
+ break;
+
+ case EOpDot:
- case EOpDot:
- ASSERT(basicType == EbtFloat);
+ if (basicType == EbtFloat)
+ {
resultArray = new TConstantUnion();
- resultArray->setFConst(
- VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize));
- break;
+ resultArray->setFConst(VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize));
+ }
+ else
+ UNREACHABLE();
+ break;
- case EOpCross:
+ case EOpCross:
+ if (basicType == EbtFloat && maxObjectSize == 3)
{
- ASSERT(basicType == EbtFloat && maxObjectSize == 3);
resultArray = new TConstantUnion[maxObjectSize];
- float x0 = unionArrays[0][0].getFConst();
- float x1 = unionArrays[0][1].getFConst();
- float x2 = unionArrays[0][2].getFConst();
- float y0 = unionArrays[1][0].getFConst();
- float y1 = unionArrays[1][1].getFConst();
- float y2 = unionArrays[1][2].getFConst();
+ float x0 = unionArrays[0][0].getFConst();
+ float x1 = unionArrays[0][1].getFConst();
+ float x2 = unionArrays[0][2].getFConst();
+ float y0 = unionArrays[1][0].getFConst();
+ float y1 = unionArrays[1][1].getFConst();
+ float y2 = unionArrays[1][2].getFConst();
resultArray[0].setFConst(x1 * y2 - y1 * x2);
resultArray[1].setFConst(x2 * y0 - y2 * x0);
resultArray[2].setFConst(x0 * y1 - y0 * x1);
- break;
}
+ else
+ UNREACHABLE();
+ break;
- case EOpReflect:
+ case EOpReflect:
+ if (basicType == EbtFloat)
{
- ASSERT(basicType == EbtFloat);
// genType reflect (genType I, genType N) :
- // For the incident vector I and surface orientation N, returns the reflection
- // direction:
+ // For the incident vector I and surface orientation N, returns the reflection direction:
// I - 2 * dot(N, I) * N.
- resultArray = new TConstantUnion[maxObjectSize];
+ resultArray = new TConstantUnion[maxObjectSize];
float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize);
for (size_t i = 0; i < maxObjectSize; i++)
{
@@ -2583,40 +2292,45 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
2.0f * dotProduct * unionArrays[1][i].getFConst();
resultArray[i].setFConst(result);
}
- break;
}
+ else
+ UNREACHABLE();
+ break;
- case EOpMul:
+ case EOpMul:
+ if (basicType == EbtFloat && (*sequence)[0]->getAsTyped()->isMatrix() &&
+ (*sequence)[1]->getAsTyped()->isMatrix())
{
- ASSERT(basicType == EbtFloat && (*sequence)[0]->getAsTyped()->isMatrix() &&
- (*sequence)[1]->getAsTyped()->isMatrix());
// Perform component-wise matrix multiplication.
resultArray = new TConstantUnion[maxObjectSize];
- int size = (*sequence)[0]->getAsTyped()->getNominalSize();
+ int size = (*sequence)[0]->getAsTyped()->getNominalSize();
angle::Matrix<float> result =
GetMatrix(unionArrays[0], size).compMult(GetMatrix(unionArrays[1], size));
SetUnionArrayFromMatrix(result, resultArray);
- break;
}
+ else
+ UNREACHABLE();
+ break;
- case EOpOuterProduct:
+ case EOpOuterProduct:
+ if (basicType == EbtFloat)
{
- ASSERT(basicType == EbtFloat);
size_t numRows = (*sequence)[0]->getAsTyped()->getType().getObjectSize();
size_t numCols = (*sequence)[1]->getAsTyped()->getType().getObjectSize();
- resultArray = new TConstantUnion[numRows * numCols];
+ resultArray = new TConstantUnion[numRows * numCols];
angle::Matrix<float> result =
GetMatrix(unionArrays[0], static_cast<int>(numRows), 1)
.outerProduct(GetMatrix(unionArrays[1], 1, static_cast<int>(numCols)));
SetUnionArrayFromMatrix(result, resultArray);
- break;
}
-
- default:
+ else
UNREACHABLE();
- // TODO: Add constant folding support for other built-in operations that take 2
- // parameters and not handled above.
- return nullptr;
+ break;
+
+ default:
+ UNREACHABLE();
+ // TODO: Add constant folding support for other built-in operations that take 2 parameters and not handled above.
+ return nullptr;
}
}
else if (paramsCount == 3)
@@ -2626,123 +2340,124 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
//
switch (op)
{
- case EOpClamp:
+ case EOpClamp:
{
resultArray = new TConstantUnion[maxObjectSize];
for (size_t i = 0; i < maxObjectSize; i++)
{
switch (basicType)
{
- case EbtFloat:
+ case EbtFloat:
{
- float x = unionArrays[0][i].getFConst();
+ float x = unionArrays[0][i].getFConst();
float min = unionArrays[1][i].getFConst();
float max = unionArrays[2][i].getFConst();
// Results are undefined if min > max.
if (min > max)
- UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
- &resultArray[i]);
+ UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]);
else
resultArray[i].setFConst(gl::clamp(x, min, max));
- break;
}
-
- case EbtInt:
+ break;
+ case EbtInt:
{
- int x = unionArrays[0][i].getIConst();
+ int x = unionArrays[0][i].getIConst();
int min = unionArrays[1][i].getIConst();
int max = unionArrays[2][i].getIConst();
// Results are undefined if min > max.
if (min > max)
- UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
- &resultArray[i]);
+ UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]);
else
resultArray[i].setIConst(gl::clamp(x, min, max));
- break;
}
- case EbtUInt:
+ break;
+ case EbtUInt:
{
- unsigned int x = unionArrays[0][i].getUConst();
+ unsigned int x = unionArrays[0][i].getUConst();
unsigned int min = unionArrays[1][i].getUConst();
unsigned int max = unionArrays[2][i].getUConst();
// Results are undefined if min > max.
if (min > max)
- UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
- &resultArray[i]);
+ UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]);
else
resultArray[i].setUConst(gl::clamp(x, min, max));
- break;
}
- default:
- UNREACHABLE();
- break;
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
- break;
}
+ break;
- case EOpMix:
+ case EOpMix:
{
- ASSERT(basicType == EbtFloat);
- resultArray = new TConstantUnion[maxObjectSize];
- for (size_t i = 0; i < maxObjectSize; i++)
+ if (basicType == EbtFloat)
{
- float x = unionArrays[0][i].getFConst();
- float y = unionArrays[1][i].getFConst();
- TBasicType type = (*sequence)[2]->getAsTyped()->getType().getBasicType();
- if (type == EbtFloat)
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
{
- // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a.
- float a = unionArrays[2][i].getFConst();
- resultArray[i].setFConst(x * (1.0f - a) + y * a);
- }
- else // 3rd parameter is EbtBool
- {
- ASSERT(type == EbtBool);
- // Selects which vector each returned component comes from.
- // For a component of a that is false, the corresponding component of x is
- // returned.
- // For a component of a that is true, the corresponding component of y is
- // returned.
- bool a = unionArrays[2][i].getBConst();
- resultArray[i].setFConst(a ? y : x);
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+ TBasicType type = (*sequence)[2]->getAsTyped()->getType().getBasicType();
+ if (type == EbtFloat)
+ {
+ // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a.
+ float a = unionArrays[2][i].getFConst();
+ resultArray[i].setFConst(x * (1.0f - a) + y * a);
+ }
+ else // 3rd parameter is EbtBool
+ {
+ ASSERT(type == EbtBool);
+ // Selects which vector each returned component comes from.
+ // For a component of a that is false, the corresponding component of x is returned.
+ // For a component of a that is true, the corresponding component of y is returned.
+ bool a = unionArrays[2][i].getBConst();
+ resultArray[i].setFConst(a ? y : x);
+ }
}
}
- break;
+ else
+ UNREACHABLE();
}
+ break;
- case EOpSmoothStep:
+ case EOpSmoothStep:
{
- ASSERT(basicType == EbtFloat);
- resultArray = new TConstantUnion[maxObjectSize];
- for (size_t i = 0; i < maxObjectSize; i++)
+ if (basicType == EbtFloat)
{
- float edge0 = unionArrays[0][i].getFConst();
- float edge1 = unionArrays[1][i].getFConst();
- float x = unionArrays[2][i].getFConst();
- // Results are undefined if edge0 >= edge1.
- if (edge0 >= edge1)
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
{
- UndefinedConstantFoldingError(loc, op, basicType, diagnostics,
- &resultArray[i]);
- }
- else
- {
- // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth
- // Hermite interpolation between 0 and 1 when edge0 < x < edge1.
- float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
- resultArray[i].setFConst(t * t * (3.0f - 2.0f * t));
+ float edge0 = unionArrays[0][i].getFConst();
+ float edge1 = unionArrays[1][i].getFConst();
+ float x = unionArrays[2][i].getFConst();
+ // Results are undefined if edge0 >= edge1.
+ if (edge0 >= edge1)
+ {
+ UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]);
+ }
+ else
+ {
+ // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth
+ // Hermite interpolation between 0 and 1 when edge0 < x < edge1.
+ float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
+ resultArray[i].setFConst(t * t * (3.0f - 2.0f * t));
+ }
}
}
- break;
+ else
+ UNREACHABLE();
}
+ break;
- case EOpFaceForward:
+ case EOpFaceForward:
+ if (basicType == EbtFloat)
{
- ASSERT(basicType == EbtFloat);
// genType faceforward(genType N, genType I, genType Nref) :
// If dot(Nref, I) < 0 return N, otherwise return -N.
- resultArray = new TConstantUnion[maxObjectSize];
+ resultArray = new TConstantUnion[maxObjectSize];
float dotProduct = VectorDotProduct(unionArrays[2], unionArrays[1], maxObjectSize);
for (size_t i = 0; i < maxObjectSize; i++)
{
@@ -2751,42 +2466,43 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
else
resultArray[i].setFConst(-unionArrays[0][i].getFConst());
}
- break;
}
+ else
+ UNREACHABLE();
+ break;
- case EOpRefract:
+ case EOpRefract:
+ if (basicType == EbtFloat)
{
- ASSERT(basicType == EbtFloat);
// genType refract(genType I, genType N, float eta) :
- // For the incident vector I and surface normal N, and the ratio of indices of
- // refraction eta,
+ // For the incident vector I and surface normal N, and the ratio of indices of refraction eta,
// return the refraction vector. The result is computed by
// k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
// if (k < 0.0)
// return genType(0.0)
// else
// return eta * I - (eta * dot(N, I) + sqrt(k)) * N
- resultArray = new TConstantUnion[maxObjectSize];
+ resultArray = new TConstantUnion[maxObjectSize];
float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize);
for (size_t i = 0; i < maxObjectSize; i++)
{
float eta = unionArrays[2][i].getFConst();
- float k = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct);
+ float k = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct);
if (k < 0.0f)
resultArray[i].setFConst(0.0f);
else
resultArray[i].setFConst(eta * unionArrays[0][i].getFConst() -
- (eta * dotProduct + sqrtf(k)) *
- unionArrays[1][i].getFConst());
+ (eta * dotProduct + sqrtf(k)) * unionArrays[1][i].getFConst());
}
- break;
}
-
- default:
+ else
UNREACHABLE();
- // TODO: Add constant folding support for other built-in operations that take 3
- // parameters and not handled above.
- return nullptr;
+ break;
+
+ default:
+ UNREACHABLE();
+ // TODO: Add constant folding support for other built-in operations that take 3 parameters and not handled above.
+ return nullptr;
}
}
return resultArray;
@@ -2815,12 +2531,14 @@ void TIntermTraverser::updateTree()
bool inserted = insertion.parent->insertChildNodes(insertion.position + 1,
insertion.insertionsAfter);
ASSERT(inserted);
+ UNUSED_ASSERTION_VARIABLE(inserted);
}
if (!insertion.insertionsBefore.empty())
{
bool inserted =
insertion.parent->insertChildNodes(insertion.position, insertion.insertionsBefore);
ASSERT(inserted);
+ UNUSED_ASSERTION_VARIABLE(inserted);
}
}
for (size_t ii = 0; ii < mReplacements.size(); ++ii)
@@ -2830,6 +2548,7 @@ void TIntermTraverser::updateTree()
bool replaced = replacement.parent->replaceChildNode(
replacement.original, replacement.replacement);
ASSERT(replaced);
+ UNUSED_ASSERTION_VARIABLE(replaced);
if (!replacement.originalBecomesChildOfReplacement)
{
@@ -2852,6 +2571,7 @@ void TIntermTraverser::updateTree()
bool replaced = replacement.parent->replaceChildNodeWithMultiple(
replacement.original, replacement.replacements);
ASSERT(replaced);
+ UNUSED_ASSERTION_VARIABLE(replaced);
}
clearReplacementQueue();
@@ -2879,5 +2599,3 @@ void TIntermTraverser::queueReplacementWithParent(TIntermNode *parent,
bool originalBecomesChild = (originalStatus == OriginalNode::BECOMES_CHILD);
mReplacements.push_back(NodeUpdateEntry(parent, original, replacement, originalBecomesChild));
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/IntermNode.h b/gfx/angle/src/compiler/translator/IntermNode.h
index 94811bd1c..7068685ee 100755
--- a/gfx/angle/src/compiler/translator/IntermNode.h
+++ b/gfx/angle/src/compiler/translator/IntermNode.h
@@ -27,22 +27,14 @@
#include "compiler/translator/Operator.h"
#include "compiler/translator/Types.h"
-namespace sh
-{
-
class TDiagnostics;
class TIntermTraverser;
class TIntermAggregate;
-class TIntermBlock;
-class TIntermDeclaration;
-class TIntermFunctionDefinition;
-class TIntermSwizzle;
class TIntermBinary;
class TIntermUnary;
class TIntermConstantUnion;
-class TIntermTernary;
-class TIntermIfElse;
+class TIntermSelection;
class TIntermSwitch;
class TIntermCase;
class TIntermTyped;
@@ -54,7 +46,6 @@ class TIntermRaw;
class TIntermBranch;
class TSymbolTable;
-class TFunction;
// Encapsulate an identifier string and track whether it is coming from the original shader code
// (not internal) or from ANGLE (internal). Usually internal names shouldn't be decorated or hashed.
@@ -99,15 +90,10 @@ class TIntermNode : angle::NonCopyable
virtual void traverse(TIntermTraverser *) = 0;
virtual TIntermTyped *getAsTyped() { return 0; }
virtual TIntermConstantUnion *getAsConstantUnion() { return 0; }
- virtual TIntermFunctionDefinition *getAsFunctionDefinition() { return nullptr; }
virtual TIntermAggregate *getAsAggregate() { return 0; }
- virtual TIntermBlock *getAsBlock() { return nullptr; }
- virtual TIntermDeclaration *getAsDeclarationNode() { return nullptr; }
- virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; }
virtual TIntermBinary *getAsBinaryNode() { return 0; }
virtual TIntermUnary *getAsUnaryNode() { return 0; }
- virtual TIntermTernary *getAsTernaryNode() { return nullptr; }
- virtual TIntermIfElse *getAsIfElseNode() { return nullptr; }
+ virtual TIntermSelection *getAsSelectionNode() { return 0; }
virtual TIntermSwitch *getAsSwitchNode() { return 0; }
virtual TIntermCase *getAsCaseNode() { return 0; }
virtual TIntermSymbol *getAsSymbolNode() { return 0; }
@@ -155,7 +141,6 @@ class TIntermTyped : public TIntermNode
TBasicType getBasicType() const { return mType.getBasicType(); }
TQualifier getQualifier() const { return mType.getQualifier(); }
TPrecision getPrecision() const { return mType.getPrecision(); }
- TMemoryQualifier getMemoryQualifier() const { return mType.getMemoryQualifier(); }
int getCols() const { return mType.getCols(); }
int getRows() const { return mType.getRows(); }
int getNominalSize() const { return mType.getNominalSize(); }
@@ -174,9 +159,6 @@ class TIntermTyped : public TIntermNode
bool isConstructorWithOnlyConstantUnionParameters();
- static TIntermTyped *CreateIndexNode(int index);
- static TIntermTyped *CreateZero(const TType &type);
-
protected:
TType mType;
@@ -200,7 +182,7 @@ class TIntermLoop : public TIntermNode
TIntermNode *init,
TIntermTyped *cond,
TIntermTyped *expr,
- TIntermBlock *body)
+ TIntermAggregate *body)
: mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body), mUnrollFlag(false)
{
}
@@ -213,11 +195,11 @@ class TIntermLoop : public TIntermNode
TIntermNode *getInit() { return mInit; }
TIntermTyped *getCondition() { return mCond; }
TIntermTyped *getExpression() { return mExpr; }
- TIntermBlock *getBody() { return mBody; }
+ TIntermAggregate *getBody() { return mBody; }
void setCondition(TIntermTyped *condition) { mCond = condition; }
void setExpression(TIntermTyped *expression) { mExpr = expression; }
- void setBody(TIntermBlock *body) { mBody = body; }
+ void setBody(TIntermAggregate *body) { mBody = body; }
void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
bool getUnrollFlag() const { return mUnrollFlag; }
@@ -227,7 +209,7 @@ class TIntermLoop : public TIntermNode
TIntermNode *mInit; // for-loop initialization
TIntermTyped *mCond; // loop exit condition
TIntermTyped *mExpr; // for-loop expression
- TIntermBlock *mBody; // loop body
+ TIntermAggregate *mBody; // loop body
bool mUnrollFlag; // Whether the loop should be unrolled or not.
};
@@ -334,7 +316,6 @@ class TIntermConstantUnion : public TIntermTyped
TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type)
: TIntermTyped(type), mUnionArrayPointer(unionPointer)
{
- ASSERT(unionPointer);
}
TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); }
@@ -362,7 +343,6 @@ class TIntermConstantUnion : public TIntermTyped
void replaceConstantUnion(const TConstantUnion *safeConstantUnion)
{
- ASSERT(safeConstantUnion);
// Previous union pointer freed on pool deallocation.
mUnionArrayPointer = safeConstantUnion;
}
@@ -373,15 +353,13 @@ class TIntermConstantUnion : public TIntermTyped
TConstantUnion *foldBinary(TOperator op,
TIntermConstantUnion *rightNode,
- TDiagnostics *diagnostics,
- const TSourceLoc &line);
- const TConstantUnion *foldIndexing(int index);
- TConstantUnion *foldUnaryNonComponentWise(TOperator op);
- TConstantUnion *foldUnaryComponentWise(TOperator op, TDiagnostics *diagnostics);
+ TDiagnostics *diagnostics);
+ TConstantUnion *foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink);
+ TConstantUnion *foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink);
- static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate);
- static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate,
- TDiagnostics *diagnostics);
+ static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate,
+ TInfoSink &infoSink);
+ static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink);
protected:
// Same data may be shared between multiple constant unions, so it can't be modified.
@@ -389,9 +367,7 @@ class TIntermConstantUnion : public TIntermTyped
private:
typedef float(*FloatTypeUnaryFunc) (float);
- void foldFloatTypeUnary(const TConstantUnion &parameter,
- FloatTypeUnaryFunc builtinFunc,
- TConstantUnion *result) const;
+ bool foldFloatTypeUnary(const TConstantUnion &parameter, FloatTypeUnaryFunc builtinFunc, TInfoSink &infoSink, TConstantUnion *result) const;
TIntermConstantUnion(const TIntermConstantUnion &node); // Note: not deleted, just private!
};
@@ -403,6 +379,7 @@ class TIntermOperator : public TIntermTyped
{
public:
TOperator getOp() const { return mOp; }
+ void setOp(TOperator op) { mOp = op; }
bool isAssignment() const;
bool isMultiplication() const;
@@ -423,54 +400,24 @@ class TIntermOperator : public TIntermTyped
TOperator mOp;
};
-// Node for vector swizzles.
-class TIntermSwizzle : public TIntermTyped
-{
- public:
- // This constructor determines the type of the node based on the operand.
- TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets);
-
- TIntermTyped *deepCopy() const override { return new TIntermSwizzle(*this); }
-
- TIntermSwizzle *getAsSwizzleNode() override { return this; };
- void traverse(TIntermTraverser *it) override;
- bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
-
- bool hasSideEffects() const override { return mOperand->hasSideEffects(); }
-
- TIntermTyped *getOperand() { return mOperand; }
- void writeOffsetsAsXYZW(TInfoSinkBase *out) const;
-
- bool hasDuplicateOffsets() const;
-
- TIntermTyped *fold();
-
- protected:
- TIntermTyped *mOperand;
- TVector<int> mSwizzleOffsets;
-
- private:
- void promote();
-
- TIntermSwizzle(const TIntermSwizzle &node); // Note: not deleted, just private!
-};
-
//
// Nodes for all the basic binary math operators.
//
class TIntermBinary : public TIntermOperator
{
public:
+ TIntermBinary(TOperator op)
+ : TIntermOperator(op),
+ mAddIndexClamp(false) {}
+
// This constructor determines the type of the binary node based on the operands and op.
+ // This is only supported for math/logical ops, not indexing.
TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right);
TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); }
static TOperator GetMulOpBasedOnOperands(const TType &left, const TType &right);
static TOperator GetMulAssignOpBasedOnOperands(const TType &left, const TType &right);
- static TQualifier GetCommaQualifier(int shaderVersion,
- const TIntermTyped *left,
- const TIntermTyped *right);
TIntermBinary *getAsBinaryNode() override { return this; };
void traverse(TIntermTraverser *it) override;
@@ -481,6 +428,8 @@ class TIntermBinary : public TIntermOperator
return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
}
+ void setLeft(TIntermTyped *node) { mLeft = node; }
+ void setRight(TIntermTyped *node) { mRight = node; }
TIntermTyped *getLeft() const { return mLeft; }
TIntermTyped *getRight() const { return mRight; }
TIntermTyped *fold(TDiagnostics *diagnostics);
@@ -507,7 +456,14 @@ class TIntermBinary : public TIntermOperator
class TIntermUnary : public TIntermOperator
{
public:
- TIntermUnary(TOperator op, TIntermTyped *operand);
+ TIntermUnary(TOperator op, const TType &type)
+ : TIntermOperator(op, type),
+ mOperand(NULL),
+ mUseEmulatedFunction(false) {}
+ TIntermUnary(TOperator op)
+ : TIntermOperator(op),
+ mOperand(NULL),
+ mUseEmulatedFunction(false) {}
TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }
@@ -517,8 +473,10 @@ class TIntermUnary : public TIntermOperator
bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); }
+ void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
- TIntermTyped *fold(TDiagnostics *diagnostics);
+ void promote(const TType *funcReturnType);
+ TIntermTyped *fold(TInfoSink &infoSink);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
@@ -531,107 +489,22 @@ class TIntermUnary : public TIntermOperator
bool mUseEmulatedFunction;
private:
- void promote();
-
TIntermUnary(const TIntermUnary &node); // note: not deleted, just private!
};
-class TFunctionSymbolInfo
-{
- public:
- POOL_ALLOCATOR_NEW_DELETE();
- TFunctionSymbolInfo() : mId(0) {}
-
- TFunctionSymbolInfo(const TFunctionSymbolInfo &) = default;
- TFunctionSymbolInfo &operator=(const TFunctionSymbolInfo &) = default;
-
- void setFromFunction(const TFunction &function);
-
- void setNameObj(const TName &name) { mName = name; }
- const TName &getNameObj() const { return mName; }
-
- const TString &getName() const { return mName.getString(); }
- void setName(const TString &name) { mName.setString(name); }
- bool isMain() const { return mName.getString() == "main("; }
-
- void setId(int functionId) { mId = functionId; }
- int getId() const { return mId; }
- private:
- TName mName;
- int mId;
-};
-
-// Node for function definitions.
-class TIntermFunctionDefinition : public TIntermTyped
-{
- public:
- // TODO(oetuaho@nvidia.com): See if TFunctionSymbolInfo could be added to constructor
- // parameters.
- TIntermFunctionDefinition(const TType &type, TIntermAggregate *parameters, TIntermBlock *body)
- : TIntermTyped(type), mParameters(parameters), mBody(body)
- {
- ASSERT(parameters != nullptr);
- ASSERT(body != nullptr);
- }
-
- TIntermFunctionDefinition *getAsFunctionDefinition() override { return this; }
- void traverse(TIntermTraverser *it) override;
- bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
-
- TIntermTyped *deepCopy() const override
- {
- UNREACHABLE();
- return nullptr;
- }
- bool hasSideEffects() const override
- {
- UNREACHABLE();
- return true;
- }
-
- TIntermAggregate *getFunctionParameters() const { return mParameters; }
- TIntermBlock *getBody() const { return mBody; }
-
- TFunctionSymbolInfo *getFunctionSymbolInfo() { return &mFunctionInfo; }
- const TFunctionSymbolInfo *getFunctionSymbolInfo() const { return &mFunctionInfo; }
-
- private:
- TIntermAggregate *mParameters;
- TIntermBlock *mBody;
-
- TFunctionSymbolInfo mFunctionInfo;
-};
-
typedef TVector<TIntermNode *> TIntermSequence;
typedef TVector<int> TQualifierList;
-// Interface for node classes that have an arbitrarily sized set of children.
-class TIntermAggregateBase
-{
- public:
- virtual ~TIntermAggregateBase() {}
-
- virtual TIntermSequence *getSequence() = 0;
- virtual const TIntermSequence *getSequence() const = 0;
-
- bool replaceChildNodeWithMultiple(TIntermNode *original, const TIntermSequence &replacements);
- bool insertChildNodes(TIntermSequence::size_type position, const TIntermSequence &insertions);
-
- protected:
- TIntermAggregateBase() {}
-
- bool replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement);
-};
-
//
// Nodes that operate on an arbitrary sized set of children.
//
-class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
+class TIntermAggregate : public TIntermOperator
{
public:
TIntermAggregate()
: TIntermOperator(EOpNull),
mUserDefined(false),
+ mFunctionId(0),
mUseEmulatedFunction(false),
mGotPrecisionFromChildren(false)
{
@@ -639,6 +512,7 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
TIntermAggregate(TOperator op)
: TIntermOperator(op),
mUserDefined(false),
+ mFunctionId(0),
mUseEmulatedFunction(false),
mGotPrecisionFromChildren(false)
{
@@ -648,22 +522,29 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
// Note: only supported for nodes that can be a part of an expression.
TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }
- void setOp(TOperator op) { mOp = op; }
-
TIntermAggregate *getAsAggregate() override { return this; }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
-
+ bool replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements);
+ bool insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions);
// Conservatively assume function calls and other aggregate operators have side-effects
bool hasSideEffects() const override { return true; }
- TIntermTyped *fold(TDiagnostics *diagnostics);
+ TIntermTyped *fold(TInfoSink &infoSink);
- TIntermSequence *getSequence() override { return &mSequence; }
- const TIntermSequence *getSequence() const override { return &mSequence; }
+ TIntermSequence *getSequence() { return &mSequence; }
+
+ void setNameObj(const TName &name) { mName = name; }
+ const TName &getNameObj() const { return mName; }
+
+ void setName(const TString &name) { mName.setString(name); }
+ const TString &getName() const { return mName.getString(); }
void setUserDefined() { mUserDefined = true; }
bool isUserDefined() const { return mUserDefined; }
+ void setFunctionId(int functionId) { mFunctionId = functionId; }
+ int getFunctionId() const { return mFunctionId; }
+
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
@@ -674,12 +555,11 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
// Returns true if changing parameter precision may affect the return value.
bool gotPrecisionFromChildren() const { return mGotPrecisionFromChildren; }
- TFunctionSymbolInfo *getFunctionSymbolInfo() { return &mFunctionInfo; }
- const TFunctionSymbolInfo *getFunctionSymbolInfo() const { return &mFunctionInfo; }
-
protected:
TIntermSequence mSequence;
+ TName mName;
bool mUserDefined; // used for user defined function names
+ int mFunctionId;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
@@ -687,110 +567,50 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
bool mGotPrecisionFromChildren;
- TFunctionSymbolInfo mFunctionInfo;
-
private:
TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just private!
};
-// A list of statements. Either the root node which contains declarations and function definitions,
-// or a block that can be marked with curly braces {}.
-class TIntermBlock : public TIntermNode, public TIntermAggregateBase
-{
- public:
- TIntermBlock() : TIntermNode() {}
- ~TIntermBlock() {}
-
- TIntermBlock *getAsBlock() override { return this; }
- void traverse(TIntermTraverser *it) override;
- bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
-
- // Only intended for initially building the block.
- void appendStatement(TIntermNode *statement);
-
- TIntermSequence *getSequence() override { return &mStatements; }
- const TIntermSequence *getSequence() const override { return &mStatements; }
-
- protected:
- TIntermSequence mStatements;
-};
-
-// Struct, interface block or variable declaration. Can contain multiple variable declarators.
-class TIntermDeclaration : public TIntermNode, public TIntermAggregateBase
+//
+// For if tests.
+//
+class TIntermSelection : public TIntermTyped
{
public:
- TIntermDeclaration() : TIntermNode() {}
- ~TIntermDeclaration() {}
-
- TIntermDeclaration *getAsDeclarationNode() override { return this; }
- void traverse(TIntermTraverser *it) override;
- bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
-
- // Only intended for initially building the declaration.
- // The declarator node should be either TIntermSymbol or TIntermBinary with op set to
- // EOpInitialize.
- void appendDeclarator(TIntermTyped *declarator);
-
- TIntermSequence *getSequence() override { return &mDeclarators; }
- const TIntermSequence *getSequence() const override { return &mDeclarators; }
- protected:
- TIntermSequence mDeclarators;
-};
+ TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB)
+ : TIntermTyped(TType(EbtVoid, EbpUndefined)),
+ mCondition(cond),
+ mTrueBlock(trueB),
+ mFalseBlock(falseB) {}
+ TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB,
+ const TType &type)
+ : TIntermTyped(type),
+ mCondition(cond),
+ mTrueBlock(trueB),
+ mFalseBlock(falseB) {}
-// For ternary operators like a ? b : c.
-class TIntermTernary : public TIntermTyped
-{
- public:
- TIntermTernary(TIntermTyped *cond, TIntermTyped *trueExpression, TIntermTyped *falseExpression);
+ // Note: only supported for ternary operator nodes.
+ TIntermTyped *deepCopy() const override { return new TIntermSelection(*this); }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
- TIntermTyped *getCondition() const { return mCondition; }
- TIntermTyped *getTrueExpression() const { return mTrueExpression; }
- TIntermTyped *getFalseExpression() const { return mFalseExpression; }
- TIntermTernary *getAsTernaryNode() override { return this; }
-
- TIntermTyped *deepCopy() const override { return new TIntermTernary(*this); }
-
- bool hasSideEffects() const override
- {
- return mCondition->hasSideEffects() || mTrueExpression->hasSideEffects() ||
- mFalseExpression->hasSideEffects();
- }
-
- static TQualifier DetermineQualifier(TIntermTyped *cond,
- TIntermTyped *trueExpression,
- TIntermTyped *falseExpression);
-
- private:
- TIntermTernary(const TIntermTernary &node); // Note: not deleted, just private!
-
- TIntermTyped *mCondition;
- TIntermTyped *mTrueExpression;
- TIntermTyped *mFalseExpression;
-};
-
-class TIntermIfElse : public TIntermNode
-{
- public:
- TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB)
- : TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB)
- {
- }
-
- void traverse(TIntermTraverser *it) override;
- bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+ // Conservatively assume selections have side-effects
+ bool hasSideEffects() const override { return true; }
- TIntermTyped *getCondition() const { return mCondition; }
- TIntermBlock *getTrueBlock() const { return mTrueBlock; }
- TIntermBlock *getFalseBlock() const { return mFalseBlock; }
- TIntermIfElse *getAsIfElseNode() override { return this; }
+ bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
+ TIntermNode *getCondition() const { return mCondition; }
+ TIntermNode *getTrueBlock() const { return mTrueBlock; }
+ TIntermNode *getFalseBlock() const { return mFalseBlock; }
+ TIntermSelection *getAsSelectionNode() override { return this; }
protected:
TIntermTyped *mCondition;
- TIntermBlock *mTrueBlock;
- TIntermBlock *mFalseBlock;
+ TIntermNode *mTrueBlock;
+ TIntermNode *mFalseBlock;
+
+ private:
+ TIntermSelection(const TIntermSelection &node); // Note: not deleted, just private!
};
//
@@ -799,8 +619,10 @@ class TIntermIfElse : public TIntermNode
class TIntermSwitch : public TIntermNode
{
public:
- TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList)
- : TIntermNode(), mInit(init), mStatementList(statementList)
+ TIntermSwitch(TIntermTyped *init, TIntermAggregate *statementList)
+ : TIntermNode(),
+ mInit(init),
+ mStatementList(statementList)
{
}
@@ -811,12 +633,12 @@ class TIntermSwitch : public TIntermNode
TIntermSwitch *getAsSwitchNode() override { return this; }
TIntermTyped *getInit() { return mInit; }
- TIntermBlock *getStatementList() { return mStatementList; }
- void setStatementList(TIntermBlock *statementList) { mStatementList = statementList; }
+ TIntermAggregate *getStatementList() { return mStatementList; }
+ void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; }
protected:
TIntermTyped *mInit;
- TIntermBlock *mStatementList;
+ TIntermAggregate *mStatementList;
};
//
@@ -872,20 +694,12 @@ class TIntermTraverser : angle::NonCopyable
virtual void visitSymbol(TIntermSymbol *node) {}
virtual void visitRaw(TIntermRaw *node) {}
virtual void visitConstantUnion(TIntermConstantUnion *node) {}
- virtual bool visitSwizzle(Visit visit, TIntermSwizzle *node) { return true; }
virtual bool visitBinary(Visit visit, TIntermBinary *node) { return true; }
virtual bool visitUnary(Visit visit, TIntermUnary *node) { return true; }
- virtual bool visitTernary(Visit visit, TIntermTernary *node) { return true; }
- virtual bool visitIfElse(Visit visit, TIntermIfElse *node) { return true; }
+ virtual bool visitSelection(Visit visit, TIntermSelection *node) { return true; }
virtual bool visitSwitch(Visit visit, TIntermSwitch *node) { return true; }
virtual bool visitCase(Visit visit, TIntermCase *node) { return true; }
- virtual bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
- {
- return true;
- }
virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; }
- virtual bool visitBlock(Visit visit, TIntermBlock *node) { return true; }
- virtual bool visitDeclaration(Visit visit, TIntermDeclaration *node) { return true; }
virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; }
virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; }
@@ -895,17 +709,12 @@ class TIntermTraverser : angle::NonCopyable
virtual void traverseSymbol(TIntermSymbol *node);
virtual void traverseRaw(TIntermRaw *node);
virtual void traverseConstantUnion(TIntermConstantUnion *node);
- virtual void traverseSwizzle(TIntermSwizzle *node);
virtual void traverseBinary(TIntermBinary *node);
virtual void traverseUnary(TIntermUnary *node);
- virtual void traverseTernary(TIntermTernary *node);
- virtual void traverseIfElse(TIntermIfElse *node);
+ virtual void traverseSelection(TIntermSelection *node);
virtual void traverseSwitch(TIntermSwitch *node);
virtual void traverseCase(TIntermCase *node);
- virtual void traverseFunctionDefinition(TIntermFunctionDefinition *node);
virtual void traverseAggregate(TIntermAggregate *node);
- virtual void traverseBlock(TIntermBlock *node);
- virtual void traverseDeclaration(TIntermDeclaration *node);
virtual void traverseLoop(TIntermLoop *node);
virtual void traverseBranch(TIntermBranch *node);
@@ -952,7 +761,7 @@ class TIntermTraverser : angle::NonCopyable
return nullptr;
}
- void pushParentBlock(TIntermBlock *node);
+ void pushParentBlock(TIntermAggregate *node);
void incrementParentBlockPos();
void popParentBlock();
@@ -964,14 +773,14 @@ class TIntermTraverser : angle::NonCopyable
// To replace a single node with multiple nodes on the parent aggregate node
struct NodeReplaceWithMultipleEntry
{
- NodeReplaceWithMultipleEntry(TIntermAggregateBase *_parent,
- TIntermNode *_original,
- TIntermSequence _replacements)
- : parent(_parent), original(_original), replacements(_replacements)
+ NodeReplaceWithMultipleEntry(TIntermAggregate *_parent, TIntermNode *_original, TIntermSequence _replacements)
+ : parent(_parent),
+ original(_original),
+ replacements(_replacements)
{
}
- TIntermAggregateBase *parent;
+ TIntermAggregate *parent;
TIntermNode *original;
TIntermSequence replacements;
};
@@ -979,7 +788,7 @@ class TIntermTraverser : angle::NonCopyable
// To insert multiple nodes on the parent aggregate node
struct NodeInsertMultipleEntry
{
- NodeInsertMultipleEntry(TIntermBlock *_parent,
+ NodeInsertMultipleEntry(TIntermAggregate *_parent,
TIntermSequence::size_type _position,
TIntermSequence _insertionsBefore,
TIntermSequence _insertionsAfter)
@@ -990,7 +799,7 @@ class TIntermTraverser : angle::NonCopyable
{
}
- TIntermBlock *parent;
+ TIntermAggregate *parent;
TIntermSequence::size_type position;
TIntermSequence insertionsBefore;
TIntermSequence insertionsAfter;
@@ -1016,11 +825,11 @@ class TIntermTraverser : angle::NonCopyable
// Helper to create a temporary symbol node.
TIntermSymbol *createTempSymbol(const TType &type);
// Create a node that declares but doesn't initialize a temporary symbol.
- TIntermDeclaration *createTempDeclaration(const TType &type);
+ TIntermAggregate *createTempDeclaration(const TType &type);
// Create a node that initializes the current temporary symbol with initializer having the given qualifier.
- TIntermDeclaration *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier);
+ TIntermAggregate *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier);
// Create a node that initializes the current temporary symbol with initializer.
- TIntermDeclaration *createTempInitDeclaration(TIntermTyped *initializer);
+ TIntermAggregate *createTempInitDeclaration(TIntermTyped *initializer);
// Create a node that assigns rightNode to the current temporary symbol.
TIntermBinary *createTempAssignment(TIntermTyped *rightNode);
// Increment temporary symbol index.
@@ -1082,12 +891,13 @@ class TIntermTraverser : angle::NonCopyable
struct ParentBlock
{
- ParentBlock(TIntermBlock *nodeIn, TIntermSequence::size_type posIn)
- : node(nodeIn), pos(posIn)
+ ParentBlock(TIntermAggregate *nodeIn, TIntermSequence::size_type posIn)
+ : node(nodeIn),
+ pos(posIn)
{
}
- TIntermBlock *node;
+ TIntermAggregate *node;
TIntermSequence::size_type pos;
};
@@ -1120,7 +930,6 @@ class TLValueTrackingTraverser : public TIntermTraverser
void traverseBinary(TIntermBinary *node) final;
void traverseUnary(TIntermUnary *node) final;
- void traverseFunctionDefinition(TIntermFunctionDefinition *node) final;
void traverseAggregate(TIntermAggregate *node) final;
protected:
@@ -1189,10 +998,8 @@ class TMaxDepthTraverser : public TIntermTraverser
bool visitBinary(Visit, TIntermBinary *) override { return depthCheck(); }
bool visitUnary(Visit, TIntermUnary *) override { return depthCheck(); }
- bool visitTernary(Visit, TIntermTernary *) override { return depthCheck(); }
- bool visitIfElse(Visit, TIntermIfElse *) override { return depthCheck(); }
+ bool visitSelection(Visit, TIntermSelection *) override { return depthCheck(); }
bool visitAggregate(Visit, TIntermAggregate *) override { return depthCheck(); }
- bool visitBlock(Visit, TIntermBlock *) override { return depthCheck(); }
bool visitLoop(Visit, TIntermLoop *) override { return depthCheck(); }
bool visitBranch(Visit, TIntermBranch *) override { return depthCheck(); }
@@ -1202,6 +1009,4 @@ class TMaxDepthTraverser : public TIntermTraverser
int mDepthLimit;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_INTERMNODE_H_
diff --git a/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.cpp b/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.cpp
index dd2054f68..b614d8365 100755
--- a/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.cpp
+++ b/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.cpp
@@ -12,9 +12,17 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
+namespace
{
+bool IsNodeBlock(TIntermNode *node)
+{
+ ASSERT(node != nullptr);
+ return (node->getAsAggregate() && node->getAsAggregate()->getOp() == EOpSequence);
+}
+
+} // anonymous namespace
+
IntermNodePatternMatcher::IntermNodePatternMatcher(const unsigned int mask) : mMask(mask)
{
}
@@ -31,7 +39,7 @@ bool IntermNodePatternMatcher::matchInternal(TIntermBinary *node, TIntermNode *p
if ((mMask & kExpressionReturningArray) != 0)
{
if (node->isArray() && node->getOp() == EOpAssign && parentNode != nullptr &&
- !parentNode->getAsBlock())
+ !IsNodeBlock(parentNode))
{
return true;
}
@@ -88,7 +96,7 @@ bool IntermNodePatternMatcher::match(TIntermAggregate *node, TIntermNode *parent
if (node->getType().isArray() && !parentIsAssignment &&
(node->isConstructor() || node->getOp() == EOpFunctionCall) &&
- !parentNode->getAsBlock())
+ !IsNodeBlock(parentNode))
{
return true;
}
@@ -97,13 +105,14 @@ bool IntermNodePatternMatcher::match(TIntermAggregate *node, TIntermNode *parent
return false;
}
-bool IntermNodePatternMatcher::match(TIntermTernary *node)
+bool IntermNodePatternMatcher::match(TIntermSelection *node)
{
if ((mMask & kUnfoldedShortCircuitExpression) != 0)
{
- return true;
+ if (node->usesTernaryOperator())
+ {
+ return true;
+ }
}
return false;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.h b/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.h
index 10f9657ed..be6fc61f7 100755
--- a/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.h
+++ b/gfx/angle/src/compiler/translator/IntermNodePatternMatcher.h
@@ -11,13 +11,10 @@
#ifndef COMPILER_TRANSLATOR_INTERMNODEPATTERNMATCHER_H_
#define COMPILER_TRANSLATOR_INTERMNODEPATTERNMATCHER_H_
-namespace sh
-{
-
class TIntermAggregate;
class TIntermBinary;
class TIntermNode;
-class TIntermTernary;
+class TIntermSelection;
class IntermNodePatternMatcher
{
@@ -45,7 +42,7 @@ class IntermNodePatternMatcher
bool match(TIntermBinary *node, TIntermNode *parentNode, bool isLValueRequiredHere);
bool match(TIntermAggregate *node, TIntermNode *parentNode);
- bool match(TIntermTernary *node);
+ bool match(TIntermSelection *node);
private:
const unsigned int mMask;
@@ -53,6 +50,4 @@ class IntermNodePatternMatcher
bool matchInternal(TIntermBinary *node, TIntermNode *parentNode);
};
-} // namespace sh
-
#endif
diff --git a/gfx/angle/src/compiler/translator/IntermTraverse.cpp b/gfx/angle/src/compiler/translator/IntermTraverse.cpp
index 7f91595d4..2f66ba7cd 100755
--- a/gfx/angle/src/compiler/translator/IntermTraverse.cpp
+++ b/gfx/angle/src/compiler/translator/IntermTraverse.cpp
@@ -8,9 +8,6 @@
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/SymbolTable.h"
-namespace sh
-{
-
void TIntermSymbol::traverse(TIntermTraverser *it)
{
it->traverseSymbol(this);
@@ -26,11 +23,6 @@ void TIntermConstantUnion::traverse(TIntermTraverser *it)
it->traverseConstantUnion(this);
}
-void TIntermSwizzle::traverse(TIntermTraverser *it)
-{
- it->traverseSwizzle(this);
-}
-
void TIntermBinary::traverse(TIntermTraverser *it)
{
it->traverseBinary(this);
@@ -41,14 +33,9 @@ void TIntermUnary::traverse(TIntermTraverser *it)
it->traverseUnary(this);
}
-void TIntermTernary::traverse(TIntermTraverser *it)
+void TIntermSelection::traverse(TIntermTraverser *it)
{
- it->traverseTernary(this);
-}
-
-void TIntermIfElse::traverse(TIntermTraverser *it)
-{
- it->traverseIfElse(this);
+ it->traverseSelection(this);
}
void TIntermSwitch::traverse(TIntermTraverser *it)
@@ -61,21 +48,6 @@ void TIntermCase::traverse(TIntermTraverser *it)
it->traverseCase(this);
}
-void TIntermFunctionDefinition::traverse(TIntermTraverser *it)
-{
- it->traverseFunctionDefinition(this);
-}
-
-void TIntermBlock::traverse(TIntermTraverser *it)
-{
- it->traverseBlock(this);
-}
-
-void TIntermDeclaration::traverse(TIntermTraverser *it)
-{
- it->traverseDeclaration(this);
-}
-
void TIntermAggregate::traverse(TIntermTraverser *it)
{
it->traverseAggregate(this);
@@ -106,7 +78,7 @@ TIntermTraverser::~TIntermTraverser()
{
}
-void TIntermTraverser::pushParentBlock(TIntermBlock *node)
+void TIntermTraverser::pushParentBlock(TIntermAggregate *node)
{
mParentBlockStack.push_back(ParentBlock(node, 0));
}
@@ -154,11 +126,7 @@ TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type, TQualifier
TIntermSymbol *node = new TIntermSymbol(0, symbolName, type);
node->setInternal(true);
-
- ASSERT(qualifier == EvqTemporary || qualifier == EvqConst || qualifier == EvqGlobal);
node->getTypePointer()->setQualifier(qualifier);
- // TODO(oetuaho): Might be useful to sanitize layout qualifier etc. on the type of the created
- // symbol. This might need to be done in other places as well.
return node;
}
@@ -167,25 +135,27 @@ TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type)
return createTempSymbol(type, EvqTemporary);
}
-TIntermDeclaration *TIntermTraverser::createTempDeclaration(const TType &type)
+TIntermAggregate *TIntermTraverser::createTempDeclaration(const TType &type)
{
- TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
- tempDeclaration->appendDeclarator(createTempSymbol(type));
+ TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
+ tempDeclaration->getSequence()->push_back(createTempSymbol(type));
return tempDeclaration;
}
-TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer,
- TQualifier qualifier)
+TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier)
{
ASSERT(initializer != nullptr);
TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier);
- TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
- TIntermBinary *tempInit = new TIntermBinary(EOpInitialize, tempSymbol, initializer);
- tempDeclaration->appendDeclarator(tempInit);
+ TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
+ TIntermBinary *tempInit = new TIntermBinary(EOpInitialize);
+ tempInit->setLeft(tempSymbol);
+ tempInit->setRight(initializer);
+ tempInit->setType(tempSymbol->getType());
+ tempDeclaration->getSequence()->push_back(tempInit);
return tempDeclaration;
}
-TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer)
+TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer)
{
return createTempInitDeclaration(initializer, EvqTemporary);
}
@@ -194,7 +164,10 @@ TIntermBinary *TIntermTraverser::createTempAssignment(TIntermTyped *rightNode)
{
ASSERT(rightNode != nullptr);
TIntermSymbol *tempSymbol = createTempSymbol(rightNode->getType());
- TIntermBinary *assignment = new TIntermBinary(EOpAssign, tempSymbol, rightNode);
+ TIntermBinary *assignment = new TIntermBinary(EOpAssign);
+ assignment->setLeft(tempSymbol);
+ assignment->setRight(rightNode);
+ assignment->setType(tempSymbol->getType());
return assignment;
}
@@ -217,14 +190,13 @@ void TLValueTrackingTraverser::addToFunctionMap(const TName &name, TIntermSequen
bool TLValueTrackingTraverser::isInFunctionMap(const TIntermAggregate *callNode) const
{
ASSERT(callNode->getOp() == EOpFunctionCall);
- return (mFunctionMap.find(callNode->getFunctionSymbolInfo()->getNameObj()) !=
- mFunctionMap.end());
+ return (mFunctionMap.find(callNode->getNameObj()) != mFunctionMap.end());
}
TIntermSequence *TLValueTrackingTraverser::getFunctionParameters(const TIntermAggregate *callNode)
{
ASSERT(isInFunctionMap(callNode));
- return mFunctionMap[callNode->getFunctionSymbolInfo()->getNameObj()];
+ return mFunctionMap[callNode->getNameObj()];
}
void TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter)
@@ -261,26 +233,6 @@ void TIntermTraverser::traverseConstantUnion(TIntermConstantUnion *node)
visitConstantUnion(node);
}
-void TIntermTraverser::traverseSwizzle(TIntermSwizzle *node)
-{
- bool visit = true;
-
- if (preVisit)
- visit = visitSwizzle(PreVisit, node);
-
- if (visit)
- {
- incrementDepth(node);
-
- node->getOperand()->traverse(this);
-
- decrementDepth();
- }
-
- if (visit && postVisit)
- visitSwizzle(PostVisit, node);
-}
-
//
// Traverse a binary node.
//
@@ -442,99 +394,9 @@ void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node)
visitUnary(PostVisit, node);
}
-// Traverse a function definition node.
-void TIntermTraverser::traverseFunctionDefinition(TIntermFunctionDefinition *node)
-{
- bool visit = true;
-
- if (preVisit)
- visit = visitFunctionDefinition(PreVisit, node);
-
- if (visit)
- {
- incrementDepth(node);
- mInGlobalScope = false;
-
- node->getFunctionParameters()->traverse(this);
- if (inVisit)
- visit = visitFunctionDefinition(InVisit, node);
- node->getBody()->traverse(this);
-
- mInGlobalScope = true;
- decrementDepth();
- }
-
- if (visit && postVisit)
- visitFunctionDefinition(PostVisit, node);
-}
-
-// Traverse a block node.
-void TIntermTraverser::traverseBlock(TIntermBlock *node)
-{
- bool visit = true;
-
- TIntermSequence *sequence = node->getSequence();
-
- if (preVisit)
- visit = visitBlock(PreVisit, node);
-
- if (visit)
- {
- incrementDepth(node);
- pushParentBlock(node);
-
- for (auto *child : *sequence)
- {
- child->traverse(this);
- if (visit && inVisit)
- {
- if (child != sequence->back())
- visit = visitBlock(InVisit, node);
- }
-
- incrementParentBlockPos();
- }
-
- popParentBlock();
- decrementDepth();
- }
-
- if (visit && postVisit)
- visitBlock(PostVisit, node);
-}
-
-// Traverse a declaration node.
-void TIntermTraverser::traverseDeclaration(TIntermDeclaration *node)
-{
- bool visit = true;
-
- TIntermSequence *sequence = node->getSequence();
-
- if (preVisit)
- visit = visitDeclaration(PreVisit, node);
-
- if (visit)
- {
- incrementDepth(node);
-
- for (auto *child : *sequence)
- {
- child->traverse(this);
- if (visit && inVisit)
- {
- if (child != sequence->back())
- visit = visitDeclaration(InVisit, node);
- }
- }
-
- decrementDepth();
- }
-
- if (visit && postVisit)
- visitDeclaration(PostVisit, node);
-}
-
+//
// Traverse an aggregate node. Same comments in binary node apply here.
+//
void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
{
bool visit = true;
@@ -548,6 +410,11 @@ void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
{
incrementDepth(node);
+ if (node->getOp() == EOpSequence)
+ pushParentBlock(node);
+ else if (node->getOp() == EOpFunction)
+ mInGlobalScope = false;
+
for (auto *child : *sequence)
{
child->traverse(this);
@@ -556,8 +423,16 @@ void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
if (child != sequence->back())
visit = visitAggregate(InVisit, node);
}
+
+ if (node->getOp() == EOpSequence)
+ incrementParentBlockPos();
}
+ if (node->getOp() == EOpSequence)
+ popParentBlock();
+ else if (node->getOp() == EOpFunction)
+ mInGlobalScope = true;
+
decrementDepth();
}
@@ -565,24 +440,26 @@ void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
visitAggregate(PostVisit, node);
}
-void TLValueTrackingTraverser::traverseFunctionDefinition(TIntermFunctionDefinition *node)
-{
- TIntermAggregate *params = node->getFunctionParameters();
- ASSERT(params != nullptr);
- ASSERT(params->getOp() == EOpParameters);
- addToFunctionMap(node->getFunctionSymbolInfo()->getNameObj(), params->getSequence());
-
- TIntermTraverser::traverseFunctionDefinition(node);
-}
-
void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
{
bool visit = true;
TIntermSequence *sequence = node->getSequence();
- if (node->getOp() == EOpPrototype)
+ switch (node->getOp())
{
- addToFunctionMap(node->getFunctionSymbolInfo()->getNameObj(), sequence);
+ case EOpFunction:
+ {
+ TIntermAggregate *params = sequence->front()->getAsAggregate();
+ ASSERT(params != nullptr);
+ ASSERT(params->getOp() == EOpParameters);
+ addToFunctionMap(node->getNameObj(), params->getSequence());
+ break;
+ }
+ case EOpPrototype:
+ addToFunctionMap(node->getNameObj(), sequence);
+ break;
+ default:
+ break;
}
if (preVisit)
@@ -628,6 +505,11 @@ void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
}
else
{
+ if (node->getOp() == EOpSequence)
+ pushParentBlock(node);
+ else if (node->getOp() == EOpFunction)
+ mInGlobalScope = false;
+
// Find the built-in function corresponding to this op so that we can determine the
// in/out qualifiers of its parameters.
TFunction *builtInFunc = nullptr;
@@ -669,10 +551,18 @@ void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
visit = visitAggregate(InVisit, node);
}
+ if (node->getOp() == EOpSequence)
+ incrementParentBlockPos();
+
++paramIndex;
}
setInFunctionCallOutParameter(false);
+
+ if (node->getOp() == EOpSequence)
+ popParentBlock();
+ else if (node->getOp() == EOpFunction)
+ mInGlobalScope = true;
}
decrementDepth();
@@ -683,37 +573,14 @@ void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
}
//
-// Traverse a ternary node. Same comments in binary node apply here.
+// Traverse a selection node. Same comments in binary node apply here.
//
-void TIntermTraverser::traverseTernary(TIntermTernary *node)
-{
- bool visit = true;
-
- if (preVisit)
- visit = visitTernary(PreVisit, node);
-
- if (visit)
- {
- incrementDepth(node);
- node->getCondition()->traverse(this);
- if (node->getTrueExpression())
- node->getTrueExpression()->traverse(this);
- if (node->getFalseExpression())
- node->getFalseExpression()->traverse(this);
- decrementDepth();
- }
-
- if (visit && postVisit)
- visitTernary(PostVisit, node);
-}
-
-// Traverse an if-else node. Same comments in binary node apply here.
-void TIntermTraverser::traverseIfElse(TIntermIfElse *node)
+void TIntermTraverser::traverseSelection(TIntermSelection *node)
{
bool visit = true;
if (preVisit)
- visit = visitIfElse(PreVisit, node);
+ visit = visitSelection(PreVisit, node);
if (visit)
{
@@ -727,7 +594,7 @@ void TIntermTraverser::traverseIfElse(TIntermIfElse *node)
}
if (visit && postVisit)
- visitIfElse(PostVisit, node);
+ visitSelection(PostVisit, node);
}
//
@@ -766,11 +633,7 @@ void TIntermTraverser::traverseCase(TIntermCase *node)
visit = visitCase(PreVisit, node);
if (visit && node->getCondition())
- {
- incrementDepth(node);
node->getCondition()->traverse(this);
- decrementDepth();
- }
if (visit && postVisit)
visitCase(PostVisit, node);
@@ -834,5 +697,3 @@ void TIntermTraverser::traverseRaw(TIntermRaw *node)
{
visitRaw(node);
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/Intermediate.cpp b/gfx/angle/src/compiler/translator/Intermediate.cpp
index 9e3e455ae..b6fefa45e 100755
--- a/gfx/angle/src/compiler/translator/Intermediate.cpp
+++ b/gfx/angle/src/compiler/translator/Intermediate.cpp
@@ -15,9 +15,6 @@
#include "compiler/translator/Intermediate.h"
#include "compiler/translator/SymbolTable.h"
-namespace sh
-{
-
////////////////////////////////////////////////////////////////////////////
//
// First set of functions are to help build the intermediate representation.
@@ -47,30 +44,52 @@ TIntermSymbol *TIntermediate::addSymbol(
// Returns the added node.
// The caller should set the type of the returned node.
//
-TIntermTyped *TIntermediate::addIndex(TOperator op,
- TIntermTyped *base,
- TIntermTyped *index,
- const TSourceLoc &line,
- TDiagnostics *diagnostics)
+TIntermTyped *TIntermediate::addIndex(
+ TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &line)
{
- TIntermBinary *node = new TIntermBinary(op, base, index);
+ TIntermBinary *node = new TIntermBinary(op);
node->setLine(line);
+ node->setLeft(base);
+ node->setRight(index);
- TIntermTyped *folded = node->fold(diagnostics);
- if (folded)
- {
- return folded;
- }
+ // caller should set the type
return node;
}
+//
+// Add one node as the parent of another that it operates on.
+//
+// Returns the added node.
+//
+TIntermTyped *TIntermediate::addUnaryMath(
+ TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType)
+{
+ //
+ // Make a new node for the operator.
+ //
+ TIntermUnary *node = new TIntermUnary(op);
+ node->setLine(line);
+ node->setOperand(child);
+ node->promote(funcReturnType);
+
+ TIntermTyped *foldedNode = node->fold(mInfoSink);
+ if (foldedNode)
+ return foldedNode;
+
+ return node;
+}
+
+//
// This is the safe way to change the operator on an aggregate, as it
// does lots of error checking and fixing. Especially for establishing
-// a function call's operation on it's set of parameters.
+// a function call's operation on it's set of parameters. Sequences
+// of instructions are also aggregates, but they just direnctly set
+// their operator to EOpSequence.
//
// Returns an aggregate node, which could be the one passed in if
// it was already an aggregate but no operator was set.
+//
TIntermAggregate *TIntermediate::setAggregateOperator(
TIntermNode *node, TOperator op, const TSourceLoc &line)
{
@@ -141,10 +160,11 @@ TIntermAggregate *TIntermediate::growAggregate(
//
// Returns an aggregate, unless NULL was passed in for the existing node.
//
-TIntermAggregate *TIntermediate::MakeAggregate(TIntermNode *node, const TSourceLoc &line)
+TIntermAggregate *TIntermediate::makeAggregate(
+ TIntermNode *node, const TSourceLoc &line)
{
- if (node == nullptr)
- return nullptr;
+ if (node == NULL)
+ return NULL;
TIntermAggregate *aggNode = new TIntermAggregate;
aggNode->getSequence()->push_back(node);
@@ -155,57 +175,70 @@ TIntermAggregate *TIntermediate::MakeAggregate(TIntermNode *node, const TSourceL
}
// If the input node is nullptr, return nullptr.
-// If the input node is a block node, return it.
-// If the input node is not a block node, put it inside a block node and return that.
-TIntermBlock *TIntermediate::EnsureBlock(TIntermNode *node)
+// If the input node is a sequence (block) node, return it.
+// If the input node is not a sequence node, put it inside a sequence node and return that.
+TIntermAggregate *TIntermediate::ensureSequence(TIntermNode *node)
{
if (node == nullptr)
return nullptr;
- TIntermBlock *blockNode = node->getAsBlock();
- if (blockNode != nullptr)
- return blockNode;
-
- blockNode = new TIntermBlock();
- blockNode->setLine(node->getLine());
- blockNode->getSequence()->push_back(node);
- return blockNode;
+ TIntermAggregate *aggNode = node->getAsAggregate();
+ if (aggNode != nullptr && aggNode->getOp() == EOpSequence)
+ return aggNode;
+
+ aggNode = makeAggregate(node, node->getLine());
+ aggNode->setOp(EOpSequence);
+ return aggNode;
}
+//
// For "if" test nodes. There are three children; a condition,
// a true path, and a false path. The two paths are in the
// nodePair.
//
-// Returns the node created.
-TIntermNode *TIntermediate::addIfElse(TIntermTyped *cond,
- TIntermNodePair nodePair,
- const TSourceLoc &line)
+// Returns the selection node created.
+//
+TIntermNode *TIntermediate::addSelection(
+ TIntermTyped *cond, TIntermNodePair nodePair, const TSourceLoc &line)
{
- // For compile time constant conditions, prune the code now.
+ //
+ // For compile time constant selections, prune the code and
+ // test now.
+ //
if (cond->getAsConstantUnion())
{
if (cond->getAsConstantUnion()->getBConst(0) == true)
{
- return EnsureBlock(nodePair.node1);
+ return nodePair.node1 ? setAggregateOperator(
+ nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL;
}
else
{
- return EnsureBlock(nodePair.node2);
+ return nodePair.node2 ? setAggregateOperator(
+ nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL;
}
}
- TIntermIfElse *node =
- new TIntermIfElse(cond, EnsureBlock(nodePair.node1), EnsureBlock(nodePair.node2));
+ TIntermSelection *node = new TIntermSelection(
+ cond, ensureSequence(nodePair.node1), ensureSequence(nodePair.node2));
node->setLine(line);
return node;
}
-TIntermTyped *TIntermediate::AddComma(TIntermTyped *left,
+TIntermTyped *TIntermediate::addComma(TIntermTyped *left,
TIntermTyped *right,
const TSourceLoc &line,
int shaderVersion)
{
+ TQualifier resultQualifier = EvqConst;
+ // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression.
+ if (shaderVersion >= 300 || left->getQualifier() != EvqConst ||
+ right->getQualifier() != EvqConst)
+ {
+ resultQualifier = EvqTemporary;
+ }
+
TIntermTyped *commaNode = nullptr;
if (!left->hasSideEffects())
{
@@ -213,53 +246,58 @@ TIntermTyped *TIntermediate::AddComma(TIntermTyped *left,
}
else
{
- commaNode = new TIntermBinary(EOpComma, left, right);
- commaNode->setLine(line);
+ commaNode = growAggregate(left, right, line);
+ commaNode->getAsAggregate()->setOp(EOpComma);
+ commaNode->setType(right->getType());
}
- TQualifier resultQualifier = TIntermBinary::GetCommaQualifier(shaderVersion, left, right);
commaNode->getTypePointer()->setQualifier(resultQualifier);
return commaNode;
}
+//
// For "?:" test nodes. There are three children; a condition,
// a true path, and a false path. The two paths are specified
// as separate parameters.
//
-// Returns the ternary node created, or one of trueExpression and falseExpression if the expression
-// could be folded.
-TIntermTyped *TIntermediate::AddTernarySelection(TIntermTyped *cond,
- TIntermTyped *trueExpression,
- TIntermTyped *falseExpression,
- const TSourceLoc &line)
+// Returns the selection node created, or one of trueBlock and falseBlock if the expression could be folded.
+//
+TIntermTyped *TIntermediate::addSelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock,
+ const TSourceLoc &line)
{
+ TQualifier resultQualifier = EvqTemporary;
+ if (cond->getQualifier() == EvqConst && trueBlock->getQualifier() == EvqConst &&
+ falseBlock->getQualifier() == EvqConst)
+ {
+ resultQualifier = EvqConst;
+ }
// Note that the node resulting from here can be a constant union without being qualified as
// constant.
if (cond->getAsConstantUnion())
{
- TQualifier resultQualifier =
- TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression);
if (cond->getAsConstantUnion()->getBConst(0))
{
- trueExpression->getTypePointer()->setQualifier(resultQualifier);
- return trueExpression;
+ trueBlock->getTypePointer()->setQualifier(resultQualifier);
+ return trueBlock;
}
else
{
- falseExpression->getTypePointer()->setQualifier(resultQualifier);
- return falseExpression;
+ falseBlock->getTypePointer()->setQualifier(resultQualifier);
+ return falseBlock;
}
}
- // Make a ternary node.
- TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
+ //
+ // Make a selection node.
+ //
+ TIntermSelection *node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
+ node->getTypePointer()->setQualifier(resultQualifier);
node->setLine(line);
return node;
}
-TIntermSwitch *TIntermediate::addSwitch(TIntermTyped *init,
- TIntermBlock *statementList,
- const TSourceLoc &line)
+TIntermSwitch *TIntermediate::addSwitch(
+ TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line)
{
TIntermSwitch *node = new TIntermSwitch(init, statementList);
node->setLine(line);
@@ -292,22 +330,24 @@ TIntermConstantUnion *TIntermediate::addConstantUnion(const TConstantUnion *cons
return node;
}
-TIntermTyped *TIntermediate::AddSwizzle(TIntermTyped *baseExpression,
- const TVectorFields &fields,
- const TSourceLoc &dotLocation)
+TIntermTyped *TIntermediate::addSwizzle(
+ TVectorFields &fields, const TSourceLoc &line)
{
- TVector<int> fieldsVector;
- for (int i = 0; i < fields.num; ++i)
- {
- fieldsVector.push_back(fields.offsets[i]);
- }
- TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldsVector);
- node->setLine(dotLocation);
- TIntermTyped *folded = node->fold();
- if (folded)
+ TIntermAggregate *node = new TIntermAggregate(EOpSequence);
+
+ node->setLine(line);
+ TIntermConstantUnion *constIntNode;
+ TIntermSequence *sequenceVector = node->getSequence();
+ TConstantUnion *unionArray;
+
+ for (int i = 0; i < fields.num; i++)
{
- return folded;
+ unionArray = new TConstantUnion[1];
+ unionArray->setIConst(fields.offsets[i]);
+ constIntNode = addConstantUnion(
+ unionArray, TType(EbtInt, EbpUndefined, EvqConst), line);
+ sequenceVector->push_back(constIntNode);
}
return node;
@@ -320,7 +360,7 @@ TIntermNode *TIntermediate::addLoop(
TLoopType type, TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr,
TIntermNode *body, const TSourceLoc &line)
{
- TIntermNode *node = new TIntermLoop(type, init, cond, expr, EnsureBlock(body));
+ TIntermNode *node = new TIntermLoop(type, init, cond, expr, ensureSequence(body));
node->setLine(line);
return node;
@@ -344,8 +384,34 @@ TIntermBranch* TIntermediate::addBranch(
return node;
}
-TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate,
- TDiagnostics *diagnostics)
+//
+// This is to be executed once the final root is put on top by the parsing
+// process.
+//
+TIntermAggregate *TIntermediate::postProcess(TIntermNode *root)
+{
+ if (root == nullptr)
+ return nullptr;
+
+ //
+ // Finish off the top level sequence, if any
+ //
+ TIntermAggregate *aggRoot = root->getAsAggregate();
+ if (aggRoot != nullptr && aggRoot->getOp() == EOpNull)
+ {
+ aggRoot->setOp(EOpSequence);
+ }
+ else if (aggRoot == nullptr || aggRoot->getOp() != EOpSequence)
+ {
+ aggRoot = new TIntermAggregate(EOpSequence);
+ aggRoot->setLine(root->getLine());
+ aggRoot->getSequence()->push_back(root);
+ }
+
+ return aggRoot;
+}
+
+TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate)
{
switch (aggregate->getOp())
{
@@ -372,16 +438,14 @@ TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate,
case EOpFaceForward:
case EOpReflect:
case EOpRefract:
- return aggregate->fold(diagnostics);
+ return aggregate->fold(mInfoSink);
default:
// TODO: Add support for folding array constructors
if (aggregate->isConstructor() && !aggregate->isArray())
{
- return aggregate->fold(diagnostics);
+ return aggregate->fold(mInfoSink);
}
// Constant folding not supported for the built-in.
return nullptr;
}
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/Intermediate.h b/gfx/angle/src/compiler/translator/Intermediate.h
index d712bf953..339daa3e8 100755
--- a/gfx/angle/src/compiler/translator/Intermediate.h
+++ b/gfx/angle/src/compiler/translator/Intermediate.h
@@ -9,9 +9,6 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
struct TVectorFields
{
int offsets[4];
@@ -19,42 +16,38 @@ struct TVectorFields
};
//
-// Set of helper functions to help build the tree.
+// Set of helper functions to help parse and build the tree.
//
+class TInfoSink;
class TIntermediate
{
public:
POOL_ALLOCATOR_NEW_DELETE();
- TIntermediate() {}
+ TIntermediate(TInfoSink &i)
+ : mInfoSink(i) { }
TIntermSymbol *addSymbol(
int id, const TString &, const TType &, const TSourceLoc &);
- TIntermTyped *addIndex(TOperator op,
- TIntermTyped *base,
- TIntermTyped *index,
- const TSourceLoc &line,
- TDiagnostics *diagnostics);
+ TIntermTyped *addIndex(
+ TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &);
TIntermTyped *addUnaryMath(
TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType);
TIntermAggregate *growAggregate(
TIntermNode *left, TIntermNode *right, const TSourceLoc &);
- static TIntermAggregate *MakeAggregate(TIntermNode *node, const TSourceLoc &line);
- static TIntermBlock *EnsureBlock(TIntermNode *node);
+ TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &);
+ TIntermAggregate *ensureSequence(TIntermNode *node);
TIntermAggregate *setAggregateOperator(TIntermNode *, TOperator, const TSourceLoc &);
- TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &line);
- static TIntermTyped *AddTernarySelection(TIntermTyped *cond,
- TIntermTyped *trueExpression,
- TIntermTyped *falseExpression,
- const TSourceLoc &line);
- TIntermSwitch *addSwitch(TIntermTyped *init,
- TIntermBlock *statementList,
- const TSourceLoc &line);
+ TIntermNode *addSelection(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &);
+ TIntermTyped *addSelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock,
+ const TSourceLoc &line);
+ TIntermSwitch *addSwitch(
+ TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line);
TIntermCase *addCase(
TIntermTyped *condition, const TSourceLoc &line);
- static TIntermTyped *AddComma(TIntermTyped *left,
- TIntermTyped *right,
- const TSourceLoc &line,
- int shaderVersion);
+ TIntermTyped *addComma(TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &line,
+ int shaderVersion);
TIntermConstantUnion *addConstantUnion(const TConstantUnion *constantUnion,
const TType &type,
const TSourceLoc &line);
@@ -62,18 +55,17 @@ class TIntermediate
TIntermNode *, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
- static TIntermTyped *AddSwizzle(TIntermTyped *baseExpression,
- const TVectorFields &fields,
- const TSourceLoc &dotLocation);
+ TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &);
+ TIntermAggregate *postProcess(TIntermNode *root);
static void outputTree(TIntermNode *, TInfoSinkBase &);
- TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate, TDiagnostics *diagnostics);
+ TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate);
private:
void operator=(TIntermediate &); // prevent assignments
-};
-} // namespace sh
+ TInfoSink & mInfoSink;
+};
#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_
diff --git a/gfx/angle/src/compiler/translator/LoopInfo.cpp b/gfx/angle/src/compiler/translator/LoopInfo.cpp
index 48fa24472..d931a18a2 100755
--- a/gfx/angle/src/compiler/translator/LoopInfo.cpp
+++ b/gfx/angle/src/compiler/translator/LoopInfo.cpp
@@ -6,9 +6,6 @@
#include "compiler/translator/LoopInfo.h"
-namespace sh
-{
-
namespace
{
@@ -96,7 +93,8 @@ void TLoopIndexInfo::fillInfo(TIntermLoop *node)
// Here we assume all the operations are valid, because the loop node is
// already validated in ValidateLimitations.
- TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
+ TIntermSequence *declSeq =
+ node->getInit()->getAsAggregate()->getSequence();
TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
@@ -211,4 +209,3 @@ void TLoopStack::pop()
pop_back();
}
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/LoopInfo.h b/gfx/angle/src/compiler/translator/LoopInfo.h
index 393aa64f6..ec73fd0fa 100755
--- a/gfx/angle/src/compiler/translator/LoopInfo.h
+++ b/gfx/angle/src/compiler/translator/LoopInfo.h
@@ -9,9 +9,6 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
class TLoopIndexInfo
{
public:
@@ -79,7 +76,5 @@ class TLoopStack : public TVector<TLoopInfo>
void pop();
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_LOOPINFO_H_
diff --git a/gfx/angle/src/compiler/translator/Operator.cpp b/gfx/angle/src/compiler/translator/Operator.cpp
index 57878b930..2a6f1e4fc 100755
--- a/gfx/angle/src/compiler/translator/Operator.cpp
+++ b/gfx/angle/src/compiler/translator/Operator.cpp
@@ -62,6 +62,8 @@ const char *GetOperatorString(TOperator op)
case EOpIndexDirectStruct:
case EOpIndexDirectInterfaceBlock: return ".";
+ case EOpVectorSwizzle: return ".";
+
case EOpRadians: return "radians";
case EOpDegrees: return "degrees";
case EOpSin: return "sin";
diff --git a/gfx/angle/src/compiler/translator/Operator.h b/gfx/angle/src/compiler/translator/Operator.h
index f7706f8ed..b3acc5f08 100755
--- a/gfx/angle/src/compiler/translator/Operator.h
+++ b/gfx/angle/src/compiler/translator/Operator.h
@@ -13,9 +13,12 @@
enum TOperator
{
EOpNull, // if in a node, should only mean a node is still being built
+ EOpSequence, // denotes a list of statements, or parameters, etc.
EOpFunctionCall,
+ EOpFunction, // For function definition
EOpParameters, // an aggregate listing the parameters to a function
+ EOpDeclaration,
EOpInvariantDeclaration, // Specialized declarations for attributing invariance
EOpPrototype,
@@ -74,6 +77,8 @@ enum TOperator
EOpIndexDirectStruct,
EOpIndexDirectInterfaceBlock,
+ EOpVectorSwizzle,
+
//
// Built-in functions potentially mapped to operators
//
diff --git a/gfx/angle/src/compiler/translator/OutputESSL.cpp b/gfx/angle/src/compiler/translator/OutputESSL.cpp
index e55d6c544..77e0a8fb3 100755
--- a/gfx/angle/src/compiler/translator/OutputESSL.cpp
+++ b/gfx/angle/src/compiler/translator/OutputESSL.cpp
@@ -6,27 +6,20 @@
#include "compiler/translator/OutputESSL.h"
-namespace sh
-{
-
TOutputESSL::TOutputESSL(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap &nameMap,
TSymbolTable &symbolTable,
- sh::GLenum shaderType,
int shaderVersion,
- bool forceHighp,
- ShCompileOptions compileOptions)
+ bool forceHighp)
: TOutputGLSLBase(objSink,
clampingStrategy,
hashFunction,
nameMap,
symbolTable,
- shaderType,
shaderVersion,
- SH_ESSL_OUTPUT,
- compileOptions),
+ SH_ESSL_OUTPUT),
mForceHighp(forceHighp)
{
}
@@ -43,5 +36,3 @@ bool TOutputESSL::writeVariablePrecision(TPrecision precision)
out << getPrecisionString(precision);
return true;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/OutputESSL.h b/gfx/angle/src/compiler/translator/OutputESSL.h
index 5b2cb9492..c5a963499 100755
--- a/gfx/angle/src/compiler/translator/OutputESSL.h
+++ b/gfx/angle/src/compiler/translator/OutputESSL.h
@@ -9,29 +9,22 @@
#include "compiler/translator/OutputGLSLBase.h"
-namespace sh
-{
-
class TOutputESSL : public TOutputGLSLBase
{
- public:
- TOutputESSL(TInfoSinkBase &objSink,
+public:
+ TOutputESSL(TInfoSinkBase& objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
- NameMap &nameMap,
- TSymbolTable &symbolTable,
- sh::GLenum shaderType,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable,
int shaderVersion,
- bool forceHighp,
- ShCompileOptions compileOptions);
+ bool forceHighp);
- protected:
- bool writeVariablePrecision(TPrecision precision) override;
+protected:
+ bool writeVariablePrecision(TPrecision precision) override;
- private:
+private:
bool mForceHighp;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_OUTPUTESSL_H_
diff --git a/gfx/angle/src/compiler/translator/OutputGLSL.cpp b/gfx/angle/src/compiler/translator/OutputGLSL.cpp
index fc2b18471..431425020 100755
--- a/gfx/angle/src/compiler/translator/OutputGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/OutputGLSL.cpp
@@ -6,27 +6,20 @@
#include "compiler/translator/OutputGLSL.h"
-namespace sh
-{
-
-TOutputGLSL::TOutputGLSL(TInfoSinkBase &objSink,
+TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
- NameMap &nameMap,
- TSymbolTable &symbolTable,
- sh::GLenum shaderType,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable,
int shaderVersion,
- ShShaderOutput output,
- ShCompileOptions compileOptions)
+ ShShaderOutput output)
: TOutputGLSLBase(objSink,
clampingStrategy,
hashFunction,
nameMap,
symbolTable,
- shaderType,
shaderVersion,
- output,
- compileOptions)
+ output)
{
}
@@ -44,11 +37,11 @@ void TOutputGLSL::visitSymbol(TIntermSymbol *node)
{
out << "gl_FragDepth";
}
- else if (symbol == "gl_FragColor" && sh::IsGLSL130OrNewer(getShaderOutput()))
+ else if (symbol == "gl_FragColor" && IsGLSL130OrNewer(getShaderOutput()))
{
out << "webgl_FragColor";
}
- else if (symbol == "gl_FragData" && sh::IsGLSL130OrNewer(getShaderOutput()))
+ else if (symbol == "gl_FragData" && IsGLSL130OrNewer(getShaderOutput()))
{
out << "webgl_FragData";
}
@@ -94,8 +87,8 @@ TString TOutputGLSL::translateTextureFunction(TString &name)
"textureCubeGradEXT", "textureGrad",
NULL, NULL
};
- const char **mapping =
- (sh::IsGLSL130OrNewer(getShaderOutput())) ? legacyToCoreRename : simpleRename;
+ const char **mapping = (IsGLSL130OrNewer(getShaderOutput())) ?
+ legacyToCoreRename : simpleRename;
for (int i = 0; mapping[i] != NULL; i += 2)
{
@@ -107,5 +100,3 @@ TString TOutputGLSL::translateTextureFunction(TString &name)
return name;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/OutputGLSL.h b/gfx/angle/src/compiler/translator/OutputGLSL.h
index d910c0004..9b1aca4ea 100755
--- a/gfx/angle/src/compiler/translator/OutputGLSL.h
+++ b/gfx/angle/src/compiler/translator/OutputGLSL.h
@@ -9,21 +9,16 @@
#include "compiler/translator/OutputGLSLBase.h"
-namespace sh
-{
-
class TOutputGLSL : public TOutputGLSLBase
{
public:
- TOutputGLSL(TInfoSinkBase &objSink,
+ TOutputGLSL(TInfoSinkBase& objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
- NameMap &nameMap,
- TSymbolTable &symbolTable,
- sh::GLenum shaderType,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable,
int shaderVersion,
- ShShaderOutput output,
- ShCompileOptions compileOptions);
+ ShShaderOutput output);
protected:
bool writeVariablePrecision(TPrecision) override;
@@ -31,6 +26,4 @@ class TOutputGLSL : public TOutputGLSLBase
TString translateTextureFunction(TString &name) override;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_OUTPUTGLSL_H_
diff --git a/gfx/angle/src/compiler/translator/OutputGLSLBase.cpp b/gfx/angle/src/compiler/translator/OutputGLSLBase.cpp
index 2c32b2ea5..296eef7d1 100755
--- a/gfx/angle/src/compiler/translator/OutputGLSLBase.cpp
+++ b/gfx/angle/src/compiler/translator/OutputGLSLBase.cpp
@@ -10,9 +10,6 @@
#include <cfloat>
-namespace sh
-{
-
namespace
{
TString arrayBrackets(const TType &type)
@@ -25,17 +22,16 @@ TString arrayBrackets(const TType &type)
bool isSingleStatement(TIntermNode *node)
{
- if (node->getAsFunctionDefinition())
- {
- return false;
- }
- else if (node->getAsBlock())
+ if (const TIntermAggregate *aggregate = node->getAsAggregate())
{
- return false;
+ return (aggregate->getOp() != EOpFunction) &&
+ (aggregate->getOp() != EOpSequence);
}
- else if (node->getAsIfElseNode())
+ else if (const TIntermSelection *selection = node->getAsSelectionNode())
{
- return false;
+ // Ternary operators are usually part of an assignment operator.
+ // This handles those rare cases in which they are all by themselves.
+ return selection->usesTernaryOperator();
}
else if (node->getAsLoopNode())
{
@@ -52,32 +48,6 @@ bool isSingleStatement(TIntermNode *node)
return true;
}
-// If SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS is enabled, layout qualifiers are spilled whenever
-// variables with specified layout qualifiers are copied. Additional checks are needed against the
-// type and storage qualifier of the variable to verify that layout qualifiers have to be outputted.
-// TODO (mradev): Fix layout qualifier spilling in ScalarizeVecAndMatConstructorArgs and remove
-// NeedsToWriteLayoutQualifier.
-bool NeedsToWriteLayoutQualifier(const TType &type)
-{
- if (type.getBasicType() == EbtInterfaceBlock)
- {
- return false;
- }
-
- const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
-
- if ((type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqVertexIn) &&
- layoutQualifier.location >= 0)
- {
- return true;
- }
- if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
- {
- return true;
- }
- return false;
-}
-
} // namespace
TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
@@ -85,10 +55,8 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
ShHashFunction64 hashFunction,
NameMap &nameMap,
TSymbolTable &symbolTable,
- sh::GLenum shaderType,
int shaderVersion,
- ShShaderOutput output,
- ShCompileOptions compileOptions)
+ ShShaderOutput output)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
mDeclaringVariables(false),
@@ -96,20 +64,9 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
mHashFunction(hashFunction),
mNameMap(nameMap),
mSymbolTable(symbolTable),
- mShaderType(shaderType),
mShaderVersion(shaderVersion),
- mOutput(output),
- mCompileOptions(compileOptions)
-{
-}
-
-void TOutputGLSLBase::writeInvariantQualifier(const TType &type)
+ mOutput(output)
{
- if (!sh::RemoveInvariant(mShaderType, mShaderVersion, mOutput, mCompileOptions))
- {
- TInfoSinkBase &out = objSink();
- out << "invariant ";
- }
}
void TOutputGLSLBase::writeTriplet(
@@ -134,121 +91,55 @@ void TOutputGLSLBase::writeBuiltInFunctionTriplet(
void TOutputGLSLBase::writeLayoutQualifier(const TType &type)
{
- if (!NeedsToWriteLayoutQualifier(type))
- {
- return;
- }
-
- TInfoSinkBase &out = objSink();
- const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
- out << "layout(";
-
if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqVertexIn)
{
+ const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
if (layoutQualifier.location >= 0)
{
- out << "location = " << layoutQualifier.location;
+ TInfoSinkBase &out = objSink();
+ out << "layout(location = " << layoutQualifier.location << ") ";
}
}
-
- if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
- {
- ASSERT(type.getQualifier() == EvqTemporary || type.getQualifier() == EvqUniform);
- out << getImageInternalFormatString(layoutQualifier.imageInternalFormat);
- }
-
- out << ") ";
-}
-
-const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier)
-{
- if (sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 &&
- (mCompileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0)
- {
- switch (qualifier)
- {
- // The return string is consistent with sh::getQualifierString() from
- // BaseTypes.h minus the "centroid" keyword.
- case EvqCentroid:
- return "";
- case EvqCentroidIn:
- return "smooth in";
- case EvqCentroidOut:
- return "smooth out";
- default:
- break;
- }
- }
- if (sh::IsGLSL130OrNewer(mOutput))
- {
- switch (qualifier)
- {
- case EvqAttribute:
- return "in";
- case EvqVaryingIn:
- return "in";
- case EvqVaryingOut:
- return "out";
- default:
- break;
- }
- }
- return sh::getQualifierString(qualifier);
}
void TOutputGLSLBase::writeVariableType(const TType &type)
{
- TQualifier qualifier = type.getQualifier();
TInfoSinkBase &out = objSink();
if (type.isInvariant())
{
- writeInvariantQualifier(type);
+ out << "invariant ";
}
if (type.getBasicType() == EbtInterfaceBlock)
{
TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
declareInterfaceBlockLayout(interfaceBlock);
}
+ TQualifier qualifier = type.getQualifier();
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
{
- const char *qualifierString = mapQualifierToString(qualifier);
- if (qualifierString && qualifierString[0] != '\0')
+ if (IsGLSL130OrNewer(mOutput))
{
- out << qualifierString << " ";
+ switch (qualifier)
+ {
+ case EvqAttribute:
+ out << "in ";
+ break;
+ case EvqVaryingIn:
+ out << "in ";
+ break;
+ case EvqVaryingOut:
+ out << "out ";
+ break;
+ default:
+ out << type.getQualifierString() << " ";
+ break;
+ }
+ }
+ else
+ {
+ out << type.getQualifierString() << " ";
}
}
-
- const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier();
- if (memoryQualifier.readonly)
- {
- ASSERT(IsImage(type.getBasicType()));
- out << "readonly ";
- }
-
- if (memoryQualifier.writeonly)
- {
- ASSERT(IsImage(type.getBasicType()));
- out << "writeonly ";
- }
-
- if (memoryQualifier.coherent)
- {
- ASSERT(IsImage(type.getBasicType()));
- out << "coherent ";
- }
-
- if (memoryQualifier.restrictQualifier)
- {
- ASSERT(IsImage(type.getBasicType()));
- out << "restrict ";
- }
-
- if (memoryQualifier.volatileQualifier)
- {
- ASSERT(IsImage(type.getBasicType()));
- out << "volatile ";
- }
-
// Declare the struct if we have not done so already.
if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
{
@@ -286,8 +177,9 @@ void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args)
const TType &type = arg->getType();
writeVariableType(type);
- if (!arg->getName().getString().empty())
- out << " " << hashName(arg->getName());
+ const TString &name = arg->getSymbol();
+ if (!name.empty())
+ out << " " << hashName(name);
if (type.isArray())
out << arrayBrackets(type);
@@ -305,7 +197,7 @@ const TConstantUnion *TOutputGLSLBase::writeConstantUnion(
if (type.getBasicType() == EbtStruct)
{
const TStructure *structure = type.getStruct();
- out << hashName(TName(structure->name())) << "(";
+ out << hashName(structure->name()) << "(";
const TFieldList &fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
@@ -379,7 +271,7 @@ void TOutputGLSLBase::visitSymbol(TIntermSymbol *node)
if (mLoopUnrollStack.needsToReplaceSymbolWithValue(node))
out << mLoopUnrollStack.getLoopIndexValue(node);
else
- out << hashVariableName(node->getName());
+ out << hashVariableName(node->getSymbol());
if (mDeclaringVariables && node->getType().isArray())
out << arrayBrackets(node->getType());
@@ -390,222 +282,241 @@ void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node)
writeConstantUnion(node->getType(), node->getUnionArrayPointer());
}
-bool TOutputGLSLBase::visitSwizzle(Visit visit, TIntermSwizzle *node)
-{
- TInfoSinkBase &out = objSink();
- if (visit == PostVisit)
- {
- out << ".";
- node->writeOffsetsAsXYZW(&out);
- }
- return true;
-}
-
bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
{
bool visitChildren = true;
TInfoSinkBase &out = objSink();
switch (node->getOp())
{
- case EOpComma:
- writeTriplet(visit, "(", ", ", ")");
- break;
- case EOpInitialize:
+ case EOpInitialize:
+ if (visit == InVisit)
+ {
+ out << " = ";
+ // RHS of initialize is not being declared.
+ mDeclaringVariables = false;
+ }
+ break;
+ case EOpAssign:
+ writeTriplet(visit, "(", " = ", ")");
+ break;
+ case EOpAddAssign:
+ writeTriplet(visit, "(", " += ", ")");
+ break;
+ case EOpSubAssign:
+ writeTriplet(visit, "(", " -= ", ")");
+ break;
+ case EOpDivAssign:
+ writeTriplet(visit, "(", " /= ", ")");
+ break;
+ case EOpIModAssign:
+ writeTriplet(visit, "(", " %= ", ")");
+ break;
+ // Notice the fall-through.
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ writeTriplet(visit, "(", " *= ", ")");
+ break;
+ case EOpBitShiftLeftAssign:
+ writeTriplet(visit, "(", " <<= ", ")");
+ break;
+ case EOpBitShiftRightAssign:
+ writeTriplet(visit, "(", " >>= ", ")");
+ break;
+ case EOpBitwiseAndAssign:
+ writeTriplet(visit, "(", " &= ", ")");
+ break;
+ case EOpBitwiseXorAssign:
+ writeTriplet(visit, "(", " ^= ", ")");
+ break;
+ case EOpBitwiseOrAssign:
+ writeTriplet(visit, "(", " |= ", ")");
+ break;
+
+ case EOpIndexDirect:
+ writeTriplet(visit, NULL, "[", "]");
+ break;
+ case EOpIndexIndirect:
+ if (node->getAddIndexClamp())
+ {
if (visit == InVisit)
{
- out << " = ";
- // RHS of initialize is not being declared.
- mDeclaringVariables = false;
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
+ out << "[int(clamp(float(";
+ else
+ out << "[webgl_int_clamp(";
}
- break;
- case EOpAssign:
- writeTriplet(visit, "(", " = ", ")");
- break;
- case EOpAddAssign:
- writeTriplet(visit, "(", " += ", ")");
- break;
- case EOpSubAssign:
- writeTriplet(visit, "(", " -= ", ")");
- break;
- case EOpDivAssign:
- writeTriplet(visit, "(", " /= ", ")");
- break;
- case EOpIModAssign:
- writeTriplet(visit, "(", " %= ", ")");
- break;
- // Notice the fall-through.
- case EOpMulAssign:
- case EOpVectorTimesMatrixAssign:
- case EOpVectorTimesScalarAssign:
- case EOpMatrixTimesScalarAssign:
- case EOpMatrixTimesMatrixAssign:
- writeTriplet(visit, "(", " *= ", ")");
- break;
- case EOpBitShiftLeftAssign:
- writeTriplet(visit, "(", " <<= ", ")");
- break;
- case EOpBitShiftRightAssign:
- writeTriplet(visit, "(", " >>= ", ")");
- break;
- case EOpBitwiseAndAssign:
- writeTriplet(visit, "(", " &= ", ")");
- break;
- case EOpBitwiseXorAssign:
- writeTriplet(visit, "(", " ^= ", ")");
- break;
- case EOpBitwiseOrAssign:
- writeTriplet(visit, "(", " |= ", ")");
- break;
-
- case EOpIndexDirect:
- writeTriplet(visit, NULL, "[", "]");
- break;
- case EOpIndexIndirect:
- if (node->getAddIndexClamp())
+ else if (visit == PostVisit)
{
- if (visit == InVisit)
+ int maxSize;
+ TIntermTyped *left = node->getLeft();
+ TType leftType = left->getType();
+
+ if (left->isArray())
{
- if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
- out << "[int(clamp(float(";
- else
- out << "[webgl_int_clamp(";
+ // The shader will fail validation if the array length is not > 0.
+ maxSize = static_cast<int>(leftType.getArraySize()) - 1;
}
- else if (visit == PostVisit)
+ else
{
- int maxSize;
- TIntermTyped *left = node->getLeft();
- TType leftType = left->getType();
-
- if (left->isArray())
- {
- // The shader will fail validation if the array length is not > 0.
- maxSize = static_cast<int>(leftType.getArraySize()) - 1;
- }
- else
- {
- maxSize = leftType.getNominalSize() - 1;
- }
-
- if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
- out << "), 0.0, float(" << maxSize << ")))]";
- else
- out << ", 0, " << maxSize << ")]";
+ maxSize = leftType.getNominalSize() - 1;
}
+
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
+ out << "), 0.0, float(" << maxSize << ")))]";
+ else
+ out << ", 0, " << maxSize << ")]";
}
- else
- {
- writeTriplet(visit, NULL, "[", "]");
- }
- break;
- case EOpIndexDirectStruct:
- if (visit == InVisit)
- {
- // Here we are writing out "foo.bar", where "foo" is struct
- // and "bar" is field. In AST, it is represented as a binary
- // node, where left child represents "foo" and right child "bar".
- // The node itself represents ".". The struct field "bar" is
- // actually stored as an index into TStructure::fields.
- out << ".";
- const TStructure *structure = node->getLeft()->getType().getStruct();
- const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
- const TField *field = structure->fields()[index->getIConst(0)];
-
- TString fieldName = field->name();
- if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion))
- fieldName = hashName(TName(fieldName));
-
- out << fieldName;
- visitChildren = false;
- }
- break;
- case EOpIndexDirectInterfaceBlock:
- if (visit == InVisit)
+ }
+ else
+ {
+ writeTriplet(visit, NULL, "[", "]");
+ }
+ break;
+ case EOpIndexDirectStruct:
+ if (visit == InVisit)
+ {
+ // Here we are writing out "foo.bar", where "foo" is struct
+ // and "bar" is field. In AST, it is represented as a binary
+ // node, where left child represents "foo" and right child "bar".
+ // The node itself represents ".". The struct field "bar" is
+ // actually stored as an index into TStructure::fields.
+ out << ".";
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+
+ TString fieldName = field->name();
+ if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion))
+ fieldName = hashName(fieldName);
+
+ out << fieldName;
+ visitChildren = false;
+ }
+ break;
+ case EOpIndexDirectInterfaceBlock:
+ if (visit == InVisit)
+ {
+ out << ".";
+ const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = interfaceBlock->fields()[index->getIConst(0)];
+
+ TString fieldName = field->name();
+ ASSERT(!mSymbolTable.findBuiltIn(interfaceBlock->name(), mShaderVersion));
+ fieldName = hashName(fieldName);
+
+ out << fieldName;
+ visitChildren = false;
+ }
+ break;
+ case EOpVectorSwizzle:
+ if (visit == InVisit)
+ {
+ out << ".";
+ TIntermAggregate *rightChild = node->getRight()->getAsAggregate();
+ TIntermSequence *sequence = rightChild->getSequence();
+ for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); ++sit)
{
- out << ".";
- const TInterfaceBlock *interfaceBlock =
- node->getLeft()->getType().getInterfaceBlock();
- const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
- const TField *field = interfaceBlock->fields()[index->getIConst(0)];
-
- TString fieldName = field->name();
- ASSERT(!mSymbolTable.findBuiltIn(interfaceBlock->name(), mShaderVersion));
- fieldName = hashName(TName(fieldName));
-
- out << fieldName;
- visitChildren = false;
+ TIntermConstantUnion *element = (*sit)->getAsConstantUnion();
+ ASSERT(element->getBasicType() == EbtInt);
+ ASSERT(element->getNominalSize() == 1);
+ const TConstantUnion& data = element->getUnionArrayPointer()[0];
+ ASSERT(data.getType() == EbtInt);
+ switch (data.getIConst())
+ {
+ case 0:
+ out << "x";
+ break;
+ case 1:
+ out << "y";
+ break;
+ case 2:
+ out << "z";
+ break;
+ case 3:
+ out << "w";
+ break;
+ default:
+ UNREACHABLE();
+ }
}
- break;
+ visitChildren = false;
+ }
+ break;
- case EOpAdd:
- writeTriplet(visit, "(", " + ", ")");
- break;
- case EOpSub:
- writeTriplet(visit, "(", " - ", ")");
- break;
- case EOpMul:
- writeTriplet(visit, "(", " * ", ")");
- break;
- case EOpDiv:
- writeTriplet(visit, "(", " / ", ")");
- break;
- case EOpIMod:
- writeTriplet(visit, "(", " % ", ")");
- break;
- case EOpBitShiftLeft:
- writeTriplet(visit, "(", " << ", ")");
- break;
- case EOpBitShiftRight:
- writeTriplet(visit, "(", " >> ", ")");
- break;
- case EOpBitwiseAnd:
- writeTriplet(visit, "(", " & ", ")");
- break;
- case EOpBitwiseXor:
- writeTriplet(visit, "(", " ^ ", ")");
- break;
- case EOpBitwiseOr:
- writeTriplet(visit, "(", " | ", ")");
- break;
+ case EOpAdd:
+ writeTriplet(visit, "(", " + ", ")");
+ break;
+ case EOpSub:
+ writeTriplet(visit, "(", " - ", ")");
+ break;
+ case EOpMul:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
+ case EOpDiv:
+ writeTriplet(visit, "(", " / ", ")");
+ break;
+ case EOpIMod:
+ writeTriplet(visit, "(", " % ", ")");
+ break;
+ case EOpBitShiftLeft:
+ writeTriplet(visit, "(", " << ", ")");
+ break;
+ case EOpBitShiftRight:
+ writeTriplet(visit, "(", " >> ", ")");
+ break;
+ case EOpBitwiseAnd:
+ writeTriplet(visit, "(", " & ", ")");
+ break;
+ case EOpBitwiseXor:
+ writeTriplet(visit, "(", " ^ ", ")");
+ break;
+ case EOpBitwiseOr:
+ writeTriplet(visit, "(", " | ", ")");
+ break;
- case EOpEqual:
- writeTriplet(visit, "(", " == ", ")");
- break;
- case EOpNotEqual:
- writeTriplet(visit, "(", " != ", ")");
- break;
- case EOpLessThan:
- writeTriplet(visit, "(", " < ", ")");
- break;
- case EOpGreaterThan:
- writeTriplet(visit, "(", " > ", ")");
- break;
- case EOpLessThanEqual:
- writeTriplet(visit, "(", " <= ", ")");
- break;
- case EOpGreaterThanEqual:
- writeTriplet(visit, "(", " >= ", ")");
- break;
+ case EOpEqual:
+ writeTriplet(visit, "(", " == ", ")");
+ break;
+ case EOpNotEqual:
+ writeTriplet(visit, "(", " != ", ")");
+ break;
+ case EOpLessThan:
+ writeTriplet(visit, "(", " < ", ")");
+ break;
+ case EOpGreaterThan:
+ writeTriplet(visit, "(", " > ", ")");
+ break;
+ case EOpLessThanEqual:
+ writeTriplet(visit, "(", " <= ", ")");
+ break;
+ case EOpGreaterThanEqual:
+ writeTriplet(visit, "(", " >= ", ")");
+ break;
- // Notice the fall-through.
- case EOpVectorTimesScalar:
- case EOpVectorTimesMatrix:
- case EOpMatrixTimesVector:
- case EOpMatrixTimesScalar:
- case EOpMatrixTimesMatrix:
- writeTriplet(visit, "(", " * ", ")");
- break;
+ // Notice the fall-through.
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
- case EOpLogicalOr:
- writeTriplet(visit, "(", " || ", ")");
- break;
- case EOpLogicalXor:
- writeTriplet(visit, "(", " ^^ ", ")");
- break;
- case EOpLogicalAnd:
- writeTriplet(visit, "(", " && ", ")");
- break;
- default:
- UNREACHABLE();
+ case EOpLogicalOr:
+ writeTriplet(visit, "(", " || ", ")");
+ break;
+ case EOpLogicalXor:
+ writeTriplet(visit, "(", " ^^ ", ")");
+ break;
+ case EOpLogicalAnd:
+ writeTriplet(visit, "(", " && ", ")");
+ break;
+ default:
+ UNREACHABLE();
}
return visitChildren;
@@ -800,40 +711,40 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
return true;
}
-bool TOutputGLSLBase::visitTernary(Visit visit, TIntermTernary *node)
+bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection *node)
{
TInfoSinkBase &out = objSink();
- // Notice two brackets at the beginning and end. The outer ones
- // encapsulate the whole ternary expression. This preserves the
- // order of precedence when ternary expressions are used in a
- // compound expression, i.e., c = 2 * (a < b ? 1 : 2).
- out << "((";
- node->getCondition()->traverse(this);
- out << ") ? (";
- node->getTrueExpression()->traverse(this);
- out << ") : (";
- node->getFalseExpression()->traverse(this);
- out << "))";
- return false;
-}
-bool TOutputGLSLBase::visitIfElse(Visit visit, TIntermIfElse *node)
-{
- TInfoSinkBase &out = objSink();
-
- out << "if (";
- node->getCondition()->traverse(this);
- out << ")\n";
+ if (node->usesTernaryOperator())
+ {
+ // Notice two brackets at the beginning and end. The outer ones
+ // encapsulate the whole ternary expression. This preserves the
+ // order of precedence when ternary expressions are used in a
+ // compound expression, i.e., c = 2 * (a < b ? 1 : 2).
+ out << "((";
+ node->getCondition()->traverse(this);
+ out << ") ? (";
+ node->getTrueBlock()->traverse(this);
+ out << ") : (";
+ node->getFalseBlock()->traverse(this);
+ out << "))";
+ }
+ else
+ {
+ out << "if (";
+ node->getCondition()->traverse(this);
+ out << ")\n";
- incrementDepth(node);
- visitCodeBlock(node->getTrueBlock());
+ incrementDepth(node);
+ visitCodeBlock(node->getTrueBlock());
- if (node->getFalseBlock())
- {
- out << "else\n";
- visitCodeBlock(node->getFalseBlock());
+ if (node->getFalseBlock())
+ {
+ out << "else\n";
+ visitCodeBlock(node->getFalseBlock());
+ }
+ decrementDepth();
}
- decrementDepth();
return false;
}
@@ -867,65 +778,6 @@ bool TOutputGLSLBase::visitCase(Visit visit, TIntermCase *node)
}
}
-bool TOutputGLSLBase::visitBlock(Visit visit, TIntermBlock *node)
-{
- TInfoSinkBase &out = objSink();
- // Scope the blocks except when at the global scope.
- if (mDepth > 0)
- {
- out << "{\n";
- }
-
- incrementDepth(node);
- for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
- iter != node->getSequence()->end(); ++iter)
- {
- TIntermNode *curNode = *iter;
- ASSERT(curNode != nullptr);
- curNode->traverse(this);
-
- if (isSingleStatement(curNode))
- out << ";\n";
- }
- decrementDepth();
-
- // Scope the blocks except when at the global scope.
- if (mDepth > 0)
- {
- out << "}\n";
- }
- return false;
-}
-
-bool TOutputGLSLBase::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
-{
- TInfoSinkBase &out = objSink();
-
- ASSERT(visit == PreVisit);
- {
- const TType &type = node->getType();
- writeVariableType(type);
- if (type.isArray())
- out << arrayBrackets(type);
- }
-
- out << " " << hashFunctionNameIfNeeded(node->getFunctionSymbolInfo()->getNameObj());
-
- incrementDepth(node);
-
- // Traverse function parameters.
- TIntermAggregate *params = node->getFunctionParameters()->getAsAggregate();
- ASSERT(params->getOp() == EOpParameters);
- params->traverse(this);
-
- // Traverse function body.
- visitCodeBlock(node->getBody());
- decrementDepth();
-
- // Fully processed; no need to visit children.
- return false;
-}
-
bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
{
bool visitChildren = true;
@@ -933,6 +785,33 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
bool useEmulatedFunction = (visit == PreVisit && node->getUseEmulatedFunction());
switch (node->getOp())
{
+ case EOpSequence:
+ // Scope the sequences except when at the global scope.
+ if (mDepth > 0)
+ {
+ out << "{\n";
+ }
+
+ incrementDepth(node);
+ for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
+ iter != node->getSequence()->end(); ++iter)
+ {
+ TIntermNode *curNode = *iter;
+ ASSERT(curNode != NULL);
+ curNode->traverse(this);
+
+ if (isSingleStatement(curNode))
+ out << ";\n";
+ }
+ decrementDepth();
+
+ // Scope the sequences except when at the global scope.
+ if (mDepth > 0)
+ {
+ out << "}\n";
+ }
+ visitChildren = false;
+ break;
case EOpPrototype:
// Function declaration.
ASSERT(visit == PreVisit);
@@ -943,7 +822,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
out << arrayBrackets(type);
}
- out << " " << hashFunctionNameIfNeeded(node->getFunctionSymbolInfo()->getNameObj());
+ out << " " << hashFunctionNameIfNeeded(node->getNameObj());
out << "(";
writeFunctionParameters(*(node->getSequence()));
@@ -951,10 +830,46 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
visitChildren = false;
break;
+ case EOpFunction: {
+ // Function definition.
+ ASSERT(visit == PreVisit);
+ {
+ const TType &type = node->getType();
+ writeVariableType(type);
+ if (type.isArray())
+ out << arrayBrackets(type);
+ }
+
+ out << " " << hashFunctionNameIfNeeded(node->getNameObj());
+
+ incrementDepth(node);
+ // Function definition node contains one or two children nodes
+ // representing function parameters and function body. The latter
+ // is not present in case of empty function bodies.
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT((sequence.size() == 1) || (sequence.size() == 2));
+ TIntermSequence::const_iterator seqIter = sequence.begin();
+
+ // Traverse function parameters.
+ TIntermAggregate *params = (*seqIter)->getAsAggregate();
+ ASSERT(params != NULL);
+ ASSERT(params->getOp() == EOpParameters);
+ params->traverse(this);
+
+ // Traverse function body.
+ TIntermAggregate *body = ++seqIter != sequence.end() ?
+ (*seqIter)->getAsAggregate() : NULL;
+ visitCodeBlock(body);
+ decrementDepth();
+
+ // Fully processed; no need to visit children.
+ visitChildren = false;
+ break;
+ }
case EOpFunctionCall:
// Function call.
if (visit == PreVisit)
- out << hashFunctionNameIfNeeded(node->getFunctionSymbolInfo()->getNameObj()) << "(";
+ out << hashFunctionNameIfNeeded(node->getNameObj()) << "(";
else if (visit == InVisit)
out << ", ";
else
@@ -968,6 +883,27 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
out << ")";
visitChildren = false;
break;
+ case EOpDeclaration:
+ // Variable declaration.
+ if (visit == PreVisit)
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ const TIntermTyped *variable = sequence.front()->getAsTyped();
+ writeLayoutQualifier(variable->getType());
+ writeVariableType(variable->getType());
+ out << " ";
+ mDeclaringVariables = true;
+ }
+ else if (visit == InVisit)
+ {
+ out << ", ";
+ mDeclaringVariables = true;
+ }
+ else
+ {
+ mDeclaringVariables = false;
+ }
+ break;
case EOpInvariantDeclaration:
// Invariant declaration.
ASSERT(visit == PreVisit);
@@ -976,7 +912,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
ASSERT(sequence && sequence->size() == 1);
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
ASSERT(symbol);
- out << "invariant " << hashVariableName(symbol->getName());
+ out << "invariant " << hashVariableName(symbol->getSymbol());
}
visitChildren = false;
break;
@@ -1031,6 +967,9 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpVectorNotEqual:
writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction);
break;
+ case EOpComma:
+ writeTriplet(visit, "(", ", ", ")");
+ break;
case EOpMod:
writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction);
@@ -1090,32 +1029,6 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
return visitChildren;
}
-bool TOutputGLSLBase::visitDeclaration(Visit visit, TIntermDeclaration *node)
-{
- TInfoSinkBase &out = objSink();
-
- // Variable declaration.
- if (visit == PreVisit)
- {
- const TIntermSequence &sequence = *(node->getSequence());
- const TIntermTyped *variable = sequence.front()->getAsTyped();
- writeLayoutQualifier(variable->getType());
- writeVariableType(variable->getType());
- out << " ";
- mDeclaringVariables = true;
- }
- else if (visit == InVisit)
- {
- out << ", ";
- mDeclaringVariables = true;
- }
- else
- {
- mDeclaringVariables = false;
- }
- return true;
-}
-
bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
{
TInfoSinkBase &out = objSink();
@@ -1149,10 +1062,11 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
else
{
// Need to put a one-iteration loop here to handle break.
- TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
+ TIntermSequence *declSeq =
+ node->getInit()->getAsAggregate()->getSequence();
TIntermSymbol *indexSymbol =
(*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
- TString name = hashVariableName(indexSymbol->getName());
+ TString name = hashVariableName(indexSymbol->getSymbol());
out << "for (int " << name << " = 0; "
<< name << " < 1; "
<< "++" << name << ")\n";
@@ -1220,7 +1134,7 @@ bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch *node)
return true;
}
-void TOutputGLSLBase::visitCodeBlock(TIntermBlock *node)
+void TOutputGLSLBase::visitCodeBlock(TIntermNode *node)
{
TInfoSinkBase &out = objSink();
if (node != NULL)
@@ -1240,43 +1154,27 @@ void TOutputGLSLBase::visitCodeBlock(TIntermBlock *node)
TString TOutputGLSLBase::getTypeName(const TType &type)
{
if (type.getBasicType() == EbtStruct)
- return hashName(TName(type.getStruct()->name()));
+ return hashName(type.getStruct()->name());
else
return type.getBuiltInTypeNameString();
}
-TString TOutputGLSLBase::hashName(const TName &name)
+TString TOutputGLSLBase::hashName(const TString &name)
{
- if (name.getString().empty())
- {
- ASSERT(!name.isInternal());
- return name.getString();
- }
- if (name.isInternal())
- {
- // TODO(oetuaho): Would be nicer to prefix non-internal names with "_" instead, like is
- // done in the HLSL output, but that requires fairly complex changes elsewhere in the code
- // as well.
- // We need to use a prefix that is reserved in WebGL in order to guarantee that the internal
- // names don't conflict with user-defined names from WebGL.
- return "webgl_angle_" + name.getString();
- }
- if (mHashFunction == nullptr)
- {
- return name.getString();
- }
- NameMap::const_iterator it = mNameMap.find(name.getString().c_str());
+ if (mHashFunction == NULL || name.empty())
+ return name;
+ NameMap::const_iterator it = mNameMap.find(name.c_str());
if (it != mNameMap.end())
return it->second.c_str();
- TString hashedName = TIntermTraverser::hash(name.getString(), mHashFunction);
- mNameMap[name.getString().c_str()] = hashedName.c_str();
+ TString hashedName = TIntermTraverser::hash(name, mHashFunction);
+ mNameMap[name.c_str()] = hashedName.c_str();
return hashedName;
}
-TString TOutputGLSLBase::hashVariableName(const TName &name)
+TString TOutputGLSLBase::hashVariableName(const TString &name)
{
- if (mSymbolTable.findBuiltIn(name.getString(), mShaderVersion) != NULL)
- return name.getString();
+ if (mSymbolTable.findBuiltIn(name, mShaderVersion) != NULL)
+ return name;
return hashName(name);
}
@@ -1287,16 +1185,9 @@ TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TName &mangledName)
if (mSymbolTable.findBuiltIn(mangledStr, mShaderVersion) != nullptr || name == "main")
return translateTextureFunction(name);
if (mangledName.isInternal())
- {
- // Internal function names are outputted as-is - they may refer to functions manually added
- // to the output shader source that are not included in the AST at all.
return name;
- }
else
- {
- TName nameObj(name);
- return hashName(nameObj);
- }
+ return hashName(name);
}
bool TOutputGLSLBase::structDeclared(const TStructure *structure) const
@@ -1314,14 +1205,14 @@ void TOutputGLSLBase::declareStruct(const TStructure *structure)
{
TInfoSinkBase &out = objSink();
- out << "struct " << hashName(TName(structure->name())) << "{\n";
+ out << "struct " << hashName(structure->name()) << "{\n";
const TFieldList &fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
{
const TField *field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
- out << getTypeName(*field->type()) << " " << hashName(TName(field->name()));
+ out << getTypeName(*field->type()) << " " << hashName(field->name());
if (field->type()->isArray())
out << arrayBrackets(*field->type());
out << ";\n";
@@ -1382,19 +1273,17 @@ void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBloc
{
TInfoSinkBase &out = objSink();
- out << hashName(TName(interfaceBlock->name())) << "{\n";
+ out << hashName(interfaceBlock->name()) << "{\n";
const TFieldList &fields = interfaceBlock->fields();
for (size_t i = 0; i < fields.size(); ++i)
{
const TField *field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
- out << getTypeName(*field->type()) << " " << hashName(TName(field->name()));
+ out << getTypeName(*field->type()) << " " << hashName(field->name());
if (field->type()->isArray())
out << arrayBrackets(*field->type());
out << ";\n";
}
out << "}";
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/OutputGLSLBase.h b/gfx/angle/src/compiler/translator/OutputGLSLBase.h
index ede4c4925..29b710487 100755
--- a/gfx/angle/src/compiler/translator/OutputGLSLBase.h
+++ b/gfx/angle/src/compiler/translator/OutputGLSLBase.h
@@ -13,9 +13,6 @@
#include "compiler/translator/LoopInfo.h"
#include "compiler/translator/ParseContext.h"
-namespace sh
-{
-
class TOutputGLSLBase : public TIntermTraverser
{
public:
@@ -23,11 +20,9 @@ class TOutputGLSLBase : public TIntermTraverser
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap &nameMap,
- TSymbolTable &symbolTable,
- sh::GLenum shaderType,
+ TSymbolTable& symbolTable,
int shaderVersion,
- ShShaderOutput output,
- ShCompileOptions compileOptions);
+ ShShaderOutput output);
ShShaderOutput getShaderOutput() const
{
@@ -38,7 +33,6 @@ class TOutputGLSLBase : public TIntermTraverser
TInfoSinkBase &objSink() { return mObjSink; }
void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
void writeLayoutQualifier(const TType &type);
- void writeInvariantQualifier(const TType &type);
void writeVariableType(const TType &type);
virtual bool writeVariablePrecision(TPrecision precision) = 0;
void writeFunctionParameters(const TIntermSequence &args);
@@ -48,27 +42,22 @@ class TOutputGLSLBase : public TIntermTraverser
void visitSymbol(TIntermSymbol *node) override;
void visitConstantUnion(TIntermConstantUnion *node) override;
- bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
bool visitBinary(Visit visit, TIntermBinary *node) override;
bool visitUnary(Visit visit, TIntermUnary *node) override;
- bool visitTernary(Visit visit, TIntermTernary *node) override;
- bool visitIfElse(Visit visit, TIntermIfElse *node) override;
+ bool visitSelection(Visit visit, TIntermSelection *node) override;
bool visitSwitch(Visit visit, TIntermSwitch *node) override;
bool visitCase(Visit visit, TIntermCase *node) override;
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
- bool visitBlock(Visit visit, TIntermBlock *node) override;
- bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
bool visitLoop(Visit visit, TIntermLoop *node) override;
bool visitBranch(Visit visit, TIntermBranch *node) override;
- void visitCodeBlock(TIntermBlock *node);
+ void visitCodeBlock(TIntermNode *node);
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
- TString hashName(const TName &name);
+ TString hashName(const TString &name);
// Same as hashName(), but without hashing built-in variables.
- TString hashVariableName(const TName &name);
+ TString hashVariableName(const TString &name);
// Same as hashName(), but without hashing built-in functions and with unmangling.
TString hashFunctionNameIfNeeded(const TName &mangledName);
// Used to translate function names for differences between ESSL and GLSL
@@ -83,8 +72,6 @@ class TOutputGLSLBase : public TIntermTraverser
void writeBuiltInFunctionTriplet(Visit visit, const char *preStr, bool useEmulatedFunction);
- const char *mapQualifierToString(TQualifier qialifier);
-
TInfoSinkBase &mObjSink;
bool mDeclaringVariables;
@@ -103,15 +90,9 @@ class TOutputGLSLBase : public TIntermTraverser
TSymbolTable &mSymbolTable;
- sh::GLenum mShaderType;
-
const int mShaderVersion;
ShShaderOutput mOutput;
-
- ShCompileOptions mCompileOptions;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
diff --git a/gfx/angle/src/compiler/translator/OutputHLSL.cpp b/gfx/angle/src/compiler/translator/OutputHLSL.cpp
index 5ef2e89f9..639178281 100755
--- a/gfx/angle/src/compiler/translator/OutputHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/OutputHLSL.cpp
@@ -28,11 +28,13 @@
#include "compiler/translator/blocklayout.h"
#include "compiler/translator/util.h"
-namespace sh
+namespace
{
-namespace
+bool IsSequence(TIntermNode *node)
{
+ return node->getAsAggregate() != nullptr && node->getAsAggregate()->getOp() == EOpSequence;
+}
void WriteSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion)
{
@@ -75,14 +77,14 @@ const TConstantUnion *WriteConstantUnionArray(TInfoSinkBase &out,
} // namespace
-OutputHLSL::OutputHLSL(sh::GLenum shaderType,
- int shaderVersion,
- const TExtensionBehavior &extensionBehavior,
- const char *sourcePath,
- ShShaderOutput outputType,
- int numRenderTargets,
- const std::vector<Uniform> &uniforms,
- ShCompileOptions compileOptions)
+namespace sh
+{
+
+OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ const char *sourcePath, ShShaderOutput outputType,
+ int numRenderTargets, const std::vector<Uniform> &uniforms,
+ int compileOptions)
: TIntermTraverser(true, true, true),
mShaderType(shaderType),
mShaderVersion(shaderVersion),
@@ -156,17 +158,12 @@ void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink)
BuiltInFunctionEmulator builtInFunctionEmulator;
InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator);
- if ((mCompileOptions & SH_EMULATE_ISNAN_FLOAT_FUNCTION) != 0)
- {
- InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(&builtInFunctionEmulator,
- mShaderVersion);
- }
-
builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(treeRoot);
// Now that we are done changing the AST, do the analyses need for HLSL generation
CallDAG::InitResult success = mCallDag.init(treeRoot, &objSink);
ASSERT(success == CallDAG::INITDAG_SUCCESS);
+ UNUSED_ASSERTION_VARIABLE(success);
mASTMetadataList = CreateASTMetadataHLSL(treeRoot, mCallDag);
// Output the body and footer first to determine what has to go in the header
@@ -842,17 +839,6 @@ bool OutputHLSL::ancestorEvaluatesToSamplerInStruct(Visit visit)
return false;
}
-bool OutputHLSL::visitSwizzle(Visit visit, TIntermSwizzle *node)
-{
- TInfoSinkBase &out = getInfoSink();
- if (visit == PostVisit)
- {
- out << ".";
- node->writeOffsetsAsXYZW(&out);
- }
- return true;
-}
-
bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{
TInfoSinkBase &out = getInfoSink();
@@ -866,139 +852,133 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
switch (node->getOp())
{
- case EOpComma:
- outputTriplet(out, visit, "(", ", ", ")");
- break;
- case EOpAssign:
- if (node->getLeft()->isArray())
- {
- TIntermAggregate *rightAgg = node->getRight()->getAsAggregate();
- if (rightAgg != nullptr && rightAgg->isConstructor())
- {
- const TString &functionName = addArrayConstructIntoFunction(node->getType());
- out << functionName << "(";
- node->getLeft()->traverse(this);
- TIntermSequence *seq = rightAgg->getSequence();
- for (auto &arrayElement : *seq)
- {
- out << ", ";
- arrayElement->traverse(this);
- }
- out << ")";
- return false;
- }
- // ArrayReturnValueToOutParameter should have eliminated expressions where a
- // function call is assigned.
- ASSERT(rightAgg == nullptr || rightAgg->getOp() != EOpFunctionCall);
-
- const TString &functionName = addArrayAssignmentFunction(node->getType());
- outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")");
- }
- else
+ case EOpAssign:
+ if (node->getLeft()->isArray())
+ {
+ TIntermAggregate *rightAgg = node->getRight()->getAsAggregate();
+ if (rightAgg != nullptr && rightAgg->isConstructor())
{
- outputTriplet(out, visit, "(", " = ", ")");
- }
- break;
- case EOpInitialize:
- if (visit == PreVisit)
- {
- TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode();
- ASSERT(symbolNode);
- TIntermTyped *expression = node->getRight();
-
- // Global initializers must be constant at this point.
- ASSERT(symbolNode->getQualifier() != EvqGlobal ||
- canWriteAsHLSLLiteral(expression));
-
- // GLSL allows to write things like "float x = x;" where a new variable x is defined
- // and the value of an existing variable x is assigned. HLSL uses C semantics (the
- // new variable is created before the assignment is evaluated), so we need to
- // convert
- // this to "float t = x, x = t;".
- if (writeSameSymbolInitializer(out, symbolNode, expression))
- {
- // Skip initializing the rest of the expression
- return false;
- }
- else if (writeConstantInitialization(out, symbolNode, expression))
+ const TString &functionName = addArrayConstructIntoFunction(node->getType());
+ out << functionName << "(";
+ node->getLeft()->traverse(this);
+ TIntermSequence *seq = rightAgg->getSequence();
+ for (auto &arrayElement : *seq)
{
- return false;
+ out << ", ";
+ arrayElement->traverse(this);
}
+ out << ")";
+ return false;
}
- else if (visit == InVisit)
- {
- out << " = ";
- }
- break;
- case EOpAddAssign:
- outputTriplet(out, visit, "(", " += ", ")");
- break;
- case EOpSubAssign:
- outputTriplet(out, visit, "(", " -= ", ")");
- break;
- case EOpMulAssign:
- outputTriplet(out, visit, "(", " *= ", ")");
- break;
- case EOpVectorTimesScalarAssign:
- outputTriplet(out, visit, "(", " *= ", ")");
- break;
- case EOpMatrixTimesScalarAssign:
- outputTriplet(out, visit, "(", " *= ", ")");
- break;
- case EOpVectorTimesMatrixAssign:
- if (visit == PreVisit)
- {
- out << "(";
- }
- else if (visit == InVisit)
- {
- out << " = mul(";
- node->getLeft()->traverse(this);
- out << ", transpose(";
- }
- else
- {
- out << ")))";
- }
- break;
- case EOpMatrixTimesMatrixAssign:
- if (visit == PreVisit)
- {
- out << "(";
- }
- else if (visit == InVisit)
+ // ArrayReturnValueToOutParameter should have eliminated expressions where a function call is assigned.
+ ASSERT(rightAgg == nullptr || rightAgg->getOp() != EOpFunctionCall);
+
+ const TString &functionName = addArrayAssignmentFunction(node->getType());
+ outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")");
+ }
+ else
+ {
+ outputTriplet(out, visit, "(", " = ", ")");
+ }
+ break;
+ case EOpInitialize:
+ if (visit == PreVisit)
+ {
+ TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode();
+ ASSERT(symbolNode);
+ TIntermTyped *expression = node->getRight();
+
+ // Global initializers must be constant at this point.
+ ASSERT(symbolNode->getQualifier() != EvqGlobal || canWriteAsHLSLLiteral(expression));
+
+ // GLSL allows to write things like "float x = x;" where a new variable x is defined
+ // and the value of an existing variable x is assigned. HLSL uses C semantics (the
+ // new variable is created before the assignment is evaluated), so we need to convert
+ // this to "float t = x, x = t;".
+ if (writeSameSymbolInitializer(out, symbolNode, expression))
{
- out << " = transpose(mul(transpose(";
- node->getLeft()->traverse(this);
- out << "), transpose(";
+ // Skip initializing the rest of the expression
+ return false;
}
- else
+ else if (writeConstantInitialization(out, symbolNode, expression))
{
- out << "))))";
+ return false;
}
- break;
- case EOpDivAssign:
- outputTriplet(out, visit, "(", " /= ", ")");
- break;
- case EOpIModAssign:
- outputTriplet(out, visit, "(", " %= ", ")");
- break;
- case EOpBitShiftLeftAssign:
- outputTriplet(out, visit, "(", " <<= ", ")");
- break;
- case EOpBitShiftRightAssign:
- outputTriplet(out, visit, "(", " >>= ", ")");
- break;
- case EOpBitwiseAndAssign:
- outputTriplet(out, visit, "(", " &= ", ")");
- break;
- case EOpBitwiseXorAssign:
- outputTriplet(out, visit, "(", " ^= ", ")");
- break;
- case EOpBitwiseOrAssign:
- outputTriplet(out, visit, "(", " |= ", ")");
- break;
- case EOpIndexDirect:
+ }
+ else if (visit == InVisit)
+ {
+ out << " = ";
+ }
+ break;
+ case EOpAddAssign:
+ outputTriplet(out, visit, "(", " += ", ")");
+ break;
+ case EOpSubAssign:
+ outputTriplet(out, visit, "(", " -= ", ")");
+ break;
+ case EOpMulAssign:
+ outputTriplet(out, visit, "(", " *= ", ")");
+ break;
+ case EOpVectorTimesScalarAssign:
+ outputTriplet(out, visit, "(", " *= ", ")");
+ break;
+ case EOpMatrixTimesScalarAssign:
+ outputTriplet(out, visit, "(", " *= ", ")");
+ break;
+ case EOpVectorTimesMatrixAssign:
+ if (visit == PreVisit)
+ {
+ out << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << " = mul(";
+ node->getLeft()->traverse(this);
+ out << ", transpose(";
+ }
+ else
+ {
+ out << ")))";
+ }
+ break;
+ case EOpMatrixTimesMatrixAssign:
+ if (visit == PreVisit)
+ {
+ out << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << " = transpose(mul(transpose(";
+ node->getLeft()->traverse(this);
+ out << "), transpose(";
+ }
+ else
+ {
+ out << "))))";
+ }
+ break;
+ case EOpDivAssign:
+ outputTriplet(out, visit, "(", " /= ", ")");
+ break;
+ case EOpIModAssign:
+ outputTriplet(out, visit, "(", " %= ", ")");
+ break;
+ case EOpBitShiftLeftAssign:
+ outputTriplet(out, visit, "(", " <<= ", ")");
+ break;
+ case EOpBitShiftRightAssign:
+ outputTriplet(out, visit, "(", " >>= ", ")");
+ break;
+ case EOpBitwiseAndAssign:
+ outputTriplet(out, visit, "(", " &= ", ")");
+ break;
+ case EOpBitwiseXorAssign:
+ outputTriplet(out, visit, "(", " ^= ", ")");
+ break;
+ case EOpBitwiseOrAssign:
+ outputTriplet(out, visit, "(", " |= ", ")");
+ break;
+ case EOpIndexDirect:
{
const TType& leftType = node->getLeft()->getType();
if (leftType.isInterfaceBlock())
@@ -1077,6 +1057,42 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
return false;
}
break;
+ case EOpVectorSwizzle:
+ if (visit == InVisit)
+ {
+ out << ".";
+
+ TIntermAggregate *swizzle = node->getRight()->getAsAggregate();
+
+ if (swizzle)
+ {
+ TIntermSequence *sequence = swizzle->getSequence();
+
+ for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
+ {
+ TIntermConstantUnion *element = (*sit)->getAsConstantUnion();
+
+ if (element)
+ {
+ int i = element->getIConst(0);
+
+ switch (i)
+ {
+ case 0: out << "x"; break;
+ case 1: out << "y"; break;
+ case 2: out << "z"; break;
+ case 3: out << "w"; break;
+ default: UNREACHABLE();
+ }
+ }
+ else UNREACHABLE();
+ }
+ }
+ else UNREACHABLE();
+
+ return false; // Fully processed
+ }
+ break;
case EOpAdd:
outputTriplet(out, visit, "(", " + ", ")");
break;
@@ -1280,12 +1296,9 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
outputTriplet(out, visit, "frac(", "", ")");
break;
case EOpIsNan:
- if (node->getUseEmulatedFunction())
- writeEmulatedFunctionTriplet(out, visit, "isnan(");
- else
- outputTriplet(out, visit, "isnan(", "", ")");
- mRequiresIEEEStrictCompiling = true;
- break;
+ outputTriplet(out, visit, "isnan(", "", ")");
+ mRequiresIEEEStrictCompiling = true;
+ break;
case EOpIsInf:
outputTriplet(out, visit, "isinf(", "", ")");
break;
@@ -1418,232 +1431,236 @@ TString OutputHLSL::samplerNamePrefixFromStruct(TIntermTyped *node)
}
}
-bool OutputHLSL::visitBlock(Visit visit, TIntermBlock *node)
-{
- TInfoSinkBase &out = getInfoSink();
-
- if (mInsideFunction)
- {
- outputLineDirective(out, node->getLine().first_line);
- out << "{\n";
- }
-
- for (TIntermSequence::iterator sit = node->getSequence()->begin();
- sit != node->getSequence()->end(); sit++)
- {
- outputLineDirective(out, (*sit)->getLine().first_line);
-
- (*sit)->traverse(this);
-
- // Don't output ; after case labels, they're terminated by :
- // This is needed especially since outputting a ; after a case statement would turn empty
- // case statements into non-empty case statements, disallowing fall-through from them.
- // Also no need to output ; after if statements or sequences. This is done just for
- // code clarity.
- if ((*sit)->getAsCaseNode() == nullptr && (*sit)->getAsIfElseNode() == nullptr &&
- (*sit)->getAsBlock() == nullptr)
- out << ";\n";
- }
-
- if (mInsideFunction)
- {
- outputLineDirective(out, node->getLine().last_line);
- out << "}\n";
- }
-
- return false;
-}
-
-bool OutputHLSL::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
TInfoSinkBase &out = getInfoSink();
- ASSERT(mCurrentFunctionMetadata == nullptr);
-
- size_t index = mCallDag.findIndex(node->getFunctionSymbolInfo());
- ASSERT(index != CallDAG::InvalidIndex);
- mCurrentFunctionMetadata = &mASTMetadataList[index];
-
- out << TypeString(node->getType()) << " ";
-
- TIntermSequence *parameters = node->getFunctionParameters()->getSequence();
-
- if (node->getFunctionSymbolInfo()->isMain())
- {
- out << "gl_main(";
- }
- else
- {
- out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj())
- << DisambiguateFunctionName(parameters) << (mOutputLod0Function ? "Lod0(" : "(");
- }
-
- for (unsigned int i = 0; i < parameters->size(); i++)
+ switch (node->getOp())
{
- TIntermSymbol *symbol = (*parameters)[i]->getAsSymbolNode();
-
- if (symbol)
+ case EOpSequence:
{
- ensureStructDefined(symbol->getType());
-
- out << argumentString(symbol);
-
- if (i < parameters->size() - 1)
+ if (mInsideFunction)
{
- out << ", ";
+ outputLineDirective(out, node->getLine().first_line);
+ out << "{\n";
}
- }
- else
- UNREACHABLE();
- }
-
- out << ")\n";
-
- mInsideFunction = true;
- // The function body node will output braces.
- node->getBody()->traverse(this);
- mInsideFunction = false;
-
- mCurrentFunctionMetadata = nullptr;
-
- bool needsLod0 = mASTMetadataList[index].mNeedsLod0;
- if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER)
- {
- ASSERT(!node->getFunctionSymbolInfo()->isMain());
- mOutputLod0Function = true;
- node->traverse(this);
- mOutputLod0Function = false;
- }
- return false;
-}
+ for (TIntermSequence::iterator sit = node->getSequence()->begin(); sit != node->getSequence()->end(); sit++)
+ {
+ outputLineDirective(out, (*sit)->getLine().first_line);
+
+ (*sit)->traverse(this);
+
+ // Don't output ; after case labels, they're terminated by :
+ // This is needed especially since outputting a ; after a case statement would turn empty
+ // case statements into non-empty case statements, disallowing fall-through from them.
+ // Also no need to output ; after selection (if) statements or sequences. This is done just
+ // for code clarity.
+ TIntermSelection *asSelection = (*sit)->getAsSelectionNode();
+ ASSERT(asSelection == nullptr || !asSelection->usesTernaryOperator());
+ if ((*sit)->getAsCaseNode() == nullptr && asSelection == nullptr && !IsSequence(*sit))
+ out << ";\n";
+ }
-bool OutputHLSL::visitDeclaration(Visit visit, TIntermDeclaration *node)
-{
- TInfoSinkBase &out = getInfoSink();
- if (visit == PreVisit)
- {
- TIntermSequence *sequence = node->getSequence();
- TIntermTyped *variable = (*sequence)[0]->getAsTyped();
- ASSERT(sequence->size() == 1);
+ if (mInsideFunction)
+ {
+ outputLineDirective(out, node->getLine().last_line);
+ out << "}\n";
+ }
- if (variable &&
- (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal ||
- variable->getQualifier() == EvqConst))
+ return false;
+ }
+ case EOpDeclaration:
+ if (visit == PreVisit)
{
- ensureStructDefined(variable->getType());
+ TIntermSequence *sequence = node->getSequence();
+ TIntermTyped *variable = (*sequence)[0]->getAsTyped();
+ ASSERT(sequence->size() == 1);
- if (!variable->getAsSymbolNode() ||
- variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
+ if (variable &&
+ (variable->getQualifier() == EvqTemporary ||
+ variable->getQualifier() == EvqGlobal || variable->getQualifier() == EvqConst))
{
- if (!mInsideFunction)
+ ensureStructDefined(variable->getType());
+
+ if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
{
- out << "static ";
- }
+ if (!mInsideFunction)
+ {
+ out << "static ";
+ }
- out << TypeString(variable->getType()) + " ";
+ out << TypeString(variable->getType()) + " ";
- TIntermSymbol *symbol = variable->getAsSymbolNode();
+ TIntermSymbol *symbol = variable->getAsSymbolNode();
- if (symbol)
- {
- symbol->traverse(this);
- out << ArrayString(symbol->getType());
- out << " = " + initializer(symbol->getType());
+ if (symbol)
+ {
+ symbol->traverse(this);
+ out << ArrayString(symbol->getType());
+ out << " = " + initializer(symbol->getType());
+ }
+ else
+ {
+ variable->traverse(this);
+ }
}
- else
+ else if (variable->getAsSymbolNode() && variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration
{
- variable->traverse(this);
+ // Already added to constructor map
}
+ else UNREACHABLE();
}
- else if (variable->getAsSymbolNode() &&
- variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration
+ else if (variable && IsVaryingOut(variable->getQualifier()))
{
- // Already added to constructor map
+ for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
+ {
+ TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
+
+ if (symbol)
+ {
+ // Vertex (output) varyings which are declared but not written to should still be declared to allow successful linking
+ mReferencedVaryings[symbol->getSymbol()] = symbol;
+ }
+ else
+ {
+ (*sit)->traverse(this);
+ }
+ }
}
- else
- UNREACHABLE();
+
+ return false;
}
- else if (variable && IsVaryingOut(variable->getQualifier()))
+ else if (visit == InVisit)
+ {
+ out << ", ";
+ }
+ break;
+ case EOpInvariantDeclaration:
+ // Do not do any translation
+ return false;
+ case EOpPrototype:
+ if (visit == PreVisit)
{
- for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
+ size_t index = mCallDag.findIndex(node);
+ // Skip the prototype if it is not implemented (and thus not used)
+ if (index == CallDAG::InvalidIndex)
{
- TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
+ return false;
+ }
+
+ TIntermSequence *arguments = node->getSequence();
+
+ TString name = DecorateFunctionIfNeeded(node->getNameObj());
+ out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(arguments)
+ << (mOutputLod0Function ? "Lod0(" : "(");
+
+ for (unsigned int i = 0; i < arguments->size(); i++)
+ {
+ TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode();
if (symbol)
{
- // Vertex (output) varyings which are declared but not written to should
- // still be declared to allow successful linking
- mReferencedVaryings[symbol->getSymbol()] = symbol;
- }
- else
- {
- (*sit)->traverse(this);
+ out << argumentString(symbol);
+
+ if (i < arguments->size() - 1)
+ {
+ out << ", ";
+ }
}
+ else UNREACHABLE();
}
- }
- }
- return false;
-}
-bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
-{
- TInfoSinkBase &out = getInfoSink();
+ out << ");\n";
- switch (node->getOp())
- {
- case EOpInvariantDeclaration:
- // Do not do any translation
- return false;
- case EOpPrototype:
- if (visit == PreVisit)
+ // Also prototype the Lod0 variant if needed
+ bool needsLod0 = mASTMetadataList[index].mNeedsLod0;
+ if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER)
{
- size_t index = mCallDag.findIndex(node->getFunctionSymbolInfo());
- // Skip the prototype if it is not implemented (and thus not used)
- if (index == CallDAG::InvalidIndex)
- {
- return false;
- }
+ mOutputLod0Function = true;
+ node->traverse(this);
+ mOutputLod0Function = false;
+ }
+
+ return false;
+ }
+ break;
+ case EOpComma:
+ outputTriplet(out, visit, "(", ", ", ")");
+ break;
+ case EOpFunction:
+ {
+ ASSERT(mCurrentFunctionMetadata == nullptr);
+ TString name = TFunction::unmangleName(node->getNameObj().getString());
+
+ size_t index = mCallDag.findIndex(node);
+ ASSERT(index != CallDAG::InvalidIndex);
+ mCurrentFunctionMetadata = &mASTMetadataList[index];
- TIntermSequence *arguments = node->getSequence();
+ out << TypeString(node->getType()) << " ";
- TString name =
- DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj());
- out << TypeString(node->getType()) << " " << name
+ TIntermSequence *sequence = node->getSequence();
+ TIntermSequence *arguments = (*sequence)[0]->getAsAggregate()->getSequence();
+
+ if (name == "main")
+ {
+ out << "gl_main(";
+ }
+ else
+ {
+ out << DecorateFunctionIfNeeded(node->getNameObj())
<< DisambiguateFunctionName(arguments) << (mOutputLod0Function ? "Lod0(" : "(");
+ }
- for (unsigned int i = 0; i < arguments->size(); i++)
+ for (unsigned int i = 0; i < arguments->size(); i++)
+ {
+ TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode();
+
+ if (symbol)
{
- TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode();
+ ensureStructDefined(symbol->getType());
- if (symbol)
- {
- out << argumentString(symbol);
+ out << argumentString(symbol);
- if (i < arguments->size() - 1)
- {
- out << ", ";
- }
+ if (i < arguments->size() - 1)
+ {
+ out << ", ";
}
- else
- UNREACHABLE();
}
+ else UNREACHABLE();
+ }
- out << ");\n";
+ out << ")\n";
- // Also prototype the Lod0 variant if needed
- bool needsLod0 = mASTMetadataList[index].mNeedsLod0;
- if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER)
- {
- mOutputLod0Function = true;
- node->traverse(this);
- mOutputLod0Function = false;
- }
+ if (sequence->size() > 1)
+ {
+ mInsideFunction = true;
+ TIntermNode *body = (*sequence)[1];
+ // The function body node will output braces.
+ ASSERT(IsSequence(body));
+ body->traverse(this);
+ mInsideFunction = false;
+ }
+ else
+ {
+ out << "{}\n";
+ }
- return false;
+ mCurrentFunctionMetadata = nullptr;
+
+ bool needsLod0 = mASTMetadataList[index].mNeedsLod0;
+ if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER)
+ {
+ ASSERT(name != "main");
+ mOutputLod0Function = true;
+ node->traverse(this);
+ mOutputLod0Function = false;
}
- break;
- case EOpFunctionCall:
+
+ return false;
+ }
+ break;
+ case EOpFunctionCall:
{
TIntermSequence *arguments = node->getSequence();
@@ -1654,23 +1671,23 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
UNIMPLEMENTED();
}
- size_t index = mCallDag.findIndex(node->getFunctionSymbolInfo());
+ size_t index = mCallDag.findIndex(node);
ASSERT(index != CallDAG::InvalidIndex);
lod0 &= mASTMetadataList[index].mNeedsLod0;
- out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj());
+ out << DecorateFunctionIfNeeded(node->getNameObj());
out << DisambiguateFunctionName(node->getSequence());
out << (lod0 ? "Lod0(" : "(");
}
- else if (node->getFunctionSymbolInfo()->getNameObj().isInternal())
+ else if (node->getNameObj().isInternal())
{
// This path is used for internal functions that don't have their definitions in the
// AST, such as precision emulation functions.
- out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj()) << "(";
+ out << DecorateFunctionIfNeeded(node->getNameObj()) << "(";
}
else
{
- TString name = TFunction::unmangleName(node->getFunctionSymbolInfo()->getName());
+ TString name = TFunction::unmangleName(node->getNameObj().getString());
TBasicType samplerType = (*arguments)[0]->getAsTyped()->getType().getBasicType();
int coords = (*arguments)[1]->getAsTyped()->getNominalSize();
TString textureFunctionName = mTextureFunctionHLSL->useTextureFunction(
@@ -1724,6 +1741,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
return false;
}
+ break;
case EOpParameters:
outputTriplet(out, visit, "(", ", ", ")\n{\n");
break;
@@ -1802,7 +1820,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpConstructMat4:
outputConstructor(out, visit, node->getType(), "mat4", node->getSequence());
break;
- case EOpConstructStruct:
+ case EOpConstructStruct:
{
if (node->getType().isArray())
{
@@ -1831,31 +1849,31 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpVectorNotEqual:
outputTriplet(out, visit, "(", " != ", ")");
break;
- case EOpMod:
- ASSERT(node->getUseEmulatedFunction());
- writeEmulatedFunctionTriplet(out, visit, "mod(");
- break;
- case EOpModf:
- outputTriplet(out, visit, "modf(", ", ", ")");
- break;
- case EOpPow:
- outputTriplet(out, visit, "pow(", ", ", ")");
- break;
- case EOpAtan:
- ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator
- ASSERT(node->getUseEmulatedFunction());
- writeEmulatedFunctionTriplet(out, visit, "atan(");
- break;
- case EOpMin:
- outputTriplet(out, visit, "min(", ", ", ")");
- break;
- case EOpMax:
- outputTriplet(out, visit, "max(", ", ", ")");
- break;
- case EOpClamp:
- outputTriplet(out, visit, "clamp(", ", ", ")");
- break;
- case EOpMix:
+ case EOpMod:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, "mod(");
+ break;
+ case EOpModf:
+ outputTriplet(out, visit, "modf(", ", ", ")");
+ break;
+ case EOpPow:
+ outputTriplet(out, visit, "pow(", ", ", ")");
+ break;
+ case EOpAtan:
+ ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, "atan(");
+ break;
+ case EOpMin:
+ outputTriplet(out, visit, "min(", ", ", ")");
+ break;
+ case EOpMax:
+ outputTriplet(out, visit, "max(", ", ", ")");
+ break;
+ case EOpClamp:
+ outputTriplet(out, visit, "clamp(", ", ", ")");
+ break;
+ case EOpMix:
{
TIntermTyped *lastParamNode = (*(node->getSequence()))[2]->getAsTyped();
if (lastParamNode->getType().getBasicType() == EbtBool)
@@ -1869,8 +1887,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
outputTriplet(out, visit, "lerp(", ", ", ")");
}
- break;
}
+ break;
case EOpStep:
outputTriplet(out, visit, "step(", ", ", ")");
break;
@@ -1886,31 +1904,30 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpCross:
outputTriplet(out, visit, "cross(", ", ", ")");
break;
- case EOpFaceForward:
- ASSERT(node->getUseEmulatedFunction());
- writeEmulatedFunctionTriplet(out, visit, "faceforward(");
- break;
- case EOpReflect:
- outputTriplet(out, visit, "reflect(", ", ", ")");
- break;
- case EOpRefract:
- outputTriplet(out, visit, "refract(", ", ", ")");
- break;
- case EOpOuterProduct:
- ASSERT(node->getUseEmulatedFunction());
- writeEmulatedFunctionTriplet(out, visit, "outerProduct(");
- break;
- case EOpMul:
- outputTriplet(out, visit, "(", " * ", ")");
- break;
- default:
- UNREACHABLE();
+ case EOpFaceForward:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, "faceforward(");
+ break;
+ case EOpReflect:
+ outputTriplet(out, visit, "reflect(", ", ", ")");
+ break;
+ case EOpRefract:
+ outputTriplet(out, visit, "refract(", ", ", ")");
+ break;
+ case EOpOuterProduct:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, "outerProduct(");
+ break;
+ case EOpMul:
+ outputTriplet(out, visit, "(", " * ", ")");
+ break;
+ default: UNREACHABLE();
}
return true;
}
-void OutputHLSL::writeIfElse(TInfoSinkBase &out, TIntermIfElse *node)
+void OutputHLSL::writeSelection(TInfoSinkBase &out, TIntermSelection *node)
{
out << "if (";
@@ -1925,6 +1942,8 @@ void OutputHLSL::writeIfElse(TInfoSinkBase &out, TIntermIfElse *node)
if (node->getTrueBlock())
{
// The trueBlock child node will output braces.
+ ASSERT(IsSequence(node->getTrueBlock()));
+
node->getTrueBlock()->traverse(this);
// Detect true discard
@@ -1945,7 +1964,9 @@ void OutputHLSL::writeIfElse(TInfoSinkBase &out, TIntermIfElse *node)
outputLineDirective(out, node->getFalseBlock()->getLine().first_line);
- // The falseBlock child node will output braces.
+ // Either this is "else if" or the falseBlock child node will output braces.
+ ASSERT(IsSequence(node->getFalseBlock()) || node->getFalseBlock()->getAsSelectionNode() != nullptr);
+
node->getFalseBlock()->traverse(this);
outputLineDirective(out, node->getFalseBlock()->getLine().first_line);
@@ -1961,18 +1982,11 @@ void OutputHLSL::writeIfElse(TInfoSinkBase &out, TIntermIfElse *node)
}
}
-bool OutputHLSL::visitTernary(Visit, TIntermTernary *)
-{
- // Ternary ops should have been already converted to something else in the AST. HLSL ternary
- // operator doesn't short-circuit, so it's not the same as the GLSL ternary operator.
- UNREACHABLE();
- return false;
-}
-
-bool OutputHLSL::visitIfElse(Visit visit, TIntermIfElse *node)
+bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
{
TInfoSinkBase &out = getInfoSink();
+ ASSERT(!node->usesTernaryOperator());
ASSERT(mInsideFunction);
// D3D errors when there is a gradient operation in a loop in an unflattened if.
@@ -1981,7 +1995,7 @@ bool OutputHLSL::visitIfElse(Visit visit, TIntermIfElse *node)
out << "FLATTEN ";
}
- writeIfElse(out, node);
+ writeSelection(out, node);
return false;
}
@@ -2085,6 +2099,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
if (node->getBody())
{
// The loop body node will output braces.
+ ASSERT(IsSequence(node->getBody()));
node->getBody()->traverse(this);
}
else
@@ -2172,6 +2187,39 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
return true;
}
+bool OutputHLSL::isSingleStatement(TIntermNode *node)
+{
+ TIntermAggregate *aggregate = node->getAsAggregate();
+
+ if (aggregate)
+ {
+ if (aggregate->getOp() == EOpSequence)
+ {
+ return false;
+ }
+ else if (aggregate->getOp() == EOpDeclaration)
+ {
+ // Declaring multiple comma-separated variables must be considered multiple statements
+ // because each individual declaration has side effects which are visible in the next.
+ return false;
+ }
+ else
+ {
+ for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++)
+ {
+ if (!isSingleStatement(*sit))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ return true;
+}
+
// Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them
// (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254).
bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node)
@@ -2189,7 +2237,7 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node)
// Parse index name and intial value
if (node->getInit())
{
- TIntermDeclaration *init = node->getInit()->getAsDeclarationNode();
+ TIntermAggregate *init = node->getInit()->getAsAggregate();
if (init)
{
@@ -2854,4 +2902,6 @@ void OutputHLSL::ensureStructDefined(const TType &type)
}
}
-} // namespace sh
+
+
+}
diff --git a/gfx/angle/src/compiler/translator/OutputHLSL.h b/gfx/angle/src/compiler/translator/OutputHLSL.h
index 833f4736b..e5204e419 100755
--- a/gfx/angle/src/compiler/translator/OutputHLSL.h
+++ b/gfx/angle/src/compiler/translator/OutputHLSL.h
@@ -30,14 +30,11 @@ typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
class OutputHLSL : public TIntermTraverser
{
public:
- OutputHLSL(sh::GLenum shaderType,
- int shaderVersion,
- const TExtensionBehavior &extensionBehavior,
- const char *sourcePath,
- ShShaderOutput outputType,
- int numRenderTargets,
- const std::vector<Uniform> &uniforms,
- ShCompileOptions compileOptions);
+ OutputHLSL(sh::GLenum shaderType, int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ const char *sourcePath, ShShaderOutput outputType,
+ int numRenderTargets, const std::vector<Uniform> &uniforms,
+ int compileOptions);
~OutputHLSL();
@@ -59,20 +56,16 @@ class OutputHLSL : public TIntermTraverser
void visitSymbol(TIntermSymbol*);
void visitRaw(TIntermRaw*);
void visitConstantUnion(TIntermConstantUnion*);
- bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
bool visitBinary(Visit visit, TIntermBinary*);
bool visitUnary(Visit visit, TIntermUnary*);
- bool visitTernary(Visit visit, TIntermTernary *);
- bool visitIfElse(Visit visit, TIntermIfElse *);
+ bool visitSelection(Visit visit, TIntermSelection*);
bool visitSwitch(Visit visit, TIntermSwitch *);
bool visitCase(Visit visit, TIntermCase *);
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
bool visitAggregate(Visit visit, TIntermAggregate*);
- bool visitBlock(Visit visit, TIntermBlock *node);
- bool visitDeclaration(Visit visit, TIntermDeclaration *node);
bool visitLoop(Visit visit, TIntermLoop*);
bool visitBranch(Visit visit, TIntermBranch*);
+ bool isSingleStatement(TIntermNode *node);
bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node);
// Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString.
@@ -108,7 +101,7 @@ class OutputHLSL : public TIntermTraverser
TIntermTyped *expression);
void writeDeferredGlobalInitializers(TInfoSinkBase &out);
- void writeIfElse(TInfoSinkBase &out, TIntermIfElse *node);
+ void writeSelection(TInfoSinkBase &out, TIntermSelection *node);
// Returns the function name
TString addStructEqualityFunction(const TStructure &structure);
@@ -124,7 +117,7 @@ class OutputHLSL : public TIntermTraverser
const TExtensionBehavior &mExtensionBehavior;
const char *mSourcePath;
const ShShaderOutput mOutputType;
- ShCompileOptions mCompileOptions;
+ int mCompileOptions;
bool mInsideFunction;
diff --git a/gfx/angle/src/compiler/translator/ParseContext.cpp b/gfx/angle/src/compiler/translator/ParseContext.cpp
index 4ad597c4f..5e15eea24 100755
--- a/gfx/angle/src/compiler/translator/ParseContext.cpp
+++ b/gfx/angle/src/compiler/translator/ParseContext.cpp
@@ -16,102 +16,12 @@
#include "compiler/translator/ValidateGlobalInitializer.h"
#include "compiler/translator/util.h"
-namespace sh
-{
-
///////////////////////////////////////////////////////////////////////
//
// Sub- vector and matrix fields
//
////////////////////////////////////////////////////////////////////////
-namespace
-{
-
-const int kWebGLMaxStructNesting = 4;
-
-bool ContainsSampler(const TType &type)
-{
- if (IsSampler(type.getBasicType()))
- return true;
-
- if (type.getBasicType() == EbtStruct || type.isInterfaceBlock())
- {
- const TFieldList &fields = type.getStruct()->fields();
- for (unsigned int i = 0; i < fields.size(); ++i)
- {
- if (ContainsSampler(*fields[i]->type()))
- return true;
- }
- }
-
- return false;
-}
-
-bool ContainsImage(const TType &type)
-{
- if (IsImage(type.getBasicType()))
- return true;
-
- if (type.getBasicType() == EbtStruct || type.isInterfaceBlock())
- {
- const TFieldList &fields = type.getStruct()->fields();
- for (unsigned int i = 0; i < fields.size(); ++i)
- {
- if (ContainsImage(*fields[i]->type()))
- return true;
- }
- }
-
- return false;
-}
-
-} // namespace
-
-TParseContext::TParseContext(TSymbolTable &symt,
- TExtensionBehavior &ext,
- sh::GLenum type,
- ShShaderSpec spec,
- ShCompileOptions options,
- bool checksPrecErrors,
- TInfoSink &is,
- const ShBuiltInResources &resources)
- : intermediate(),
- symbolTable(symt),
- mDeferredSingleDeclarationErrorCheck(false),
- mShaderType(type),
- mShaderSpec(spec),
- mCompileOptions(options),
- mShaderVersion(100),
- mTreeRoot(nullptr),
- mLoopNestingLevel(0),
- mStructNestingLevel(0),
- mSwitchNestingLevel(0),
- mCurrentFunctionType(nullptr),
- mFunctionReturnsValue(false),
- mChecksPrecisionErrors(checksPrecErrors),
- mFragmentPrecisionHighOnESSL1(false),
- mDefaultMatrixPacking(EmpColumnMajor),
- mDefaultBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
- mDiagnostics(is),
- mDirectiveHandler(ext,
- mDiagnostics,
- mShaderVersion,
- mShaderType,
- resources.WEBGL_debug_shader_precision == 1),
- mPreprocessor(&mDiagnostics, &mDirectiveHandler),
- mScanner(nullptr),
- mUsesFragData(false),
- mUsesFragColor(false),
- mUsesSecondaryOutputs(false),
- mMinProgramTexelOffset(resources.MinProgramTexelOffset),
- mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
- mComputeShaderLocalSizeDeclared(false),
- mDeclaringFunction(false)
-{
- mComputeShaderLocalSize.fill(-1);
-}
-
//
// Look at a '.' field selector string and change it into offsets
// for a vector.
@@ -303,12 +213,6 @@ void TParseContext::checkPrecisionSpecified(const TSourceLoc &line,
{
if (!mChecksPrecisionErrors)
return;
-
- if (precision != EbpUndefined && !SupportsPrecision(type))
- {
- error(line, "illegal type for precision qualifier", getBasicString(type));
- }
-
if (precision == EbpUndefined)
{
switch (type)
@@ -327,11 +231,6 @@ void TParseContext::checkPrecisionSpecified(const TSourceLoc &line,
error(line, "No precision specified (sampler)", "");
return;
}
- if (IsImage(type))
- {
- error(line, "No precision specified (image)", "");
- return;
- }
}
}
}
@@ -342,18 +241,6 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn
{
TIntermSymbol *symNode = node->getAsSymbolNode();
TIntermBinary *binaryNode = node->getAsBinaryNode();
- TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
-
- if (swizzleNode)
- {
- bool ok = checkCanBeLValue(line, op, swizzleNode->getOperand());
- if (ok && swizzleNode->hasDuplicateOffsets())
- {
- error(line, " l-value of swizzle cannot have duplicate components", op);
- return false;
- }
- return ok;
- }
if (binaryNode)
{
@@ -364,10 +251,34 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn
case EOpIndexDirectStruct:
case EOpIndexDirectInterfaceBlock:
return checkCanBeLValue(line, op, binaryNode->getLeft());
+ case EOpVectorSwizzle:
+ {
+ bool ok = checkCanBeLValue(line, op, binaryNode->getLeft());
+ if (ok)
+ {
+ int offsetCount[4] = {0, 0, 0, 0};
+
+ TIntermAggregate *swizzleOffsets = binaryNode->getRight()->getAsAggregate();
+
+ for (const auto &offset : *swizzleOffsets->getSequence())
+ {
+ int value = offset->getAsTyped()->getAsConstantUnion()->getIConst(0);
+ offsetCount[value]++;
+ if (offsetCount[value] > 1)
+ {
+ error(line, " l-value of swizzle cannot have duplicate components", op);
+ return false;
+ }
+ }
+ }
+
+ return ok;
+ }
default:
break;
}
error(line, " l-value required", op);
+
return false;
}
@@ -441,10 +352,6 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn
{
message = "can't modify a sampler";
}
- if (IsImage(node->getBasicType()))
- {
- message = "can't modify an image";
- }
}
if (message == 0 && binaryNode == 0 && symNode == 0)
@@ -528,7 +435,7 @@ bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const TString &id
error(line, reservedErrMsg, "gl_");
return false;
}
- if (sh::IsWebGLBasedSpec(mShaderSpec))
+ if (IsWebGLBasedSpec(mShaderSpec))
{
if (identifier.compare(0, 6, "webgl_") == 0)
{
@@ -540,6 +447,11 @@ bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const TString &id
error(line, reservedErrMsg, "_webgl_");
return false;
}
+ if (mShaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0)
+ {
+ error(line, reservedErrMsg, "css_");
+ return false;
+ }
}
if (identifier.find("__") != TString::npos)
{
@@ -675,11 +587,6 @@ bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
error(line, "cannot convert a sampler", "constructor");
return false;
}
- if (op != EOpConstructStruct && IsImage(argTyped->getBasicType()))
- {
- error(line, "cannot convert an image", "constructor");
- return false;
- }
if (argTyped->getBasicType() == EbtVoid)
{
error(line, "cannot convert a void", "constructor");
@@ -754,19 +661,19 @@ void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped
// or not.
void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType)
{
- if (pType.getBasicType() != EbtBool || pType.isAggregate())
+ if (pType.type != EbtBool || pType.isAggregate())
{
error(line, "boolean expression expected", "");
}
}
bool TParseContext::checkIsNotSampler(const TSourceLoc &line,
- const TTypeSpecifierNonArray &pType,
+ const TPublicType &pType,
const char *reason)
{
if (pType.type == EbtStruct)
{
- if (ContainsSampler(*pType.userDef))
+ if (containsSampler(*pType.userDef))
{
error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
return false;
@@ -783,31 +690,6 @@ bool TParseContext::checkIsNotSampler(const TSourceLoc &line,
return true;
}
-bool TParseContext::checkIsNotImage(const TSourceLoc &line,
- const TTypeSpecifierNonArray &pType,
- const char *reason)
-{
- if (pType.type == EbtStruct)
- {
- if (ContainsImage(*pType.userDef))
- {
- error(line, reason, getBasicString(pType.type), "(structure contains an image)");
-
- return false;
- }
-
- return true;
- }
- else if (IsImage(pType.type))
- {
- error(line, reason, getBasicString(pType.type));
-
- return false;
- }
-
- return true;
-}
-
void TParseContext::checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line,
const TPublicType &pType)
{
@@ -828,34 +710,33 @@ void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location,
}
}
-void TParseContext::checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
- TQualifier qualifier,
- const TType &type)
-{
- checkOutParameterIsNotSampler(line, qualifier, type);
- checkOutParameterIsNotImage(line, qualifier, type);
-}
-
void TParseContext::checkOutParameterIsNotSampler(const TSourceLoc &line,
TQualifier qualifier,
const TType &type)
{
- ASSERT(qualifier == EvqOut || qualifier == EvqInOut);
- if (IsSampler(type.getBasicType()))
+ if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct &&
+ IsSampler(type.getBasicType()))
{
error(line, "samplers cannot be output parameters", type.getBasicString());
}
}
-void TParseContext::checkOutParameterIsNotImage(const TSourceLoc &line,
- TQualifier qualifier,
- const TType &type)
+bool TParseContext::containsSampler(const TType &type)
{
- ASSERT(qualifier == EvqOut || qualifier == EvqInOut);
- if (IsImage(type.getBasicType()))
+ if (IsSampler(type.getBasicType()))
+ return true;
+
+ if (type.getBasicType() == EbtStruct || type.isInterfaceBlock())
{
- error(line, "images cannot be output parameters", type.getBasicString());
+ const TFieldList &fields = type.getStruct()->fields();
+ for (unsigned int i = 0; i < fields.size(); ++i)
+ {
+ if (containsSampler(*fields[i]->type()))
+ return true;
+ }
}
+
+ return false;
}
// Do size checking for an array type's size.
@@ -942,7 +823,7 @@ bool TParseContext::checkIsValidTypeForArray(const TSourceLoc &line, const TPubl
// In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere.
// In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section
// 4.3.4).
- if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct &&
+ if (mShaderVersion >= 300 && elementType.type == EbtStruct &&
sh::IsVarying(elementType.qualifier))
{
error(line, "cannot declare arrays of structs of this qualifier",
@@ -1047,33 +928,27 @@ bool TParseContext::declareVariable(const TSourceLoc &line,
return true;
}
-void TParseContext::checkIsParameterQualifierValid(
- const TSourceLoc &line,
- const TTypeQualifierBuilder &typeQualifierBuilder,
- TType *type)
+void TParseContext::checkIsParameterQualifierValid(const TSourceLoc &line,
+ TQualifier qualifier,
+ TQualifier paramQualifier,
+ TType *type)
{
- TTypeQualifier typeQualifier = typeQualifierBuilder.getParameterTypeQualifier(&mDiagnostics);
-
- if (typeQualifier.qualifier == EvqOut || typeQualifier.qualifier == EvqInOut)
+ if (qualifier != EvqConst && qualifier != EvqTemporary)
{
- checkOutParameterIsNotOpaqueType(line, typeQualifier.qualifier, *type);
- }
-
- if (!IsImage(type->getBasicType()))
- {
- checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, line);
+ error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
+ return;
}
- else
+ if (qualifier == EvqConst && paramQualifier != EvqIn)
{
- type->setMemoryQualifier(typeQualifier.memoryQualifier);
+ error(line, "qualifier not allowed with ", getQualifierString(qualifier),
+ getQualifierString(paramQualifier));
+ return;
}
- type->setQualifier(typeQualifier.qualifier);
-
- if (typeQualifier.precision != EbpUndefined)
- {
- type->setPrecision(typeQualifier.precision);
- }
+ if (qualifier == EvqConst)
+ type->setQualifier(EvqConstReadOnly);
+ else
+ type->setQualifier(paramQualifier);
}
bool TParseContext::checkCanUseExtension(const TSourceLoc &line, const TString &extension)
@@ -1113,7 +988,7 @@ void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
case EvqVertexIn:
case EvqFragmentOut:
case EvqComputeIn:
- if (publicType.getBasicType() == EbtStruct)
+ if (publicType.type == EbtStruct)
{
error(identifierLocation, "cannot be used with a structure",
getQualifierString(publicType.qualifier));
@@ -1125,14 +1000,7 @@ void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
}
if (publicType.qualifier != EvqUniform &&
- !checkIsNotSampler(identifierLocation, publicType.typeSpecifierNonArray,
- "samplers must be uniform"))
- {
- return;
- }
- if (publicType.qualifier != EvqUniform &&
- !checkIsNotImage(identifierLocation, publicType.typeSpecifierNonArray,
- "images must be uniform"))
+ !checkIsNotSampler(identifierLocation, publicType, "samplers must be uniform"))
{
return;
}
@@ -1160,89 +1028,6 @@ void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType,
{
checkLocationIsNotSpecified(identifierLocation, publicType.layoutQualifier);
}
-
- if (IsImage(publicType.getBasicType()))
- {
-
- switch (layoutQualifier.imageInternalFormat)
- {
- case EiifRGBA32F:
- case EiifRGBA16F:
- case EiifR32F:
- case EiifRGBA8:
- case EiifRGBA8_SNORM:
- if (!IsFloatImage(publicType.getBasicType()))
- {
- error(identifierLocation,
- "internal image format requires a floating image type",
- getBasicString(publicType.getBasicType()));
- return;
- }
- break;
- case EiifRGBA32I:
- case EiifRGBA16I:
- case EiifRGBA8I:
- case EiifR32I:
- if (!IsIntegerImage(publicType.getBasicType()))
- {
- error(identifierLocation,
- "internal image format requires an integer image type",
- getBasicString(publicType.getBasicType()));
- return;
- }
- break;
- case EiifRGBA32UI:
- case EiifRGBA16UI:
- case EiifRGBA8UI:
- case EiifR32UI:
- if (!IsUnsignedImage(publicType.getBasicType()))
- {
- error(identifierLocation,
- "internal image format requires an unsigned image type",
- getBasicString(publicType.getBasicType()));
- return;
- }
- break;
- case EiifUnspecified:
- error(identifierLocation, "layout qualifier", "No image internal format specified");
- return;
- default:
- error(identifierLocation, "layout qualifier", "unrecognized token");
- return;
- }
-
- // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
- switch (layoutQualifier.imageInternalFormat)
- {
- case EiifR32F:
- case EiifR32I:
- case EiifR32UI:
- break;
- default:
- if (!publicType.memoryQualifier.readonly && !publicType.memoryQualifier.writeonly)
- {
- error(identifierLocation, "layout qualifier",
- "Except for images with the r32f, r32i and r32ui format qualifiers, "
- "image variables must be qualified readonly and/or writeonly");
- return;
- }
- break;
- }
- }
- else
- {
-
- if (!checkInternalFormatIsNotSpecified(identifierLocation,
- layoutQualifier.imageInternalFormat))
- {
- return;
- }
-
- if (!checkIsMemoryQualifierNotSpecified(publicType.memoryQualifier, identifierLocation))
- {
- return;
- }
- }
}
void TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location,
@@ -1273,18 +1058,6 @@ bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
return true;
}
-bool TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location,
- TLayoutImageInternalFormat internalFormat)
-{
- if (internalFormat != EiifUnspecified)
- {
- error(location, "invalid layout qualifier:", getImageInternalFormatString(internalFormat),
- "only valid when used with images");
- return false;
- }
- return true;
-}
-
void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate,
TIntermAggregate *fnCall)
{
@@ -1304,27 +1077,12 @@ void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate,
}
}
-void TParseContext::checkInvariantVariableQualifier(bool invariant,
- const TQualifier qualifier,
- const TSourceLoc &invariantLocation)
+void TParseContext::checkInvariantIsOutVariableES3(const TQualifier qualifier,
+ const TSourceLoc &invariantLocation)
{
- if (!invariant)
- return;
-
- if (mShaderVersion < 300)
- {
- // input variables in the fragment shader can be also qualified as invariant
- if (!sh::CanBeInvariantESSL1(qualifier))
- {
- error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
- }
- }
- else
+ if (!sh::IsVaryingOut(qualifier) && qualifier != EvqFragmentOut)
{
- if (!sh::CanBeInvariantESSL3OrGreater(qualifier))
- {
- error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
- }
+ error(invariantLocation, "Only out variables can be invariant.", "invariant");
}
}
@@ -1522,26 +1280,15 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
const TString &identifier,
const TPublicType &pType,
TIntermTyped *initializer,
- TIntermBinary **initNode)
+ TIntermNode **intermNode)
{
- ASSERT(initNode != nullptr);
- ASSERT(*initNode == nullptr);
+ ASSERT(intermNode != nullptr);
TType type = TType(pType);
TVariable *variable = nullptr;
if (type.isUnsizedArray())
{
- // We have not checked yet whether the initializer actually is an array or not.
- if (initializer->isArray())
- {
- type.setArraySize(initializer->getArraySize());
- }
- else
- {
- // Having a non-array initializer for an unsized array will result in an error later,
- // so we don't generate an error message here.
- type.setArraySize(1u);
- }
+ type.setArraySize(initializer->getArraySize());
}
if (!declareVariable(line, identifier, type, &variable))
{
@@ -1607,7 +1354,7 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
if (initializer->getAsConstantUnion())
{
variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
- *initNode = nullptr;
+ *intermNode = nullptr;
return false;
}
else if (initializer->getAsSymbolNode())
@@ -1620,7 +1367,7 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
if (constArray)
{
variable->shareConstPointer(constArray);
- *initNode = nullptr;
+ *intermNode = nullptr;
return false;
}
}
@@ -1628,8 +1375,8 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
TIntermSymbol *intermSymbol = intermediate.addSymbol(
variable->getUniqueId(), variable->getName(), variable->getType(), line);
- *initNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
- if (*initNode == nullptr)
+ *intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
+ if (*intermNode == nullptr)
{
assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
return true;
@@ -1638,80 +1385,51 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
return false;
}
-void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
-{
- checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
- typeSpecifier->getBasicType());
-
- if (mShaderVersion < 300 && typeSpecifier->array)
- {
- error(typeSpecifier->getLine(), "not supported", "first-class array");
- typeSpecifier->clearArrayness();
- }
-}
-
-TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
+TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier,
+ bool invariant,
+ TLayoutQualifier layoutQualifier,
const TPublicType &typeSpecifier)
{
- TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
-
TPublicType returnType = typeSpecifier;
- returnType.qualifier = typeQualifier.qualifier;
- returnType.invariant = typeQualifier.invariant;
- returnType.layoutQualifier = typeQualifier.layoutQualifier;
- returnType.memoryQualifier = typeQualifier.memoryQualifier;
- returnType.precision = typeSpecifier.precision;
-
- if (typeQualifier.precision != EbpUndefined)
- {
- returnType.precision = typeQualifier.precision;
- }
+ returnType.qualifier = qualifier;
+ returnType.invariant = invariant;
+ returnType.layoutQualifier = layoutQualifier;
- checkPrecisionSpecified(typeSpecifier.getLine(), returnType.precision,
- typeSpecifier.getBasicType());
-
- checkInvariantVariableQualifier(returnType.invariant, returnType.qualifier,
- typeSpecifier.getLine());
-
- checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier);
+ checkWorkGroupSizeIsNotSpecified(typeSpecifier.line, layoutQualifier);
if (mShaderVersion < 300)
{
if (typeSpecifier.array)
{
- error(typeSpecifier.getLine(), "not supported", "first-class array");
+ error(typeSpecifier.line, "not supported", "first-class array");
returnType.clearArrayness();
}
- if (returnType.qualifier == EvqAttribute &&
- (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
+ if (qualifier == EvqAttribute &&
+ (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
{
- error(typeSpecifier.getLine(), "cannot be bool or int",
- getQualifierString(returnType.qualifier));
+ error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
}
- if ((returnType.qualifier == EvqVaryingIn || returnType.qualifier == EvqVaryingOut) &&
- (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
+ if ((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) &&
+ (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
{
- error(typeSpecifier.getLine(), "cannot be bool or int",
- getQualifierString(returnType.qualifier));
+ error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
}
}
else
{
- if (!returnType.layoutQualifier.isEmpty())
+ if (!layoutQualifier.isEmpty())
{
- checkIsAtGlobalLevel(typeSpecifier.getLine(), "layout");
+ checkIsAtGlobalLevel(typeSpecifier.line, "layout");
}
- if (sh::IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn ||
- returnType.qualifier == EvqFragmentOut)
+ if (sh::IsVarying(qualifier) || qualifier == EvqVertexIn || qualifier == EvqFragmentOut)
{
- checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier,
- typeSpecifier.getLine());
+ checkInputOutputTypeIsValidES3(qualifier, typeSpecifier, typeSpecifier.line);
}
- if (returnType.qualifier == EvqComputeIn)
+ if (qualifier == EvqComputeIn)
{
- error(typeSpecifier.getLine(), "'in' can be only used to specify the local group size",
+ error(typeSpecifier.line, "'in' can be only used to specify the local group size",
"in");
}
}
@@ -1724,7 +1442,7 @@ void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
const TSourceLoc &qualifierLocation)
{
// An input/output variable can never be bool or a sampler. Samplers are checked elsewhere.
- if (type.getBasicType() == EbtBool)
+ if (type.type == EbtBool)
{
error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
}
@@ -1742,7 +1460,7 @@ void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
return;
case EvqFragmentOut:
// ESSL 3.00 section 4.3.6
- if (type.typeSpecifierNonArray.isMatrix())
+ if (type.isMatrix())
{
error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier));
}
@@ -1755,15 +1473,15 @@ void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
// Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of
// restrictions.
bool typeContainsIntegers =
- (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt ||
- type.isStructureContainingType(EbtInt) || type.isStructureContainingType(EbtUInt));
+ (type.type == EbtInt || type.type == EbtUInt || type.isStructureContainingType(EbtInt) ||
+ type.isStructureContainingType(EbtUInt));
if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut)
{
error(qualifierLocation, "must use 'flat' interpolation here",
getQualifierString(qualifier));
}
- if (type.getBasicType() == EbtStruct)
+ if (type.type == EbtStruct)
{
// ESSL 3.00 sections 4.3.4 and 4.3.6.
// These restrictions are only implied by the ESSL 3.00 spec, but
@@ -1791,57 +1509,9 @@ void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
}
}
-void TParseContext::checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier)
-{
- if (qualifier.getType() == QtStorage)
- {
- const TStorageQualifierWrapper &storageQualifier =
- static_cast<const TStorageQualifierWrapper &>(qualifier);
- if (!declaringFunction() && storageQualifier.getQualifier() != EvqConst &&
- !symbolTable.atGlobalLevel())
- {
- error(storageQualifier.getLine(),
- "Local variables can only use the const storage qualifier.",
- storageQualifier.getQualifierString().c_str());
- }
- }
-}
-
-bool TParseContext::checkIsMemoryQualifierNotSpecified(const TMemoryQualifier &memoryQualifier,
- const TSourceLoc &location)
-{
- if (memoryQualifier.readonly)
- {
- error(location, "Only allowed with images.", "readonly");
- return false;
- }
- if (memoryQualifier.writeonly)
- {
- error(location, "Only allowed with images.", "writeonly");
- return false;
- }
- if (memoryQualifier.coherent)
- {
- error(location, "Only allowed with images.", "coherent");
- return false;
- }
- if (memoryQualifier.restrictQualifier)
- {
- error(location, "Only allowed with images.", "restrict");
- return false;
- }
- if (memoryQualifier.volatileQualifier)
- {
- error(location, "Only allowed with images.", "volatile");
- return false;
- }
- return true;
-}
-
-TIntermDeclaration *TParseContext::parseSingleDeclaration(
- TPublicType &publicType,
- const TSourceLoc &identifierOrTypeLocation,
- const TString &identifier)
+TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierOrTypeLocation,
+ const TString &identifier)
{
TType type(publicType);
if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) &&
@@ -1877,9 +1547,6 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
mDeferredSingleDeclarationErrorCheck = emptyDeclaration;
- TIntermDeclaration *declaration = new TIntermDeclaration();
- declaration->setLine(identifierOrTypeLocation);
-
if (emptyDeclaration)
{
if (publicType.isUnsizedArray())
@@ -1900,23 +1567,17 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
declareVariable(identifierOrTypeLocation, identifier, type, &variable);
if (variable && symbol)
- {
symbol->setId(variable->getUniqueId());
- }
}
- // We append the symbol even if the declaration is empty, mainly because of struct declarations
- // that may just declare a type.
- declaration->appendDeclarator(symbol);
-
- return declaration;
+ return intermediate.makeAggregate(symbol, identifierOrTypeLocation);
}
-TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression)
+TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression)
{
mDeferredSingleDeclarationErrorCheck = false;
@@ -1936,44 +1597,38 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &publ
TVariable *variable = nullptr;
declareVariable(identifierLocation, identifier, arrayType, &variable);
- TIntermDeclaration *declaration = new TIntermDeclaration();
- declaration->setLine(identifierLocation);
-
TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation);
if (variable && symbol)
- {
symbol->setId(variable->getUniqueId());
- declaration->appendDeclarator(symbol);
- }
- return declaration;
+ return intermediate.makeAggregate(symbol, identifierLocation);
}
-TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer)
+TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer)
{
mDeferredSingleDeclarationErrorCheck = false;
singleDeclarationErrorCheck(publicType, identifierLocation);
- TIntermDeclaration *declaration = new TIntermDeclaration();
- declaration->setLine(identifierLocation);
-
- TIntermBinary *initNode = nullptr;
- if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
+ TIntermNode *intermNode = nullptr;
+ if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
{
- if (initNode)
- {
- declaration->appendDeclarator(initNode);
- }
+ //
+ // Build intermediate representation
+ //
+ return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : nullptr;
+ }
+ else
+ {
+ return nullptr;
}
- return declaration;
}
-TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
+TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration(
TPublicType &publicType,
const TSourceLoc &identifierLocation,
const TString &identifier,
@@ -2001,81 +1656,58 @@ TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
// This ensures useless error messages regarding the variable's non-arrayness won't follow.
arrayType.setArraySize(size);
- TIntermDeclaration *declaration = new TIntermDeclaration();
- declaration->setLine(identifierLocation);
-
// initNode will correspond to the whole of "type b[n] = initializer".
- TIntermBinary *initNode = nullptr;
+ TIntermNode *initNode = nullptr;
if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
{
- if (initNode)
- {
- declaration->appendDeclarator(initNode);
- }
+ return initNode ? intermediate.makeAggregate(initNode, initLocation) : nullptr;
}
-
- return declaration;
-}
-
-TIntermAggregate *TParseContext::parseInvariantDeclaration(
- const TTypeQualifierBuilder &typeQualifierBuilder,
- const TSourceLoc &identifierLoc,
- const TString *identifier,
- const TSymbol *symbol)
-{
- TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
-
- if (!typeQualifier.invariant)
+ else
{
- error(identifierLoc, "Expected invariant", identifier->c_str());
return nullptr;
}
- if (!checkIsAtGlobalLevel(identifierLoc, "invariant varying"))
- {
+}
+
+TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
+ const TSourceLoc &identifierLoc,
+ const TString *identifier,
+ const TSymbol *symbol)
+{
+ // invariant declaration
+ if (!checkIsAtGlobalLevel(invariantLoc, "invariant varying"))
return nullptr;
- }
+
if (!symbol)
{
error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
return nullptr;
}
- if (!IsQualifierUnspecified(typeQualifier.qualifier))
- {
- error(identifierLoc, "invariant declaration specifies qualifier",
- getQualifierString(typeQualifier.qualifier));
- }
- if (typeQualifier.precision != EbpUndefined)
- {
- error(identifierLoc, "invariant declaration specifies precision",
- getPrecisionString(typeQualifier.precision));
- }
- if (!typeQualifier.layoutQualifier.isEmpty())
+ else
{
- error(identifierLoc, "invariant declaration specifies layout", "'layout'");
- }
-
- const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
- ASSERT(variable);
- const TType &type = variable->getType();
-
- checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(),
- typeQualifier.line);
- checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
-
- symbolTable.addInvariantVarying(std::string(identifier->c_str()));
-
- TIntermSymbol *intermSymbol =
- intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc);
+ const TString kGlFrontFacing("gl_FrontFacing");
+ if (*identifier == kGlFrontFacing)
+ {
+ error(identifierLoc, "identifier should not be declared as invariant",
+ identifier->c_str());
+ return nullptr;
+ }
+ symbolTable.addInvariantVarying(std::string(identifier->c_str()));
+ const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
+ ASSERT(variable);
+ const TType &type = variable->getType();
+ TIntermSymbol *intermSymbol =
+ intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc);
- TIntermAggregate *aggregate = TIntermediate::MakeAggregate(intermSymbol, identifierLoc);
- aggregate->setOp(EOpInvariantDeclaration);
- return aggregate;
+ TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
+ aggregate->setOp(EOpInvariantDeclaration);
+ return aggregate;
+ }
}
-void TParseContext::parseDeclarator(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- TIntermDeclaration *declarationOut)
+TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType,
+ TIntermAggregate *aggregateDeclaration,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier)
{
// If the declaration starting this declarator list was empty (example: int,), some checks were
// not performed.
@@ -2095,18 +1727,17 @@ void TParseContext::parseDeclarator(TPublicType &publicType,
TIntermSymbol *symbol =
intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
if (variable && symbol)
- {
symbol->setId(variable->getUniqueId());
- declarationOut->appendDeclarator(symbol);
- }
+
+ return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
}
-void TParseContext::parseArrayDeclarator(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &arrayLocation,
- TIntermTyped *indexExpression,
- TIntermDeclaration *declarationOut)
+TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType,
+ TIntermAggregate *aggregateDeclaration,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &arrayLocation,
+ TIntermTyped *indexExpression)
{
// If the declaration starting this declarator list was empty (example: int,), some checks were
// not performed.
@@ -2134,16 +1765,18 @@ void TParseContext::parseArrayDeclarator(TPublicType &publicType,
if (variable && symbol)
symbol->setId(variable->getUniqueId());
- declarationOut->appendDeclarator(symbol);
+ return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
}
+
+ return nullptr;
}
-void TParseContext::parseInitDeclarator(const TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer,
- TIntermDeclaration *declarationOut)
+TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicType,
+ TIntermAggregate *aggregateDeclaration,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer)
{
// If the declaration starting this declarator list was empty (example: int,), some checks were
// not performed.
@@ -2155,27 +1788,35 @@ void TParseContext::parseInitDeclarator(const TPublicType &publicType,
checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
- TIntermBinary *initNode = nullptr;
- if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &initNode))
+ TIntermNode *intermNode = nullptr;
+ if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode))
{
//
// build the intermediate representation
//
- if (initNode)
+ if (intermNode)
{
- declarationOut->appendDeclarator(initNode);
+ return intermediate.growAggregate(aggregateDeclaration, intermNode, initLocation);
}
+ else
+ {
+ return aggregateDeclaration;
+ }
+ }
+ else
+ {
+ return nullptr;
}
}
-void TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer,
- TIntermDeclaration *declarationOut)
+TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
+ TIntermAggregate *aggregateDeclaration,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer)
{
// If the declaration starting this declarator list was empty (example: int,), some checks were
// not performed.
@@ -2203,24 +1844,28 @@ void TParseContext::parseArrayInitDeclarator(const TPublicType &publicType,
arrayType.setArraySize(size);
// initNode will correspond to the whole of "b[n] = initializer".
- TIntermBinary *initNode = nullptr;
+ TIntermNode *initNode = nullptr;
if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
{
if (initNode)
{
- declarationOut->appendDeclarator(initNode);
+ return intermediate.growAggregate(aggregateDeclaration, initNode, initLocation);
+ }
+ else
+ {
+ return aggregateDeclaration;
}
}
+ else
+ {
+ return nullptr;
+ }
}
-void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder)
+void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
{
- TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
- checkInvariantVariableQualifier(typeQualifier.invariant, typeQualifier.qualifier,
- typeQualifier.line);
-
// It should never be the case, but some strange parser errors can send us here.
if (layoutQualifier.isEmpty())
{
@@ -2234,10 +1879,6 @@ void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &type
return;
}
- checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
-
- checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
-
if (typeQualifier.qualifier == EvqComputeIn)
{
if (mComputeShaderLocalSizeDeclared &&
@@ -2325,31 +1966,30 @@ void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &type
}
}
-TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
+TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function,
const TSourceLoc &location)
{
- // Note: function found from the symbol table could be the same as parsedFunction if this is the
- // first declaration. Either way the instance in the symbol table is used to track whether the
- // function is declared multiple times.
- TFunction *function = static_cast<TFunction *>(
- symbolTable.find(parsedFunction.getMangledName(), getShaderVersion()));
- if (function->hasPrototypeDeclaration() && mShaderVersion == 100)
+ // Note: symbolTableFunction could be the same as function if this is the first declaration.
+ // Either way the instance in the symbol table is used to track whether the function is declared
+ // multiple times.
+ TFunction *symbolTableFunction =
+ static_cast<TFunction *>(symbolTable.find(function.getMangledName(), getShaderVersion()));
+ if (symbolTableFunction->hasPrototypeDeclaration() && mShaderVersion == 100)
{
// ESSL 1.00.17 section 4.2.7.
// Doesn't apply to ESSL 3.00.4: see section 4.2.3.
error(location, "duplicate function prototype declarations are not allowed", "function");
}
- function->setHasPrototypeDeclaration();
+ symbolTableFunction->setHasPrototypeDeclaration();
TIntermAggregate *prototype = new TIntermAggregate;
- // TODO(oetuaho@nvidia.com): Instead of converting the function information here, the node could
- // point to the data that already exists in the symbol table.
- prototype->setType(function->getReturnType());
- prototype->getFunctionSymbolInfo()->setFromFunction(*function);
+ prototype->setType(function.getReturnType());
+ prototype->setName(function.getMangledName());
+ prototype->setFunctionId(function.getUniqueId());
- for (size_t i = 0; i < function->getParamCount(); i++)
+ for (size_t i = 0; i < function.getParamCount(); i++)
{
- const TConstParameter &param = function->getParam(i);
+ const TConstParameter &param = function.getParam(i);
if (param.name != 0)
{
TVariable variable(param.name, *param.type);
@@ -2378,83 +2018,71 @@ TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction
return prototype;
}
-TIntermFunctionDefinition *TParseContext::addFunctionDefinition(
- const TFunction &function,
- TIntermAggregate *functionParameters,
- TIntermBlock *functionBody,
- const TSourceLoc &location)
+TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function,
+ TIntermAggregate *functionPrototype,
+ TIntermAggregate *functionBody,
+ const TSourceLoc &location)
{
- // Check that non-void functions have at least one return statement.
+ //?? Check that all paths return a value if return type != void ?
+ // May be best done as post process phase on intermediate code
if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
{
error(location, "function does not return a value:", "", function.getName().c_str());
}
- if (functionBody == nullptr)
- {
- functionBody = new TIntermBlock();
- functionBody->setLine(location);
- }
- TIntermFunctionDefinition *functionNode =
- new TIntermFunctionDefinition(function.getReturnType(), functionParameters, functionBody);
- functionNode->setLine(location);
-
- functionNode->getFunctionSymbolInfo()->setFromFunction(function);
+ TIntermAggregate *aggregate =
+ intermediate.growAggregate(functionPrototype, functionBody, location);
+ intermediate.setAggregateOperator(aggregate, EOpFunction, location);
+ aggregate->setName(function.getMangledName().c_str());
+ aggregate->setType(function.getReturnType());
+ aggregate->setFunctionId(function.getUniqueId());
symbolTable.pop();
- return functionNode;
+ return aggregate;
}
-void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
- TFunction **function,
- TIntermAggregate **aggregateOut)
+void TParseContext::parseFunctionPrototype(const TSourceLoc &location,
+ TFunction *function,
+ TIntermAggregate **aggregateOut)
{
- ASSERT(function);
- ASSERT(*function);
const TSymbol *builtIn =
- symbolTable.findBuiltIn((*function)->getMangledName(), getShaderVersion());
+ symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
if (builtIn)
{
- error(location, "built-in functions cannot be redefined", (*function)->getName().c_str());
+ error(location, "built-in functions cannot be redefined", function->getName().c_str());
}
- else
- {
- TFunction *prevDec = static_cast<TFunction *>(
- symbolTable.find((*function)->getMangledName(), getShaderVersion()));
-
- // Note: 'prevDec' could be 'function' if this is the first time we've seen function as it
- // would have just been put in the symbol table. Otherwise, we're looking up an earlier
- // occurance.
- if (*function != prevDec)
- {
- // Swap the parameters of the previous declaration to the parameters of the function
- // definition (parameter names may differ).
- prevDec->swapParameters(**function);
-
- // The function definition will share the same symbol as any previous declaration.
- *function = prevDec;
- }
-
- if ((*function)->isDefined())
- {
- error(location, "function already has a body", (*function)->getName().c_str());
- }
- (*function)->setDefined();
+ TFunction *prevDec =
+ static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
+ //
+ // Note: 'prevDec' could be 'function' if this is the first time we've seen function
+ // as it would have just been put in the symbol table. Otherwise, we're looking up
+ // an earlier occurance.
+ //
+ if (prevDec->isDefined())
+ {
+ // Then this function already has a body.
+ error(location, "function already has a body", function->getName().c_str());
}
+ prevDec->setDefined();
+ //
+ // Overload the unique ID of the definition to be the same unique ID as the declaration.
+ // Eventually we will probably want to have only a single definition and just swap the
+ // arguments to be the definition's arguments.
+ //
+ function->setUniqueId(prevDec->getUniqueId());
// Raise error message if main function takes any parameters or return anything other than void
- if ((*function)->getName() == "main")
+ if (function->getName() == "main")
{
- if ((*function)->getParamCount() > 0)
+ if (function->getParamCount() > 0)
{
- error(location, "function cannot take any parameter(s)",
- (*function)->getName().c_str());
+ error(location, "function cannot take any parameter(s)", function->getName().c_str());
}
- if ((*function)->getReturnType().getBasicType() != EbtVoid)
+ if (function->getReturnType().getBasicType() != EbtVoid)
{
- error(location, "", (*function)->getReturnType().getBasicString(),
+ error(location, "", function->getReturnType().getBasicString(),
"main function cannot return a value");
}
}
@@ -2462,7 +2090,7 @@ void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
//
// Remember the return type for later checking for RETURN statements.
//
- mCurrentFunctionType = &((*function)->getReturnType());
+ mCurrentFunctionType = &(prevDec->getReturnType());
mFunctionReturnsValue = false;
//
@@ -2474,9 +2102,9 @@ void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
// knows where to find parameters.
//
TIntermAggregate *paramNodes = new TIntermAggregate;
- for (size_t i = 0; i < (*function)->getParamCount(); i++)
+ for (size_t i = 0; i < function->getParamCount(); i++)
{
- const TConstParameter &param = (*function)->getParam(i);
+ const TConstParameter &param = function->getParam(i);
if (param.name != 0)
{
TVariable *variable = new TVariable(param.name, *param.type);
@@ -2534,7 +2162,7 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
{
if (prevDec->getReturnType() != function->getReturnType())
{
- error(location, "function must have the same return type in all of its declarations",
+ error(location, "overloaded functions must have the same return type",
function->getReturnType().getBasicString());
}
for (size_t i = 0; i < prevDec->getParamCount(); ++i)
@@ -2542,8 +2170,7 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
if (prevDec->getParam(i).type->getQualifier() !=
function->getParam(i).type->getQualifier())
{
- error(location,
- "function must have the same parameter qualifiers in all of its declarations",
+ error(location, "overloaded functions must have the same parameter qualifiers",
function->getParam(i).type->getQualifierString());
}
}
@@ -2563,7 +2190,9 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
else
{
// Insert the unmangled name to detect potential future redefinition as a variable.
- symbolTable.getOuterLevel()->insertUnmangled(function);
+ TFunction *newFunction =
+ new TFunction(NewPoolTString(function->getName().c_str()), &function->getReturnType());
+ symbolTable.getOuterLevel()->insertUnmangled(newFunction);
}
// We're at the inner scope level of the function's arguments and body statement.
@@ -2591,10 +2220,8 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
{
error(location, "no qualifiers allowed for function return", "layout");
}
- // make sure a sampler or an image is not involved as well...
- checkIsNotSampler(location, type.typeSpecifierNonArray,
- "samplers can't be function return values");
- checkIsNotImage(location, type.typeSpecifierNonArray, "images can't be function return values");
+ // make sure a sampler is not involved as well...
+ checkIsNotSampler(location, type, "samplers can't be function return values");
if (mShaderVersion < 300)
{
// Array return values are forbidden, but there's also no valid syntax for declaring array
@@ -2616,14 +2243,14 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn)
{
TPublicType publicType = publicTypeIn;
- if (publicType.isStructSpecifier())
+ if (publicType.isStructSpecifier)
{
- error(publicType.getLine(), "constructor can't be a structure definition",
- getBasicString(publicType.getBasicType()));
+ error(publicType.line, "constructor can't be a structure definition",
+ getBasicString(publicType.type));
}
TOperator op = EOpNull;
- if (publicType.getUserDef())
+ if (publicType.userDef)
{
op = EOpConstructStruct;
}
@@ -2632,9 +2259,8 @@ TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn)
op = sh::TypeToConstructorOperator(TType(publicType));
if (op == EOpNull)
{
- error(publicType.getLine(), "cannot construct this type",
- getBasicString(publicType.getBasicType()));
- publicType.setBasicType(EbtFloat);
+ error(publicType.line, "cannot construct this type", getBasicString(publicType.type));
+ publicType.type = EbtFloat;
op = EOpConstructFloat;
}
}
@@ -2657,12 +2283,6 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments,
TType type = fnCall->getReturnType();
if (type.isUnsizedArray())
{
- if (fnCall->getParamCount() == 0)
- {
- error(line, "implicitly sized array constructor must have at least one argument", "[]");
- type.setArraySize(1u);
- return TIntermTyped::CreateZero(type);
- }
type.setArraySize(static_cast<unsigned int>(fnCall->getParamCount()));
}
bool constType = true;
@@ -2702,7 +2322,7 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments,
constructor->setType(type);
- TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor, &mDiagnostics);
+ TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor);
if (constConstructor)
{
return constConstructor;
@@ -2711,36 +2331,118 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments,
return constructor;
}
+// This function returns vector field(s) being accessed from a constant vector.
+TIntermConstantUnion *TParseContext::foldVectorSwizzle(TVectorFields &fields,
+ TIntermConstantUnion *baseNode,
+ const TSourceLoc &location)
+{
+ const TConstantUnion *unionArray = baseNode->getUnionArrayPointer();
+ ASSERT(unionArray);
+
+ TConstantUnion *constArray = new TConstantUnion[fields.num];
+ const auto &type = baseNode->getType();
+
+ for (int i = 0; i < fields.num; i++)
+ {
+ // Out-of-range indices should already be checked.
+ ASSERT(fields.offsets[i] < type.getNominalSize());
+ constArray[i] = unionArray[fields.offsets[i]];
+ }
+ return intermediate.addConstantUnion(constArray, type, location);
+}
+
+// This function returns the column vector being accessed from a constant matrix.
+TIntermConstantUnion *TParseContext::foldMatrixSubscript(int index,
+ TIntermConstantUnion *baseNode,
+ const TSourceLoc &location)
+{
+ ASSERT(index < baseNode->getType().getCols());
+
+ const TConstantUnion *unionArray = baseNode->getUnionArrayPointer();
+ int size = baseNode->getType().getRows();
+ return intermediate.addConstantUnion(&unionArray[size * index], baseNode->getType(), location);
+}
+
+// This function returns an element of an array accessed from a constant array.
+TIntermConstantUnion *TParseContext::foldArraySubscript(int index,
+ TIntermConstantUnion *baseNode,
+ const TSourceLoc &location)
+{
+ ASSERT(index < static_cast<int>(baseNode->getArraySize()));
+
+ TType arrayElementType = baseNode->getType();
+ arrayElementType.clearArrayness();
+ size_t arrayElementSize = arrayElementType.getObjectSize();
+ const TConstantUnion *unionArray = baseNode->getUnionArrayPointer();
+ return intermediate.addConstantUnion(&unionArray[arrayElementSize * index], baseNode->getType(),
+ location);
+}
+
+//
+// This function returns the value of a particular field inside a constant structure from the symbol
+// table.
+// If there is an embedded/nested struct, it appropriately calls addConstStructNested or
+// addConstStructFromAggr function and returns the parse-tree with the values of the embedded/nested
+// struct.
+//
+TIntermTyped *TParseContext::addConstStruct(const TString &identifier,
+ TIntermTyped *node,
+ const TSourceLoc &line)
+{
+ const TFieldList &fields = node->getType().getStruct()->fields();
+ size_t instanceSize = 0;
+
+ for (size_t index = 0; index < fields.size(); ++index)
+ {
+ if (fields[index]->name() == identifier)
+ {
+ break;
+ }
+ else
+ {
+ instanceSize += fields[index]->type()->getObjectSize();
+ }
+ }
+
+ TIntermTyped *typedNode;
+ TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
+ if (tempConstantNode)
+ {
+ const TConstantUnion *constArray = tempConstantNode->getUnionArrayPointer();
+
+ // type will be changed in the calling function
+ typedNode = intermediate.addConstantUnion(constArray + instanceSize,
+ tempConstantNode->getType(), line);
+ }
+ else
+ {
+ error(line, "Cannot offset into the structure", "Error");
+ return nullptr;
+ }
+
+ return typedNode;
+}
+
//
// Interface/uniform blocks
//
-TIntermDeclaration *TParseContext::addInterfaceBlock(
- const TTypeQualifierBuilder &typeQualifierBuilder,
- const TSourceLoc &nameLine,
- const TString &blockName,
- TFieldList *fieldList,
- const TString *instanceName,
- const TSourceLoc &instanceLine,
- TIntermTyped *arrayIndex,
- const TSourceLoc &arrayIndexLine)
+TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualifier,
+ const TSourceLoc &nameLine,
+ const TString &blockName,
+ TFieldList *fieldList,
+ const TString *instanceName,
+ const TSourceLoc &instanceLine,
+ TIntermTyped *arrayIndex,
+ const TSourceLoc &arrayIndexLine)
{
checkIsNotReserved(nameLine, blockName);
- TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
-
if (typeQualifier.qualifier != EvqUniform)
{
error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier),
"interface blocks must be uniform");
}
- if (typeQualifier.invariant)
- {
- error(typeQualifier.line, "invalid qualifier on interface block member", "invariant");
- }
-
- checkIsMemoryQualifierNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
-
TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
@@ -2756,8 +2458,6 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier);
- checkInternalFormatIsNotSpecified(nameLine, blockLayoutQualifier.imageInternalFormat);
-
TSymbol *blockNameSymbol = new TInterfaceBlockName(&blockName);
if (!symbolTable.declare(blockNameSymbol))
{
@@ -2775,12 +2475,6 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
"sampler types are not allowed in interface blocks");
}
- if (IsImage(fieldType->getBasicType()))
- {
- error(field->line(), "unsupported type", fieldType->getBasicString(),
- "image types are not allowed in interface blocks");
- }
-
const TQualifier qualifier = fieldType->getQualifier();
switch (qualifier)
{
@@ -2793,11 +2487,6 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
break;
}
- if (fieldType->isInvariant())
- {
- error(field->line(), "invalid qualifier on interface block member", "invariant");
- }
-
// check layout qualifiers
TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
checkLocationIsNotSpecified(field->line(), fieldLayoutQualifier);
@@ -2876,14 +2565,13 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
symbolName = instanceTypeDef->getName();
}
- TIntermSymbol *blockSymbol =
- intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line);
- TIntermDeclaration *declaration = new TIntermDeclaration();
- declaration->appendDeclarator(blockSymbol);
- declaration->setLine(nameLine);
+ TIntermAggregate *aggregate = intermediate.makeAggregate(
+ intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line),
+ nameLine);
+ aggregate->setOp(EOpDeclaration);
exitStructDeclaration();
- return declaration;
+ return aggregate;
}
void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier)
@@ -2904,9 +2592,15 @@ void TParseContext::exitStructDeclaration()
--mStructNestingLevel;
}
+namespace
+{
+const int kWebGLMaxStructNesting = 4;
+
+} // namespace
+
void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field)
{
- if (!sh::IsWebGLBasedSpec(mShaderSpec))
+ if (!IsWebGLBasedSpec(mShaderSpec))
{
return;
}
@@ -2936,6 +2630,8 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
const TSourceLoc &location,
TIntermTyped *indexExpression)
{
+ TIntermTyped *indexedExpression = NULL;
+
if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
{
if (baseExpression->getAsSymbolNode())
@@ -2947,11 +2643,6 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
{
error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
}
-
- TConstantUnion *unionArray = new TConstantUnion[1];
- unionArray->setFConst(0.0f);
- return intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst),
- location);
}
TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
@@ -2981,78 +2672,151 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
if (indexConstantUnion)
{
- // If an out-of-range index is not qualified as constant, the behavior in the spec is
- // undefined. This applies even if ANGLE has been able to constant fold it (ANGLE may
- // constant fold expressions that are not constant expressions). The most compatible way to
- // handle this case is to report a warning instead of an error and force the index to be in
- // the correct range.
+ // If the index is not qualified as constant, the behavior in the spec is undefined. This
+ // applies even if ANGLE has been able to constant fold it (ANGLE may constant fold
+ // expressions that are not constant expressions). The most compatible way to handle this
+ // case is to report a warning instead of an error and force the index to be in the
+ // correct range.
bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst;
int index = indexConstantUnion->getIConst(0);
+ if (!baseExpression->isArray())
+ {
+ // Array checks are done later because a different error message might be generated
+ // based on the index in some cases.
+ if (baseExpression->isVector())
+ {
+ index = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
+ baseExpression->getType().getNominalSize(),
+ "vector field selection out of range", "[]");
+ }
+ else if (baseExpression->isMatrix())
+ {
+ index = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
+ baseExpression->getType().getCols(),
+ "matrix field selection out of range", "[]");
+ }
+ }
- int safeIndex = -1;
-
- if (baseExpression->isArray())
+ TIntermConstantUnion *baseConstantUnion = baseExpression->getAsConstantUnion();
+ if (baseConstantUnion)
{
- if (baseExpression->getQualifier() == EvqFragData && index > 0)
+ if (baseExpression->isArray())
{
- if (mShaderSpec == SH_WEBGL2_SPEC)
+ index = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
+ baseExpression->getArraySize(),
+ "array index out of range", "[]");
+ // Constant folding for array indexing.
+ indexedExpression = foldArraySubscript(index, baseConstantUnion, location);
+ }
+ else if (baseExpression->isVector())
+ {
+ // Constant folding for vector indexing - reusing vector swizzle folding.
+ TVectorFields fields;
+ fields.num = 1;
+ fields.offsets[0] = index;
+ indexedExpression = foldVectorSwizzle(fields, baseConstantUnion, location);
+ }
+ else if (baseExpression->isMatrix())
+ {
+ // Constant folding for matrix indexing.
+ indexedExpression = foldMatrixSubscript(index, baseConstantUnion, location);
+ }
+ }
+ else
+ {
+ int safeIndex = -1;
+
+ if (baseExpression->isArray())
+ {
+ if (baseExpression->getQualifier() == EvqFragData && index > 0)
{
- // Error has been already generated if index is not const.
- if (indexExpression->getQualifier() == EvqConst)
+ if (mShaderSpec == SH_WEBGL2_SPEC)
{
- error(location, "", "[",
- "array index for gl_FragData must be constant zero");
+ // Error has been already generated if index is not const.
+ if (indexExpression->getQualifier() == EvqConst)
+ {
+ error(location, "", "[",
+ "array index for gl_FragData must be constant zero");
+ }
+ safeIndex = 0;
+ }
+ else if (!isExtensionEnabled("GL_EXT_draw_buffers"))
+ {
+ outOfRangeError(outOfRangeIndexIsError, location, "", "[",
+ "array index for gl_FragData must be zero when "
+ "GL_EXT_draw_buffers is disabled");
+ safeIndex = 0;
}
- safeIndex = 0;
}
- else if (!isExtensionEnabled("GL_EXT_draw_buffers"))
+ // Only do generic out-of-range check if similar error hasn't already been reported.
+ if (safeIndex < 0)
{
- outOfRangeError(outOfRangeIndexIsError, location, "", "[",
- "array index for gl_FragData must be zero when "
- "GL_EXT_draw_buffers is disabled");
- safeIndex = 0;
+ safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
+ baseExpression->getArraySize(),
+ "array index out of range", "[]");
}
}
- // Only do generic out-of-range check if similar error hasn't already been reported.
- if (safeIndex < 0)
+
+ // Data of constant unions can't be changed, because it may be shared with other
+ // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
+ // sanitized object.
+ if (safeIndex != -1)
{
- safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
- baseExpression->getArraySize(),
- "array index out of range", "[]");
+ TConstantUnion *safeConstantUnion = new TConstantUnion();
+ safeConstantUnion->setIConst(safeIndex);
+ indexConstantUnion->replaceConstantUnion(safeConstantUnion);
}
- }
- else if (baseExpression->isMatrix())
- {
- safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
- baseExpression->getType().getCols(),
- "matrix field selection out of range", "[]");
- }
- else if (baseExpression->isVector())
- {
- safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
- baseExpression->getType().getNominalSize(),
- "vector field selection out of range", "[]");
- }
- ASSERT(safeIndex >= 0);
- // Data of constant unions can't be changed, because it may be shared with other
- // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
- // sanitized object.
- if (safeIndex != index)
- {
- TConstantUnion *safeConstantUnion = new TConstantUnion();
- safeConstantUnion->setIConst(safeIndex);
- indexConstantUnion->replaceConstantUnion(safeConstantUnion);
+ indexedExpression =
+ intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
}
+ }
+ else
+ {
+ indexedExpression =
+ intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
+ }
+
+ if (indexedExpression == 0)
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setFConst(0.0f);
+ indexedExpression =
+ intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location);
+ }
+ else if (baseExpression->isArray())
+ {
+ TType indexedType = baseExpression->getType();
+ indexedType.clearArrayness();
+ indexedExpression->setType(indexedType);
+ }
+ else if (baseExpression->isMatrix())
+ {
+ indexedExpression->setType(TType(baseExpression->getBasicType(),
+ baseExpression->getPrecision(), EvqTemporary,
+ static_cast<unsigned char>(baseExpression->getRows())));
+ }
+ else if (baseExpression->isVector())
+ {
+ indexedExpression->setType(
+ TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary));
+ }
+ else
+ {
+ indexedExpression->setType(baseExpression->getType());
+ }
- return intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location,
- &mDiagnostics);
+ if (baseExpression->getType().getQualifier() == EvqConst &&
+ indexExpression->getType().getQualifier() == EvqConst)
+ {
+ indexedExpression->getTypePointer()->setQualifier(EvqConst);
}
else
{
- return intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location,
- &mDiagnostics);
+ indexedExpression->getTypePointer()->setQualifier(EvqTemporary);
}
+
+ return indexedExpression;
}
int TParseContext::checkIndexOutOfRange(bool outOfRangeIndexIsError,
@@ -3085,10 +2849,11 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
const TString &fieldString,
const TSourceLoc &fieldLocation)
{
+ TIntermTyped *indexedExpression = NULL;
+
if (baseExpression->isArray())
{
error(fieldLocation, "cannot apply dot operator to an array", ".");
- return baseExpression;
}
if (baseExpression->isVector())
@@ -3101,19 +2866,41 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
fields.offsets[0] = 0;
}
- return TIntermediate::AddSwizzle(baseExpression, fields, dotLocation);
+ if (baseExpression->getAsConstantUnion())
+ {
+ // constant folding for vector fields
+ indexedExpression =
+ foldVectorSwizzle(fields, baseExpression->getAsConstantUnion(), fieldLocation);
+ }
+ else
+ {
+ TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation);
+ indexedExpression =
+ intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation);
+ }
+ if (indexedExpression == nullptr)
+ {
+ indexedExpression = baseExpression;
+ }
+ else
+ {
+ // Note that the qualifier set here will be corrected later.
+ indexedExpression->setType(TType(baseExpression->getBasicType(),
+ baseExpression->getPrecision(), EvqTemporary,
+ static_cast<unsigned char>(fields.num)));
+ }
}
else if (baseExpression->getBasicType() == EbtStruct)
{
+ bool fieldFound = false;
const TFieldList &fields = baseExpression->getType().getStruct()->fields();
if (fields.empty())
{
error(dotLocation, "structure has no fields", "Internal Error");
- return baseExpression;
+ indexedExpression = baseExpression;
}
else
{
- bool fieldFound = false;
unsigned int i;
for (i = 0; i < fields.size(); ++i)
{
@@ -3125,29 +2912,47 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
}
if (fieldFound)
{
- TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
- index->setLine(fieldLocation);
- return intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index,
- dotLocation, &mDiagnostics);
+ if (baseExpression->getAsConstantUnion())
+ {
+ indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation);
+ if (indexedExpression == 0)
+ {
+ indexedExpression = baseExpression;
+ }
+ else
+ {
+ indexedExpression->setType(*fields[i]->type());
+ }
+ }
+ else
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setIConst(i);
+ TIntermTyped *index = intermediate.addConstantUnion(
+ unionArray, *fields[i]->type(), fieldLocation);
+ indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression,
+ index, dotLocation);
+ indexedExpression->setType(*fields[i]->type());
+ }
}
else
{
error(dotLocation, " no such field in structure", fieldString.c_str());
- return baseExpression;
+ indexedExpression = baseExpression;
}
}
}
else if (baseExpression->isInterfaceBlock())
{
+ bool fieldFound = false;
const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
if (fields.empty())
{
error(dotLocation, "interface block has no fields", "Internal Error");
- return baseExpression;
+ indexedExpression = baseExpression;
}
else
{
- bool fieldFound = false;
unsigned int i;
for (i = 0; i < fields.size(); ++i)
{
@@ -3159,15 +2964,18 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
}
if (fieldFound)
{
- TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
- index->setLine(fieldLocation);
- return intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index,
- dotLocation, &mDiagnostics);
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setIConst(i);
+ TIntermTyped *index =
+ intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation);
+ indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock,
+ baseExpression, index, dotLocation);
+ indexedExpression->setType(*fields[i]->type());
}
else
{
error(dotLocation, " no such field in interface block", fieldString.c_str());
- return baseExpression;
+ indexedExpression = baseExpression;
}
}
}
@@ -3185,8 +2993,19 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
"side",
fieldString.c_str());
}
- return baseExpression;
+ indexedExpression = baseExpression;
+ }
+
+ if (baseExpression->getQualifier() == EvqConst)
+ {
+ indexedExpression->getTypePointer()->setQualifier(EvqConst);
}
+ else
+ {
+ indexedExpression->getTypePointer()->setQualifier(EvqTemporary);
+ }
+
+ return indexedExpression;
}
TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
@@ -3196,18 +3015,10 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp
if (qualifierType == "shared")
{
- if (sh::IsWebGLBasedSpec(mShaderSpec))
- {
- error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "shared");
- }
qualifier.blockStorage = EbsShared;
}
else if (qualifierType == "packed")
{
- if (sh::IsWebGLBasedSpec(mShaderSpec))
- {
- error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "packed");
- }
qualifier.blockStorage = EbsPacked;
}
else if (qualifierType == "std140")
@@ -3227,72 +3038,6 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp
error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(),
"location requires an argument");
}
- else if (qualifierType == "rgba32f")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA32F;
- }
- else if (qualifierType == "rgba16f")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA16F;
- }
- else if (qualifierType == "r32f")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifR32F;
- }
- else if (qualifierType == "rgba8")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA8;
- }
- else if (qualifierType == "rgba8_snorm")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA8_SNORM;
- }
- else if (qualifierType == "rgba32i")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA32I;
- }
- else if (qualifierType == "rgba16i")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA16I;
- }
- else if (qualifierType == "rgba8i")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA8I;
- }
- else if (qualifierType == "r32i")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifR32I;
- }
- else if (qualifierType == "rgba32ui")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA32UI;
- }
- else if (qualifierType == "rgba16ui")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA16UI;
- }
- else if (qualifierType == "rgba8ui")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifRGBA8UI;
- }
- else if (qualifierType == "r32ui")
- {
- checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
- qualifier.imageInternalFormat = EiifR32UI;
- }
-
else
{
error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str());
@@ -3338,7 +3083,6 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp
else
{
qualifier.location = intValue;
- qualifier.locationsSpecified = 1;
}
}
else if (qualifierType == "local_size_x")
@@ -3364,48 +3108,106 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp
return qualifier;
}
-TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLoc &loc)
-{
- return new TTypeQualifierBuilder(
- new TStorageQualifierWrapper(symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary, loc),
- mShaderVersion);
-}
-
TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier,
TLayoutQualifier rightQualifier,
const TSourceLoc &rightQualifierLocation)
{
- return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation,
- &mDiagnostics);
+ TLayoutQualifier joinedQualifier = leftQualifier;
+
+ if (rightQualifier.location != -1)
+ {
+ joinedQualifier.location = rightQualifier.location;
+ }
+ if (rightQualifier.matrixPacking != EmpUnspecified)
+ {
+ joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
+ }
+ if (rightQualifier.blockStorage != EbsUnspecified)
+ {
+ joinedQualifier.blockStorage = rightQualifier.blockStorage;
+ }
+
+ for (size_t i = 0u; i < rightQualifier.localSize.size(); ++i)
+ {
+ if (rightQualifier.localSize[i] != -1)
+ {
+ if (joinedQualifier.localSize[i] != -1 &&
+ joinedQualifier.localSize[i] != rightQualifier.localSize[i])
+ {
+ error(rightQualifierLocation,
+ "Cannot have multiple different work group size specifiers",
+ getWorkGroupSizeString(i));
+ }
+ joinedQualifier.localSize[i] = rightQualifier.localSize[i];
+ }
+ }
+
+ return joinedQualifier;
}
-TFieldList *TParseContext::addStructDeclaratorListWithQualifiers(
- const TTypeQualifierBuilder &typeQualifierBuilder,
- TPublicType *typeSpecifier,
- TFieldList *fieldList)
+TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc,
+ TQualifier interpolationQualifier,
+ const TSourceLoc &storageLoc,
+ TQualifier storageQualifier)
{
- TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics);
+ TQualifier mergedQualifier = EvqSmoothIn;
- typeSpecifier->qualifier = typeQualifier.qualifier;
- typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier;
- typeSpecifier->memoryQualifier = typeQualifier.memoryQualifier;
- typeSpecifier->invariant = typeQualifier.invariant;
- if (typeQualifier.precision != EbpUndefined)
+ if (storageQualifier == EvqFragmentIn)
{
- typeSpecifier->precision = typeQualifier.precision;
+ if (interpolationQualifier == EvqSmooth)
+ mergedQualifier = EvqSmoothIn;
+ else if (interpolationQualifier == EvqFlat)
+ mergedQualifier = EvqFlatIn;
+ else
+ UNREACHABLE();
+ }
+ else if (storageQualifier == EvqCentroidIn)
+ {
+ if (interpolationQualifier == EvqSmooth)
+ mergedQualifier = EvqCentroidIn;
+ else if (interpolationQualifier == EvqFlat)
+ mergedQualifier = EvqFlatIn;
+ else
+ UNREACHABLE();
+ }
+ else if (storageQualifier == EvqVertexOut)
+ {
+ if (interpolationQualifier == EvqSmooth)
+ mergedQualifier = EvqSmoothOut;
+ else if (interpolationQualifier == EvqFlat)
+ mergedQualifier = EvqFlatOut;
+ else
+ UNREACHABLE();
+ }
+ else if (storageQualifier == EvqCentroidOut)
+ {
+ if (interpolationQualifier == EvqSmooth)
+ mergedQualifier = EvqCentroidOut;
+ else if (interpolationQualifier == EvqFlat)
+ mergedQualifier = EvqFlatOut;
+ else
+ UNREACHABLE();
}
- return addStructDeclaratorList(*typeSpecifier, fieldList);
+ else
+ {
+ error(interpolationLoc,
+ "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier",
+ getInterpolationString(interpolationQualifier));
+
+ mergedQualifier = storageQualifier;
+ }
+
+ TPublicType type;
+ type.setBasic(EbtVoid, mergedQualifier, storageLoc);
+ return type;
}
TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier,
TFieldList *fieldList)
{
- checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision,
- typeSpecifier.getBasicType());
+ checkIsNonVoid(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type);
- checkIsNonVoid(typeSpecifier.getLine(), (*fieldList)[0]->name(), typeSpecifier.getBasicType());
-
- checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier);
+ checkWorkGroupSizeIsNotSpecified(typeSpecifier.line, typeSpecifier.layoutQualifier);
for (unsigned int i = 0; i < fieldList->size(); ++i)
{
@@ -3413,43 +3215,42 @@ TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecif
// Careful not to replace already known aspects of type, like array-ness
//
TType *type = (*fieldList)[i]->type();
- type->setBasicType(typeSpecifier.getBasicType());
- type->setPrimarySize(typeSpecifier.getPrimarySize());
- type->setSecondarySize(typeSpecifier.getSecondarySize());
+ type->setBasicType(typeSpecifier.type);
+ type->setPrimarySize(typeSpecifier.primarySize);
+ type->setSecondarySize(typeSpecifier.secondarySize);
type->setPrecision(typeSpecifier.precision);
type->setQualifier(typeSpecifier.qualifier);
type->setLayoutQualifier(typeSpecifier.layoutQualifier);
- type->setMemoryQualifier(typeSpecifier.memoryQualifier);
- type->setInvariant(typeSpecifier.invariant);
// don't allow arrays of arrays
if (type->isArray())
{
- checkIsValidTypeForArray(typeSpecifier.getLine(), typeSpecifier);
+ checkIsValidTypeForArray(typeSpecifier.line, typeSpecifier);
}
if (typeSpecifier.array)
type->setArraySize(static_cast<unsigned int>(typeSpecifier.arraySize));
- if (typeSpecifier.getUserDef())
+ if (typeSpecifier.userDef)
{
- type->setStruct(typeSpecifier.getUserDef()->getStruct());
+ type->setStruct(typeSpecifier.userDef->getStruct());
}
- checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *(*fieldList)[i]);
+ checkIsBelowStructNestingLimit(typeSpecifier.line, *(*fieldList)[i]);
}
return fieldList;
}
-TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
- const TSourceLoc &nameLine,
- const TString *structName,
- TFieldList *fieldList)
+TPublicType TParseContext::addStructure(const TSourceLoc &structLine,
+ const TSourceLoc &nameLine,
+ const TString *structName,
+ TFieldList *fieldList)
{
TStructure *structure = new TStructure(structName, fieldList);
TType *structureType = new TType(structure);
// Store a bool in the struct if we're at global scope, to allow us to
// skip the local struct scoping workaround in HLSL.
+ structure->setUniqueId(TSymbolTable::nextUniqueId());
structure->setAtGlobalScope(symbolTable.atGlobalLevel());
if (!structName->empty())
@@ -3477,31 +3278,19 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
getQualifierString(qualifier));
break;
}
- if (field.type()->isInvariant())
- {
- error(field.line(), "invalid qualifier on struct member", "invariant");
- }
- if (IsImage(field.type()->getBasicType()))
- {
- error(field.line(), "disallowed type in struct", field.type()->getBasicString());
- }
-
- checkIsMemoryQualifierNotSpecified(field.type()->getMemoryQualifier(), field.line());
-
- checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier());
}
- TTypeSpecifierNonArray typeSpecifierNonArray;
- typeSpecifierNonArray.initialize(EbtStruct, structLine);
- typeSpecifierNonArray.userDef = structureType;
- typeSpecifierNonArray.isStructSpecifier = true;
+ TPublicType publicType;
+ publicType.setBasic(EbtStruct, EvqTemporary, structLine);
+ publicType.userDef = structureType;
+ publicType.isStructSpecifier = true;
exitStructDeclaration();
- return typeSpecifierNonArray;
+ return publicType;
}
TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
- TIntermBlock *statementList,
+ TIntermAggregate *statementList,
const TSourceLoc &loc)
{
TBasicType switchType = init->getBasicType();
@@ -3613,7 +3402,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
case EOpNegative:
case EOpPositive:
if (child->getBasicType() == EbtStruct || child->getBasicType() == EbtBool ||
- child->isArray() || IsOpaqueType(child->getBasicType()))
+ child->isArray() || IsSampler(child->getBasicType()))
{
return nullptr;
}
@@ -3622,14 +3411,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
break;
}
- TIntermUnary *node = new TIntermUnary(op, child);
- node->setLine(loc);
-
- TIntermTyped *foldedNode = node->fold(&mDiagnostics);
- if (foldedNode)
- return foldedNode;
-
- return node;
+ return intermediate.addUnaryMath(op, child, loc, funcReturnType);
}
TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
@@ -3778,14 +3560,6 @@ bool TParseContext::binaryOpCommonCheck(TOperator op,
GetOperatorString(op));
return false;
}
-
- if ((op == EOpAssign || op == EOpInitialize) &&
- left->getType().isStructureContainingImages())
- {
- error(loc, "undefined operation for structs containing images",
- GetOperatorString(op));
- return false;
- }
case EOpLessThan:
case EOpGreaterThan:
case EOpLessThanEqual:
@@ -3916,12 +3690,10 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op,
case EOpLogicalAnd:
ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
!right->getType().getStruct());
- if (left->getBasicType() != EbtBool || !left->isScalar() || !right->isScalar())
+ if (left->getBasicType() != EbtBool || left->isMatrix() || left->isVector())
{
return nullptr;
}
- // Basic types matching should have been already checked.
- ASSERT(right->getBasicType() == EbtBool);
break;
case EOpAdd:
case EOpSub:
@@ -4000,10 +3772,10 @@ TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op,
return node;
}
-TIntermBinary *TParseContext::createAssign(TOperator op,
- TIntermTyped *left,
- TIntermTyped *right,
- const TSourceLoc &loc)
+TIntermTyped *TParseContext::createAssign(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
{
if (binaryOpCommonCheck(op, left, right, loc))
{
@@ -4053,7 +3825,7 @@ TIntermTyped *TParseContext::addComma(TIntermTyped *left,
",");
}
- return TIntermediate::AddComma(left, right, loc, mShaderVersion);
+ return intermediate.addComma(left, right, loc, mShaderVersion);
}
TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
@@ -4105,7 +3877,7 @@ TIntermBranch *TParseContext::addBranch(TOperator op,
void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall)
{
ASSERT(!functionCall->isUserDefined());
- const TString &name = functionCall->getFunctionSymbolInfo()->getName();
+ const TString &name = functionCall->getName();
TIntermNode *offset = nullptr;
TIntermSequence *arguments = functionCall->getSequence();
if (name.compare(0, 16, "texelFetchOffset") == 0 ||
@@ -4153,99 +3925,6 @@ void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall)
}
}
-// GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
-void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
-{
- ASSERT(!functionCall->isUserDefined());
- const TString &name = functionCall->getFunctionSymbolInfo()->getName();
-
- if (name.compare(0, 5, "image") == 0)
- {
- TIntermSequence *arguments = functionCall->getSequence();
- TIntermNode *imageNode = (*arguments)[0];
- TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
-
- const TMemoryQualifier &memoryQualifier = imageSymbol->getMemoryQualifier();
-
- if (name.compare(5, 5, "Store") == 0)
- {
- if (memoryQualifier.readonly)
- {
- error(imageNode->getLine(),
- "'imageStore' cannot be used with images qualified as 'readonly'",
- imageSymbol->getSymbol().c_str());
- }
- }
- else if (name.compare(5, 4, "Load") == 0)
- {
- if (memoryQualifier.writeonly)
- {
- error(imageNode->getLine(),
- "'imageLoad' cannot be used with images qualified as 'writeonly'",
- imageSymbol->getSymbol().c_str());
- }
- }
- }
-}
-
-// GLSL ES 3.10 Revision 4, 13.51 Matching of Memory Qualifiers in Function Parameters
-void TParseContext::checkImageMemoryAccessForUserDefinedFunctions(
- const TFunction *functionDefinition,
- const TIntermAggregate *functionCall)
-{
- ASSERT(functionCall->isUserDefined());
-
- const TIntermSequence &arguments = *functionCall->getSequence();
-
- ASSERT(functionDefinition->getParamCount() == arguments.size());
-
- for (size_t i = 0; i < arguments.size(); ++i)
- {
- const TType &functionArgumentType = arguments[i]->getAsTyped()->getType();
- const TType &functionParameterType = *functionDefinition->getParam(i).type;
- ASSERT(functionArgumentType.getBasicType() == functionParameterType.getBasicType());
-
- if (IsImage(functionArgumentType.getBasicType()))
- {
- const TMemoryQualifier &functionArgumentMemoryQualifier =
- functionArgumentType.getMemoryQualifier();
- const TMemoryQualifier &functionParameterMemoryQualifier =
- functionParameterType.getMemoryQualifier();
- if (functionArgumentMemoryQualifier.readonly &&
- !functionParameterMemoryQualifier.readonly)
- {
- error(functionCall->getLine(),
- "Function call discards the 'readonly' qualifier from image",
- arguments[i]->getAsSymbolNode()->getSymbol().c_str());
- }
-
- if (functionArgumentMemoryQualifier.writeonly &&
- !functionParameterMemoryQualifier.writeonly)
- {
- error(functionCall->getLine(),
- "Function call discards the 'writeonly' qualifier from image",
- arguments[i]->getAsSymbolNode()->getSymbol().c_str());
- }
-
- if (functionArgumentMemoryQualifier.coherent &&
- !functionParameterMemoryQualifier.coherent)
- {
- error(functionCall->getLine(),
- "Function call discards the 'coherent' qualifier from image",
- arguments[i]->getAsSymbolNode()->getSymbol().c_str());
- }
-
- if (functionArgumentMemoryQualifier.volatileQualifier &&
- !functionParameterMemoryQualifier.volatileQualifier)
- {
- error(functionCall->getLine(),
- "Function call discards the 'volatile' qualifier from image",
- arguments[i]->getAsSymbolNode()->getSymbol().c_str());
- }
- }
- }
-}
-
TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
TIntermNode *paramNode,
TIntermNode *thisNode,
@@ -4361,8 +4040,7 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
// See if we can constant fold a built-in. Note that this may be possible even
// if it is not const-qualified.
- TIntermTyped *foldedNode =
- intermediate.foldAggregateBuiltIn(aggregate, &mDiagnostics);
+ TIntermTyped *foldedNode = intermediate.foldAggregateBuiltIn(aggregate);
if (foldedNode)
{
callNode = foldedNode;
@@ -4387,20 +4065,15 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
// if builtIn == true, it's definitely a builtIn function with EOpNull
if (!builtIn)
aggregate->setUserDefined();
- aggregate->getFunctionSymbolInfo()->setFromFunction(*fnCandidate);
+ aggregate->setName(fnCandidate->getMangledName());
+ aggregate->setFunctionId(fnCandidate->getUniqueId());
- // This needs to happen after the function info including name is set
+ // This needs to happen after the name is set
if (builtIn)
{
aggregate->setBuiltInFunctionPrecision();
checkTextureOffsetConst(aggregate);
-
- checkImageMemoryAccessForBuiltinFunctions(aggregate);
- }
- else
- {
- checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, aggregate);
}
callNode = aggregate;
@@ -4422,46 +4095,34 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
}
TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
- TIntermTyped *trueExpression,
- TIntermTyped *falseExpression,
+ TIntermTyped *trueBlock,
+ TIntermTyped *falseBlock,
const TSourceLoc &loc)
{
checkIsScalarBool(loc, cond);
- if (trueExpression->getType() != falseExpression->getType())
+ if (trueBlock->getType() != falseBlock->getType())
{
- binaryOpError(loc, ":", trueExpression->getCompleteString(),
- falseExpression->getCompleteString());
- return falseExpression;
+ binaryOpError(loc, ":", trueBlock->getCompleteString(), falseBlock->getCompleteString());
+ return falseBlock;
}
- if (IsOpaqueType(trueExpression->getBasicType()))
- {
- // ESSL 1.00 section 4.1.7
- // ESSL 3.00 section 4.1.7
- // Opaque/sampler types are not allowed in most types of expressions, including ternary.
- // Note that structs containing opaque types don't need to be checked as structs are
- // forbidden below.
- error(loc, "ternary operator is not allowed for opaque types", ":");
- return falseExpression;
- }
-
// ESSL1 sections 5.2 and 5.7:
// ESSL3 section 5.7:
// Ternary operator is not among the operators allowed for structures/arrays.
- if (trueExpression->isArray() || trueExpression->getBasicType() == EbtStruct)
+ if (trueBlock->isArray() || trueBlock->getBasicType() == EbtStruct)
{
error(loc, "ternary operator is not allowed for structures or arrays", ":");
- return falseExpression;
+ return falseBlock;
}
// WebGL2 section 5.26, the following results in an error:
// "Ternary operator applied to void, arrays, or structs containing arrays"
- if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid)
+ if (mShaderSpec == SH_WEBGL2_SPEC && trueBlock->getBasicType() == EbtVoid)
{
error(loc, "ternary operator is not allowed for void", ":");
- return falseExpression;
+ return falseBlock;
}
- return TIntermediate::AddTernarySelection(cond, trueExpression, falseExpression, loc);
+ return intermediate.addSelection(cond, trueBlock, falseBlock, loc);
}
//
@@ -4488,5 +4149,3 @@ int PaParseStrings(size_t count,
return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ParseContext.h b/gfx/angle/src/compiler/translator/ParseContext.h
index cdc80755a..cf153db36 100755
--- a/gfx/angle/src/compiler/translator/ParseContext.h
+++ b/gfx/angle/src/compiler/translator/ParseContext.h
@@ -11,12 +11,8 @@
#include "compiler/translator/DirectiveHandler.h"
#include "compiler/translator/Intermediate.h"
#include "compiler/translator/SymbolTable.h"
-#include "compiler/translator/QualifierTypes.h"
#include "compiler/preprocessor/Preprocessor.h"
-namespace sh
-{
-
struct TMatrixFields
{
bool wholeRow;
@@ -34,12 +30,47 @@ class TParseContext : angle::NonCopyable
public:
TParseContext(TSymbolTable &symt,
TExtensionBehavior &ext,
+ TIntermediate &interm,
sh::GLenum type,
ShShaderSpec spec,
- ShCompileOptions options,
+ int options,
bool checksPrecErrors,
TInfoSink &is,
- const ShBuiltInResources &resources);
+ const ShBuiltInResources &resources)
+ : intermediate(interm),
+ symbolTable(symt),
+ mDeferredSingleDeclarationErrorCheck(false),
+ mShaderType(type),
+ mShaderSpec(spec),
+ mCompileOptions(options),
+ mShaderVersion(100),
+ mTreeRoot(nullptr),
+ mLoopNestingLevel(0),
+ mStructNestingLevel(0),
+ mSwitchNestingLevel(0),
+ mCurrentFunctionType(nullptr),
+ mFunctionReturnsValue(false),
+ mChecksPrecisionErrors(checksPrecErrors),
+ mFragmentPrecisionHighOnESSL1(false),
+ mDefaultMatrixPacking(EmpColumnMajor),
+ mDefaultBlockStorage(EbsShared),
+ mDiagnostics(is),
+ mDirectiveHandler(ext,
+ mDiagnostics,
+ mShaderVersion,
+ mShaderType,
+ resources.WEBGL_debug_shader_precision == 1),
+ mPreprocessor(&mDiagnostics, &mDirectiveHandler),
+ mScanner(nullptr),
+ mUsesFragData(false),
+ mUsesFragColor(false),
+ mUsesSecondaryOutputs(false),
+ mMinProgramTexelOffset(resources.MinProgramTexelOffset),
+ mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
+ mComputeShaderLocalSizeDeclared(false)
+ {
+ mComputeShaderLocalSize.fill(-1);
+ }
const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
@@ -62,8 +93,8 @@ class TParseContext : angle::NonCopyable
const char *token,
const char *extraInfo = "");
- TIntermBlock *getTreeRoot() const { return mTreeRoot; }
- void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; }
+ TIntermNode *getTreeRoot() const { return mTreeRoot; }
+ void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; }
bool getFragmentPrecisionHigh() const
{
@@ -88,12 +119,6 @@ class TParseContext : angle::NonCopyable
bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
sh::WorkGroupSize getComputeShaderLocalSize() const;
- void enterFunctionDeclaration() { mDeclaringFunction = true; }
-
- void exitFunctionDeclaration() { mDeclaringFunction = false; }
-
- bool declaringFunction() const { return mDeclaringFunction; }
-
// This method is guaranteed to succeed, even if no variable with 'name' exists.
const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
@@ -127,17 +152,16 @@ class TParseContext : angle::NonCopyable
bool checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type);
void checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
- bool checkIsNotSampler(const TSourceLoc &line,
- const TTypeSpecifierNonArray &pType,
- const char *reason);
- bool checkIsNotImage(const TSourceLoc &line,
- const TTypeSpecifierNonArray &pType,
- const char *reason);
+ bool checkIsNotSampler(const TSourceLoc &line, const TPublicType &pType, const char *reason);
void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType);
void checkLocationIsNotSpecified(const TSourceLoc &location,
const TLayoutQualifier &layoutQualifier);
+ void checkOutParameterIsNotSampler(const TSourceLoc &line,
+ TQualifier qualifier,
+ const TType &type);
void checkIsParameterQualifierValid(const TSourceLoc &line,
- const TTypeQualifierBuilder &typeQualifierBuilder,
+ TQualifier qualifier,
+ TQualifier paramQualifier,
TType *type);
bool checkCanUseExtension(const TSourceLoc &line, const TString &extension);
void singleDeclarationErrorCheck(const TPublicType &publicType,
@@ -147,16 +171,14 @@ class TParseContext : angle::NonCopyable
int versionRequired);
bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
const TLayoutQualifier &layoutQualifier);
- bool checkInternalFormatIsNotSpecified(const TSourceLoc &location,
- TLayoutImageInternalFormat internalFormat);
+
void functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
- void checkInvariantVariableQualifier(bool invariant,
- const TQualifier qualifier,
- const TSourceLoc &invariantLocation);
+ void checkInvariantIsOutVariableES3(const TQualifier qualifier,
+ const TSourceLoc &invariantLocation);
void checkInputOutputTypeIsValidES3(const TQualifier qualifier,
const TPublicType &type,
const TSourceLoc &qualifierLocation);
- void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
+
const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
const TExtensionBehavior &extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); }
bool supportsExtension(const char *extension);
@@ -164,84 +186,86 @@ class TParseContext : angle::NonCopyable
void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
void handlePragmaDirective(const TSourceLoc &loc, const char *name, const char *value, bool stdgl);
+ bool containsSampler(const TType &type);
const TFunction* findFunction(
const TSourceLoc &line, TFunction *pfnCall, int inputShaderVersion, bool *builtIn = 0);
bool executeInitializer(const TSourceLoc &line,
const TString &identifier,
const TPublicType &pType,
TIntermTyped *initializer,
- TIntermBinary **initNode);
+ TIntermNode **intermNode);
- void addFullySpecifiedType(TPublicType *typeSpecifier);
- TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
+ TPublicType addFullySpecifiedType(TQualifier qualifier,
+ bool invariant,
+ TLayoutQualifier layoutQualifier,
const TPublicType &typeSpecifier);
- TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
- const TSourceLoc &identifierOrTypeLocation,
- const TString &identifier);
- TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression);
- TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer);
+ TIntermAggregate *parseSingleDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierOrTypeLocation,
+ const TString &identifier);
+ TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression);
+ TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
// Parse a declaration like "type a[n] = initializer"
// Note that this does not apply to declarations like "type[n] a = initializer"
- TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer);
-
- TIntermAggregate *parseInvariantDeclaration(const TTypeQualifierBuilder &typeQualifierBuilder,
+ TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
+
+ TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc,
const TSourceLoc &identifierLoc,
const TString *identifier,
const TSymbol *symbol);
- void parseDeclarator(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- TIntermDeclaration *declarationOut);
- void parseArrayDeclarator(TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &arrayLocation,
- TIntermTyped *indexExpression,
- TIntermDeclaration *declarationOut);
- void parseInitDeclarator(const TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer,
- TIntermDeclaration *declarationOut);
+ TIntermAggregate *parseDeclarator(TPublicType &publicType,
+ TIntermAggregate *aggregateDeclaration,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier);
+ TIntermAggregate *parseArrayDeclarator(TPublicType &publicType,
+ TIntermAggregate *aggregateDeclaration,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &arrayLocation,
+ TIntermTyped *indexExpression);
+ TIntermAggregate *parseInitDeclarator(const TPublicType &publicType,
+ TIntermAggregate *aggregateDeclaration,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
// Parse a declarator like "a[n] = initializer"
- void parseArrayInitDeclarator(const TPublicType &publicType,
- const TSourceLoc &identifierLocation,
- const TString &identifier,
- const TSourceLoc &indexLocation,
- TIntermTyped *indexExpression,
- const TSourceLoc &initLocation,
- TIntermTyped *initializer,
- TIntermDeclaration *declarationOut);
-
- void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
- TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
+ TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType,
+ TIntermAggregate *aggregateDeclaration,
+ const TSourceLoc &identifierLocation,
+ const TString &identifier,
+ const TSourceLoc &indexLocation,
+ TIntermTyped *indexExpression,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
+
+ void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
+ TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &function,
const TSourceLoc &location);
- TIntermFunctionDefinition *addFunctionDefinition(const TFunction &function,
- TIntermAggregate *functionParameters,
- TIntermBlock *functionBody,
- const TSourceLoc &location);
- void parseFunctionDefinitionHeader(const TSourceLoc &location,
- TFunction **function,
- TIntermAggregate **aggregateOut);
+ TIntermAggregate *addFunctionDefinition(const TFunction &function,
+ TIntermAggregate *functionPrototype,
+ TIntermAggregate *functionBody,
+ const TSourceLoc &location);
+ void parseFunctionPrototype(const TSourceLoc &location,
+ TFunction *function,
+ TIntermAggregate **aggregateOut);
TFunction *parseFunctionDeclarator(const TSourceLoc &location,
TFunction *function);
TFunction *parseFunctionHeader(const TPublicType &type,
@@ -253,6 +277,8 @@ class TParseContext : angle::NonCopyable
TFunction *fnCall,
const TSourceLoc &line);
+ TIntermTyped *addConstStruct(
+ const TString &identifier, TIntermTyped *node, const TSourceLoc& line);
TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
const TSourceLoc& location,
TIntermTyped *indexExpression);
@@ -261,24 +287,20 @@ class TParseContext : angle::NonCopyable
const TString &fieldString,
const TSourceLoc &fieldLocation);
- TFieldList *addStructDeclaratorListWithQualifiers(
- const TTypeQualifierBuilder &typeQualifierBuilder,
- TPublicType *typeSpecifier,
- TFieldList *fieldList);
TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
- TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
+ TPublicType addStructure(const TSourceLoc &structLine,
+ const TSourceLoc &nameLine,
+ const TString *structName,
+ TFieldList *fieldList);
+
+ TIntermAggregate* addInterfaceBlock(const TPublicType &typeQualifier,
const TSourceLoc &nameLine,
- const TString *structName,
- TFieldList *fieldList);
-
- TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
- const TSourceLoc &nameLine,
- const TString &blockName,
- TFieldList *fieldList,
- const TString *instanceName,
- const TSourceLoc &instanceLine,
- TIntermTyped *arrayIndex,
- const TSourceLoc &arrayIndexLine);
+ const TString &blockName,
+ TFieldList *fieldList,
+ const TString *instanceName,
+ const TSourceLoc &instanceLine,
+ TIntermTyped *arrayIndex,
+ const TSourceLoc& arrayIndexLine);
void parseLocalSize(const TString &qualifierType,
const TSourceLoc &qualifierTypeLine,
@@ -293,10 +315,11 @@ class TParseContext : angle::NonCopyable
const TSourceLoc &qualifierTypeLine,
int intValue,
const TSourceLoc &intValueLine);
- TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
TLayoutQualifier rightQualifier,
const TSourceLoc &rightQualifierLocation);
+ TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
+ const TSourceLoc &storageLoc, TQualifier storageQualifier);
// Performs an error check for embedded struct declarations.
void enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
@@ -304,9 +327,7 @@ class TParseContext : angle::NonCopyable
void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
- TIntermSwitch *addSwitch(TIntermTyped *init,
- TIntermBlock *statementList,
- const TSourceLoc &loc);
+ TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc);
TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
TIntermCase *addDefault(const TSourceLoc &loc);
@@ -325,22 +346,17 @@ class TParseContext : angle::NonCopyable
TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
void checkTextureOffsetConst(TIntermAggregate *functionCall);
- void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
- void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
- const TIntermAggregate *functionCall);
TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
TIntermNode *paramNode,
TIntermNode *thisNode,
const TSourceLoc &loc,
bool *fatalError);
- TIntermTyped *addTernarySelection(TIntermTyped *cond,
- TIntermTyped *trueExpression,
- TIntermTyped *falseExpression,
- const TSourceLoc &line);
+ TIntermTyped *addTernarySelection(
+ TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line);
// TODO(jmadill): make these private
- TIntermediate intermediate; // to build a parse tree
+ TIntermediate &intermediate; // to hold and build a parse tree
TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
private:
@@ -352,6 +368,18 @@ class TParseContext : angle::NonCopyable
const char *reason,
const char *token);
+ // Constant folding for element access. Note that the returned node does not have the correct
+ // type - it is expected to be fixed later.
+ TIntermConstantUnion *foldVectorSwizzle(TVectorFields &fields,
+ TIntermConstantUnion *baseNode,
+ const TSourceLoc &location);
+ TIntermConstantUnion *foldMatrixSubscript(int index,
+ TIntermConstantUnion *baseNode,
+ const TSourceLoc &location);
+ TIntermConstantUnion *foldArraySubscript(int index,
+ TIntermConstantUnion *baseNode,
+ const TSourceLoc &location);
+
bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
@@ -364,24 +392,10 @@ class TParseContext : angle::NonCopyable
// Assumes that multiplication op has already been set based on the types.
bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
- bool checkIsMemoryQualifierNotSpecified(const TMemoryQualifier &memoryQualifier,
- const TSourceLoc &location);
- void checkOutParameterIsNotImage(const TSourceLoc &line,
- TQualifier qualifier,
- const TType &type);
- void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
- TQualifier qualifier,
- const TType &type);
- void checkOutParameterIsNotSampler(const TSourceLoc &line,
- TQualifier qualifier,
- const TType &type);
-
TIntermTyped *addBinaryMathInternal(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
- TIntermBinary *createAssign(TOperator op,
- TIntermTyped *left,
- TIntermTyped *right,
- const TSourceLoc &loc);
+ TIntermTyped *createAssign(
+ TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
// The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
// It is expected to be null for other unary operators.
TIntermTyped *createUnaryMath(
@@ -395,18 +409,16 @@ class TParseContext : angle::NonCopyable
bool mDeferredSingleDeclarationErrorCheck;
sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack)
- ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
- ShCompileOptions mCompileOptions; // Options passed to TCompiler
+ ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
+ int mCompileOptions; // Options passed to TCompiler
int mShaderVersion;
- TIntermBlock *mTreeRoot; // root of parse tree being created
+ TIntermNode *mTreeRoot; // root of parse tree being created
int mLoopNestingLevel; // 0 if outside all loops
- int mStructNestingLevel; // incremented while parsing a struct declaration
+ int mStructNestingLevel; // incremented while parsing a struct declaration
int mSwitchNestingLevel; // 0 if outside all switch statements
- const TType
- *mCurrentFunctionType; // the return type of the function that's currently being parsed
+ const TType *mCurrentFunctionType; // the return type of the function that's currently being parsed
bool mFunctionReturnsValue; // true if a non-void function has a return
- bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared
- // without precision, explicit or implicit.
+ bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling
// ESSL1.
TLayoutMatrixPacking mDefaultMatrixPacking;
@@ -426,13 +438,9 @@ class TParseContext : angle::NonCopyable
// keep track of local group size declared in layout. It should be declared only once.
bool mComputeShaderLocalSizeDeclared;
sh::WorkGroupSize mComputeShaderLocalSize;
- // keeps track whether we are declaring / defining a function
- bool mDeclaringFunction;
};
int PaParseStrings(
size_t count, const char *const string[], const int length[], TParseContext *context);
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_
diff --git a/gfx/angle/src/compiler/translator/PoolAlloc.cpp b/gfx/angle/src/compiler/translator/PoolAlloc.cpp
index 3b44afe33..27e1c06b5 100755
--- a/gfx/angle/src/compiler/translator/PoolAlloc.cpp
+++ b/gfx/angle/src/compiler/translator/PoolAlloc.cpp
@@ -50,18 +50,29 @@ void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
// Implement the functionality of the TPoolAllocator class, which
// is documented in PoolAlloc.h.
//
-TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment)
- : alignment(allocationAlignment),
-#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
- pageSize(growthIncrement),
- freeList(0),
- inUseList(0),
- numCalls(0),
- totalBytes(0),
-#endif
- mLocked(false)
+TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
+ pageSize(growthIncrement),
+ alignment(allocationAlignment),
+ freeList(0),
+ inUseList(0),
+ numCalls(0),
+ totalBytes(0),
+ mLocked(false)
{
//
+ // Don't allow page sizes we know are smaller than all common
+ // OS page sizes.
+ //
+ if (pageSize < 4*1024)
+ pageSize = 4*1024;
+
+ //
+ // A large currentPageOffset indicates a new page needs to
+ // be obtained to allocate memory.
+ //
+ currentPageOffset = pageSize;
+
+ //
// Adjust alignment to be at least pointer aligned and
// power of 2.
//
@@ -75,20 +86,6 @@ TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment)
alignment = a;
alignmentMask = a - 1;
-#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
- //
- // Don't allow page sizes we know are smaller than all common
- // OS page sizes.
- //
- if (pageSize < 4 * 1024)
- pageSize = 4 * 1024;
-
- //
- // A large currentPageOffset indicates a new page needs to
- // be obtained to allocate memory.
- //
- currentPageOffset = pageSize;
-
//
// Align header skip
//
@@ -96,14 +93,10 @@ TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment)
if (headerSkip < sizeof(tHeader)) {
headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
}
-#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
- mStack.push_back({});
-#endif
}
TPoolAllocator::~TPoolAllocator()
{
-#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
while (inUseList) {
tHeader* next = inUseList->nextPage;
inUseList->~tHeader();
@@ -120,16 +113,6 @@ TPoolAllocator::~TPoolAllocator()
delete [] reinterpret_cast<char*>(freeList);
freeList = next;
}
-#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
- for (auto &allocs : mStack)
- {
- for (auto alloc : allocs)
- {
- free(alloc);
- }
- }
- mStack.clear();
-#endif
}
// Support MSVC++ 6.0
@@ -170,18 +153,14 @@ void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, co
void TPoolAllocator::push()
{
-#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
tAllocState state = { currentPageOffset, inUseList };
- mStack.push_back(state);
-
+ stack.push_back(state);
+
//
// Indicate there is no current page to allocate from.
//
currentPageOffset = pageSize;
-#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
- mStack.push_back({});
-#endif
}
//
@@ -193,12 +172,11 @@ void TPoolAllocator::push()
//
void TPoolAllocator::pop()
{
- if (mStack.size() < 1)
+ if (stack.size() < 1)
return;
-#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
- tHeader *page = mStack.back().page;
- currentPageOffset = mStack.back().offset;
+ tHeader* page = stack.back().page;
+ currentPageOffset = stack.back().offset;
while (inUseList != page) {
// invoke destructor to free allocation list
@@ -214,14 +192,7 @@ void TPoolAllocator::pop()
inUseList = nextInUse;
}
- mStack.pop_back();
-#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
- for (auto &alloc : mStack.back())
- {
- free(alloc);
- }
- mStack.pop_back();
-#endif
+ stack.pop_back();
}
//
@@ -230,7 +201,7 @@ void TPoolAllocator::pop()
//
void TPoolAllocator::popAll()
{
- while (mStack.size() > 0)
+ while (stack.size() > 0)
pop();
}
@@ -238,7 +209,6 @@ void* TPoolAllocator::allocate(size_t numBytes)
{
ASSERT(!mLocked);
-#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
//
// Just keep some interesting statistics.
//
@@ -315,14 +285,6 @@ void* TPoolAllocator::allocate(size_t numBytes)
currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
return initializeAllocation(inUseList, ret, numBytes);
-#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
- void *alloc = malloc(numBytes + alignmentMask);
- mStack.back().push_back(alloc);
-
- intptr_t intAlloc = reinterpret_cast<intptr_t>(alloc);
- intAlloc = (intAlloc + alignmentMask) & ~alignmentMask;
- return reinterpret_cast<void *>(intAlloc);
-#endif
}
void TPoolAllocator::lock()
diff --git a/gfx/angle/src/compiler/translator/PoolAlloc.h b/gfx/angle/src/compiler/translator/PoolAlloc.h
index f15b3e05d..026e7a5c1 100755
--- a/gfx/angle/src/compiler/translator/PoolAlloc.h
+++ b/gfx/angle/src/compiler/translator/PoolAlloc.h
@@ -157,12 +157,7 @@ public:
void lock();
void unlock();
- private:
- size_t alignment; // all returned allocations will be aligned at
- // this granularity, which will be a power of 2
- size_t alignmentMask;
-
-#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
+protected:
friend struct tHeader;
struct tHeader {
@@ -205,21 +200,20 @@ public:
}
size_t pageSize; // granularity of allocation from the OS
+ size_t alignment; // all returned allocations will be aligned at
+ // this granularity, which will be a power of 2
+ size_t alignmentMask;
size_t headerSkip; // amount of memory to skip to make room for the
// header (basically, size of header, rounded
// up to make it aligned
size_t currentPageOffset; // next offset in top of inUseList to allocate from
tHeader* freeList; // list of popped memory
tHeader* inUseList; // list of all memory currently being used
- tAllocStack mStack; // stack of where to allocate from, to partition pool
+ tAllocStack stack; // stack of where to allocate from, to partition pool
int numCalls; // just an interesting statistic
size_t totalBytes; // just an interesting statistic
-
-#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC)
- std::vector<std::vector<void *>> mStack;
-#endif
-
+private:
TPoolAllocator& operator=(const TPoolAllocator&); // dont allow assignment operator
TPoolAllocator(const TPoolAllocator&); // dont allow default copy constructor
bool mLocked;
diff --git a/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.cpp b/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.cpp
index 7ec434796..8cbeb7dee 100755
--- a/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.cpp
+++ b/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.cpp
@@ -9,9 +9,6 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
namespace
{
@@ -21,7 +18,7 @@ class PruneEmptyDeclarationsTraverser : private TIntermTraverser
static void apply(TIntermNode *root);
private:
PruneEmptyDeclarationsTraverser();
- bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *node) override;
};
void PruneEmptyDeclarationsTraverser::apply(TIntermNode *root)
@@ -36,71 +33,65 @@ PruneEmptyDeclarationsTraverser::PruneEmptyDeclarationsTraverser()
{
}
-bool PruneEmptyDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+bool PruneEmptyDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node)
{
- TIntermSequence *sequence = node->getSequence();
- if (sequence->size() >= 1)
+ if (node->getOp() == EOpDeclaration)
{
- TIntermSymbol *sym = sequence->front()->getAsSymbolNode();
- // Prune declarations without a variable name, unless it's an interface block declaration.
- if (sym != nullptr && sym->getSymbol() == "" && !sym->isInterfaceBlock())
+ TIntermSequence *sequence = node->getSequence();
+ if (sequence->size() >= 1)
{
- if (sequence->size() > 1)
- {
- // Generate a replacement that will remove the empty declarator in the beginning of
- // a declarator list. Example of a declaration that will be changed:
- // float, a;
- // will be changed to
- // float a;
- // This applies also to struct declarations.
- TIntermSequence emptyReplacement;
- mMultiReplacements.push_back(
- NodeReplaceWithMultipleEntry(node, sym, emptyReplacement));
- }
- else if (sym->getBasicType() != EbtStruct)
+ TIntermSymbol *sym = sequence->front()->getAsSymbolNode();
+ // Prune declarations without a variable name, unless it's an interface block declaration.
+ if (sym != nullptr && sym->getSymbol() == "" && !sym->isInterfaceBlock())
{
- // Single struct declarations may just declare the struct type and no variables, so
- // they should not be pruned. All other single empty declarations can be pruned
- // entirely. Example of an empty declaration that will be pruned:
- // float;
- TIntermSequence emptyReplacement;
- TIntermBlock *parentAsBlock = getParentNode()->getAsBlock();
- // The declaration may be inside a block or in a loop init expression.
- ASSERT(parentAsBlock != nullptr || getParentNode()->getAsLoopNode() != nullptr);
- if (parentAsBlock)
+ if (sequence->size() > 1)
{
- mMultiReplacements.push_back(
- NodeReplaceWithMultipleEntry(parentAsBlock, node, emptyReplacement));
+ // Generate a replacement that will remove the empty declarator in the beginning of a declarator
+ // list. Example of a declaration that will be changed:
+ // float, a;
+ // will be changed to
+ // float a;
+ // This applies also to struct declarations.
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(node, sym, emptyReplacement));
}
- else
+ else if (sym->getBasicType() != EbtStruct)
{
- queueReplacement(node, nullptr, OriginalNode::IS_DROPPED);
+ // Single struct declarations may just declare the struct type and no variables, so they should
+ // not be pruned. All other single empty declarations can be pruned entirely. Example of an empty
+ // declaration that will be pruned:
+ // float;
+ TIntermSequence emptyReplacement;
+ TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
+ ASSERT(parentAgg != nullptr);
+ mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, emptyReplacement));
}
- }
- else if (sym->getType().getQualifier() != EvqGlobal &&
- sym->getType().getQualifier() != EvqTemporary)
- {
- // We've hit an empty struct declaration with a qualifier, for example like
- // this:
- // const struct a { int i; };
- // NVIDIA GL driver version 367.27 doesn't accept this kind of declarations, so
- // we convert the declaration to a regular struct declaration. This is okay,
- // since ESSL 1.00 spec section 4.1.8 says about structs that "The optional
- // qualifiers only apply to any declarators, and are not part of the type being
- // defined for name."
-
- if (mInGlobalScope)
- {
- sym->getTypePointer()->setQualifier(EvqGlobal);
- }
- else
+ else if (sym->getType().getQualifier() != EvqGlobal &&
+ sym->getType().getQualifier() != EvqTemporary)
{
- sym->getTypePointer()->setQualifier(EvqTemporary);
+ // We've hit an empty struct declaration with a qualifier, for example like
+ // this:
+ // const struct a { int i; };
+ // NVIDIA GL driver version 367.27 doesn't accept this kind of declarations, so
+ // we convert the declaration to a regular struct declaration. This is okay,
+ // since ESSL 1.00 spec section 4.1.8 says about structs that "The optional
+ // qualifiers only apply to any declarators, and are not part of the type being
+ // defined for name."
+
+ if (mInGlobalScope)
+ {
+ sym->getTypePointer()->setQualifier(EvqGlobal);
+ }
+ else
+ {
+ sym->getTypePointer()->setQualifier(EvqTemporary);
+ }
}
}
}
+ return false;
}
- return false;
+ return true;
}
} // namespace
@@ -109,5 +100,3 @@ void PruneEmptyDeclarations(TIntermNode *root)
{
PruneEmptyDeclarationsTraverser::apply(root);
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.h b/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.h
index f03657766..122e83090 100755
--- a/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.h
+++ b/gfx/angle/src/compiler/translator/PruneEmptyDeclarations.h
@@ -8,11 +8,8 @@
#ifndef COMPILER_TRANSLATOR_PRUNEEMPTYDECLARATIONS_H_
#define COMPILER_TRANSLATOR_PRUNEEMPTYDECLARATIONS_H_
-namespace sh
-{
class TIntermNode;
void PruneEmptyDeclarations(TIntermNode *root);
-}
#endif // COMPILER_TRANSLATOR_PRUNEEMPTYDECLARATIONS_H_
diff --git a/gfx/angle/src/compiler/translator/QualifierTypes.cpp b/gfx/angle/src/compiler/translator/QualifierTypes.cpp
deleted file mode 100644
index 302f5177d..000000000
--- a/gfx/angle/src/compiler/translator/QualifierTypes.cpp
+++ /dev/null
@@ -1,727 +0,0 @@
-//
-// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "compiler/translator/QualifierTypes.h"
-
-#include "compiler/translator/Diagnostics.h"
-
-#include <algorithm>
-
-namespace sh
-{
-
-namespace
-{
-
-// GLSL ES 3.10 does not impose a strict order on type qualifiers and allows multiple layout
-// declarations.
-// GLSL ES 3.10 Revision 4, 4.10 Order of Qualification
-bool AreTypeQualifierChecksRelaxed(int shaderVersion)
-{
- return shaderVersion >= 310;
-}
-
-bool IsScopeQualifier(TQualifier qualifier)
-{
- return qualifier == EvqGlobal || qualifier == EvqTemporary;
-}
-
-bool IsScopeQualifierWrapper(const TQualifierWrapperBase *qualifier)
-{
- if (qualifier->getType() != QtStorage)
- return false;
- const TStorageQualifierWrapper *storageQualifier =
- static_cast<const TStorageQualifierWrapper *>(qualifier);
- TQualifier q = storageQualifier->getQualifier();
- return IsScopeQualifier(q);
-}
-
-// Returns true if the invariant for the qualifier sequence holds
-bool IsInvariantCorrect(const TTypeQualifierBuilder::QualifierSequence &qualifiers)
-{
- // We should have at least one qualifier.
- // The first qualifier always tells the scope.
- return qualifiers.size() >= 1 && IsScopeQualifierWrapper(qualifiers[0]);
-}
-
-// Returns true if there are qualifiers which have been specified multiple times
-// If areQualifierChecksRelaxed is set to true, then layout qualifier repetition is allowed.
-bool HasRepeatingQualifiers(const TTypeQualifierBuilder::QualifierSequence &qualifiers,
- bool areQualifierChecksRelaxed,
- std::string *errorMessage)
-{
- bool invariantFound = false;
- bool precisionFound = false;
- bool layoutFound = false;
- bool interpolationFound = false;
-
- unsigned int locationsSpecified = 0;
- bool isOut = false;
-
- // The iteration starts from one since the first qualifier only reveals the scope of the
- // expression. It is inserted first whenever the sequence gets created.
- for (size_t i = 1; i < qualifiers.size(); ++i)
- {
- switch (qualifiers[i]->getType())
- {
- case QtInvariant:
- {
- if (invariantFound)
- {
- *errorMessage = "The invariant qualifier specified multiple times.";
- return true;
- }
- invariantFound = true;
- break;
- }
- case QtPrecision:
- {
- if (precisionFound)
- {
- *errorMessage = "The precision qualifier specified multiple times.";
- return true;
- }
- precisionFound = true;
- break;
- }
- case QtLayout:
- {
- if (layoutFound && !areQualifierChecksRelaxed)
- {
- *errorMessage = "The layout qualifier specified multiple times.";
- return true;
- }
- if (invariantFound && !areQualifierChecksRelaxed)
- {
- // This combination is not correct according to the syntax specified in the
- // formal grammar in the ESSL 3.00 spec. In ESSL 3.10 the grammar does not have
- // a similar restriction.
- *errorMessage =
- "The layout qualifier and invariant qualifier cannot coexist in the same "
- "declaration according to the grammar.";
- return true;
- }
- layoutFound = true;
- const TLayoutQualifier &currentQualifier =
- static_cast<const TLayoutQualifierWrapper *>(qualifiers[i])->getQualifier();
- locationsSpecified += currentQualifier.locationsSpecified;
- break;
- }
- case QtInterpolation:
- {
- // 'centroid' is treated as a storage qualifier
- // 'flat centroid' will be squashed to 'flat'
- // 'smooth centroid' will be squashed to 'centroid'
- if (interpolationFound)
- {
- *errorMessage = "The interpolation qualifier specified multiple times.";
- return true;
- }
- interpolationFound = true;
- break;
- }
- case QtStorage:
- {
- // Go over all of the storage qualifiers up until the current one and check for
- // repetitions.
- TQualifier currentQualifier =
- static_cast<const TStorageQualifierWrapper *>(qualifiers[i])->getQualifier();
- if (currentQualifier == EvqVertexOut || currentQualifier == EvqFragmentOut)
- {
- isOut = true;
- }
- for (size_t j = 1; j < i; ++j)
- {
- if (qualifiers[j]->getType() == QtStorage)
- {
- const TStorageQualifierWrapper *previousQualifierWrapper =
- static_cast<const TStorageQualifierWrapper *>(qualifiers[j]);
- TQualifier previousQualifier = previousQualifierWrapper->getQualifier();
- if (currentQualifier == previousQualifier)
- {
- *errorMessage = previousQualifierWrapper->getQualifierString().c_str();
- *errorMessage += " specified multiple times";
- return true;
- }
- }
- }
- break;
- }
- case QtMemory:
- {
- // Go over all of the memory qualifiers up until the current one and check for
- // repetitions.
- // Having both readonly and writeonly in a sequence is valid.
- // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
- TQualifier currentQualifier =
- static_cast<const TMemoryQualifierWrapper *>(qualifiers[i])->getQualifier();
- for (size_t j = 1; j < i; ++j)
- {
- if (qualifiers[j]->getType() == QtMemory)
- {
- const TMemoryQualifierWrapper *previousQualifierWrapper =
- static_cast<const TMemoryQualifierWrapper *>(qualifiers[j]);
- TQualifier previousQualifier = previousQualifierWrapper->getQualifier();
- if (currentQualifier == previousQualifier)
- {
- *errorMessage = previousQualifierWrapper->getQualifierString().c_str();
- *errorMessage += " specified multiple times";
- return true;
- }
- }
- }
- break;
- }
- default:
- UNREACHABLE();
- }
- }
-
- if (locationsSpecified > 1 && isOut)
- {
- // GLSL ES 3.00.6 section 4.3.8.2 Output Layout Qualifiers
- // GLSL ES 3.10 section 4.4.2 Output Layout Qualifiers
- // "The qualifier may appear at most once within a declaration."
- *errorMessage = "Output layout location specified multiple times.";
- return true;
- }
-
- return false;
-}
-
-// GLSL ES 3.00_6, 4.7 Order of Qualification
-// The correct order of qualifiers is:
-// invariant-qualifier interpolation-qualifier storage-qualifier precision-qualifier
-// layout-qualifier has to be before storage-qualifier.
-bool AreQualifiersInOrder(const TTypeQualifierBuilder::QualifierSequence &qualifiers,
- std::string *errorMessage)
-{
- bool foundInterpolation = false;
- bool foundStorage = false;
- bool foundPrecision = false;
- for (size_t i = 1; i < qualifiers.size(); ++i)
- {
- switch (qualifiers[i]->getType())
- {
- case QtInvariant:
- if (foundInterpolation || foundStorage || foundPrecision)
- {
- *errorMessage = "The invariant qualifier has to be first in the expression.";
- return false;
- }
- break;
- case QtInterpolation:
- if (foundStorage)
- {
- *errorMessage = "Storage qualifiers have to be after interpolation qualifiers.";
- return false;
- }
- else if (foundPrecision)
- {
- *errorMessage =
- "Precision qualifiers have to be after interpolation qualifiers.";
- return false;
- }
- foundInterpolation = true;
- break;
- case QtLayout:
- if (foundStorage)
- {
- *errorMessage = "Storage qualifiers have to be after layout qualifiers.";
- return false;
- }
- else if (foundPrecision)
- {
- *errorMessage = "Precision qualifiers have to be after layout qualifiers.";
- return false;
- }
- break;
- case QtStorage:
- if (foundPrecision)
- {
- *errorMessage = "Precision qualifiers have to be after storage qualifiers.";
- return false;
- }
- foundStorage = true;
- break;
- case QtMemory:
- if (foundPrecision)
- {
- *errorMessage = "Precision qualifiers have to be after memory qualifiers.";
- return false;
- }
- break;
- case QtPrecision:
- foundPrecision = true;
- break;
- default:
- UNREACHABLE();
- }
- }
- return true;
-}
-
-struct QualifierComparator
-{
- bool operator()(const TQualifierWrapperBase *q1, const TQualifierWrapperBase *q2)
- {
- return q1->getRank() < q2->getRank();
- }
-};
-
-void SortSequence(TTypeQualifierBuilder::QualifierSequence &qualifiers)
-{
- // We need a stable sorting algorithm since the order of layout-qualifier declarations matter.
- // The sorting starts from index 1, instead of 0, since the element at index 0 tells the scope
- // and we always want it to be first.
- std::stable_sort(qualifiers.begin() + 1, qualifiers.end(), QualifierComparator());
-}
-
-// Handles the joining of storage qualifiers for variables.
-bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storageQualifier)
-{
- switch (*joinedQualifier)
- {
- case EvqGlobal:
- *joinedQualifier = storageQualifier;
- break;
- case EvqTemporary:
- {
- switch (storageQualifier)
- {
- case EvqConst:
- *joinedQualifier = storageQualifier;
- break;
- default:
- return false;
- }
- break;
- }
- case EvqSmooth:
- {
- switch (storageQualifier)
- {
- case EvqCentroid:
- *joinedQualifier = EvqCentroid;
- break;
- case EvqVertexOut:
- *joinedQualifier = EvqSmoothOut;
- break;
- case EvqFragmentIn:
- *joinedQualifier = EvqSmoothIn;
- break;
- default:
- return false;
- }
- break;
- }
- case EvqFlat:
- {
- switch (storageQualifier)
- {
- case EvqCentroid:
- *joinedQualifier = EvqFlat;
- break;
- case EvqVertexOut:
- *joinedQualifier = EvqFlatOut;
- break;
- case EvqFragmentIn:
- *joinedQualifier = EvqFlatIn;
- break;
- default:
- return false;
- }
- break;
- }
- case EvqCentroid:
- {
- switch (storageQualifier)
- {
- case EvqVertexOut:
- *joinedQualifier = EvqCentroidOut;
- break;
- case EvqFragmentIn:
- *joinedQualifier = EvqCentroidIn;
- break;
- default:
- return false;
- }
- break;
- }
- default:
- return false;
- }
- return true;
-}
-
-// Handles the joining of storage qualifiers for a parameter in a function.
-bool JoinParameterStorageQualifier(TQualifier *joinedQualifier, TQualifier storageQualifier)
-{
- switch (*joinedQualifier)
- {
- case EvqTemporary:
- *joinedQualifier = storageQualifier;
- break;
- case EvqConst:
- {
- switch (storageQualifier)
- {
- case EvqIn:
- *joinedQualifier = EvqConstReadOnly;
- break;
- default:
- return false;
- }
- break;
- }
- default:
- return false;
- }
- return true;
-}
-
-bool JoinMemoryQualifier(TMemoryQualifier *joinedMemoryQualifier, TQualifier memoryQualifier)
-{
- switch (memoryQualifier)
- {
- case EvqReadOnly:
- joinedMemoryQualifier->readonly = true;
- break;
- case EvqWriteOnly:
- joinedMemoryQualifier->writeonly = true;
- break;
- case EvqCoherent:
- joinedMemoryQualifier->coherent = true;
- break;
- case EvqRestrict:
- joinedMemoryQualifier->restrictQualifier = true;
- break;
- case EvqVolatile:
- // Variables having the volatile qualifier are automatcally treated as coherent as well.
- // GLSL ES 3.10, Revision 4, 4.9 Memory Access Qualifiers
- joinedMemoryQualifier->volatileQualifier = true;
- joinedMemoryQualifier->coherent = true;
- break;
- default:
- UNREACHABLE();
- }
- return true;
-}
-
-TTypeQualifier GetVariableTypeQualifierFromSortedSequence(
- const TTypeQualifierBuilder::QualifierSequence &sortedSequence,
- TDiagnostics *diagnostics)
-{
- TTypeQualifier typeQualifier(
- static_cast<const TStorageQualifierWrapper *>(sortedSequence[0])->getQualifier(),
- sortedSequence[0]->getLine());
- for (size_t i = 1; i < sortedSequence.size(); ++i)
- {
- const TQualifierWrapperBase *qualifier = sortedSequence[i];
- bool isQualifierValid = false;
- switch (qualifier->getType())
- {
- case QtInvariant:
- isQualifierValid = true;
- typeQualifier.invariant = true;
- break;
- case QtInterpolation:
- {
- switch (typeQualifier.qualifier)
- {
- case EvqGlobal:
- isQualifierValid = true;
- typeQualifier.qualifier =
- static_cast<const TInterpolationQualifierWrapper *>(qualifier)
- ->getQualifier();
- break;
- default:
- isQualifierValid = false;
- }
- break;
- }
- case QtLayout:
- {
- const TLayoutQualifierWrapper *layoutQualifierWrapper =
- static_cast<const TLayoutQualifierWrapper *>(qualifier);
- isQualifierValid = true;
- typeQualifier.layoutQualifier = sh::JoinLayoutQualifiers(
- typeQualifier.layoutQualifier, layoutQualifierWrapper->getQualifier(),
- layoutQualifierWrapper->getLine(), diagnostics);
- break;
- }
- case QtStorage:
- isQualifierValid = JoinVariableStorageQualifier(
- &typeQualifier.qualifier,
- static_cast<const TStorageQualifierWrapper *>(qualifier)->getQualifier());
- break;
- case QtPrecision:
- isQualifierValid = true;
- typeQualifier.precision =
- static_cast<const TPrecisionQualifierWrapper *>(qualifier)->getQualifier();
- ASSERT(typeQualifier.precision != EbpUndefined);
- break;
- case QtMemory:
- isQualifierValid = JoinMemoryQualifier(
- &typeQualifier.memoryQualifier,
- static_cast<const TMemoryQualifierWrapper *>(qualifier)->getQualifier());
- break;
- default:
- UNREACHABLE();
- }
- if (!isQualifierValid)
- {
- const TString &qualifierString = qualifier->getQualifierString();
- diagnostics->error(qualifier->getLine(), "invalid qualifier combination",
- qualifierString.c_str(), "");
- break;
- }
- }
- return typeQualifier;
-}
-
-TTypeQualifier GetParameterTypeQualifierFromSortedSequence(
- const TTypeQualifierBuilder::QualifierSequence &sortedSequence,
- TDiagnostics *diagnostics)
-{
- TTypeQualifier typeQualifier(EvqTemporary, sortedSequence[0]->getLine());
- for (size_t i = 1; i < sortedSequence.size(); ++i)
- {
- const TQualifierWrapperBase *qualifier = sortedSequence[i];
- bool isQualifierValid = false;
- switch (qualifier->getType())
- {
- case QtInvariant:
- case QtInterpolation:
- case QtLayout:
- break;
- case QtMemory:
- isQualifierValid = JoinMemoryQualifier(
- &typeQualifier.memoryQualifier,
- static_cast<const TMemoryQualifierWrapper *>(qualifier)->getQualifier());
- break;
- case QtStorage:
- isQualifierValid = JoinParameterStorageQualifier(
- &typeQualifier.qualifier,
- static_cast<const TStorageQualifierWrapper *>(qualifier)->getQualifier());
- break;
- case QtPrecision:
- isQualifierValid = true;
- typeQualifier.precision =
- static_cast<const TPrecisionQualifierWrapper *>(qualifier)->getQualifier();
- ASSERT(typeQualifier.precision != EbpUndefined);
- break;
- default:
- UNREACHABLE();
- }
- if (!isQualifierValid)
- {
- const TString &qualifierString = qualifier->getQualifierString();
- diagnostics->error(qualifier->getLine(), "invalid parameter qualifier",
- qualifierString.c_str(), "");
- break;
- }
- }
-
- switch (typeQualifier.qualifier)
- {
- case EvqIn:
- case EvqConstReadOnly: // const in
- case EvqOut:
- case EvqInOut:
- break;
- case EvqConst:
- typeQualifier.qualifier = EvqConstReadOnly;
- break;
- case EvqTemporary:
- // no qualifier has been specified, set it to EvqIn which is the default
- typeQualifier.qualifier = EvqIn;
- break;
- default:
- diagnostics->error(sortedSequence[0]->getLine(), "Invalid parameter qualifier ",
- getQualifierString(typeQualifier.qualifier), "");
- }
- return typeQualifier;
-}
-} // namespace
-
-TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier,
- TLayoutQualifier rightQualifier,
- const TSourceLoc &rightQualifierLocation,
- TDiagnostics *diagnostics)
-{
- TLayoutQualifier joinedQualifier = leftQualifier;
-
- if (rightQualifier.location != -1)
- {
- joinedQualifier.location = rightQualifier.location;
- ++joinedQualifier.locationsSpecified;
- }
- if (rightQualifier.matrixPacking != EmpUnspecified)
- {
- joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
- }
- if (rightQualifier.blockStorage != EbsUnspecified)
- {
- joinedQualifier.blockStorage = rightQualifier.blockStorage;
- }
-
- for (size_t i = 0u; i < rightQualifier.localSize.size(); ++i)
- {
- if (rightQualifier.localSize[i] != -1)
- {
- if (joinedQualifier.localSize[i] != -1 &&
- joinedQualifier.localSize[i] != rightQualifier.localSize[i])
- {
- diagnostics->error(rightQualifierLocation,
- "Cannot have multiple different work group size specifiers",
- getWorkGroupSizeString(i), "");
- }
- joinedQualifier.localSize[i] = rightQualifier.localSize[i];
- }
- }
-
- if (rightQualifier.imageInternalFormat != EiifUnspecified)
- {
- joinedQualifier.imageInternalFormat = rightQualifier.imageInternalFormat;
- }
-
- return joinedQualifier;
-}
-
-unsigned int TInvariantQualifierWrapper::getRank() const
-{
- return 0u;
-}
-
-unsigned int TInterpolationQualifierWrapper::getRank() const
-{
- return 1u;
-}
-
-unsigned int TLayoutQualifierWrapper::getRank() const
-{
- return 2u;
-}
-
-unsigned int TStorageQualifierWrapper::getRank() const
-{
- // Force the 'centroid' auxilary storage qualifier to be always first among all storage
- // qualifiers.
- if (mStorageQualifier == EvqCentroid)
- {
- return 3u;
- }
- else
- {
- return 4u;
- }
-}
-
-unsigned int TMemoryQualifierWrapper::getRank() const
-{
- return 4u;
-}
-
-unsigned int TPrecisionQualifierWrapper::getRank() const
-{
- return 5u;
-}
-
-TTypeQualifier::TTypeQualifier(TQualifier scope, const TSourceLoc &loc)
- : layoutQualifier(TLayoutQualifier::create()),
- memoryQualifier(TMemoryQualifier::create()),
- precision(EbpUndefined),
- qualifier(scope),
- invariant(false),
- line(loc)
-{
- ASSERT(IsScopeQualifier(qualifier));
-}
-
-TTypeQualifierBuilder::TTypeQualifierBuilder(const TStorageQualifierWrapper *scope,
- int shaderVersion)
- : mShaderVersion(shaderVersion)
-{
- ASSERT(IsScopeQualifier(scope->getQualifier()));
- mQualifiers.push_back(scope);
-}
-
-void TTypeQualifierBuilder::appendQualifier(const TQualifierWrapperBase *qualifier)
-{
- mQualifiers.push_back(qualifier);
-}
-
-bool TTypeQualifierBuilder::checkSequenceIsValid(TDiagnostics *diagnostics) const
-{
- bool areQualifierChecksRelaxed = AreTypeQualifierChecksRelaxed(mShaderVersion);
- std::string errorMessage;
- if (HasRepeatingQualifiers(mQualifiers, areQualifierChecksRelaxed, &errorMessage))
- {
- diagnostics->error(mQualifiers[0]->getLine(), "qualifier sequence", errorMessage.c_str(),
- "");
- return false;
- }
-
- if (!areQualifierChecksRelaxed && !AreQualifiersInOrder(mQualifiers, &errorMessage))
- {
- diagnostics->error(mQualifiers[0]->getLine(), "qualifier sequence", errorMessage.c_str(),
- "");
- return false;
- }
-
- return true;
-}
-
-TTypeQualifier TTypeQualifierBuilder::getParameterTypeQualifier(TDiagnostics *diagnostics) const
-{
- ASSERT(IsInvariantCorrect(mQualifiers));
- ASSERT(static_cast<const TStorageQualifierWrapper *>(mQualifiers[0])->getQualifier() ==
- EvqTemporary);
-
- if (!checkSequenceIsValid(diagnostics))
- {
- return TTypeQualifier(EvqTemporary, mQualifiers[0]->getLine());
- }
-
- // If the qualifier checks are relaxed, then it is easier to sort the qualifiers so
- // that the order imposed by the GLSL ES 3.00 spec is kept. Then we can use the same code to
- // combine the qualifiers.
- if (AreTypeQualifierChecksRelaxed(mShaderVersion))
- {
- // Copy the qualifier sequence so that we can sort them.
- QualifierSequence sortedQualifierSequence = mQualifiers;
- SortSequence(sortedQualifierSequence);
- return GetParameterTypeQualifierFromSortedSequence(sortedQualifierSequence, diagnostics);
- }
- return GetParameterTypeQualifierFromSortedSequence(mQualifiers, diagnostics);
-}
-
-TTypeQualifier TTypeQualifierBuilder::getVariableTypeQualifier(TDiagnostics *diagnostics) const
-{
- ASSERT(IsInvariantCorrect(mQualifiers));
-
- if (!checkSequenceIsValid(diagnostics))
- {
- return TTypeQualifier(
- static_cast<const TStorageQualifierWrapper *>(mQualifiers[0])->getQualifier(),
- mQualifiers[0]->getLine());
- }
-
- // If the qualifier checks are relaxed, then it is easier to sort the qualifiers so
- // that the order imposed by the GLSL ES 3.00 spec is kept. Then we can use the same code to
- // combine the qualifiers.
- if (AreTypeQualifierChecksRelaxed(mShaderVersion))
- {
- // Copy the qualifier sequence so that we can sort them.
- QualifierSequence sortedQualifierSequence = mQualifiers;
- SortSequence(sortedQualifierSequence);
- return GetVariableTypeQualifierFromSortedSequence(sortedQualifierSequence, diagnostics);
- }
- return GetVariableTypeQualifierFromSortedSequence(mQualifiers, diagnostics);
-}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/QualifierTypes.h b/gfx/angle/src/compiler/translator/QualifierTypes.h
deleted file mode 100644
index 10bdeed89..000000000
--- a/gfx/angle/src/compiler/translator/QualifierTypes.h
+++ /dev/null
@@ -1,191 +0,0 @@
-//
-// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#ifndef COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_
-#define COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_
-
-#include "common/angleutils.h"
-#include "compiler/translator/BaseTypes.h"
-#include "compiler/translator/Types.h"
-
-namespace sh
-{
-class TDiagnostics;
-
-TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier,
- TLayoutQualifier rightQualifier,
- const TSourceLoc &rightQualifierLocation,
- TDiagnostics *diagnostics);
-
-enum TQualifierType
-{
- QtInvariant,
- QtInterpolation,
- QtLayout,
- QtStorage,
- QtPrecision,
- QtMemory
-};
-
-class TQualifierWrapperBase : angle::NonCopyable
-{
- public:
- POOL_ALLOCATOR_NEW_DELETE();
- TQualifierWrapperBase(const TSourceLoc &line) : mLine(line) {}
- virtual ~TQualifierWrapperBase(){};
- virtual TQualifierType getType() const = 0;
- virtual TString getQualifierString() const = 0;
- virtual unsigned int getRank() const = 0;
- const TSourceLoc &getLine() const { return mLine; }
- private:
- TSourceLoc mLine;
-};
-
-class TInvariantQualifierWrapper final : public TQualifierWrapperBase
-{
- public:
- TInvariantQualifierWrapper(const TSourceLoc &line) : TQualifierWrapperBase(line) {}
- ~TInvariantQualifierWrapper() {}
-
- TQualifierType getType() const { return QtInvariant; }
- TString getQualifierString() const { return "invariant"; }
- unsigned int getRank() const;
-};
-
-class TInterpolationQualifierWrapper final : public TQualifierWrapperBase
-{
- public:
- TInterpolationQualifierWrapper(TQualifier interpolationQualifier, const TSourceLoc &line)
- : TQualifierWrapperBase(line), mInterpolationQualifier(interpolationQualifier)
- {
- }
- ~TInterpolationQualifierWrapper() {}
-
- TQualifierType getType() const { return QtInterpolation; }
- TString getQualifierString() const { return sh::getQualifierString(mInterpolationQualifier); }
- TQualifier getQualifier() const { return mInterpolationQualifier; }
- unsigned int getRank() const;
-
- private:
- TQualifier mInterpolationQualifier;
-};
-
-class TLayoutQualifierWrapper final : public TQualifierWrapperBase
-{
- public:
- TLayoutQualifierWrapper(TLayoutQualifier layoutQualifier, const TSourceLoc &line)
- : TQualifierWrapperBase(line), mLayoutQualifier(layoutQualifier)
- {
- }
- ~TLayoutQualifierWrapper() {}
-
- TQualifierType getType() const { return QtLayout; }
- TString getQualifierString() const { return "layout"; }
- const TLayoutQualifier &getQualifier() const { return mLayoutQualifier; }
- unsigned int getRank() const;
-
- private:
- TLayoutQualifier mLayoutQualifier;
-};
-
-class TStorageQualifierWrapper final : public TQualifierWrapperBase
-{
- public:
- TStorageQualifierWrapper(TQualifier storageQualifier, const TSourceLoc &line)
- : TQualifierWrapperBase(line), mStorageQualifier(storageQualifier)
- {
- }
- ~TStorageQualifierWrapper() {}
-
- TQualifierType getType() const { return QtStorage; }
- TString getQualifierString() const { return sh::getQualifierString(mStorageQualifier); }
- TQualifier getQualifier() const { return mStorageQualifier; }
- unsigned int getRank() const;
-
- private:
- TQualifier mStorageQualifier;
-};
-
-class TPrecisionQualifierWrapper final : public TQualifierWrapperBase
-{
- public:
- TPrecisionQualifierWrapper(TPrecision precisionQualifier, const TSourceLoc &line)
- : TQualifierWrapperBase(line), mPrecisionQualifier(precisionQualifier)
- {
- }
- ~TPrecisionQualifierWrapper() {}
-
- TQualifierType getType() const { return QtPrecision; }
- TString getQualifierString() const { return sh::getPrecisionString(mPrecisionQualifier); }
- TPrecision getQualifier() const { return mPrecisionQualifier; }
- unsigned int getRank() const;
-
- private:
- TPrecision mPrecisionQualifier;
-};
-
-class TMemoryQualifierWrapper final : public TQualifierWrapperBase
-{
- public:
- TMemoryQualifierWrapper(TQualifier memoryQualifier, const TSourceLoc &line)
- : TQualifierWrapperBase(line), mMemoryQualifier(memoryQualifier)
- {
- }
- ~TMemoryQualifierWrapper() {}
-
- TQualifierType getType() const { return QtMemory; }
- TString getQualifierString() const { return sh::getQualifierString(mMemoryQualifier); }
- TQualifier getQualifier() const { return mMemoryQualifier; }
- unsigned int getRank() const;
-
- private:
- TQualifier mMemoryQualifier;
-};
-
-// TTypeQualifier tightly covers type_qualifier from the grammar
-struct TTypeQualifier
-{
- // initializes all of the qualifiers and sets the scope
- TTypeQualifier(TQualifier scope, const TSourceLoc &loc);
-
- TLayoutQualifier layoutQualifier;
- TMemoryQualifier memoryQualifier;
- TPrecision precision;
- TQualifier qualifier;
- bool invariant;
- TSourceLoc line;
-};
-
-// TTypeQualifierBuilder contains all of the qualifiers when type_qualifier gets parsed.
-// It is to be used to validate the qualifier sequence and build a TTypeQualifier from it.
-class TTypeQualifierBuilder : angle::NonCopyable
-{
- public:
- using QualifierSequence = TVector<const TQualifierWrapperBase *>;
-
- public:
- POOL_ALLOCATOR_NEW_DELETE();
- TTypeQualifierBuilder(const TStorageQualifierWrapper *scope, int shaderVersion);
- // Adds the passed qualifier to the end of the sequence.
- void appendQualifier(const TQualifierWrapperBase *qualifier);
- // Checks for the order of qualification and repeating qualifiers.
- bool checkSequenceIsValid(TDiagnostics *diagnostics) const;
- // Goes over the qualifier sequence and parses it to form a type qualifier for a function
- // parameter.
- // The returned object is initialized even if the parsing fails.
- TTypeQualifier getParameterTypeQualifier(TDiagnostics *diagnostics) const;
- // Goes over the qualifier sequence and parses it to form a type qualifier for a variable.
- // The returned object is initialized even if the parsing fails.
- TTypeQualifier getVariableTypeQualifier(TDiagnostics *diagnostics) const;
-
- private:
- QualifierSequence mQualifiers;
- int mShaderVersion;
-};
-
-} // namespace sh
-
-#endif // COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_
diff --git a/gfx/angle/src/compiler/translator/RecordConstantPrecision.cpp b/gfx/angle/src/compiler/translator/RecordConstantPrecision.cpp
index 6b8515a2c..af1d1d1a3 100755
--- a/gfx/angle/src/compiler/translator/RecordConstantPrecision.cpp
+++ b/gfx/angle/src/compiler/translator/RecordConstantPrecision.cpp
@@ -18,9 +18,6 @@
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
namespace
{
@@ -48,11 +45,6 @@ RecordConstantPrecisionTraverser::RecordConstantPrecisionTraverser()
bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TIntermTyped *operand)
{
- if (getParentNode()->getAsCaseNode() || getParentNode()->getAsBlock())
- {
- return false;
- }
-
const TIntermBinary *parentAsBinary = getParentNode()->getAsBinaryNode();
if (parentAsBinary != nullptr)
{
@@ -163,5 +155,3 @@ void RecordConstantPrecision(TIntermNode *root, unsigned int *temporaryIndex)
}
while (traverser.foundHigherPrecisionConstant());
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/RecordConstantPrecision.h b/gfx/angle/src/compiler/translator/RecordConstantPrecision.h
index a62831e22..2cd401b41 100755
--- a/gfx/angle/src/compiler/translator/RecordConstantPrecision.h
+++ b/gfx/angle/src/compiler/translator/RecordConstantPrecision.h
@@ -16,11 +16,8 @@
#ifndef COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_
#define COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_
-namespace sh
-{
class TIntermNode;
void RecordConstantPrecision(TIntermNode *root, unsigned int *temporaryIndex);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_
diff --git a/gfx/angle/src/compiler/translator/RegenerateStructNames.cpp b/gfx/angle/src/compiler/translator/RegenerateStructNames.cpp
index a01d79abe..5e0db2ad2 100755
--- a/gfx/angle/src/compiler/translator/RegenerateStructNames.cpp
+++ b/gfx/angle/src/compiler/translator/RegenerateStructNames.cpp
@@ -7,9 +7,6 @@
#include "common/debug.h"
#include "compiler/translator/RegenerateStructNames.h"
-namespace sh
-{
-
void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol)
{
ASSERT(symbol);
@@ -61,16 +58,25 @@ void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol)
userType->setName(tmp);
}
-bool RegenerateStructNames::visitBlock(Visit, TIntermBlock *block)
+bool RegenerateStructNames::visitAggregate(Visit, TIntermAggregate *aggregate)
{
- ++mScopeDepth;
- TIntermSequence &sequence = *(block->getSequence());
- for (TIntermNode *node : sequence)
+ ASSERT(aggregate);
+ switch (aggregate->getOp())
{
- node->traverse(this);
+ case EOpSequence:
+ ++mScopeDepth;
+ {
+ TIntermSequence &sequence = *(aggregate->getSequence());
+ for (size_t ii = 0; ii < sequence.size(); ++ii)
+ {
+ TIntermNode *node = sequence[ii];
+ ASSERT(node != NULL);
+ node->traverse(this);
+ }
+ }
+ --mScopeDepth;
+ return false;
+ default:
+ return true;
}
- --mScopeDepth;
- return false;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/RegenerateStructNames.h b/gfx/angle/src/compiler/translator/RegenerateStructNames.h
index 86c5060b3..3b98e5d70 100755
--- a/gfx/angle/src/compiler/translator/RegenerateStructNames.h
+++ b/gfx/angle/src/compiler/translator/RegenerateStructNames.h
@@ -12,9 +12,6 @@
#include <set>
-namespace sh
-{
-
class RegenerateStructNames : public TIntermTraverser
{
public:
@@ -27,7 +24,7 @@ class RegenerateStructNames : public TIntermTraverser
protected:
void visitSymbol(TIntermSymbol *) override;
- bool visitBlock(Visit, TIntermBlock *block) override;
+ bool visitAggregate(Visit, TIntermAggregate *) override;
private:
const TSymbolTable &mSymbolTable;
@@ -41,6 +38,4 @@ class RegenerateStructNames : public TIntermTraverser
std::set<int> mDeclaredGlobalStructs;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_
diff --git a/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp b/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
index 31914dcf3..37955e736 100755
--- a/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -14,9 +14,6 @@
#include "compiler/translator/IntermNodePatternMatcher.h"
#include "compiler/translator/SymbolTable.h"
-namespace sh
-{
-
namespace
{
@@ -95,15 +92,21 @@ TIntermBinary *CreateIndexDirectBaseSymbolNode(const TType &indexedType,
const int index,
TQualifier baseQualifier)
{
+ TIntermBinary *indexNode = new TIntermBinary(EOpIndexDirect);
+ indexNode->setType(fieldType);
TIntermSymbol *baseSymbol = CreateBaseSymbol(indexedType, baseQualifier);
- TIntermBinary *indexNode =
- new TIntermBinary(EOpIndexDirect, baseSymbol, TIntermTyped::CreateIndexNode(index));
+ indexNode->setLeft(baseSymbol);
+ indexNode->setRight(CreateIntConstantNode(index));
return indexNode;
}
TIntermBinary *CreateAssignValueSymbolNode(TIntermTyped *targetNode, const TType &assignedValueType)
{
- return new TIntermBinary(EOpAssign, targetNode, CreateValueSymbol(assignedValueType));
+ TIntermBinary *assignNode = new TIntermBinary(EOpAssign);
+ assignNode->setType(assignedValueType);
+ assignNode->setLeft(targetNode);
+ assignNode->setRight(CreateValueSymbol(assignedValueType));
+ return assignNode;
}
TIntermTyped *EnsureSignedInt(TIntermTyped *node)
@@ -175,7 +178,7 @@ TType GetFieldType(const TType &indexedType)
// base[1] = value;
// }
// Note that else is not used in above functions to avoid the RewriteElseBlocks transformation.
-TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type, bool write)
+TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write)
{
ASSERT(!type.isArray());
// Conservatively use highp here, even if the indexed type is not highp. That way the code can't
@@ -183,6 +186,8 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type, bool write)
// 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.
type.setPrecision(EbpHigh);
+ TIntermAggregate *indexingFunction = new TIntermAggregate(EOpFunction);
+ indexingFunction->setNameObj(GetIndexFunctionName(type, write));
TType fieldType = GetFieldType(type);
int numCases = 0;
@@ -194,6 +199,14 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type, bool write)
{
numCases = type.getNominalSize();
}
+ if (write)
+ {
+ indexingFunction->setType(TType(EbtVoid));
+ }
+ else
+ {
+ indexingFunction->setType(fieldType);
+ }
TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters);
TQualifier baseQualifier = EvqInOut;
@@ -208,8 +221,9 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type, bool write)
TIntermSymbol *valueParam = CreateValueSymbol(fieldType);
paramsNode->getSequence()->push_back(valueParam);
}
+ indexingFunction->getSequence()->push_back(paramsNode);
- TIntermBlock *statementList = new TIntermBlock();
+ TIntermAggregate *statementList = new TIntermAggregate(EOpSequence);
for (int i = 0; i < numCases; ++i)
{
TIntermCase *caseNode = new TIntermCase(CreateIntConstantNode(i));
@@ -239,17 +253,18 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type, bool write)
TIntermSwitch *switchNode = new TIntermSwitch(CreateIndexSymbol(), statementList);
- TIntermBlock *bodyNode = new TIntermBlock();
+ TIntermAggregate *bodyNode = new TIntermAggregate(EOpSequence);
bodyNode->getSequence()->push_back(switchNode);
- TIntermBinary *cond =
- new TIntermBinary(EOpLessThan, CreateIndexSymbol(), CreateIntConstantNode(0));
+ TIntermBinary *cond = new TIntermBinary(EOpLessThan);
cond->setType(TType(EbtBool, EbpUndefined));
+ cond->setLeft(CreateIndexSymbol());
+ cond->setRight(CreateIntConstantNode(0));
// Two blocks: one accesses (either reads or writes) the first element and returns,
// the other accesses the last element.
- TIntermBlock *useFirstBlock = new TIntermBlock();
- TIntermBlock *useLastBlock = new TIntermBlock();
+ TIntermAggregate *useFirstBlock = new TIntermAggregate(EOpSequence);
+ TIntermAggregate *useLastBlock = new TIntermAggregate(EOpSequence);
TIntermBinary *indexFirstNode =
CreateIndexDirectBaseSymbolNode(type, fieldType, 0, baseQualifier);
TIntermBinary *indexLastNode =
@@ -272,20 +287,12 @@ TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type, bool write)
TIntermBranch *returnLastNode = new TIntermBranch(EOpReturn, indexLastNode);
useLastBlock->getSequence()->push_back(returnLastNode);
}
- TIntermIfElse *ifNode = new TIntermIfElse(cond, useFirstBlock, nullptr);
+ TIntermSelection *ifNode = new TIntermSelection(cond, useFirstBlock, nullptr);
bodyNode->getSequence()->push_back(ifNode);
bodyNode->getSequence()->push_back(useLastBlock);
- TIntermFunctionDefinition *indexingFunction = nullptr;
- if (write)
- {
- indexingFunction = new TIntermFunctionDefinition(TType(EbtVoid), paramsNode, bodyNode);
- }
- else
- {
- indexingFunction = new TIntermFunctionDefinition(fieldType, paramsNode, bodyNode);
- }
- indexingFunction->getFunctionSymbolInfo()->setNameObj(GetIndexFunctionName(type, write));
+ indexingFunction->getSequence()->push_back(bodyNode);
+
return indexingFunction;
}
@@ -327,8 +334,8 @@ RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(const TSymbolTabl
void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root)
{
- TIntermBlock *rootBlock = root->getAsBlock();
- ASSERT(rootBlock != nullptr);
+ TIntermAggregate *rootAgg = root->getAsAggregate();
+ ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence);
TIntermSequence insertions;
for (TType type : mIndexedVecAndMatrixTypes)
{
@@ -338,7 +345,7 @@ void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root)
{
insertions.push_back(GetIndexFunctionDefinition(type, true));
}
- mInsertions.push_back(NodeInsertMultipleEntry(rootBlock, 0, insertions, TIntermSequence()));
+ mInsertions.push_back(NodeInsertMultipleEntry(rootAgg, 0, insertions, TIntermSequence()));
}
// Create a call to dyn_index_*() based on an indirect indexing op node
@@ -350,8 +357,7 @@ TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node,
TIntermAggregate *indexingCall = new TIntermAggregate(EOpFunctionCall);
indexingCall->setLine(node->getLine());
indexingCall->setUserDefined();
- indexingCall->getFunctionSymbolInfo()->setNameObj(
- GetIndexFunctionName(indexedNode->getType(), false));
+ indexingCall->setNameObj(GetIndexFunctionName(indexedNode->getType(), false));
indexingCall->getSequence()->push_back(indexedNode);
indexingCall->getSequence()->push_back(index);
@@ -369,8 +375,7 @@ TIntermAggregate *CreateIndexedWriteFunctionCall(TIntermBinary *node,
ASSERT(leftCopy != nullptr && leftCopy->getAsTyped() != nullptr);
TIntermAggregate *indexedWriteCall =
CreateIndexFunctionCall(node, leftCopy->getAsTyped(), index);
- indexedWriteCall->getFunctionSymbolInfo()->setNameObj(
- GetIndexFunctionName(node->getLeft()->getType(), true));
+ indexedWriteCall->setNameObj(GetIndexFunctionName(node->getLeft()->getType(), true));
indexedWriteCall->setType(TType(EbtVoid));
indexedWriteCall->getSequence()->push_back(writtenValue);
return indexedWriteCall;
@@ -393,7 +398,7 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
// Now v_expr[s0] can be safely executed several times without unintended side effects.
// Init the temp variable holding the index
- TIntermDeclaration *initIndex = createTempInitDeclaration(node->getRight());
+ TIntermAggregate *initIndex = createTempInitDeclaration(node->getRight());
insertStatementInParentBlock(initIndex);
mUsedTreeInsertion = true;
@@ -444,7 +449,7 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
// Store the index in a temporary signed int variable.
TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight());
- TIntermDeclaration *initIndex = createTempInitDeclaration(indexInitializer);
+ TIntermAggregate *initIndex = createTempInitDeclaration(indexInitializer);
initIndex->setLine(node->getLine());
insertionsBefore.push_back(initIndex);
@@ -509,5 +514,3 @@ void RemoveDynamicIndexing(TIntermNode *root,
traverser.insertHelperDefinitions(root);
traverser.updateTree();
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.h b/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.h
index 06305d0f8..ae3a93c9b 100755
--- a/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.h
+++ b/gfx/angle/src/compiler/translator/RemoveDynamicIndexing.h
@@ -10,9 +10,6 @@
#ifndef COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
#define COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
-namespace sh
-{
-
class TIntermNode;
class TSymbolTable;
@@ -21,6 +18,4 @@ void RemoveDynamicIndexing(TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion);
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_
diff --git a/gfx/angle/src/compiler/translator/RemoveInvariantDeclaration.cpp b/gfx/angle/src/compiler/translator/RemoveInvariantDeclaration.cpp
deleted file mode 100644
index f6f016310..000000000
--- a/gfx/angle/src/compiler/translator/RemoveInvariantDeclaration.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "compiler/translator/RemoveInvariantDeclaration.h"
-
-#include "compiler/translator/IntermNode.h"
-
-namespace sh
-{
-
-namespace
-{
-
-// An AST traverser that removes invariant declaration for input in fragment shader
-// when GLSL >= 4.20 and for output in vertex shader when GLSL < 4.2.
-class RemoveInvariantDeclarationTraverser : public TIntermTraverser
-{
- public:
- RemoveInvariantDeclarationTraverser() : TIntermTraverser(true, false, false) {}
-
- private:
- bool visitAggregate(Visit visit, TIntermAggregate *node) override
- {
- if (node->getOp() == EOpInvariantDeclaration)
- {
- TIntermSequence emptyReplacement;
- mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(),
- node, emptyReplacement));
- return false;
- }
- return true;
- }
-};
-
-} // anonymous namespace
-
-void RemoveInvariantDeclaration(TIntermNode *root)
-{
- RemoveInvariantDeclarationTraverser traverser;
- root->traverse(&traverser);
- traverser.updateTree();
-}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/RemoveInvariantDeclaration.h b/gfx/angle/src/compiler/translator/RemoveInvariantDeclaration.h
deleted file mode 100644
index cf9d4aa4c..000000000
--- a/gfx/angle/src/compiler/translator/RemoveInvariantDeclaration.h
+++ /dev/null
@@ -1,18 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#ifndef COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_
-#define COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_
-
-class TIntermNode;
-namespace sh
-{
-
-void RemoveInvariantDeclaration(TIntermNode *root);
-
-} // namespace sh
-
-#endif // COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_
diff --git a/gfx/angle/src/compiler/translator/RemovePow.cpp b/gfx/angle/src/compiler/translator/RemovePow.cpp
index 192084c36..ba505753a 100755
--- a/gfx/angle/src/compiler/translator/RemovePow.cpp
+++ b/gfx/angle/src/compiler/translator/RemovePow.cpp
@@ -13,9 +13,6 @@
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
namespace
{
@@ -58,15 +55,19 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
TIntermTyped *x = node->getSequence()->at(0)->getAsTyped();
TIntermTyped *y = node->getSequence()->at(1)->getAsTyped();
- TIntermUnary *log = new TIntermUnary(EOpLog2, x);
+ TIntermUnary *log = new TIntermUnary(EOpLog2);
+ log->setOperand(x);
log->setLine(node->getLine());
+ log->setType(x->getType());
TOperator op = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType());
TIntermBinary *mul = new TIntermBinary(op, y, log);
mul->setLine(node->getLine());
- TIntermUnary *exp = new TIntermUnary(EOpExp2, mul);
+ TIntermUnary *exp = new TIntermUnary(EOpExp2);
+ exp->setOperand(mul);
exp->setLine(node->getLine());
+ exp->setType(node->getType());
queueReplacement(node, exp, OriginalNode::IS_DROPPED);
@@ -95,5 +96,3 @@ void RemovePow(TIntermNode *root)
}
while (traverser.needAnotherIteration());
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/RemovePow.h b/gfx/angle/src/compiler/translator/RemovePow.h
index 1e2f4e116..40f9d672b 100755
--- a/gfx/angle/src/compiler/translator/RemovePow.h
+++ b/gfx/angle/src/compiler/translator/RemovePow.h
@@ -11,11 +11,8 @@
#ifndef COMPILER_TRANSLATOR_REMOVEPOW_H_
#define COMPILER_TRANSLATOR_REMOVEPOW_H_
-namespace sh
-{
class TIntermNode;
void RemovePow(TIntermNode *root);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_REMOVEPOW_H_
diff --git a/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp b/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp
index dd995af47..b278b5343 100755
--- a/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp
+++ b/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp
@@ -6,10 +6,7 @@
#include "compiler/translator/RemoveSwitchFallThrough.h"
-namespace sh
-{
-
-TIntermBlock *RemoveSwitchFallThrough::removeFallThrough(TIntermBlock *statementList)
+TIntermAggregate *RemoveSwitchFallThrough::removeFallThrough(TIntermAggregate *statementList)
{
RemoveSwitchFallThrough rm(statementList);
ASSERT(statementList);
@@ -25,13 +22,14 @@ TIntermBlock *RemoveSwitchFallThrough::removeFallThrough(TIntermBlock *statement
return rm.mStatementListOut;
}
-RemoveSwitchFallThrough::RemoveSwitchFallThrough(TIntermBlock *statementList)
+RemoveSwitchFallThrough::RemoveSwitchFallThrough(TIntermAggregate *statementList)
: TIntermTraverser(true, false, false),
mStatementList(statementList),
mLastStatementWasBreak(false),
mPreviousCase(nullptr)
{
- mStatementListOut = new TIntermBlock();
+ mStatementListOut = new TIntermAggregate();
+ mStatementListOut->setOp(EOpSequence);
}
void RemoveSwitchFallThrough::visitSymbol(TIntermSymbol *node)
@@ -64,14 +62,7 @@ bool RemoveSwitchFallThrough::visitUnary(Visit, TIntermUnary *node)
return false;
}
-bool RemoveSwitchFallThrough::visitTernary(Visit, TIntermTernary *node)
-{
- mPreviousCase->getSequence()->push_back(node);
- mLastStatementWasBreak = false;
- return false;
-}
-
-bool RemoveSwitchFallThrough::visitIfElse(Visit, TIntermIfElse *node)
+bool RemoveSwitchFallThrough::visitSelection(Visit, TIntermSelection *node)
{
mPreviousCase->getSequence()->push_back(node);
mLastStatementWasBreak = false;
@@ -132,7 +123,8 @@ void RemoveSwitchFallThrough::handlePreviousCase()
bool RemoveSwitchFallThrough::visitCase(Visit, TIntermCase *node)
{
handlePreviousCase();
- mPreviousCase = new TIntermBlock();
+ mPreviousCase = new TIntermAggregate();
+ mPreviousCase->setOp(EOpSequence);
mPreviousCase->getSequence()->push_back(node);
// Don't traverse the condition of the case statement
return false;
@@ -140,13 +132,6 @@ bool RemoveSwitchFallThrough::visitCase(Visit, TIntermCase *node)
bool RemoveSwitchFallThrough::visitAggregate(Visit, TIntermAggregate *node)
{
- mPreviousCase->getSequence()->push_back(node);
- mLastStatementWasBreak = false;
- return false;
-}
-
-bool RemoveSwitchFallThrough::visitBlock(Visit, TIntermBlock *node)
-{
if (node != mStatementList)
{
mPreviousCase->getSequence()->push_back(node);
@@ -170,5 +155,3 @@ bool RemoveSwitchFallThrough::visitBranch(Visit, TIntermBranch *node)
mLastStatementWasBreak = true;
return false;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.h b/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.h
index fd8bf4fa2..db8699327 100755
--- a/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.h
+++ b/gfx/angle/src/compiler/translator/RemoveSwitchFallThrough.h
@@ -9,42 +9,35 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
class RemoveSwitchFallThrough : public TIntermTraverser
{
public:
// When given a statementList from a switch AST node, return an updated
// statementList that has fall-through removed.
- static TIntermBlock *removeFallThrough(TIntermBlock *statementList);
+ static TIntermAggregate *removeFallThrough(TIntermAggregate *statementList);
private:
- RemoveSwitchFallThrough(TIntermBlock *statementList);
+ RemoveSwitchFallThrough(TIntermAggregate *statementList);
void visitSymbol(TIntermSymbol *node) override;
void visitConstantUnion(TIntermConstantUnion *node) override;
bool visitBinary(Visit, TIntermBinary *node) override;
bool visitUnary(Visit, TIntermUnary *node) override;
- bool visitTernary(Visit visit, TIntermTernary *node) override;
- bool visitIfElse(Visit visit, TIntermIfElse *node) override;
+ bool visitSelection(Visit visit, TIntermSelection *node) override;
bool visitSwitch(Visit, TIntermSwitch *node) override;
bool visitCase(Visit, TIntermCase *node) override;
bool visitAggregate(Visit, TIntermAggregate *node) override;
- bool visitBlock(Visit, TIntermBlock *node) override;
bool visitLoop(Visit, TIntermLoop *node) override;
bool visitBranch(Visit, TIntermBranch *node) override;
void outputSequence(TIntermSequence *sequence, size_t startIndex);
void handlePreviousCase();
- TIntermBlock *mStatementList;
- TIntermBlock *mStatementListOut;
+ TIntermAggregate *mStatementList;
+ TIntermAggregate *mStatementListOut;
bool mLastStatementWasBreak;
- TIntermBlock *mPreviousCase;
- std::vector<TIntermBlock *> mCasesSharingBreak;
+ TIntermAggregate *mPreviousCase;
+ std::vector<TIntermAggregate *> mCasesSharingBreak;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_
diff --git a/gfx/angle/src/compiler/translator/RenameFunction.h b/gfx/angle/src/compiler/translator/RenameFunction.h
new file mode 100644
index 000000000..fd6a365fe
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/RenameFunction.h
@@ -0,0 +1,36 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_RENAMEFUNCTION_H_
+#define COMPILER_TRANSLATOR_RENAMEFUNCTION_H_
+
+#include "compiler/translator/IntermNode.h"
+
+//
+// Renames a function, including its declaration and any calls to it.
+//
+class RenameFunction : public TIntermTraverser
+{
+public:
+ RenameFunction(const TString& oldFunctionName, const TString& newFunctionName)
+ : TIntermTraverser(true, false, false)
+ , mOldFunctionName(oldFunctionName)
+ , mNewFunctionName(newFunctionName) {}
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ TOperator op = node->getOp();
+ if ((op == EOpFunction || op == EOpFunctionCall) && node->getName() == mOldFunctionName)
+ node->setName(mNewFunctionName);
+ return true;
+ }
+
+private:
+ const TString mOldFunctionName;
+ const TString mNewFunctionName;
+};
+
+#endif // COMPILER_TRANSLATOR_RENAMEFUNCTION_H_
diff --git a/gfx/angle/src/compiler/translator/RewriteDoWhile.cpp b/gfx/angle/src/compiler/translator/RewriteDoWhile.cpp
index 7999cbf49..834744754 100755
--- a/gfx/angle/src/compiler/translator/RewriteDoWhile.cpp
+++ b/gfx/angle/src/compiler/translator/RewriteDoWhile.cpp
@@ -11,9 +11,6 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
namespace
{
@@ -46,11 +43,15 @@ class DoWhileRewriter : public TIntermTraverser
public:
DoWhileRewriter() : TIntermTraverser(true, false, false) {}
- bool visitBlock(Visit, TIntermBlock *node) override
+ bool visitAggregate(Visit, TIntermAggregate *node) override
{
- // A well-formed AST can only have do-while inside TIntermBlock. By doing a prefix traversal
- // we are able to replace the do-while in the sequence directly as the content of the
- // do-while will be traversed later.
+ // A well-formed AST can only have do-while in EOpSequence which represent lists of
+ // statements. By doing a prefix traversal we are able to replace the do-while in the
+ // sequence directly as the content of the do-while will be traversed later.
+ if (node->getOp() != EOpSequence)
+ {
+ return true;
+ }
TIntermSequence *statements = node->getSequence();
@@ -70,7 +71,7 @@ class DoWhileRewriter : public TIntermTraverser
TType boolType = TType(EbtBool);
// bool temp = false;
- TIntermDeclaration *tempDeclaration = nullptr;
+ TIntermAggregate *tempDeclaration = nullptr;
{
TConstantUnion *falseConstant = new TConstantUnion();
falseConstant->setBConst(false);
@@ -94,22 +95,23 @@ class DoWhileRewriter : public TIntermTraverser
// break;
// }
// }
- TIntermIfElse *breakIf = nullptr;
+ TIntermSelection *breakIf = nullptr;
{
TIntermBranch *breakStatement = new TIntermBranch(EOpBreak, nullptr);
- TIntermBlock *breakBlock = new TIntermBlock();
+ TIntermAggregate *breakBlock = new TIntermAggregate(EOpSequence);
breakBlock->getSequence()->push_back(breakStatement);
- TIntermUnary *negatedCondition =
- new TIntermUnary(EOpLogicalNot, loop->getCondition());
+ TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot);
+ negatedCondition->setOperand(loop->getCondition());
- TIntermIfElse *innerIf = new TIntermIfElse(negatedCondition, breakBlock, nullptr);
+ TIntermSelection *innerIf =
+ new TIntermSelection(negatedCondition, breakBlock, nullptr);
- TIntermBlock *innerIfBlock = new TIntermBlock();
+ TIntermAggregate *innerIfBlock = new TIntermAggregate(EOpSequence);
innerIfBlock->getSequence()->push_back(innerIf);
- breakIf = new TIntermIfElse(createTempSymbol(boolType), innerIfBlock, nullptr);
+ breakIf = new TIntermSelection(createTempSymbol(boolType), innerIfBlock, nullptr);
}
// Assemble the replacement loops, reusing the do-while loop's body and inserting our
@@ -120,10 +122,14 @@ class DoWhileRewriter : public TIntermTraverser
trueConstant->setBConst(true);
TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, boolType);
- TIntermBlock *body = loop->getBody();
- if (body == nullptr)
+ TIntermAggregate *body = nullptr;
+ if (loop->getBody() != nullptr)
{
- body = new TIntermBlock();
+ body = loop->getBody()->getAsAggregate();
+ }
+ else
+ {
+ body = new TIntermAggregate(EOpSequence);
}
auto sequence = body->getSequence();
sequence->insert(sequence->begin(), assignTrue);
@@ -155,5 +161,3 @@ void RewriteDoWhile(TIntermNode *root, unsigned int *temporaryIndex)
root->traverse(&rewriter);
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/RewriteDoWhile.h b/gfx/angle/src/compiler/translator/RewriteDoWhile.h
index 91a7958c0..f6ec1caf0 100755
--- a/gfx/angle/src/compiler/translator/RewriteDoWhile.h
+++ b/gfx/angle/src/compiler/translator/RewriteDoWhile.h
@@ -10,10 +10,7 @@
#ifndef COMPILER_TRANSLATOR_REWRITEDOWHILE_H_
#define COMPILER_TRANSLATOR_REWRITEDOWHILE_H_
-namespace sh
-{
class TIntermNode;
void RewriteDoWhile(TIntermNode *root, unsigned int *temporaryIndex);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_REWRITEDOWHILE_H_
diff --git a/gfx/angle/src/compiler/translator/RewriteElseBlocks.cpp b/gfx/angle/src/compiler/translator/RewriteElseBlocks.cpp
index 937de11cd..52ede1743 100755
--- a/gfx/angle/src/compiler/translator/RewriteElseBlocks.cpp
+++ b/gfx/angle/src/compiler/translator/RewriteElseBlocks.cpp
@@ -8,8 +8,6 @@
//
#include "compiler/translator/RewriteElseBlocks.h"
-
-#include "compiler/translator/Intermediate.h"
#include "compiler/translator/NodeSearch.h"
#include "compiler/translator/SymbolTable.h"
@@ -25,60 +23,81 @@ class ElseBlockRewriter : public TIntermTraverser
ElseBlockRewriter();
protected:
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *aggregate) override;
- bool visitBlock(Visit visit, TIntermBlock *block) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *aggregate) override;
private:
const TType *mFunctionType;
- TIntermNode *rewriteIfElse(TIntermIfElse *ifElse);
+ TIntermNode *rewriteSelection(TIntermSelection *selection);
};
+TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand)
+{
+ TIntermUnary *unary = new TIntermUnary(op, operand->getType());
+ unary->setOperand(operand);
+ return unary;
+}
+
ElseBlockRewriter::ElseBlockRewriter()
: TIntermTraverser(true, false, true),
mFunctionType(NULL)
{}
-bool ElseBlockRewriter::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node)
{
- // Store the current function context (see comment below)
- mFunctionType = ((visit == PreVisit) ? &node->getType() : nullptr);
- return true;
-}
-
-bool ElseBlockRewriter::visitBlock(Visit visit, TIntermBlock *node)
-{
- if (visit == PostVisit)
+ switch (node->getOp())
{
- for (size_t statementIndex = 0; statementIndex != node->getSequence()->size();
- statementIndex++)
+ case EOpSequence:
+ if (visit == PostVisit)
{
- TIntermNode *statement = (*node->getSequence())[statementIndex];
- TIntermIfElse *ifElse = statement->getAsIfElseNode();
- if (ifElse && ifElse->getFalseBlock() != nullptr)
+ for (size_t statementIndex = 0; statementIndex != node->getSequence()->size(); statementIndex++)
{
- (*node->getSequence())[statementIndex] = rewriteIfElse(ifElse);
+ TIntermNode *statement = (*node->getSequence())[statementIndex];
+ TIntermSelection *selection = statement->getAsSelectionNode();
+ if (selection && selection->getFalseBlock() != nullptr)
+ {
+ // Check for if / else if
+ TIntermSelection *elseIfBranch = selection->getFalseBlock()->getAsSelectionNode();
+ if (elseIfBranch)
+ {
+ selection->replaceChildNode(elseIfBranch, rewriteSelection(elseIfBranch));
+ delete elseIfBranch;
+ }
+
+ (*node->getSequence())[statementIndex] = rewriteSelection(selection);
+ delete selection;
+ }
}
}
+ break;
+
+ case EOpFunction:
+ // Store the current function context (see comment below)
+ mFunctionType = ((visit == PreVisit) ? &node->getType() : NULL);
+ break;
+
+ default: break;
}
+
return true;
}
-TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse)
+TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
{
- ASSERT(ifElse != nullptr);
+ ASSERT(selection != nullptr);
nextTemporaryIndex();
- TIntermDeclaration *storeCondition = createTempInitDeclaration(ifElse->getCondition());
+ TIntermTyped *typedCondition = selection->getCondition()->getAsTyped();
+ TIntermAggregate *storeCondition = createTempInitDeclaration(typedCondition);
- TIntermBlock *falseBlock = nullptr;
+ TIntermSelection *falseBlock = nullptr;
TType boolType(EbtBool, EbpUndefined, EvqTemporary);
- if (ifElse->getFalseBlock())
+ if (selection->getFalseBlock())
{
- TIntermBlock *negatedElse = nullptr;
+ TIntermAggregate *negatedElse = nullptr;
// crbug.com/346463
// D3D generates error messages claiming a function has no return value, when rewriting
// an if-else clause that returns something non-void in a function. By appending dummy
@@ -89,24 +108,22 @@ TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse)
mFunctionType->getBasicString();
TString rawText = "return (" + typeString + ")0";
TIntermRaw *returnNode = new TIntermRaw(*mFunctionType, rawText);
- negatedElse = new TIntermBlock();
+ negatedElse = new TIntermAggregate(EOpSequence);
negatedElse->getSequence()->push_back(returnNode);
}
TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType);
- TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot, conditionSymbolElse);
- TIntermIfElse *falseIfElse =
- new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse);
- falseBlock = TIntermediate::EnsureBlock(falseIfElse);
+ TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse);
+ falseBlock = new TIntermSelection(negatedCondition,
+ selection->getFalseBlock(), negatedElse);
}
TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType);
- TIntermIfElse *newIfElse =
- new TIntermIfElse(conditionSymbolSel, ifElse->getTrueBlock(), falseBlock);
+ TIntermSelection *newSelection = new TIntermSelection(conditionSymbolSel, selection->getTrueBlock(), falseBlock);
- TIntermBlock *block = new TIntermBlock();
+ TIntermAggregate *block = new TIntermAggregate(EOpSequence);
block->getSequence()->push_back(storeCondition);
- block->getSequence()->push_back(newIfElse);
+ block->getSequence()->push_back(newSelection);
return block;
}
diff --git a/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp b/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp
index 487c90991..4ceceb226 100755
--- a/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp
+++ b/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp
@@ -22,6 +22,7 @@ class Traverser : public TIntermTraverser
{
public:
static void Apply(TIntermNode *root,
+ unsigned int *tempIndex,
const TSymbolTable &symbolTable,
int shaderVersion);
@@ -42,10 +43,12 @@ Traverser::Traverser(const TSymbolTable &symbolTable, int shaderVersion)
// static
void Traverser::Apply(TIntermNode *root,
+ unsigned int *tempIndex,
const TSymbolTable &symbolTable,
int shaderVersion)
{
Traverser traverser(symbolTable, shaderVersion);
+ traverser.useTemporaryIndex(tempIndex);
do
{
traverser.nextIteration();
@@ -60,6 +63,7 @@ void Traverser::Apply(TIntermNode *root,
void Traverser::nextIteration()
{
mFound = false;
+ nextTemporaryIndex();
}
bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
@@ -75,7 +79,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
return true;
}
- if (node->getFunctionSymbolInfo()->getName().compare(0, 16, "texelFetchOffset") != 0)
+ if (node->getName().compare(0, 16, "texelFetchOffset") != 0)
{
return true;
}
@@ -83,36 +87,42 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
// Potential problem case detected, apply workaround.
const TIntermSequence *sequence = node->getSequence();
ASSERT(sequence->size() == 4u);
+ nextTemporaryIndex();
// Decide if there is a 2DArray sampler.
- bool is2DArray = node->getFunctionSymbolInfo()->getName().find("s2a1") != TString::npos;
+ bool is2DArray = node->getName().find("s2a1") != TString::npos;
// Create new argument list from node->getName().
// e.g. Get "(is2a1;vi3;i1;" from "texelFetchOffset(is2a1;vi3;i1;vi2;"
- TString newArgs = node->getFunctionSymbolInfo()->getName().substr(
- 16, node->getFunctionSymbolInfo()->getName().length() - 20);
+ TString newArgs = node->getName().substr(16, node->getName().length() - 20);
TString newName = "texelFetch" + newArgs;
TSymbol *texelFetchSymbol = symbolTable->findBuiltIn(newName, shaderVersion);
ASSERT(texelFetchSymbol);
int uniqueId = texelFetchSymbol->getUniqueId();
// Create new node that represents the call of function texelFetch.
- // Its argument list will be: texelFetch(sampler, Position+offset, lod).
TIntermAggregate *texelFetchNode = new TIntermAggregate(EOpFunctionCall);
- texelFetchNode->getFunctionSymbolInfo()->setName(newName);
- texelFetchNode->getFunctionSymbolInfo()->setId(uniqueId);
+ texelFetchNode->setName(newName);
+ texelFetchNode->setFunctionId(uniqueId);
texelFetchNode->setType(node->getType());
texelFetchNode->setLine(node->getLine());
+ // Create argument List of texelFetch(sampler, Position+offset, lod).
+ TIntermSequence newsequence;
+
// sampler
- texelFetchNode->getSequence()->push_back(sequence->at(0));
+ newsequence.push_back(sequence->at(0));
+ // Position+offset
+ TIntermBinary *add = new TIntermBinary(EOpAdd);
+ add->setType(node->getType());
// Position
TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped();
ASSERT(texCoordNode);
-
+ add->setLine(texCoordNode->getLine());
+ add->setType(texCoordNode->getType());
+ add->setLeft(texCoordNode);
// offset
- TIntermTyped *offsetNode = nullptr;
ASSERT(sequence->at(3)->getAsTyped());
if (is2DArray)
{
@@ -122,31 +132,28 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
constructIVec3Node->setLine(texCoordNode->getLine());
constructIVec3Node->setType(texCoordNode->getType());
- constructIVec3Node->getSequence()->push_back(sequence->at(3)->getAsTyped());
+ TIntermSequence ivec3Sequence;
+ ivec3Sequence.push_back(sequence->at(3)->getAsTyped());
TConstantUnion *zero = new TConstantUnion();
zero->setIConst(0);
TType *intType = new TType(EbtInt);
TIntermConstantUnion *zeroNode = new TIntermConstantUnion(zero, *intType);
- constructIVec3Node->getSequence()->push_back(zeroNode);
+ ivec3Sequence.push_back(zeroNode);
+ constructIVec3Node->insertChildNodes(0, ivec3Sequence);
- offsetNode = constructIVec3Node;
+ add->setRight(constructIVec3Node);
}
else
{
- offsetNode = sequence->at(3)->getAsTyped();
+ add->setRight(sequence->at(3)->getAsTyped());
}
-
- // Position+offset
- TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode);
- add->setLine(texCoordNode->getLine());
- texelFetchNode->getSequence()->push_back(add);
+ newsequence.push_back(add);
// lod
- texelFetchNode->getSequence()->push_back(sequence->at(2));
-
- ASSERT(texelFetchNode->getSequence()->size() == 3u);
+ newsequence.push_back(sequence->at(2));
+ texelFetchNode->insertChildNodes(0, newsequence);
// Replace the old node by this new node.
queueReplacement(node, texelFetchNode, OriginalNode::IS_DROPPED);
@@ -157,6 +164,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
} // anonymous namespace
void RewriteTexelFetchOffset(TIntermNode *root,
+ unsigned int *tempIndex,
const TSymbolTable &symbolTable,
int shaderVersion)
{
@@ -164,7 +172,7 @@ void RewriteTexelFetchOffset(TIntermNode *root,
if (shaderVersion < 300)
return;
- Traverser::Apply(root, symbolTable, shaderVersion);
+ Traverser::Apply(root, tempIndex, symbolTable, shaderVersion);
}
} // namespace sh \ No newline at end of file
diff --git a/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.h b/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.h
index 4218f0b69..a60c26331 100755
--- a/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.h
+++ b/gfx/angle/src/compiler/translator/RewriteTexelFetchOffset.h
@@ -22,6 +22,7 @@ namespace sh
{
void RewriteTexelFetchOffset(TIntermNode *root,
+ unsigned int *tempIndex,
const TSymbolTable &symbolTable,
int shaderVersion);
diff --git a/gfx/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp b/gfx/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp
deleted file mode 100644
index ef708cb2e..000000000
--- a/gfx/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Implementation of evaluating unary integer variable bug workaround.
-// See header for more info.
-
-#include "compiler/translator/RewriteUnaryMinusOperatorInt.h"
-
-#include "compiler/translator/IntermNode.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class Traverser : public TIntermTraverser
-{
- public:
- static void Apply(TIntermNode *root);
-
- private:
- Traverser();
- bool visitUnary(Visit visit, TIntermUnary *node) override;
- void nextIteration();
-
- bool mFound = false;
-};
-
-// static
-void Traverser::Apply(TIntermNode *root)
-{
- Traverser traverser;
- do
- {
- traverser.nextIteration();
- root->traverse(&traverser);
- if (traverser.mFound)
- {
- traverser.updateTree();
- }
- } while (traverser.mFound);
-}
-
-Traverser::Traverser() : TIntermTraverser(true, false, false)
-{
-}
-
-void Traverser::nextIteration()
-{
- mFound = false;
-}
-
-bool Traverser::visitUnary(Visit visit, TIntermUnary *node)
-{
- if (mFound)
- {
- return false;
- }
-
- // Decide if the current unary operator is unary minus.
- if (node->getOp() != EOpNegative)
- {
- return true;
- }
-
- // Decide if the current operand is an integer variable.
- TIntermTyped *opr = node->getOperand();
- if (!opr->getType().isScalarInt())
- {
- return true;
- }
-
- // Potential problem case detected, apply workaround: -(int) -> ~(int) + 1.
- // ~(int)
- TIntermUnary *bitwiseNot = new TIntermUnary(EOpBitwiseNot, opr);
- bitwiseNot->setLine(opr->getLine());
-
- // Constant 1 (or 1u)
- TConstantUnion *one = new TConstantUnion();
- if (opr->getType().getBasicType() == EbtInt)
- {
- one->setIConst(1);
- }
- else
- {
- one->setUConst(1u);
- }
- TIntermConstantUnion *oneNode = new TIntermConstantUnion(one, opr->getType());
- oneNode->getTypePointer()->setQualifier(EvqConst);
- oneNode->setLine(opr->getLine());
-
- // ~(int) + 1
- TIntermBinary *add = new TIntermBinary(EOpAdd, bitwiseNot, oneNode);
- add->setLine(opr->getLine());
-
- queueReplacement(node, add, OriginalNode::IS_DROPPED);
-
- mFound = true;
- return false;
-}
-
-} // anonymous namespace
-
-void RewriteUnaryMinusOperatorInt(TIntermNode *root)
-{
- Traverser::Apply(root);
-}
-
-} // namespace sh \ No newline at end of file
diff --git a/gfx/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h b/gfx/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h
deleted file mode 100644
index 50f0c442a..000000000
--- a/gfx/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// This mutating tree traversal works around a bug on evaluating unary
-// integer variable on Intel D3D driver. It works by rewriting -(int) to
-// ~(int) + 1 when evaluating unary integer variables.
-
-#ifndef COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_
-#define COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_
-
-class TIntermNode;
-namespace sh
-{
-
-void RewriteUnaryMinusOperatorInt(TIntermNode *root);
-
-} // namespace sh
-
-#endif // COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_ \ No newline at end of file
diff --git a/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
index 5afa0d308..775c5d871 100755
--- a/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
+++ b/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
@@ -3,10 +3,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// Scalarize vector and matrix constructor args, so that vectors built from components don't have
-// matrix arguments, and matrices built from components don't have vector arguments. This avoids
-// driver bugs around vector and matrix constructors.
-//
#include "common/debug.h"
#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
@@ -15,10 +11,6 @@
#include "angle_gl.h"
#include "common/angleutils.h"
-#include "compiler/translator/IntermNode.h"
-
-namespace sh
-{
namespace
{
@@ -45,9 +37,23 @@ bool ContainsVectorNode(const TIntermSequence &sequence)
return false;
}
+TIntermConstantUnion *ConstructIndexNode(int index)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setIConst(index);
+
+ TType type(EbtInt, EbpUndefined, EvqConst, 1);
+ TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+ return node;
+}
+
TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index)
{
- return new TIntermBinary(EOpIndexDirect, symbolNode, TIntermTyped::CreateIndexNode(index));
+ TIntermBinary *binary = new TIntermBinary(EOpIndexDirect);
+ binary->setLeft(symbolNode);
+ TIntermConstantUnion *indexNode = ConstructIndexNode(index);
+ binary->setRight(indexNode);
+ return binary;
}
TIntermBinary *ConstructMatrixIndexBinaryNode(
@@ -56,53 +62,40 @@ TIntermBinary *ConstructMatrixIndexBinaryNode(
TIntermBinary *colVectorNode =
ConstructVectorIndexBinaryNode(symbolNode, colIndex);
- return new TIntermBinary(EOpIndexDirect, colVectorNode,
- TIntermTyped::CreateIndexNode(rowIndex));
+ TIntermBinary *binary = new TIntermBinary(EOpIndexDirect);
+ binary->setLeft(colVectorNode);
+ TIntermConstantUnion *rowIndexNode = ConstructIndexNode(rowIndex);
+ binary->setRight(rowIndexNode);
+ return binary;
}
-class ScalarizeArgsTraverser : public TIntermTraverser
-{
- public:
- ScalarizeArgsTraverser(sh::GLenum shaderType,
- bool fragmentPrecisionHigh,
- unsigned int *temporaryIndex)
- : TIntermTraverser(true, false, false),
- mShaderType(shaderType),
- mFragmentPrecisionHigh(fragmentPrecisionHigh)
- {
- useTemporaryIndex(temporaryIndex);
- }
-
- protected:
- bool visitAggregate(Visit visit, TIntermAggregate *node) override;
- bool visitBlock(Visit visit, TIntermBlock *node) override;
-
- private:
- void scalarizeArgs(TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix);
-
- // If we have the following code:
- // mat4 m(0);
- // vec4 v(1, m);
- // We will rewrite to:
- // mat4 m(0);
- // mat4 s0 = m;
- // vec4 v(1, s0[0][0], s0[0][1], s0[0][2]);
- // This function is to create nodes for "mat4 s0 = m;" and insert it to the code sequence. This
- // way the possible side effects of the constructor argument will only be evaluated once.
- void createTempVariable(TIntermTyped *original);
-
- std::vector<TIntermSequence> mBlockStack;
-
- sh::GLenum mShaderType;
- bool mFragmentPrecisionHigh;
-};
+} // namespace anonymous
-bool ScalarizeArgsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+bool ScalarizeVecAndMatConstructorArgs::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (visit == PreVisit)
{
switch (node->getOp())
{
+ case EOpSequence:
+ mSequenceStack.push_back(TIntermSequence());
+ {
+ for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
+ iter != node->getSequence()->end(); ++iter)
+ {
+ TIntermNode *child = *iter;
+ ASSERT(child != NULL);
+ child->traverse(this);
+ mSequenceStack.back().push_back(child);
+ }
+ }
+ if (mSequenceStack.back().size() > node->getSequence()->size())
+ {
+ node->getSequence()->clear();
+ *(node->getSequence()) = mSequenceStack.back();
+ }
+ mSequenceStack.pop_back();
+ return false;
case EOpConstructVec2:
case EOpConstructVec3:
case EOpConstructVec4:
@@ -134,29 +127,8 @@ bool ScalarizeArgsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
return true;
}
-bool ScalarizeArgsTraverser::visitBlock(Visit visit, TIntermBlock *node)
-{
- mBlockStack.push_back(TIntermSequence());
- {
- for (TIntermNode *child : *node->getSequence())
- {
- ASSERT(child != nullptr);
- child->traverse(this);
- mBlockStack.back().push_back(child);
- }
- }
- if (mBlockStack.back().size() > node->getSequence()->size())
- {
- node->getSequence()->clear();
- *(node->getSequence()) = mBlockStack.back();
- }
- mBlockStack.pop_back();
- return false;
-}
-
-void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
- bool scalarizeVector,
- bool scalarizeMatrix)
+void ScalarizeVecAndMatConstructorArgs::scalarizeArgs(
+ TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix)
{
ASSERT(aggregate);
int size = 0;
@@ -207,10 +179,12 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
ASSERT(size > 0);
TIntermTyped *node = original[ii]->getAsTyped();
ASSERT(node);
- createTempVariable(node);
+ TString varName = createTempVariable(node);
if (node->isScalar())
{
- sequence->push_back(createTempSymbol(node->getType()));
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
+ sequence->push_back(symbolNode);
size--;
}
else if (node->isVector())
@@ -221,7 +195,8 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
size -= repeat;
for (int index = 0; index < repeat; ++index)
{
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
TIntermBinary *newNode = ConstructVectorIndexBinaryNode(
symbolNode, index);
sequence->push_back(newNode);
@@ -229,7 +204,8 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
}
else
{
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
sequence->push_back(symbolNode);
size -= node->getNominalSize();
}
@@ -244,7 +220,8 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
size -= repeat;
while (repeat > 0)
{
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
TIntermBinary *newNode = ConstructMatrixIndexBinaryNode(
symbolNode, colIndex, rowIndex);
sequence->push_back(newNode);
@@ -259,7 +236,8 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
}
else
{
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
+ TIntermSymbol *symbolNode =
+ new TIntermSymbol(-1, varName, node->getType());
sequence->push_back(symbolNode);
size -= node->getCols() * node->getRows();
}
@@ -267,13 +245,29 @@ void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
}
}
-void ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
+TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *original)
{
- ASSERT(original);
- nextTemporaryIndex();
- TIntermDeclaration *decl = createTempInitDeclaration(original);
+ TString tempVarName = "_webgl_tmp_";
+ if (original->isScalar())
+ {
+ tempVarName += "scalar_";
+ }
+ else if (original->isVector())
+ {
+ tempVarName += "vec_";
+ }
+ else
+ {
+ ASSERT(original->isMatrix());
+ tempVarName += "mat_";
+ }
+ tempVarName += Str(mTempVarCount).c_str();
+ mTempVarCount++;
+ ASSERT(original);
TType type = original->getType();
+ type.setQualifier(EvqTemporary);
+
if (mShaderType == GL_FRAGMENT_SHADER &&
type.getBasicType() == EbtFloat &&
type.getPrecision() == EbpUndefined)
@@ -281,26 +275,21 @@ void ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
// 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.
- TIntermBinary *init = decl->getSequence()->at(0)->getAsBinaryNode();
- init->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
- init->getLeft()->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh
- : EbpMedium);
+ type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
}
- ASSERT(mBlockStack.size() > 0);
- TIntermSequence &sequence = mBlockStack.back();
- sequence.push_back(decl);
-}
+ TIntermBinary *init = new TIntermBinary(EOpInitialize);
+ TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type);
+ init->setLeft(symbolNode);
+ init->setRight(original);
+ init->setType(type);
-} // namespace anonymous
+ TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration);
+ decl->getSequence()->push_back(init);
-void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root,
- sh::GLenum shaderType,
- bool fragmentPrecisionHigh,
- unsigned int *temporaryIndex)
-{
- ScalarizeArgsTraverser scalarizer(shaderType, fragmentPrecisionHigh, temporaryIndex);
- root->traverse(&scalarizer);
-}
+ ASSERT(mSequenceStack.size() > 0);
+ TIntermSequence &sequence = mSequenceStack.back();
+ sequence.push_back(decl);
-} // namespace sh
+ return tempVarName;
+}
diff --git a/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h b/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
index 14bbbe13e..d7553be23 100755
--- a/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
+++ b/gfx/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
@@ -3,24 +3,46 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// Scalarize vector and matrix constructor args, so that vectors built from components don't have
-// matrix arguments, and matrices built from components don't have vector arguments. This avoids
-// driver bugs around vector and matrix constructors.
-//
#ifndef COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
#define COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
-#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/IntermNode.h"
-namespace sh
+class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser
{
-class TIntermBlock;
+ public:
+ ScalarizeVecAndMatConstructorArgs(sh::GLenum shaderType,
+ bool fragmentPrecisionHigh)
+ : TIntermTraverser(true, false, false),
+ mTempVarCount(0),
+ mShaderType(shaderType),
+ mFragmentPrecisionHigh(fragmentPrecisionHigh) {}
+
+ protected:
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ private:
+ void scalarizeArgs(TIntermAggregate *aggregate,
+ bool scalarizeVector, bool scalarizeMatrix);
+
+ // If we have the following code:
+ // mat4 m(0);
+ // vec4 v(1, m);
+ // We will rewrite to:
+ // mat4 m(0);
+ // mat4 _webgl_tmp_mat_0 = m;
+ // vec4 v(1, _webgl_tmp_mat_0[0][0], _webgl_tmp_mat_0[0][1], _webgl_tmp_mat_0[0][2]);
+ // This function is to create nodes for "mat4 _webgl_tmp_mat_0 = m;" and insert it to
+ // the code sequence.
+ // Return the temporary variable name.
+ TString createTempVariable(TIntermTyped *original);
+
+ std::vector<TIntermSequence> mSequenceStack;
+ int mTempVarCount;
-void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root,
- sh::GLenum shaderType,
- bool fragmentPrecisionHigh,
- unsigned int *temporaryIndex);
-} // namespace sh
+ sh::GLenum mShaderType;
+ bool mFragmentPrecisionHigh;
+};
#endif // COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
diff --git a/gfx/angle/src/compiler/translator/SeparateArrayInitialization.cpp b/gfx/angle/src/compiler/translator/SeparateArrayInitialization.cpp
index 98e010a56..de9050cd8 100755
--- a/gfx/angle/src/compiler/translator/SeparateArrayInitialization.cpp
+++ b/gfx/angle/src/compiler/translator/SeparateArrayInitialization.cpp
@@ -20,9 +20,6 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/OutputHLSL.h"
-namespace sh
-{
-
namespace
{
@@ -32,7 +29,7 @@ class SeparateArrayInitTraverser : private TIntermTraverser
static void apply(TIntermNode *root);
private:
SeparateArrayInitTraverser();
- bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *node) override;
};
void SeparateArrayInitTraverser::apply(TIntermNode *root)
@@ -47,38 +44,44 @@ SeparateArrayInitTraverser::SeparateArrayInitTraverser()
{
}
-bool SeparateArrayInitTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node)
{
- TIntermSequence *sequence = node->getSequence();
- TIntermBinary *initNode = sequence->back()->getAsBinaryNode();
- if (initNode != nullptr && initNode->getOp() == EOpInitialize)
+ if (node->getOp() == EOpDeclaration)
{
- TIntermTyped *initializer = initNode->getRight();
- if (initializer->isArray() && !sh::OutputHLSL::canWriteAsHLSLLiteral(initializer))
+ TIntermSequence *sequence = node->getSequence();
+ TIntermBinary *initNode = sequence->back()->getAsBinaryNode();
+ if (initNode != nullptr && initNode->getOp() == EOpInitialize)
{
- // We rely on that array declarations have been isolated to single declarations.
- ASSERT(sequence->size() == 1);
- TIntermTyped *symbol = initNode->getLeft();
- TIntermBlock *parentBlock = getParentNode()->getAsBlock();
- ASSERT(parentBlock != nullptr);
+ TIntermTyped *initializer = initNode->getRight();
+ if (initializer->isArray() && !sh::OutputHLSL::canWriteAsHLSLLiteral(initializer))
+ {
+ // We rely on that array declarations have been isolated to single declarations.
+ ASSERT(sequence->size() == 1);
+ TIntermTyped *symbol = initNode->getLeft();
+ TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
+ ASSERT(parentAgg != nullptr);
- TIntermSequence replacements;
+ TIntermSequence replacements;
- TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
- replacementDeclaration->appendDeclarator(symbol);
- replacementDeclaration->setLine(symbol->getLine());
- replacements.push_back(replacementDeclaration);
+ TIntermAggregate *replacementDeclaration = new TIntermAggregate;
+ replacementDeclaration->setOp(EOpDeclaration);
+ replacementDeclaration->getSequence()->push_back(symbol);
+ replacementDeclaration->setLine(symbol->getLine());
+ replacements.push_back(replacementDeclaration);
- TIntermBinary *replacementAssignment =
- new TIntermBinary(EOpAssign, symbol, initializer);
- replacementAssignment->setLine(symbol->getLine());
- replacements.push_back(replacementAssignment);
+ TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign);
+ replacementAssignment->setLeft(symbol);
+ replacementAssignment->setRight(initializer);
+ replacementAssignment->setType(initializer->getType());
+ replacementAssignment->setLine(symbol->getLine());
+ replacements.push_back(replacementAssignment);
- mMultiReplacements.push_back(
- NodeReplaceWithMultipleEntry(parentBlock, node, replacements));
+ mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements));
+ }
}
+ return false;
}
- return false;
+ return true;
}
} // namespace
@@ -87,5 +90,3 @@ void SeparateArrayInitialization(TIntermNode *root)
{
SeparateArrayInitTraverser::apply(root);
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/SeparateArrayInitialization.h b/gfx/angle/src/compiler/translator/SeparateArrayInitialization.h
index 038d38a61..d16357a3a 100755
--- a/gfx/angle/src/compiler/translator/SeparateArrayInitialization.h
+++ b/gfx/angle/src/compiler/translator/SeparateArrayInitialization.h
@@ -18,11 +18,8 @@
#ifndef COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_
#define COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_
-namespace sh
-{
class TIntermNode;
void SeparateArrayInitialization(TIntermNode *root);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_
diff --git a/gfx/angle/src/compiler/translator/SeparateDeclarations.cpp b/gfx/angle/src/compiler/translator/SeparateDeclarations.cpp
index 4d3835370..d33747f85 100755
--- a/gfx/angle/src/compiler/translator/SeparateDeclarations.cpp
+++ b/gfx/angle/src/compiler/translator/SeparateDeclarations.cpp
@@ -17,9 +17,6 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
namespace
{
@@ -29,7 +26,7 @@ class SeparateDeclarationsTraverser : private TIntermTraverser
static void apply(TIntermNode *root);
private:
SeparateDeclarationsTraverser();
- bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *node) override;
};
void SeparateDeclarationsTraverser::apply(TIntermNode *root)
@@ -44,28 +41,32 @@ SeparateDeclarationsTraverser::SeparateDeclarationsTraverser()
{
}
-bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+bool SeparateDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node)
{
- TIntermSequence *sequence = node->getSequence();
- if (sequence->size() > 1)
+ if (node->getOp() == EOpDeclaration)
{
- TIntermBlock *parentBlock = getParentNode()->getAsBlock();
- ASSERT(parentBlock != nullptr);
-
- TIntermSequence replacementDeclarations;
- for (size_t ii = 0; ii < sequence->size(); ++ii)
+ TIntermSequence *sequence = node->getSequence();
+ if (sequence->size() > 1)
{
- TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
+ TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
+ ASSERT(parentAgg != nullptr);
- replacementDeclaration->appendDeclarator(sequence->at(ii)->getAsTyped());
- replacementDeclaration->setLine(sequence->at(ii)->getLine());
- replacementDeclarations.push_back(replacementDeclaration);
- }
+ TIntermSequence replacementDeclarations;
+ for (size_t ii = 0; ii < sequence->size(); ++ii)
+ {
+ TIntermAggregate *replacementDeclaration = new TIntermAggregate;
- mMultiReplacements.push_back(
- NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations));
+ replacementDeclaration->setOp(EOpDeclaration);
+ replacementDeclaration->getSequence()->push_back(sequence->at(ii));
+ replacementDeclaration->setLine(sequence->at(ii)->getLine());
+ replacementDeclarations.push_back(replacementDeclaration);
+ }
+
+ mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacementDeclarations));
+ }
+ return false;
}
- return false;
+ return true;
}
} // namespace
@@ -74,5 +75,3 @@ void SeparateDeclarations(TIntermNode *root)
{
SeparateDeclarationsTraverser::apply(root);
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/SeparateDeclarations.h b/gfx/angle/src/compiler/translator/SeparateDeclarations.h
index 2c2611a49..77913ab8b 100755
--- a/gfx/angle/src/compiler/translator/SeparateDeclarations.h
+++ b/gfx/angle/src/compiler/translator/SeparateDeclarations.h
@@ -16,11 +16,8 @@
#ifndef COMPILER_TRANSLATOR_SEPARATEDECLARATIONS_H_
#define COMPILER_TRANSLATOR_SEPARATEDECLARATIONS_H_
-namespace sh
-{
class TIntermNode;
void SeparateDeclarations(TIntermNode *root);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_SEPARATEDECLARATIONS_H_
diff --git a/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp b/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
index 0f7c404d3..4041be971 100755
--- a/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
+++ b/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
@@ -14,9 +14,6 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNodePatternMatcher.h"
-namespace sh
-{
-
namespace
{
@@ -52,7 +49,11 @@ SeparateExpressionsTraverser::SeparateExpressionsTraverser()
// and also needs to be replaced in its original location by a different node.
TIntermBinary *CopyAssignmentNode(TIntermBinary *node)
{
- return new TIntermBinary(node->getOp(), node->getLeft(), node->getRight());
+ TIntermBinary *copyNode = new TIntermBinary(node->getOp());
+ copyNode->setLeft(node->getLeft());
+ copyNode->setRight(node->getRight());
+ copyNode->setType(node->getType());
+ return copyNode;
}
// Performs a shallow copy of a constructor/function call node.
@@ -62,11 +63,12 @@ TIntermAggregate *CopyAggregateNode(TIntermAggregate *node)
TIntermSequence *copySeq = copyNode->getSequence();
copySeq->insert(copySeq->begin(), node->getSequence()->begin(), node->getSequence()->end());
copyNode->setType(node->getType());
- *copyNode->getFunctionSymbolInfo() = *node->getFunctionSymbolInfo();
+ copyNode->setFunctionId(node->getFunctionId());
if (node->isUserDefined())
{
copyNode->setUserDefined();
}
+ copyNode->setNameObj(node->getNameObj());
return copyNode;
}
@@ -140,5 +142,3 @@ void SeparateExpressionsReturningArrays(TIntermNode *root, unsigned int *tempora
}
while (traverser.foundArrayExpression());
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.h b/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.h
index d0c73dc18..b178ebb3e 100755
--- a/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.h
+++ b/gfx/angle/src/compiler/translator/SeparateExpressionsReturningArrays.h
@@ -12,11 +12,8 @@
#ifndef COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
#define COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
-namespace sh
-{
class TIntermNode;
void SeparateExpressionsReturningArrays(TIntermNode *root, unsigned int *temporaryIndex);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
diff --git a/gfx/angle/src/compiler/translator/ShaderLang.cpp b/gfx/angle/src/compiler/translator/ShaderLang.cpp
index b776ca50b..429bbf2e4 100755
--- a/gfx/angle/src/compiler/translator/ShaderLang.cpp
+++ b/gfx/angle/src/compiler/translator/ShaderLang.cpp
@@ -20,8 +20,6 @@
#include "compiler/translator/VariablePacker.h"
#include "angle_gl.h"
-using namespace sh;
-
namespace
{
@@ -36,31 +34,31 @@ template <typename VarT>
const std::vector<VarT> *GetVariableList(const TCompiler *compiler);
template <>
-const std::vector<Uniform> *GetVariableList(const TCompiler *compiler)
+const std::vector<sh::Uniform> *GetVariableList(const TCompiler *compiler)
{
return &compiler->getUniforms();
}
template <>
-const std::vector<Varying> *GetVariableList(const TCompiler *compiler)
+const std::vector<sh::Varying> *GetVariableList(const TCompiler *compiler)
{
return &compiler->getVaryings();
}
template <>
-const std::vector<Attribute> *GetVariableList(const TCompiler *compiler)
+const std::vector<sh::Attribute> *GetVariableList(const TCompiler *compiler)
{
return &compiler->getAttributes();
}
template <>
-const std::vector<OutputVariable> *GetVariableList(const TCompiler *compiler)
+const std::vector<sh::OutputVariable> *GetVariableList(const TCompiler *compiler)
{
return &compiler->getOutputVariables();
}
template <>
-const std::vector<InterfaceBlock> *GetVariableList(const TCompiler *compiler)
+const std::vector<sh::InterfaceBlock> *GetVariableList(const TCompiler *compiler)
{
return &compiler->getInterfaceBlocks();
}
@@ -237,9 +235,8 @@ ShHandle ShConstructCompiler(sh::GLenum type, ShShaderSpec spec,
}
// Generate built-in symbol table.
- if (!compiler->Init(*resources))
- {
- sh::Destruct(base);
+ if (!compiler->Init(*resources)) {
+ ShDestruct(base);
return 0;
}
@@ -271,10 +268,11 @@ const std::string &ShGetBuiltInResourcesString(const ShHandle handle)
// Return: The return value of ShCompile is really boolean, indicating
// success or failure.
//
-bool ShCompile(const ShHandle handle,
- const char *const shaderStrings[],
- size_t numStrings,
- ShCompileOptions compileOptions)
+bool ShCompile(
+ const ShHandle handle,
+ const char *const shaderStrings[],
+ size_t numStrings,
+ int compileOptions)
{
TCompiler *compiler = GetCompilerFromHandle(handle);
ASSERT(compiler);
@@ -335,32 +333,32 @@ const std::map<std::string, std::string> *ShGetNameHashingMap(
return &(compiler->getNameMap());
}
-const std::vector<Uniform> *ShGetUniforms(const ShHandle handle)
+const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
{
- return GetShaderVariables<Uniform>(handle);
+ return GetShaderVariables<sh::Uniform>(handle);
}
-const std::vector<Varying> *ShGetVaryings(const ShHandle handle)
+const std::vector<sh::Varying> *ShGetVaryings(const ShHandle handle)
{
- return GetShaderVariables<Varying>(handle);
+ return GetShaderVariables<sh::Varying>(handle);
}
-const std::vector<Attribute> *ShGetAttributes(const ShHandle handle)
+const std::vector<sh::Attribute> *ShGetAttributes(const ShHandle handle)
{
- return GetShaderVariables<Attribute>(handle);
+ return GetShaderVariables<sh::Attribute>(handle);
}
-const std::vector<OutputVariable> *ShGetOutputVariables(const ShHandle handle)
+const std::vector<sh::OutputVariable> *ShGetOutputVariables(const ShHandle handle)
{
- return GetShaderVariables<OutputVariable>(handle);
+ return GetShaderVariables<sh::OutputVariable>(handle);
}
-const std::vector<InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle)
+const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handle)
{
- return GetShaderVariables<InterfaceBlock>(handle);
+ return GetShaderVariables<sh::InterfaceBlock>(handle);
}
-WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle)
+sh::WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle)
{
ASSERT(handle);
@@ -372,7 +370,7 @@ WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle)
}
bool ShCheckVariablesWithinPackingLimits(int maxVectors,
- const std::vector<ShaderVariable> &variables)
+ const std::vector<sh::ShaderVariable> &variables)
{
VariablePacker packer;
return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
@@ -408,126 +406,7 @@ const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(const ShHandl
return translator->getUniformRegisterMap();
#else
- return nullptr;
+ static std::map<std::string, unsigned int> map;
+ return &map;
#endif // ANGLE_ENABLE_HLSL
}
-
-namespace sh
-{
-bool Initialize()
-{
- return ShInitialize();
-}
-
-bool Finalize()
-{
- return ShFinalize();
-}
-
-void InitBuiltInResources(ShBuiltInResources *resources)
-{
- ShInitBuiltInResources(resources);
-}
-
-const std::string &GetBuiltInResourcesString(const ShHandle handle)
-{
- return ShGetBuiltInResourcesString(handle);
-}
-
-ShHandle ConstructCompiler(sh::GLenum type,
- ShShaderSpec spec,
- ShShaderOutput output,
- const ShBuiltInResources *resources)
-{
- return ShConstructCompiler(type, spec, output, resources);
-}
-
-void Destruct(ShHandle handle)
-{
- return ShDestruct(handle);
-}
-
-bool Compile(const ShHandle handle,
- const char *const shaderStrings[],
- size_t numStrings,
- ShCompileOptions compileOptions)
-{
- return ShCompile(handle, shaderStrings, numStrings, compileOptions);
-}
-
-void ClearResults(const ShHandle handle)
-{
- return ShClearResults(handle);
-}
-
-int GetShaderVersion(const ShHandle handle)
-{
- return ShGetShaderVersion(handle);
-}
-
-ShShaderOutput GetShaderOutputType(const ShHandle handle)
-{
- return ShGetShaderOutputType(handle);
-}
-
-const std::string &GetInfoLog(const ShHandle handle)
-{
- return ShGetInfoLog(handle);
-}
-
-const std::string &GetObjectCode(const ShHandle handle)
-{
- return ShGetObjectCode(handle);
-}
-
-const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle)
-{
- return ShGetNameHashingMap(handle);
-}
-
-const std::vector<sh::Uniform> *GetUniforms(const ShHandle handle)
-{
- return ShGetUniforms(handle);
-}
-const std::vector<sh::Varying> *GetVaryings(const ShHandle handle)
-{
- return ShGetVaryings(handle);
-}
-const std::vector<sh::Attribute> *GetAttributes(const ShHandle handle)
-{
- return ShGetAttributes(handle);
-}
-
-const std::vector<sh::OutputVariable> *GetOutputVariables(const ShHandle handle)
-{
- return ShGetOutputVariables(handle);
-}
-const std::vector<sh::InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle)
-{
- return ShGetInterfaceBlocks(handle);
-}
-
-sh::WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle)
-{
- return ShGetComputeShaderLocalGroupSize(handle);
-}
-
-bool CheckVariablesWithinPackingLimits(int maxVectors,
- const std::vector<sh::ShaderVariable> &variables)
-{
- return ShCheckVariablesWithinPackingLimits(maxVectors, variables);
-}
-
-bool GetInterfaceBlockRegister(const ShHandle handle,
- const std::string &interfaceBlockName,
- unsigned int *indexOut)
-{
- return ShGetInterfaceBlockRegister(handle, interfaceBlockName, indexOut);
-}
-
-const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle)
-{
- return ShGetUniformRegisterMap(handle);
-}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/SimplifyLoopConditions.cpp b/gfx/angle/src/compiler/translator/SimplifyLoopConditions.cpp
index 85c166e59..61a68fc93 100755
--- a/gfx/angle/src/compiler/translator/SimplifyLoopConditions.cpp
+++ b/gfx/angle/src/compiler/translator/SimplifyLoopConditions.cpp
@@ -13,9 +13,6 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNodePatternMatcher.h"
-namespace sh
-{
-
namespace
{
@@ -39,7 +36,7 @@ class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser
bool visitBinary(Visit visit, TIntermBinary *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
- bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitSelection(Visit visit, TIntermSelection *node) override;
void nextIteration();
bool foundLoopToChange() const { return mFoundLoopToChange; }
@@ -97,20 +94,20 @@ bool SimplifyLoopConditionsTraverser::visitAggregate(Visit visit, TIntermAggrega
// If we're outside a loop condition, we only need to traverse nodes that may contain loops.
if (!mInsideLoopConditionOrExpression)
- return false;
+ return (node->getOp() == EOpSequence || node->getOp() == EOpFunction);
mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode());
return !mFoundLoopToChange;
}
-bool SimplifyLoopConditionsTraverser::visitTernary(Visit visit, TIntermTernary *node)
+bool SimplifyLoopConditionsTraverser::visitSelection(Visit visit, TIntermSelection *node)
{
if (mFoundLoopToChange)
return false;
// Don't traverse ternary operators outside loop conditions.
if (!mInsideLoopConditionOrExpression)
- return false;
+ return !node->usesTernaryOperator();
mFoundLoopToChange = mConditionsToSimplify.match(node);
return !mFoundLoopToChange;
@@ -148,9 +145,10 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
tempInitSeq.push_back(createTempInitDeclaration(node->getCondition()->deepCopy()));
insertStatementsInParentBlock(tempInitSeq);
- TIntermBlock *newBody = new TIntermBlock();
+ TIntermAggregate *newBody = new TIntermAggregate(EOpSequence);
if (node->getBody())
{
+ ASSERT(node->getBody()->getOp() == EOpSequence);
newBody->getSequence()->push_back(node->getBody());
}
newBody->getSequence()->push_back(
@@ -178,9 +176,10 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
tempInitSeq.push_back(createTempInitDeclaration(CreateBoolConstantNode(true)));
insertStatementsInParentBlock(tempInitSeq);
- TIntermBlock *newBody = new TIntermBlock();
+ TIntermAggregate *newBody = new TIntermAggregate(EOpSequence);
if (node->getBody())
{
+ ASSERT(node->getBody()->getOp() == EOpSequence);
newBody->getSequence()->push_back(node->getBody());
}
newBody->getSequence()->push_back(
@@ -203,7 +202,7 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
// bool s0 = expr;
// while (s0) { { body; } exprB; s0 = expr; }
// }
- TIntermBlock *loopScope = new TIntermBlock();
+ TIntermAggregate *loopScope = new TIntermAggregate(EOpSequence);
if (node->getInit())
{
loopScope->getSequence()->push_back(node->getInit());
@@ -211,15 +210,12 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
loopScope->getSequence()->push_back(
createTempInitDeclaration(node->getCondition()->deepCopy()));
- TIntermBlock *whileLoopBody = new TIntermBlock();
+ TIntermAggregate *whileLoopBody = new TIntermAggregate(EOpSequence);
if (node->getBody())
{
whileLoopBody->getSequence()->push_back(node->getBody());
}
- if (node->getExpression())
- {
- whileLoopBody->getSequence()->push_back(node->getExpression());
- }
+ whileLoopBody->getSequence()->push_back(node->getExpression());
whileLoopBody->getSequence()->push_back(
createTempAssignment(node->getCondition()->deepCopy()));
TIntermLoop *whileLoop = new TIntermLoop(
@@ -246,8 +242,8 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
// for (init; expr; ) { { body; } exprB; }
TIntermTyped *loopExpression = node->getExpression();
node->setExpression(nullptr);
- TIntermBlock *oldBody = node->getBody();
- node->setBody(new TIntermBlock());
+ TIntermAggregate *oldBody = node->getBody();
+ node->setBody(new TIntermAggregate(EOpSequence));
if (oldBody != nullptr)
{
node->getBody()->getSequence()->push_back(oldBody);
@@ -284,5 +280,3 @@ void SimplifyLoopConditions(TIntermNode *root,
traverser.updateTree();
} while (traverser.foundLoopToChange());
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/SimplifyLoopConditions.h b/gfx/angle/src/compiler/translator/SimplifyLoopConditions.h
index 968089d54..b8802aa11 100755
--- a/gfx/angle/src/compiler/translator/SimplifyLoopConditions.h
+++ b/gfx/angle/src/compiler/translator/SimplifyLoopConditions.h
@@ -11,8 +11,6 @@
#ifndef COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_
#define COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_
-namespace sh
-{
class TIntermNode;
class TSymbolTable;
@@ -21,6 +19,5 @@ void SimplifyLoopConditions(TIntermNode *root,
unsigned int *temporaryIndex,
const TSymbolTable &symbolTable,
int shaderVersion);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_
diff --git a/gfx/angle/src/compiler/translator/SplitSequenceOperator.cpp b/gfx/angle/src/compiler/translator/SplitSequenceOperator.cpp
index 4c63b59f7..45fc8dc9b 100755
--- a/gfx/angle/src/compiler/translator/SplitSequenceOperator.cpp
+++ b/gfx/angle/src/compiler/translator/SplitSequenceOperator.cpp
@@ -14,9 +14,6 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNodePatternMatcher.h"
-namespace sh
-{
-
namespace
{
@@ -29,7 +26,7 @@ class SplitSequenceOperatorTraverser : public TLValueTrackingTraverser
bool visitBinary(Visit visit, TIntermBinary *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
- bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitSelection(Visit visit, TIntermSelection *node) override;
void nextIteration();
bool foundExpressionToSplit() const { return mFoundExpressionToSplit; }
@@ -60,7 +57,7 @@ void SplitSequenceOperatorTraverser::nextIteration()
nextTemporaryIndex();
}
-bool SplitSequenceOperatorTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+bool SplitSequenceOperatorTraverser::visitBinary(Visit visit, TIntermBinary *node)
{
if (mFoundExpressionToSplit)
return false;
@@ -68,14 +65,15 @@ bool SplitSequenceOperatorTraverser::visitAggregate(Visit visit, TIntermAggregat
if (mInsideSequenceOperator > 0 && visit == PreVisit)
{
// Detect expressions that need to be simplified
- mFoundExpressionToSplit = mPatternToSplitMatcher.match(node, getParentNode());
+ mFoundExpressionToSplit =
+ mPatternToSplitMatcher.match(node, getParentNode(), isLValueRequiredHere());
return !mFoundExpressionToSplit;
}
return true;
}
-bool SplitSequenceOperatorTraverser::visitBinary(Visit visit, TIntermBinary *node)
+bool SplitSequenceOperatorTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (node->getOp() == EOpComma)
{
@@ -93,12 +91,19 @@ bool SplitSequenceOperatorTraverser::visitBinary(Visit visit, TIntermBinary *nod
// execution order.
if (mFoundExpressionToSplit && mInsideSequenceOperator == 1)
{
- // Move the left side operand into a separate statement in the parent block.
+ // Move all operands of the sequence operation except the last one into separate
+ // statements in the parent block.
TIntermSequence insertions;
- insertions.push_back(node->getLeft());
+ for (auto *sequenceChild : *node->getSequence())
+ {
+ if (sequenceChild != node->getSequence()->back())
+ {
+ insertions.push_back(sequenceChild);
+ }
+ }
insertStatementsInParentBlock(insertions);
- // Replace the comma node with its right side operand.
- queueReplacement(node, node->getRight(), OriginalNode::IS_DROPPED);
+ // Replace the sequence with its last operand
+ queueReplacement(node, node->getSequence()->back(), OriginalNode::IS_DROPPED);
}
mInsideSequenceOperator--;
}
@@ -111,15 +116,14 @@ bool SplitSequenceOperatorTraverser::visitBinary(Visit visit, TIntermBinary *nod
if (mInsideSequenceOperator > 0 && visit == PreVisit)
{
// Detect expressions that need to be simplified
- mFoundExpressionToSplit =
- mPatternToSplitMatcher.match(node, getParentNode(), isLValueRequiredHere());
+ mFoundExpressionToSplit = mPatternToSplitMatcher.match(node, getParentNode());
return !mFoundExpressionToSplit;
}
return true;
}
-bool SplitSequenceOperatorTraverser::visitTernary(Visit visit, TIntermTernary *node)
+bool SplitSequenceOperatorTraverser::visitSelection(Visit visit, TIntermSelection *node)
{
if (mFoundExpressionToSplit)
return false;
@@ -154,5 +158,3 @@ void SplitSequenceOperator(TIntermNode *root,
traverser.updateTree();
} while (traverser.foundExpressionToSplit());
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/SplitSequenceOperator.h b/gfx/angle/src/compiler/translator/SplitSequenceOperator.h
index 6df9d458e..4a46fe36c 100755
--- a/gfx/angle/src/compiler/translator/SplitSequenceOperator.h
+++ b/gfx/angle/src/compiler/translator/SplitSequenceOperator.h
@@ -12,9 +12,6 @@
#ifndef COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_
#define COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_
-namespace sh
-{
-
class TIntermNode;
class TSymbolTable;
@@ -24,6 +21,4 @@ void SplitSequenceOperator(TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion);
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_
diff --git a/gfx/angle/src/compiler/translator/SymbolTable.cpp b/gfx/angle/src/compiler/translator/SymbolTable.cpp
index 188f810e3..059c5c76a 100755
--- a/gfx/angle/src/compiler/translator/SymbolTable.cpp
+++ b/gfx/angle/src/compiler/translator/SymbolTable.cpp
@@ -19,38 +19,15 @@
#include <stdio.h>
#include <algorithm>
-namespace sh
-{
-
int TSymbolTable::uniqueIdCounter = 0;
-TSymbol::TSymbol(const TString *n) : uniqueId(TSymbolTable::nextUniqueId()), name(n)
-{
-}
-
//
// Functions have buried pointers to delete.
//
TFunction::~TFunction()
{
- clearParameters();
-}
-
-void TFunction::clearParameters()
-{
for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
delete (*i).type;
- parameters.clear();
- mangledName = nullptr;
-}
-
-void TFunction::swapParameters(const TFunction &parametersSource)
-{
- clearParameters();
- for (auto parameter : parametersSource.parameters)
- {
- addParameter(parameter);
- }
}
const TString *TFunction::buildMangledName() const
@@ -76,6 +53,8 @@ TSymbolTableLevel::~TSymbolTableLevel()
bool TSymbolTableLevel::insert(TSymbol *symbol)
{
+ symbol->setUniqueId(TSymbolTable::nextUniqueId());
+
// returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
@@ -84,6 +63,8 @@ bool TSymbolTableLevel::insert(TSymbol *symbol)
bool TSymbolTableLevel::insertUnmangled(TFunction *function)
{
+ function->setUniqueId(TSymbolTable::nextUniqueId());
+
// returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(function->getName(), function));
@@ -126,12 +107,6 @@ TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
return symbol;
}
-TSymbol *TSymbolTable::findGlobal(const TString &name) const
-{
- ASSERT(table.size() > GLOBAL_LEVEL);
- return table[GLOBAL_LEVEL]->find(name);
-}
-
TSymbol *TSymbolTable::findBuiltIn(
const TString &name, int shaderVersion) const
{
@@ -258,43 +233,6 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e
insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
}
- else if (IsGImage(ptype1->getBasicType()))
- {
- insertUnmangledBuiltIn(name);
-
- const TType *floatType = TCache::getType(EbtFloat, 4);
- const TType *intType = TCache::getType(EbtInt, 4);
- const TType *unsignedType = TCache::getType(EbtUInt, 4);
-
- const TType *floatImage =
- TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
- const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
- const TType *unsignedImage =
- TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
-
- // GLSL ES 3.10, Revision 4, 8.12 Image Functions
- if (rvalue->getBasicType() == EbtGVec4)
- {
- // imageLoad
- insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
- }
- else if (rvalue->getBasicType() == EbtVoid)
- {
- // imageStore
- insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
- insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
- insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
- }
- else
- {
- // imageSize
- insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
- }
- }
else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
{
ASSERT(!ptype4 && !ptype5);
@@ -367,5 +305,3 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
}
return prec;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/SymbolTable.h b/gfx/angle/src/compiler/translator/SymbolTable.h
index 7c4d3aab3..60e0b9929 100755
--- a/gfx/angle/src/compiler/translator/SymbolTable.h
+++ b/gfx/angle/src/compiler/translator/SymbolTable.h
@@ -38,16 +38,16 @@
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
// Symbol base class. (Can build functions or variables out of these...)
class TSymbol : angle::NonCopyable
{
public:
POOL_ALLOCATOR_NEW_DELETE();
- TSymbol(const TString *n);
-
+ TSymbol(const TString *n)
+ : uniqueId(0),
+ name(n)
+ {
+ }
virtual ~TSymbol()
{
// don't delete name, it's from the pool
@@ -69,6 +69,10 @@ class TSymbol : angle::NonCopyable
{
return false;
}
+ void setUniqueId(int id)
+ {
+ uniqueId = id;
+ }
int getUniqueId() const
{
return uniqueId;
@@ -83,7 +87,7 @@ class TSymbol : angle::NonCopyable
}
private:
- const int uniqueId;
+ int uniqueId; // For real comparing during code generation
const TString *name;
TString extension;
};
@@ -225,8 +229,6 @@ class TFunction : public TSymbol
mangledName = nullptr;
}
- void swapParameters(const TFunction &parametersSource);
-
const TString &getMangledName() const override
{
if (mangledName == nullptr)
@@ -260,8 +262,6 @@ class TFunction : public TSymbol
}
private:
- void clearParameters();
-
const TString *buildMangledName() const;
typedef TVector<TConstParameter> TParamList;
@@ -459,11 +459,8 @@ class TSymbolTable : angle::NonCopyable
TSymbol *find(const TString &name, int shaderVersion,
bool *builtIn = NULL, bool *sameScope = NULL) const;
-
- TSymbol *findGlobal(const TString &name) const;
-
TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;
-
+
TSymbolTableLevel *getOuterLevel()
{
assert(currentLevel() >= 1);
@@ -474,15 +471,15 @@ class TSymbolTable : angle::NonCopyable
bool setDefaultPrecision(const TPublicType &type, TPrecision prec)
{
- if (!SupportsPrecision(type.getBasicType()))
+ if (!SupportsPrecision(type.type))
return false;
- if (type.getBasicType() == EbtUInt)
+ if (type.type == EbtUInt)
return false; // ESSL 3.00.4 section 4.5.4
if (type.isAggregate())
return false; // Not allowed to set for aggregate types
int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
// Uses map operator [], overwrites the current value
- (*precisionStack[indexOfLastElement])[type.getBasicType()] = prec;
+ (*precisionStack[indexOfLastElement])[type.type] = prec;
return true;
}
@@ -544,6 +541,4 @@ class TSymbolTable : angle::NonCopyable
static int uniqueIdCounter;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_
diff --git a/gfx/angle/src/compiler/translator/TextureFunctionHLSL.cpp b/gfx/angle/src/compiler/translator/TextureFunctionHLSL.cpp
index 33d098531..6580f258d 100755
--- a/gfx/angle/src/compiler/translator/TextureFunctionHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/TextureFunctionHLSL.cpp
@@ -393,22 +393,41 @@ void OutputTextureFunctionArgumentList(TInfoSinkBase &out,
{
switch (textureFunction.sampler)
{
+ case EbtSampler2D:
+ out << ", int2 offset";
+ break;
case EbtSampler3D:
- case EbtISampler3D:
- case EbtUSampler3D:
out << ", int3 offset";
break;
- case EbtSampler2D:
case EbtSampler2DArray:
+ out << ", int2 offset";
+ break;
case EbtISampler2D:
+ out << ", int2 offset";
+ break;
+ case EbtISampler3D:
+ out << ", int3 offset";
+ break;
case EbtISampler2DArray:
+ out << ", int2 offset";
+ break;
case EbtUSampler2D:
+ out << ", int2 offset";
+ break;
+ case EbtUSampler3D:
+ out << ", int3 offset";
+ break;
case EbtUSampler2DArray:
+ out << ", int2 offset";
+ break;
case EbtSampler2DShadow:
+ out << ", int2 offset";
+ break;
case EbtSampler2DArrayShadow:
- case EbtSamplerExternalOES:
out << ", int2 offset";
break;
+ case EbtSamplerExternalOES:
+ out << ", int2 offset";
default:
UNREACHABLE();
}
@@ -1094,8 +1113,32 @@ const char *TextureFunctionHLSL::TextureFunction::getReturnType() const
bool TextureFunctionHLSL::TextureFunction::operator<(const TextureFunction &rhs) const
{
- return std::tie(sampler, coords, proj, offset, method) <
- std::tie(rhs.sampler, rhs.coords, rhs.proj, rhs.offset, rhs.method);
+ if (sampler < rhs.sampler)
+ return true;
+ if (sampler > rhs.sampler)
+ return false;
+
+ if (coords < rhs.coords)
+ return true;
+ if (coords > rhs.coords)
+ return false;
+
+ if (!proj && rhs.proj)
+ return true;
+ if (proj && !rhs.proj)
+ return false;
+
+ if (!offset && rhs.offset)
+ return true;
+ if (offset && !rhs.offset)
+ return false;
+
+ if (method < rhs.method)
+ return true;
+ if (method > rhs.method)
+ return false;
+
+ return false;
}
TString TextureFunctionHLSL::useTextureFunction(const TString &name,
diff --git a/gfx/angle/src/compiler/translator/TranslatorESSL.cpp b/gfx/angle/src/compiler/translator/TranslatorESSL.cpp
index 43bce74cc..fef176857 100755
--- a/gfx/angle/src/compiler/translator/TranslatorESSL.cpp
+++ b/gfx/angle/src/compiler/translator/TranslatorESSL.cpp
@@ -6,20 +6,26 @@
#include "compiler/translator/TranslatorESSL.h"
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
#include "compiler/translator/EmulatePrecision.h"
#include "compiler/translator/RecordConstantPrecision.h"
#include "compiler/translator/OutputESSL.h"
#include "angle_gl.h"
-namespace sh
-{
-
TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
: TCompiler(type, spec, SH_ESSL_OUTPUT)
{
}
-void TranslatorESSL::translate(TIntermNode *root, ShCompileOptions compileOptions)
+void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions)
+{
+ if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)
+ {
+ InitBuiltInFunctionEmulatorForGLSLWorkarounds(emu, getShaderType());
+ }
+}
+
+void TranslatorESSL::translate(TIntermNode *root, int compileOptions)
{
TInfoSinkBase& sink = getInfoSink().obj;
@@ -81,8 +87,7 @@ void TranslatorESSL::translate(TIntermNode *root, ShCompileOptions compileOption
// Write translated shader.
TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(),
- getSymbolTable(), getShaderType(), shaderVer, precisionEmulation,
- compileOptions);
+ getSymbolTable(), shaderVer, precisionEmulation);
root->traverse(&outputESSL);
}
@@ -111,5 +116,3 @@ void TranslatorESSL::writeExtensionBehavior() {
}
}
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/TranslatorESSL.h b/gfx/angle/src/compiler/translator/TranslatorESSL.h
index b7b46a65e..0fbc47de5 100755
--- a/gfx/angle/src/compiler/translator/TranslatorESSL.h
+++ b/gfx/angle/src/compiler/translator/TranslatorESSL.h
@@ -9,22 +9,19 @@
#include "compiler/translator/Compiler.h"
-namespace sh
-{
-
class TranslatorESSL : public TCompiler
{
public:
TranslatorESSL(sh::GLenum type, ShShaderSpec spec);
protected:
- void translate(TIntermNode *root, ShCompileOptions compileOptions) override;
+ void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override;
+
+ void translate(TIntermNode *root, int compileOptions) override;
bool shouldFlattenPragmaStdglInvariantAll() override;
private:
void writeExtensionBehavior();
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_TRANSLATORESSL_H_
diff --git a/gfx/angle/src/compiler/translator/TranslatorGLSL.cpp b/gfx/angle/src/compiler/translator/TranslatorGLSL.cpp
index 1d6582b02..0ee96f590 100755
--- a/gfx/angle/src/compiler/translator/TranslatorGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/TranslatorGLSL.cpp
@@ -11,36 +11,26 @@
#include "compiler/translator/EmulatePrecision.h"
#include "compiler/translator/ExtensionGLSL.h"
#include "compiler/translator/OutputGLSL.h"
-#include "compiler/translator/RewriteTexelFetchOffset.h"
#include "compiler/translator/VersionGLSL.h"
-namespace sh
-{
-
TranslatorGLSL::TranslatorGLSL(sh::GLenum type,
ShShaderSpec spec,
ShShaderOutput output)
: TCompiler(type, spec, output) {
}
-void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
- ShCompileOptions compileOptions)
+void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions)
{
- if (compileOptions & SH_EMULATE_ABS_INT_FUNCTION)
- {
- InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(emu, getShaderType());
- }
-
- if (compileOptions & SH_EMULATE_ISNAN_FLOAT_FUNCTION)
+ if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)
{
- InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(emu, getShaderVersion());
+ InitBuiltInFunctionEmulatorForGLSLWorkarounds(emu, getShaderType());
}
int targetGLSLVersion = ShaderOutputTypeToGLSLVersion(getOutputType());
InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion);
}
-void TranslatorGLSL::translate(TIntermNode *root, ShCompileOptions compileOptions)
+void TranslatorGLSL::translate(TIntermNode *root, int compileOptions)
{
TInfoSinkBase& sink = getInfoSink().obj;
@@ -60,7 +50,7 @@ void TranslatorGLSL::translate(TIntermNode *root, ShCompileOptions compileOption
// variables that are actually used, to avoid affecting the behavior of the shader.
if ((compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) && getPragma().stdgl.invariantAll)
{
- ASSERT(wereVariablesCollected());
+ collectVariables(root);
switch (getShaderType())
{
@@ -85,11 +75,6 @@ void TranslatorGLSL::translate(TIntermNode *root, ShCompileOptions compileOption
}
}
- if ((compileOptions & SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH) != 0)
- {
- sh::RewriteTexelFetchOffset(root, getSymbolTable(), getShaderVersion());
- }
-
bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision;
if (precisionEmulation)
@@ -188,9 +173,13 @@ void TranslatorGLSL::translate(TIntermNode *root, ShCompileOptions compileOption
}
// Write translated shader.
- TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(),
- getSymbolTable(), getShaderType(), getShaderVersion(), getOutputType(),
- compileOptions);
+ TOutputGLSL outputGLSL(sink,
+ getArrayIndexClampingStrategy(),
+ getHashFunction(),
+ getNameMap(),
+ getSymbolTable(),
+ getShaderVersion(),
+ getOutputType());
root->traverse(&outputGLSL);
}
@@ -201,12 +190,6 @@ bool TranslatorGLSL::shouldFlattenPragmaStdglInvariantAll()
return IsGLSL130OrNewer(getOutputType());
}
-bool TranslatorGLSL::shouldCollectVariables(ShCompileOptions compileOptions)
-{
- return (compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) ||
- TCompiler::shouldCollectVariables(compileOptions);
-}
-
void TranslatorGLSL::writeVersion(TIntermNode *root)
{
TVersionGLSL versionGLSL(getShaderType(), getPragma(), getOutputType());
@@ -294,5 +277,3 @@ void TranslatorGLSL::conditionallyOutputInvariantDeclaration(const char *builtin
sink << "invariant " << builtinVaryingName << ";\n";
}
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/TranslatorGLSL.h b/gfx/angle/src/compiler/translator/TranslatorGLSL.h
index d6f694824..91df58868 100755
--- a/gfx/angle/src/compiler/translator/TranslatorGLSL.h
+++ b/gfx/angle/src/compiler/translator/TranslatorGLSL.h
@@ -9,21 +9,16 @@
#include "compiler/translator/Compiler.h"
-namespace sh
-{
-
class TranslatorGLSL : public TCompiler
{
public:
TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
protected:
- void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
- ShCompileOptions compileOptions) override;
+ void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override;
- void translate(TIntermNode *root, ShCompileOptions compileOptions) override;
+ void translate(TIntermNode *root, int compileOptions) override;
bool shouldFlattenPragmaStdglInvariantAll() override;
- bool shouldCollectVariables(ShCompileOptions compileOptions) override;
private:
void writeVersion(TIntermNode *root);
@@ -31,6 +26,4 @@ class TranslatorGLSL : public TCompiler
void conditionallyOutputInvariantDeclaration(const char *builtinVaryingName);
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_TRANSLATORGLSL_H_
diff --git a/gfx/angle/src/compiler/translator/TranslatorHLSL.cpp b/gfx/angle/src/compiler/translator/TranslatorHLSL.cpp
index 7ef1d4e36..6721d8942 100755
--- a/gfx/angle/src/compiler/translator/TranslatorHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/TranslatorHLSL.cpp
@@ -8,7 +8,6 @@
#include "compiler/translator/AddDefaultReturnStatements.h"
#include "compiler/translator/ArrayReturnValueToOutParameter.h"
-#include "compiler/translator/BreakVariableAliasingInInnerLoops.h"
#include "compiler/translator/EmulatePrecision.h"
#include "compiler/translator/ExpandIntegerPowExpressions.h"
#include "compiler/translator/IntermNodePatternMatcher.h"
@@ -16,7 +15,6 @@
#include "compiler/translator/RemoveDynamicIndexing.h"
#include "compiler/translator/RewriteElseBlocks.h"
#include "compiler/translator/RewriteTexelFetchOffset.h"
-#include "compiler/translator/RewriteUnaryMinusOperatorInt.h"
#include "compiler/translator/SeparateArrayInitialization.h"
#include "compiler/translator/SeparateDeclarations.h"
#include "compiler/translator/SeparateExpressionsReturningArrays.h"
@@ -24,15 +22,12 @@
#include "compiler/translator/SplitSequenceOperator.h"
#include "compiler/translator/UnfoldShortCircuitToIf.h"
-namespace sh
-{
-
TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
: TCompiler(type, spec, output)
{
}
-void TranslatorHLSL::translate(TIntermNode *root, ShCompileOptions compileOptions)
+void TranslatorHLSL::translate(TIntermNode *root, int compileOptions)
{
const ShBuiltInResources &resources = getResources();
int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
@@ -80,12 +75,6 @@ void TranslatorHLSL::translate(TIntermNode *root, ShCompileOptions compileOption
sh::RewriteElseBlocks(root, getTemporaryIndex());
}
- // Work around an HLSL compiler frontend aliasing optimization bug.
- // TODO(cwallez) The date is 2016-08-25, Microsoft said the bug would be fixed
- // in the next release of d3dcompiler.dll, it would be nice to detect the DLL
- // version and only apply the workaround if it is too old.
- sh::BreakVariableAliasingInInnerLoops(root);
-
bool precisionEmulation =
getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision;
@@ -105,13 +94,8 @@ void TranslatorHLSL::translate(TIntermNode *root, ShCompileOptions compileOption
if ((compileOptions & SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH) != 0)
{
- sh::RewriteTexelFetchOffset(root, getSymbolTable(), getShaderVersion());
- }
-
- if (((compileOptions & SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR) != 0) &&
- getShaderType() == GL_VERTEX_SHADER)
- {
- sh::RewriteUnaryMinusOperatorInt(root);
+ sh::RewriteTexelFetchOffset(root, getTemporaryIndex(), getSymbolTable(),
+ getShaderVersion());
}
sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(),
@@ -144,5 +128,3 @@ const std::map<std::string, unsigned int> *TranslatorHLSL::getUniformRegisterMap
{
return &mUniformRegisterMap;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/TranslatorHLSL.h b/gfx/angle/src/compiler/translator/TranslatorHLSL.h
index 3bf64b2e6..f96c18dff 100755
--- a/gfx/angle/src/compiler/translator/TranslatorHLSL.h
+++ b/gfx/angle/src/compiler/translator/TranslatorHLSL.h
@@ -9,9 +9,6 @@
#include "compiler/translator/Compiler.h"
-namespace sh
-{
-
class TranslatorHLSL : public TCompiler
{
public:
@@ -24,16 +21,14 @@ class TranslatorHLSL : public TCompiler
const std::map<std::string, unsigned int> *getUniformRegisterMap() const;
protected:
- void translate(TIntermNode *root, ShCompileOptions compileOptions) override;
+ void translate(TIntermNode *root, int compileOptions) override;
bool shouldFlattenPragmaStdglInvariantAll() override;
// collectVariables needs to be run always so registers can be assigned.
- bool shouldCollectVariables(ShCompileOptions compileOptions) override { return true; }
+ bool shouldCollectVariables(int compileOptions) override { return true; }
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
std::map<std::string, unsigned int> mUniformRegisterMap;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
diff --git a/gfx/angle/src/compiler/translator/Types.cpp b/gfx/angle/src/compiler/translator/Types.cpp
index af79d3eea..be1f9822c 100755
--- a/gfx/angle/src/compiler/translator/Types.cpp
+++ b/gfx/angle/src/compiler/translator/Types.cpp
@@ -11,86 +11,49 @@
#include "compiler/translator/Types.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/SymbolTable.h"
#include <algorithm>
#include <climits>
-namespace sh
-{
-
const char* getBasicString(TBasicType t)
{
switch (t)
{
- case EbtVoid: return "void";
- case EbtFloat: return "float";
- case EbtInt: return "int";
- case EbtUInt: return "uint";
- case EbtBool: return "bool";
- case EbtSampler2D: return "sampler2D";
- case EbtSampler3D: return "sampler3D";
- case EbtSamplerCube: return "samplerCube";
- case EbtSamplerExternalOES: return "samplerExternalOES";
- case EbtSampler2DRect: return "sampler2DRect";
- case EbtSampler2DArray: return "sampler2DArray";
- case EbtISampler2D: return "isampler2D";
- case EbtISampler3D: return "isampler3D";
- case EbtISamplerCube: return "isamplerCube";
- case EbtISampler2DArray: return "isampler2DArray";
- case EbtUSampler2D: return "usampler2D";
- case EbtUSampler3D: return "usampler3D";
- case EbtUSamplerCube: return "usamplerCube";
- case EbtUSampler2DArray: return "usampler2DArray";
- case EbtSampler2DShadow: return "sampler2DShadow";
- case EbtSamplerCubeShadow: return "samplerCubeShadow";
- case EbtSampler2DArrayShadow: return "sampler2DArrayShadow";
- case EbtStruct: return "structure";
- case EbtInterfaceBlock: return "interface block";
- case EbtImage2D:
- return "image2D";
- case EbtIImage2D:
- return "iimage2D";
- case EbtUImage2D:
- return "uimage2D";
- case EbtImage3D:
- return "image3D";
- case EbtIImage3D:
- return "iimage3D";
- case EbtUImage3D:
- return "uimage3D";
- case EbtImage2DArray:
- return "image2DArray";
- case EbtIImage2DArray:
- return "iimage2DArray";
- case EbtUImage2DArray:
- return "uimage2DArray";
- case EbtImageCube:
- return "imageCube";
- case EbtIImageCube:
- return "iimageCube";
- case EbtUImageCube:
- return "uimageCube";
- default: UNREACHABLE(); return "unknown type";
+ case EbtVoid: return "void"; break;
+ case EbtFloat: return "float"; break;
+ case EbtInt: return "int"; break;
+ case EbtUInt: return "uint"; break;
+ case EbtBool: return "bool"; break;
+ case EbtSampler2D: return "sampler2D"; break;
+ case EbtSampler3D: return "sampler3D"; break;
+ case EbtSamplerCube: return "samplerCube"; break;
+ case EbtSamplerExternalOES: return "samplerExternalOES"; break;
+ case EbtSampler2DRect: return "sampler2DRect"; break;
+ case EbtSampler2DArray: return "sampler2DArray"; break;
+ case EbtISampler2D: return "isampler2D"; break;
+ case EbtISampler3D: return "isampler3D"; break;
+ case EbtISamplerCube: return "isamplerCube"; break;
+ case EbtISampler2DArray: return "isampler2DArray"; break;
+ case EbtUSampler2D: return "usampler2D"; break;
+ case EbtUSampler3D: return "usampler3D"; break;
+ case EbtUSamplerCube: return "usamplerCube"; break;
+ case EbtUSampler2DArray: return "usampler2DArray"; break;
+ case EbtSampler2DShadow: return "sampler2DShadow"; break;
+ case EbtSamplerCubeShadow: return "samplerCubeShadow"; break;
+ case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break;
+ case EbtStruct: return "structure"; break;
+ case EbtInterfaceBlock: return "interface block"; break;
+ default: UNREACHABLE(); return "unknown type";
}
}
TType::TType(const TPublicType &p)
- : type(p.getBasicType()),
- precision(p.precision),
- qualifier(p.qualifier),
- invariant(p.invariant),
- memoryQualifier(p.memoryQualifier),
- layoutQualifier(p.layoutQualifier),
- primarySize(p.getPrimarySize()),
- secondarySize(p.getSecondarySize()),
- array(p.array),
- arraySize(p.arraySize),
- interfaceBlock(0),
- structure(0)
+ : type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(p.invariant),
+ layoutQualifier(p.layoutQualifier), primarySize(p.primarySize), secondarySize(p.secondarySize),
+ array(p.array), arraySize(p.arraySize), interfaceBlock(0), structure(0)
{
- if (p.getUserDef())
- structure = p.getUserDef()->getStruct();
+ if (p.userDef)
+ structure = p.userDef->getStruct();
}
bool TStructure::equals(const TStructure &other) const
@@ -311,42 +274,6 @@ TString TType::buildMangledName() const
case EbtSampler2DArrayShadow:
mangledName += "s2as";
break;
- case EbtImage2D:
- mangledName += "im2";
- break;
- case EbtIImage2D:
- mangledName += "iim2";
- break;
- case EbtUImage2D:
- mangledName += "uim2";
- break;
- case EbtImage3D:
- mangledName += "im3";
- break;
- case EbtIImage3D:
- mangledName += "iim3";
- break;
- case EbtUImage3D:
- mangledName += "uim3";
- break;
- case EbtImage2DArray:
- mangledName += "im2a";
- break;
- case EbtIImage2DArray:
- mangledName += "iim2a";
- break;
- case EbtUImage2DArray:
- mangledName += "uim2a";
- break;
- case EbtImageCube:
- mangledName += "imc";
- break;
- case EbtIImageCube:
- mangledName += "iimc";
- break;
- case EbtUImageCube:
- mangledName += "uimc";
- break;
case EbtStruct:
mangledName += structure->mangledName();
break;
@@ -391,9 +318,6 @@ size_t TType::getObjectSize() const
if (isArray())
{
- if (totalSize == 0)
- return 0;
-
size_t currentArraySize = getArraySize();
if (currentArraySize > INT_MAX / totalSize)
totalSize = INT_MAX;
@@ -404,14 +328,6 @@ size_t TType::getObjectSize() const
return totalSize;
}
-TStructure::TStructure(const TString *name, TFieldList *fields)
- : TFieldListCollection(name, fields),
- mDeepestNesting(0),
- mUniqueId(TSymbolTable::nextUniqueId()),
- mAtGlobalScope(false)
-{
-}
-
bool TStructure::containsArrays() const
{
for (size_t i = 0; i < mFields->size(); ++i)
@@ -445,17 +361,6 @@ bool TStructure::containsSamplers() const
return false;
}
-bool TStructure::containsImages() const
-{
- for (size_t i = 0; i < mFields->size(); ++i)
- {
- const TType *fieldType = (*mFields)[i]->type();
- if (IsImage(fieldType->getBasicType()) || fieldType->isStructureContainingImages())
- return true;
- }
- return false;
-}
-
void TStructure::createSamplerSymbols(const TString &structName,
const TString &structAPIName,
const unsigned int arrayOfStructsSize,
@@ -560,5 +465,3 @@ int TStructure::calculateDeepestNesting() const
maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
return 1 + maxNesting;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/Types.h b/gfx/angle/src/compiler/translator/Types.h
index fc26d5f59..2a85e010c 100755
--- a/gfx/angle/src/compiler/translator/Types.h
+++ b/gfx/angle/src/compiler/translator/Types.h
@@ -13,9 +13,6 @@
#include "compiler/translator/BaseTypes.h"
#include "compiler/translator/Common.h"
-namespace sh
-{
-
struct TPublicType;
class TType;
class TSymbol;
@@ -106,7 +103,13 @@ class TStructure : public TFieldListCollection
{
public:
POOL_ALLOCATOR_NEW_DELETE();
- TStructure(const TString *name, TFieldList *fields);
+ TStructure(const TString *name, TFieldList *fields)
+ : TFieldListCollection(name, fields),
+ mDeepestNesting(0),
+ mUniqueId(0),
+ mAtGlobalScope(false)
+ {
+ }
int deepestNesting() const
{
@@ -117,7 +120,6 @@ class TStructure : public TFieldListCollection
bool containsArrays() const;
bool containsType(TBasicType t) const;
bool containsSamplers() const;
- bool containsImages() const;
void createSamplerSymbols(const TString &structName,
const TString &structAPIName,
@@ -233,18 +235,10 @@ class TType
public:
POOL_ALLOCATOR_NEW_DELETE();
TType()
- : type(EbtVoid),
- precision(EbpUndefined),
- qualifier(EvqGlobal),
- invariant(false),
- memoryQualifier(TMemoryQualifier::create()),
+ : type(EbtVoid), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false),
layoutQualifier(TLayoutQualifier::create()),
- primarySize(0),
- secondarySize(0),
- array(false),
- arraySize(0),
- interfaceBlock(nullptr),
- structure(nullptr)
+ primarySize(0), secondarySize(0), array(false), arraySize(0),
+ interfaceBlock(nullptr), structure(nullptr)
{
}
explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
@@ -252,7 +246,6 @@ class TType
precision(EbpUndefined),
qualifier(EvqGlobal),
invariant(false),
- memoryQualifier(TMemoryQualifier::create()),
layoutQualifier(TLayoutQualifier::create()),
primarySize(ps),
secondarySize(ss),
@@ -262,24 +255,12 @@ class TType
structure(0)
{
}
- TType(TBasicType t,
- TPrecision p,
- TQualifier q = EvqTemporary,
- unsigned char ps = 1,
- unsigned char ss = 1,
- bool a = false)
- : type(t),
- precision(p),
- qualifier(q),
- invariant(false),
- memoryQualifier(TMemoryQualifier::create()),
+ TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary,
+ unsigned char ps = 1, unsigned char ss = 1, bool a = false)
+ : type(t), precision(p), qualifier(q), invariant(false),
layoutQualifier(TLayoutQualifier::create()),
- primarySize(ps),
- secondarySize(ss),
- array(a),
- arraySize(0),
- interfaceBlock(0),
- structure(0)
+ primarySize(ps), secondarySize(ss), array(a), arraySize(0),
+ interfaceBlock(0), structure(0)
{
}
explicit TType(const TPublicType &p);
@@ -288,7 +269,6 @@ class TType
precision(p),
qualifier(EvqTemporary),
invariant(false),
- memoryQualifier(TMemoryQualifier::create()),
layoutQualifier(TLayoutQualifier::create()),
primarySize(1),
secondarySize(1),
@@ -298,22 +278,12 @@ class TType
structure(userDef)
{
}
- TType(TInterfaceBlock *interfaceBlockIn,
- TQualifier qualifierIn,
- TLayoutQualifier layoutQualifierIn,
- int arraySizeIn)
- : type(EbtInterfaceBlock),
- precision(EbpUndefined),
- qualifier(qualifierIn),
- invariant(false),
- memoryQualifier(TMemoryQualifier::create()),
- layoutQualifier(layoutQualifierIn),
- primarySize(1),
- secondarySize(1),
- array(arraySizeIn > 0),
- arraySize(arraySizeIn),
- interfaceBlock(interfaceBlockIn),
- structure(0)
+ TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn,
+ TLayoutQualifier layoutQualifierIn, int arraySizeIn)
+ : type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn),
+ invariant(false), layoutQualifier(layoutQualifierIn),
+ primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn),
+ interfaceBlock(interfaceBlockIn), structure(0)
{
}
@@ -358,9 +328,6 @@ class TType
void setInvariant(bool i) { invariant = i; }
- TMemoryQualifier getMemoryQualifier() const { return memoryQualifier; }
- void setMemoryQualifier(const TMemoryQualifier &mq) { memoryQualifier = mq; }
-
TLayoutQualifier getLayoutQualifier() const
{
return layoutQualifier;
@@ -538,16 +505,16 @@ class TType
const char *getBasicString() const
{
- return sh::getBasicString(type);
+ return ::getBasicString(type);
}
const char *getPrecisionString() const
{
- return sh::getPrecisionString(precision);
+ return ::getPrecisionString(precision);
}
const char *getQualifierString() const
{
- return sh::getQualifierString(qualifier);
+ return ::getQualifierString(qualifier);
}
const char *getBuiltInTypeNameString() const;
@@ -586,11 +553,6 @@ class TType
return structure ? structure->containsSamplers() : false;
}
- bool isStructureContainingImages() const
- {
- return structure ? structure->containsImages() : false;
- }
-
void createSamplerSymbols(const TString &structName,
const TString &structAPIName,
const unsigned int arrayOfStructsSize,
@@ -617,7 +579,6 @@ class TType
TPrecision precision;
TQualifier qualifier;
bool invariant;
- TMemoryQualifier memoryQualifier;
TLayoutQualifier layoutQualifier;
unsigned char primarySize; // size of vector or cols matrix
unsigned char secondarySize; // rows of a matrix
@@ -633,25 +594,44 @@ class TType
mutable TString mangled;
};
-// TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the
-// grammar
-struct TTypeSpecifierNonArray
+//
+// This is a workaround for a problem with the yacc stack, It can't have
+// types that it thinks have non-trivial constructors. It should
+// just be used while recognizing the grammar, not anything else. Pointers
+// could be used, but also trying to avoid lots of memory management overhead.
+//
+// Not as bad as it looks, there is no actual assumption that the fields
+// match up or are name the same or anything like that.
+//
+struct TPublicType
{
TBasicType type;
+ TLayoutQualifier layoutQualifier;
+ TQualifier qualifier;
+ bool invariant;
+ TPrecision precision;
unsigned char primarySize; // size of vector or cols of matrix
unsigned char secondarySize; // rows of matrix
+ bool array;
+ int arraySize;
TType *userDef;
TSourceLoc line;
// true if the type was defined by a struct specifier rather than a reference to a type name.
bool isStructSpecifier;
- void initialize(TBasicType bt, const TSourceLoc &ln)
+ void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln)
{
type = bt;
+ layoutQualifier = TLayoutQualifier::create();
+ qualifier = q;
+ invariant = false;
+ precision = EbpUndefined;
primarySize = 1;
secondarySize = 1;
- userDef = nullptr;
+ array = false;
+ arraySize = 0;
+ userDef = 0;
line = ln;
isStructSpecifier = false;
}
@@ -661,113 +641,79 @@ struct TTypeSpecifierNonArray
primarySize = size;
}
- void setMatrix(unsigned char columns, unsigned char rows)
+ void setMatrix(unsigned char c, unsigned char r)
{
- ASSERT(columns > 1 && rows > 1 && columns <= 4 && rows <= 4);
- primarySize = columns;
- secondarySize = rows;
+ ASSERT(c > 1 && r > 1 && c <= 4 && r <= 4);
+ primarySize = c;
+ secondarySize = r;
}
- bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
-
- bool isVector() const { return primarySize > 1 && secondarySize == 1; }
-};
-
-//
-// This is a workaround for a problem with the yacc stack, It can't have
-// types that it thinks have non-trivial constructors. It should
-// just be used while recognizing the grammar, not anything else. Pointers
-// could be used, but also trying to avoid lots of memory management overhead.
-//
-// Not as bad as it looks, there is no actual assumption that the fields
-// match up or are name the same or anything like that.
-//
-struct TPublicType
-{
- TTypeSpecifierNonArray typeSpecifierNonArray;
- TLayoutQualifier layoutQualifier;
- TMemoryQualifier memoryQualifier;
- TQualifier qualifier;
- bool invariant;
- TPrecision precision;
- bool array;
- int arraySize;
-
- void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
+ bool isUnsizedArray() const
{
- typeSpecifierNonArray = typeSpecifier;
- layoutQualifier = TLayoutQualifier::create();
- memoryQualifier = TMemoryQualifier::create();
- qualifier = q;
- invariant = false;
- precision = EbpUndefined;
- array = false;
- arraySize = 0;
+ return array && arraySize == 0;
}
-
- void initializeBasicType(TBasicType basicType)
+ void setArraySize(int s)
{
- typeSpecifierNonArray.type = basicType;
- typeSpecifierNonArray.primarySize = 1;
- typeSpecifierNonArray.secondarySize = 1;
- layoutQualifier = TLayoutQualifier::create();
- memoryQualifier = TMemoryQualifier::create();
- qualifier = EvqTemporary;
- invariant = false;
- precision = EbpUndefined;
- array = false;
- arraySize = 0;
+ array = true;
+ arraySize = s;
+ }
+ void clearArrayness()
+ {
+ array = false;
+ arraySize = 0;
}
-
- TBasicType getBasicType() const { return typeSpecifierNonArray.type; }
- void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; }
-
- unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
- unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; }
-
- const TType *getUserDef() const { return typeSpecifierNonArray.userDef; }
- const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }
-
- bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }
bool isStructureContainingArrays() const
{
- if (!typeSpecifierNonArray.userDef)
+ if (!userDef)
{
return false;
}
- return typeSpecifierNonArray.userDef->isStructureContainingArrays();
+ return userDef->isStructureContainingArrays();
}
bool isStructureContainingType(TBasicType t) const
{
- if (!typeSpecifierNonArray.userDef)
+ if (!userDef)
{
return false;
}
- return typeSpecifierNonArray.userDef->isStructureContainingType(t);
+ return userDef->isStructureContainingType(t);
}
- bool isUnsizedArray() const { return array && arraySize == 0; }
- void setArraySize(int s)
+ bool isMatrix() const
{
- array = true;
- arraySize = s;
+ return primarySize > 1 && secondarySize > 1;
}
- void clearArrayness()
+
+ bool isVector() const
{
- array = false;
- arraySize = 0;
+ return primarySize > 1 && secondarySize == 1;
+ }
+
+ int getCols() const
+ {
+ ASSERT(isMatrix());
+ return primarySize;
+ }
+
+ int getRows() const
+ {
+ ASSERT(isMatrix());
+ return secondarySize;
+ }
+
+ int getNominalSize() const
+ {
+ return primarySize;
}
bool isAggregate() const
{
- return array || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
+ return array || isMatrix() || isVector();
}
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_TYPES_H_
diff --git a/gfx/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp b/gfx/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp
index b6a355a13..3ef555fc8 100755
--- a/gfx/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp
+++ b/gfx/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp
@@ -6,37 +6,36 @@
#include "compiler/translator/UnfoldShortCircuitAST.h"
-namespace sh
-{
-
namespace
{
// "x || y" is equivalent to "x ? true : y".
-TIntermTernary *UnfoldOR(TIntermTyped *x, TIntermTyped *y)
+TIntermSelection *UnfoldOR(TIntermTyped *x, TIntermTyped *y)
{
+ const TType boolType(EbtBool, EbpUndefined);
TConstantUnion *u = new TConstantUnion;
u->setBConst(true);
TIntermConstantUnion *trueNode = new TIntermConstantUnion(
u, TType(EbtBool, EbpUndefined, EvqConst, 1));
- return new TIntermTernary(x, trueNode, y);
+ return new TIntermSelection(x, trueNode, y, boolType);
}
// "x && y" is equivalent to "x ? y : false".
-TIntermTernary *UnfoldAND(TIntermTyped *x, TIntermTyped *y)
+TIntermSelection *UnfoldAND(TIntermTyped *x, TIntermTyped *y)
{
+ const TType boolType(EbtBool, EbpUndefined);
TConstantUnion *u = new TConstantUnion;
u->setBConst(false);
TIntermConstantUnion *falseNode = new TIntermConstantUnion(
u, TType(EbtBool, EbpUndefined, EvqConst, 1));
- return new TIntermTernary(x, y, falseNode);
+ return new TIntermSelection(x, y, falseNode, boolType);
}
} // namespace anonymous
bool UnfoldShortCircuitAST::visitBinary(Visit visit, TIntermBinary *node)
{
- TIntermTernary *replacement = nullptr;
+ TIntermSelection *replacement = NULL;
switch (node->getOp())
{
@@ -55,5 +54,3 @@ bool UnfoldShortCircuitAST::visitBinary(Visit visit, TIntermBinary *node)
}
return true;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/UnfoldShortCircuitAST.h b/gfx/angle/src/compiler/translator/UnfoldShortCircuitAST.h
index ac18bbf99..b92a4e915 100755
--- a/gfx/angle/src/compiler/translator/UnfoldShortCircuitAST.h
+++ b/gfx/angle/src/compiler/translator/UnfoldShortCircuitAST.h
@@ -13,9 +13,6 @@
#include "common/angleutils.h"
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
// This traverser identifies all the short circuit binary nodes that need to
// be replaced, and creates the corresponding replacement nodes. However,
// the actual replacements happen after the traverse through updateTree().
@@ -31,6 +28,4 @@ class UnfoldShortCircuitAST : public TIntermTraverser
bool visitBinary(Visit visit, TIntermBinary *) override;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_
diff --git a/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp b/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp
index 22fa54287..4f32d6a7f 100755
--- a/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp
+++ b/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp
@@ -13,9 +13,6 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNodePatternMatcher.h"
-namespace sh
-{
-
namespace
{
@@ -26,7 +23,7 @@ class UnfoldShortCircuitTraverser : public TIntermTraverser
UnfoldShortCircuitTraverser();
bool visitBinary(Visit visit, TIntermBinary *node) override;
- bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitSelection(Visit visit, TIntermSelection *node) override;
void nextIteration();
bool foundShortCircuit() const { return mFoundShortCircuit; }
@@ -78,12 +75,13 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
ASSERT(node->getLeft()->getType() == boolType);
insertions.push_back(createTempInitDeclaration(node->getLeft()));
- TIntermBlock *assignRightBlock = new TIntermBlock();
+ TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence);
ASSERT(node->getRight()->getType() == boolType);
assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight()));
- TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, createTempSymbol(boolType));
- TIntermIfElse *ifNode = new TIntermIfElse(notTempSymbol, assignRightBlock, nullptr);
+ TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, boolType);
+ notTempSymbol->setOperand(createTempSymbol(boolType));
+ TIntermSelection *ifNode = new TIntermSelection(notTempSymbol, assignRightBlock, nullptr);
insertions.push_back(ifNode);
insertStatementsInParentBlock(insertions);
@@ -102,12 +100,12 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
ASSERT(node->getLeft()->getType() == boolType);
insertions.push_back(createTempInitDeclaration(node->getLeft()));
- TIntermBlock *assignRightBlock = new TIntermBlock();
+ TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence);
ASSERT(node->getRight()->getType() == boolType);
assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight()));
- TIntermIfElse *ifNode =
- new TIntermIfElse(createTempSymbol(boolType), assignRightBlock, nullptr);
+ TIntermSelection *ifNode =
+ new TIntermSelection(createTempSymbol(boolType), assignRightBlock, nullptr);
insertions.push_back(ifNode);
insertStatementsInParentBlock(insertions);
@@ -121,7 +119,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
}
}
-bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node)
+bool UnfoldShortCircuitTraverser::visitSelection(Visit visit, TIntermSelection *node)
{
if (mFoundShortCircuit)
return false;
@@ -134,22 +132,26 @@ bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node
mFoundShortCircuit = true;
+ ASSERT(node->usesTernaryOperator());
+
// Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
TIntermSequence insertions;
- TIntermDeclaration *tempDeclaration = createTempDeclaration(node->getType());
+ TIntermSymbol *tempSymbol = createTempSymbol(node->getType());
+ TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
+ tempDeclaration->getSequence()->push_back(tempSymbol);
insertions.push_back(tempDeclaration);
- TIntermBlock *trueBlock = new TIntermBlock();
- TIntermBinary *trueAssignment = createTempAssignment(node->getTrueExpression());
+ TIntermAggregate *trueBlock = new TIntermAggregate(EOpSequence);
+ TIntermBinary *trueAssignment = createTempAssignment(node->getTrueBlock()->getAsTyped());
trueBlock->getSequence()->push_back(trueAssignment);
- TIntermBlock *falseBlock = new TIntermBlock();
- TIntermBinary *falseAssignment = createTempAssignment(node->getFalseExpression());
+ TIntermAggregate *falseBlock = new TIntermAggregate(EOpSequence);
+ TIntermBinary *falseAssignment = createTempAssignment(node->getFalseBlock()->getAsTyped());
falseBlock->getSequence()->push_back(falseAssignment);
- TIntermIfElse *ifNode =
- new TIntermIfElse(node->getCondition()->getAsTyped(), trueBlock, falseBlock);
+ TIntermSelection *ifNode =
+ new TIntermSelection(node->getCondition()->getAsTyped(), trueBlock, falseBlock);
insertions.push_back(ifNode);
insertStatementsInParentBlock(insertions);
@@ -183,5 +185,3 @@ void UnfoldShortCircuitToIf(TIntermNode *root, unsigned int *temporaryIndex)
}
while (traverser.foundShortCircuit());
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.h b/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.h
index 24ff289a3..0fe37b714 100755
--- a/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.h
+++ b/gfx/angle/src/compiler/translator/UnfoldShortCircuitToIf.h
@@ -11,11 +11,8 @@
#ifndef COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_
#define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_
-namespace sh
-{
class TIntermNode;
void UnfoldShortCircuitToIf(TIntermNode *root, unsigned int *temporaryIndex);
-} // namespace sh
#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_
diff --git a/gfx/angle/src/compiler/translator/UseInterfaceBlockFields.cpp b/gfx/angle/src/compiler/translator/UseInterfaceBlockFields.cpp
deleted file mode 100644
index 390e2b092..000000000
--- a/gfx/angle/src/compiler/translator/UseInterfaceBlockFields.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-//
-// Copyright 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// UseInterfaceBlockFields.cpp: insert statements to reference all members in InterfaceBlock list at
-// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
-// uniform blocks as inactive.
-
-#include "compiler/translator/UseInterfaceBlockFields.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/SymbolTable.h"
-#include "compiler/translator/util.h"
-
-namespace sh
-{
-
-namespace
-{
-
-class UseUniformBlockMembers : public TIntermTraverser
-{
- public:
- UseUniformBlockMembers(const InterfaceBlockList &blocks, const TSymbolTable &symbolTable)
- : TIntermTraverser(true, false, false),
- mBlocks(blocks),
- mSymbolTable(symbolTable),
- mCodeInserted(false)
- {
- ASSERT(mSymbolTable.atGlobalLevel());
- }
-
- protected:
- bool visitAggregate(Visit visit, TIntermAggregate *node) override { return !mCodeInserted; }
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
-
- private:
- void insertUseCode(TIntermSequence *sequence);
- void AddFieldUseStatements(const ShaderVariable &var, TIntermSequence *sequence);
-
- const InterfaceBlockList &mBlocks;
- const TSymbolTable &mSymbolTable;
- bool mCodeInserted;
-};
-
-bool UseUniformBlockMembers::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
-{
- ASSERT(visit == PreVisit);
- if (node->getFunctionSymbolInfo()->isMain())
- {
- TIntermBlock *body = node->getBody();
- ASSERT(body);
- insertUseCode(body->getSequence());
- mCodeInserted = true;
- return false;
- }
- return !mCodeInserted;
-}
-
-void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var,
- TIntermSequence *sequence)
-{
- TString name = TString(var.name.c_str());
- if (var.isArray())
- {
- size_t pos = name.find_last_of('[');
- if (pos != TString::npos)
- {
- name = name.substr(0, pos);
- }
- }
- const TType *type;
- TType basicType;
- if (var.isStruct())
- {
- TVariable *structInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
- ASSERT(structInfo);
- const TType &structType = structInfo->getType();
- type = &structType;
- }
- else
- {
- basicType = sh::GetShaderVariableBasicType(var);
- type = &basicType;
- }
- ASSERT(type);
-
- TIntermSymbol *symbol = new TIntermSymbol(0, name, *type);
- if (var.isArray())
- {
- for (unsigned int i = 0; i < var.arraySize; ++i)
- {
- TIntermBinary *element =
- new TIntermBinary(EOpIndexDirect, symbol, TIntermTyped::CreateIndexNode(i));
- sequence->insert(sequence->begin(), element);
- }
- }
- else
- {
- sequence->insert(sequence->begin(), symbol);
- }
-}
-
-void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence)
-{
- for (const auto &block : mBlocks)
- {
- if (block.instanceName.empty())
- {
- for (const auto &var : block.fields)
- {
- AddFieldUseStatements(var, sequence);
- }
- }
- else if (block.arraySize > 0)
- {
- TString name = TString(block.instanceName.c_str());
- TVariable *ubInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
- ASSERT(ubInfo);
- TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, ubInfo->getType());
- for (unsigned int i = 0; i < block.arraySize; ++i)
- {
- TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol,
- TIntermTyped::CreateIndexNode(i));
- for (unsigned int j = 0; j < block.fields.size(); ++j)
- {
- TIntermBinary *element =
- new TIntermBinary(EOpIndexDirectInterfaceBlock, instanceSymbol,
- TIntermTyped::CreateIndexNode(j));
- sequence->insert(sequence->begin(), element);
- }
- }
- }
- else
- {
- TString name = TString(block.instanceName.c_str());
- TVariable *ubInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
- ASSERT(ubInfo);
- TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, ubInfo->getType());
- for (unsigned int i = 0; i < block.fields.size(); ++i)
- {
- TIntermBinary *element = new TIntermBinary(
- EOpIndexDirectInterfaceBlock, blockSymbol, TIntermTyped::CreateIndexNode(i));
-
- sequence->insert(sequence->begin(), element);
- }
- }
- }
-}
-
-} // namespace anonymous
-
-void UseInterfaceBlockFields(TIntermNode *root,
- const InterfaceBlockList &blocks,
- const TSymbolTable &symbolTable)
-{
- UseUniformBlockMembers useUniformBlock(blocks, symbolTable);
- root->traverse(&useUniformBlock);
-}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/UseInterfaceBlockFields.h b/gfx/angle/src/compiler/translator/UseInterfaceBlockFields.h
deleted file mode 100644
index a789bb7e9..000000000
--- a/gfx/angle/src/compiler/translator/UseInterfaceBlockFields.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright 2016 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// UseInterfaceBlockFields.h: insert statements to reference all members in InterfaceBlock list at
-// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
-// uniform blocks as inactive.
-
-#ifndef COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
-#define COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
-
-#include <GLSLANG/ShaderLang.h>
-
-class TIntermNode;
-namespace sh
-{
-
-class TSymbolTable;
-
-using InterfaceBlockList = std::vector<sh::InterfaceBlock>;
-
-void UseInterfaceBlockFields(TIntermNode *root,
- const InterfaceBlockList &blocks,
- const TSymbolTable &symbolTable);
-
-} // namespace sh
-
-#endif // COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
diff --git a/gfx/angle/src/compiler/translator/UtilsHLSL.cpp b/gfx/angle/src/compiler/translator/UtilsHLSL.cpp
index 221d5d9b5..b3a065f19 100755
--- a/gfx/angle/src/compiler/translator/UtilsHLSL.cpp
+++ b/gfx/angle/src/compiler/translator/UtilsHLSL.cpp
@@ -173,8 +173,6 @@ TString TextureTypeSuffix(const TBasicType type)
return "Cube_int4_";
case EbtUSamplerCube:
return "Cube_uint4_";
- case EbtSamplerExternalOES:
- return "_External";
default:
// All other types are identified by their group suffix
return TextureGroupSuffix(type);
diff --git a/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.cpp b/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.cpp
index d5b1b3be4..2461b6a43 100755
--- a/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.cpp
@@ -8,9 +8,6 @@
#include "compiler/translator/ParseContext.h"
-namespace sh
-{
-
namespace
{
@@ -113,4 +110,3 @@ bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *c
return validate.isValid();
}
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.h b/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.h
index 89b4b1176..c3d2a47eb 100755
--- a/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.h
+++ b/gfx/angle/src/compiler/translator/ValidateGlobalInitializer.h
@@ -7,15 +7,10 @@
#ifndef COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
#define COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
-namespace sh
-{
-
class TIntermTyped;
class TParseContext;
// Returns true if the initializer is valid.
bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning);
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
diff --git a/gfx/angle/src/compiler/translator/ValidateLimitations.cpp b/gfx/angle/src/compiler/translator/ValidateLimitations.cpp
index 75a0c5156..ba8cdd0aa 100755
--- a/gfx/angle/src/compiler/translator/ValidateLimitations.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateLimitations.cpp
@@ -10,9 +10,6 @@
#include "compiler/translator/ParseContext.h"
#include "angle_gl.h"
-namespace sh
-{
-
namespace
{
@@ -216,8 +213,8 @@ int ValidateLimitations::validateForLoopInit(TIntermLoop *node)
// init-declaration has the form:
// type-specifier identifier = constant-expression
//
- TIntermDeclaration *decl = init->getAsDeclarationNode();
- if (decl == nullptr)
+ TIntermAggregate *decl = init->getAsAggregate();
+ if ((decl == NULL) || (decl->getOp() != EOpDeclaration))
{
error(init->getLine(), "Invalid init declaration", "for");
return -1;
@@ -426,8 +423,7 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate *node)
bool valid = true;
TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
- TSymbol *symbol = symbolTable.find(node->getFunctionSymbolInfo()->getName(),
- GetGlobalParseContext()->getShaderVersion());
+ TSymbol* symbol = symbolTable.find(node->getName(), GetGlobalParseContext()->getShaderVersion());
ASSERT(symbol && symbol->isFunction());
TFunction *function = static_cast<TFunction *>(symbol);
for (ParamIndex::const_iterator i = pIndex.begin();
@@ -499,4 +495,3 @@ bool ValidateLimitations::validateIndexing(TIntermBinary *node)
return valid;
}
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ValidateLimitations.h b/gfx/angle/src/compiler/translator/ValidateLimitations.h
index 4c84f9db7..666e38ff5 100755
--- a/gfx/angle/src/compiler/translator/ValidateLimitations.h
+++ b/gfx/angle/src/compiler/translator/ValidateLimitations.h
@@ -10,9 +10,6 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/LoopInfo.h"
-namespace sh
-{
-
class TInfoSinkBase;
// Traverses intermediate tree to ensure that the shader does not exceed the
@@ -63,6 +60,4 @@ class ValidateLimitations : public TIntermTraverser
bool mValidateInnerLoops;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
diff --git a/gfx/angle/src/compiler/translator/ValidateMaxParameters.cpp b/gfx/angle/src/compiler/translator/ValidateMaxParameters.cpp
index f97f7a907..00b3c9b45 100755
--- a/gfx/angle/src/compiler/translator/ValidateMaxParameters.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateMaxParameters.cpp
@@ -7,9 +7,6 @@
#include "compiler/translator/ValidateMaxParameters.h"
-namespace sh
-{
-
ValidateMaxParameters::ValidateMaxParameters(unsigned int maxParameters)
: TIntermTraverser(true, false, false), mMaxParameters(maxParameters), mValid(true)
{
@@ -36,5 +33,3 @@ bool ValidateMaxParameters::validate(TIntermNode *root, unsigned int maxParamete
root->traverse(&argsTraverser);
return argsTraverser.mValid;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ValidateMaxParameters.h b/gfx/angle/src/compiler/translator/ValidateMaxParameters.h
index fdd0b8d09..87916afef 100755
--- a/gfx/angle/src/compiler/translator/ValidateMaxParameters.h
+++ b/gfx/angle/src/compiler/translator/ValidateMaxParameters.h
@@ -10,9 +10,6 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
-
class ValidateMaxParameters : public TIntermTraverser
{
public:
@@ -29,6 +26,4 @@ class ValidateMaxParameters : public TIntermTraverser
bool mValid;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_
diff --git a/gfx/angle/src/compiler/translator/ValidateOutputs.cpp b/gfx/angle/src/compiler/translator/ValidateOutputs.cpp
index e48da8a79..9f5f8f577 100755
--- a/gfx/angle/src/compiler/translator/ValidateOutputs.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateOutputs.cpp
@@ -9,9 +9,6 @@
#include "compiler/translator/InitializeParseContext.h"
#include "compiler/translator/ParseContext.h"
-namespace sh
-{
-
namespace
{
void error(int *errorCount, TInfoSinkBase &sink, const TIntermSymbol &symbol, const char *reason)
@@ -109,5 +106,3 @@ int ValidateOutputs::validateAndCountErrors(TInfoSinkBase &sink) const
}
return errorCount;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ValidateOutputs.h b/gfx/angle/src/compiler/translator/ValidateOutputs.h
index 0788f4ed6..0122ca25f 100755
--- a/gfx/angle/src/compiler/translator/ValidateOutputs.h
+++ b/gfx/angle/src/compiler/translator/ValidateOutputs.h
@@ -12,9 +12,6 @@
#include <set>
-namespace sh
-{
-
class TInfoSinkBase;
class ValidateOutputs : public TIntermTraverser
@@ -36,6 +33,4 @@ class ValidateOutputs : public TIntermTraverser
std::set<std::string> mVisitedSymbols;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
diff --git a/gfx/angle/src/compiler/translator/ValidateSwitch.cpp b/gfx/angle/src/compiler/translator/ValidateSwitch.cpp
index 9bcd8f5fe..9a4ed3363 100755
--- a/gfx/angle/src/compiler/translator/ValidateSwitch.cpp
+++ b/gfx/angle/src/compiler/translator/ValidateSwitch.cpp
@@ -8,13 +8,8 @@
#include "compiler/translator/ParseContext.h"
-namespace sh
-{
-
-bool ValidateSwitch::validate(TBasicType switchType,
- TParseContext *context,
- TIntermBlock *statementList,
- const TSourceLoc &loc)
+bool ValidateSwitch::validate(TBasicType switchType, TParseContext *context,
+ TIntermAggregate *statementList, const TSourceLoc &loc)
{
ValidateSwitch validate(switchType, context);
ASSERT(statementList);
@@ -64,19 +59,11 @@ bool ValidateSwitch::visitUnary(Visit, TIntermUnary *)
{
if (!mFirstCaseFound)
mStatementBeforeCase = true;
- mLastStatementWasCase = false;
- return true;
-}
-
-bool ValidateSwitch::visitTernary(Visit, TIntermTernary *)
-{
- if (!mFirstCaseFound)
- mStatementBeforeCase = true;
mLastStatementWasCase = false;
return true;
}
-bool ValidateSwitch::visitIfElse(Visit visit, TIntermIfElse *)
+bool ValidateSwitch::visitSelection(Visit visit, TIntermSelection *)
{
if (visit == PreVisit)
++mControlFlowDepth;
@@ -211,5 +198,3 @@ bool ValidateSwitch::validateInternal(const TSourceLoc &loc)
return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow &&
!mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases;
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/ValidateSwitch.h b/gfx/angle/src/compiler/translator/ValidateSwitch.h
index feffbc03c..ddbefc561 100755
--- a/gfx/angle/src/compiler/translator/ValidateSwitch.h
+++ b/gfx/angle/src/compiler/translator/ValidateSwitch.h
@@ -9,8 +9,6 @@
#include "compiler/translator/IntermNode.h"
-namespace sh
-{
class TParseContext;
class ValidateSwitch : public TIntermTraverser
@@ -18,17 +16,14 @@ class ValidateSwitch : public TIntermTraverser
public:
// Check for errors and output messages any remaining errors on the context.
// Returns true if there are no errors.
- static bool validate(TBasicType switchType,
- TParseContext *context,
- TIntermBlock *statementList,
- const TSourceLoc &loc);
+ static bool validate(TBasicType switchType, TParseContext *context,
+ TIntermAggregate *statementList, const TSourceLoc &loc);
void visitSymbol(TIntermSymbol *) override;
void visitConstantUnion(TIntermConstantUnion *) override;
bool visitBinary(Visit, TIntermBinary *) override;
bool visitUnary(Visit, TIntermUnary *) override;
- bool visitTernary(Visit, TIntermTernary *) override;
- bool visitIfElse(Visit visit, TIntermIfElse *) override;
+ bool visitSelection(Visit visit, TIntermSelection *) override;
bool visitSwitch(Visit, TIntermSwitch *) override;
bool visitCase(Visit, TIntermCase *node) override;
bool visitAggregate(Visit, TIntermAggregate *) override;
@@ -54,6 +49,4 @@ class ValidateSwitch : public TIntermTraverser
bool mDuplicateCases;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_
diff --git a/gfx/angle/src/compiler/translator/VariableInfo.cpp b/gfx/angle/src/compiler/translator/VariableInfo.cpp
index 07fe12e5d..7e1e5cd82 100755
--- a/gfx/angle/src/compiler/translator/VariableInfo.cpp
+++ b/gfx/angle/src/compiler/translator/VariableInfo.cpp
@@ -559,43 +559,54 @@ void CollectVariables::visitInfoList(const TIntermSequence &sequence,
}
}
-bool CollectVariables::visitDeclaration(Visit, TIntermDeclaration *node)
+bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
{
- const TIntermSequence &sequence = *(node->getSequence());
- ASSERT(!sequence.empty());
+ bool visitChildren = true;
- const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
- TQualifier qualifier = typedNode.getQualifier();
-
- if (typedNode.getBasicType() == EbtInterfaceBlock)
+ switch (node->getOp())
{
- visitInfoList(sequence, mInterfaceBlocks);
- return false;
- }
- else if (qualifier == EvqAttribute || qualifier == EvqVertexIn || qualifier == EvqFragmentOut ||
- qualifier == EvqUniform || IsVarying(qualifier))
- {
- switch (qualifier)
+ case EOpDeclaration:
{
- case EvqAttribute:
- case EvqVertexIn:
- visitInfoList(sequence, mAttribs);
- break;
- case EvqFragmentOut:
- visitInfoList(sequence, mOutputVariables);
- break;
- case EvqUniform:
- visitInfoList(sequence, mUniforms);
- break;
- default:
- visitInfoList(sequence, mVaryings);
- break;
- }
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT(!sequence.empty());
- return false;
+ const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
+ TQualifier qualifier = typedNode.getQualifier();
+
+ if (typedNode.getBasicType() == EbtInterfaceBlock)
+ {
+ visitInfoList(sequence, mInterfaceBlocks);
+ visitChildren = false;
+ }
+ else if (qualifier == EvqAttribute || qualifier == EvqVertexIn ||
+ qualifier == EvqFragmentOut || qualifier == EvqUniform ||
+ IsVarying(qualifier))
+ {
+ switch (qualifier)
+ {
+ case EvqAttribute:
+ case EvqVertexIn:
+ visitInfoList(sequence, mAttribs);
+ break;
+ case EvqFragmentOut:
+ visitInfoList(sequence, mOutputVariables);
+ break;
+ case EvqUniform:
+ visitInfoList(sequence, mUniforms);
+ break;
+ default:
+ visitInfoList(sequence, mVaryings);
+ break;
+ }
+
+ visitChildren = false;
+ }
+ break;
+ }
+ default: break;
}
- return true;
+ return visitChildren;
}
bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
diff --git a/gfx/angle/src/compiler/translator/VariableInfo.h b/gfx/angle/src/compiler/translator/VariableInfo.h
index 6b2115656..f79035d38 100755
--- a/gfx/angle/src/compiler/translator/VariableInfo.h
+++ b/gfx/angle/src/compiler/translator/VariableInfo.h
@@ -31,7 +31,7 @@ class CollectVariables : public TIntermTraverser
const TExtensionBehavior &extensionBehavior);
void visitSymbol(TIntermSymbol *symbol) override;
- bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *node) override;
bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
private:
diff --git a/gfx/angle/src/compiler/translator/VersionGLSL.cpp b/gfx/angle/src/compiler/translator/VersionGLSL.cpp
index 9e593ac76..c8718daa1 100755
--- a/gfx/angle/src/compiler/translator/VersionGLSL.cpp
+++ b/gfx/angle/src/compiler/translator/VersionGLSL.cpp
@@ -6,9 +6,6 @@
#include "compiler/translator/VersionGLSL.h"
-namespace sh
-{
-
int ShaderOutputTypeToGLSLVersion(ShShaderOutput output)
{
switch (output)
@@ -65,22 +62,25 @@ void TVersionGLSL::visitSymbol(TIntermSymbol *node)
}
}
-bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
-{
- const TIntermSequence &sequence = *(node->getSequence());
- if (sequence.front()->getAsTyped()->getType().isInvariant())
- {
- ensureVersionIsAtLeast(GLSL_VERSION_120);
- }
- return true;
-}
-
bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
{
bool visitChildren = true;
switch (node->getOp())
{
+ case EOpSequence:
+ // We need to visit sequence children to get to global or inner scope.
+ visitChildren = true;
+ break;
+ case EOpDeclaration:
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ if (sequence.front()->getAsTyped()->getType().isInvariant())
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ break;
+ }
case EOpInvariantDeclaration:
ensureVersionIsAtLeast(GLSL_VERSION_120);
break;
@@ -138,4 +138,3 @@ void TVersionGLSL::ensureVersionIsAtLeast(int version)
mVersion = std::max(version, mVersion);
}
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/VersionGLSL.h b/gfx/angle/src/compiler/translator/VersionGLSL.h
index 380349be0..c41069d42 100755
--- a/gfx/angle/src/compiler/translator/VersionGLSL.h
+++ b/gfx/angle/src/compiler/translator/VersionGLSL.h
@@ -11,9 +11,6 @@
#include "compiler/translator/Pragma.h"
-namespace sh
-{
-
static const int GLSL_VERSION_110 = 110;
static const int GLSL_VERSION_120 = 120;
static const int GLSL_VERSION_130 = 130;
@@ -61,7 +58,6 @@ class TVersionGLSL : public TIntermTraverser
void visitSymbol(TIntermSymbol *) override;
bool visitAggregate(Visit, TIntermAggregate *) override;
- bool visitDeclaration(Visit, TIntermDeclaration *node) override;
private:
void ensureVersionIsAtLeast(int version);
@@ -69,6 +65,4 @@ class TVersionGLSL : public TIntermTraverser
int mVersion;
};
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_VERSIONGLSL_H_
diff --git a/gfx/angle/src/compiler/translator/blocklayout.h b/gfx/angle/src/compiler/translator/blocklayout.h
index 298a72c92..dd5fe0737 100755
--- a/gfx/angle/src/compiler/translator/blocklayout.h
+++ b/gfx/angle/src/compiler/translator/blocklayout.h
@@ -24,7 +24,7 @@ struct Uniform;
struct Varying;
struct InterfaceBlock;
-struct BlockMemberInfo
+struct COMPILER_EXPORT BlockMemberInfo
{
BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {}
@@ -46,7 +46,7 @@ struct BlockMemberInfo
bool isRowMajorMatrix;
};
-class BlockLayoutEncoder
+class COMPILER_EXPORT BlockLayoutEncoder
{
public:
BlockLayoutEncoder();
@@ -77,7 +77,7 @@ class BlockLayoutEncoder
// Block layout according to the std140 block layout
// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
-class Std140BlockEncoder : public BlockLayoutEncoder
+class COMPILER_EXPORT Std140BlockEncoder : public BlockLayoutEncoder
{
public:
Std140BlockEncoder();
diff --git a/gfx/angle/src/compiler/translator/blocklayoutHLSL.h b/gfx/angle/src/compiler/translator/blocklayoutHLSL.h
index 8d98847bd..c61cb1ae5 100755
--- a/gfx/angle/src/compiler/translator/blocklayoutHLSL.h
+++ b/gfx/angle/src/compiler/translator/blocklayoutHLSL.h
@@ -24,7 +24,7 @@ namespace sh
// The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
// for everything else (D3D10+ constant blocks and all attributes/varyings).
-class HLSLBlockEncoder : public BlockLayoutEncoder
+class COMPILER_EXPORT HLSLBlockEncoder : public BlockLayoutEncoder
{
public:
enum HLSLBlockEncoderStrategy
@@ -54,8 +54,9 @@ class HLSLBlockEncoder : public BlockLayoutEncoder
// This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder
// class to count the number of used registers in a struct (which are individually packed according to the same rules).
-unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMatrices);
-unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType);
+COMPILER_EXPORT unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMatrices);
+COMPILER_EXPORT unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType);
+
}
#endif // COMMON_BLOCKLAYOUTHLSL_H_
diff --git a/gfx/angle/src/compiler/translator/depgraph/DependencyGraph.cpp b/gfx/angle/src/compiler/translator/depgraph/DependencyGraph.cpp
new file mode 100644
index 000000000..4dee0dbd2
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/depgraph/DependencyGraph.cpp
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/depgraph/DependencyGraph.h"
+#include "compiler/translator/depgraph/DependencyGraphBuilder.h"
+
+TDependencyGraph::TDependencyGraph(TIntermNode* intermNode)
+{
+ TDependencyGraphBuilder::build(intermNode, this);
+}
+
+TDependencyGraph::~TDependencyGraph()
+{
+ for (TGraphNodeVector::const_iterator iter = mAllNodes.begin(); iter != mAllNodes.end(); ++iter)
+ {
+ TGraphNode* node = *iter;
+ delete node;
+ }
+}
+
+TGraphArgument* TDependencyGraph::createArgument(TIntermAggregate* intermFunctionCall,
+ int argumentNumber)
+{
+ TGraphArgument* argument = new TGraphArgument(intermFunctionCall, argumentNumber);
+ mAllNodes.push_back(argument);
+ return argument;
+}
+
+TGraphFunctionCall* TDependencyGraph::createFunctionCall(TIntermAggregate* intermFunctionCall)
+{
+ TGraphFunctionCall* functionCall = new TGraphFunctionCall(intermFunctionCall);
+ mAllNodes.push_back(functionCall);
+ if (functionCall->getIntermFunctionCall()->isUserDefined())
+ mUserDefinedFunctionCalls.push_back(functionCall);
+ return functionCall;
+}
+
+TGraphSymbol* TDependencyGraph::getOrCreateSymbol(TIntermSymbol* intermSymbol)
+{
+ TSymbolIdMap::const_iterator iter = mSymbolIdMap.find(intermSymbol->getId());
+
+ TGraphSymbol* symbol = NULL;
+
+ if (iter != mSymbolIdMap.end()) {
+ TSymbolIdPair pair = *iter;
+ symbol = pair.second;
+ } else {
+ symbol = new TGraphSymbol(intermSymbol);
+ mAllNodes.push_back(symbol);
+
+ TSymbolIdPair pair(intermSymbol->getId(), symbol);
+ mSymbolIdMap.insert(pair);
+
+ // We save all sampler symbols in a collection, so we can start graph traversals from them quickly.
+ if (IsSampler(intermSymbol->getBasicType()))
+ mSamplerSymbols.push_back(symbol);
+ }
+
+ return symbol;
+}
+
+TGraphSelection* TDependencyGraph::createSelection(TIntermSelection* intermSelection)
+{
+ TGraphSelection* selection = new TGraphSelection(intermSelection);
+ mAllNodes.push_back(selection);
+ return selection;
+}
+
+TGraphLoop* TDependencyGraph::createLoop(TIntermLoop* intermLoop)
+{
+ TGraphLoop* loop = new TGraphLoop(intermLoop);
+ mAllNodes.push_back(loop);
+ return loop;
+}
+
+TGraphLogicalOp* TDependencyGraph::createLogicalOp(TIntermBinary* intermLogicalOp)
+{
+ TGraphLogicalOp* logicalOp = new TGraphLogicalOp(intermLogicalOp);
+ mAllNodes.push_back(logicalOp);
+ return logicalOp;
+}
+
+const char* TGraphLogicalOp::getOpString() const
+{
+ const char* opString = NULL;
+ switch (getIntermLogicalOp()->getOp()) {
+ case EOpLogicalAnd: opString = "and"; break;
+ case EOpLogicalOr: opString = "or"; break;
+ default: opString = "unknown"; break;
+ }
+ return opString;
+}
diff --git a/gfx/angle/src/compiler/translator/depgraph/DependencyGraph.h b/gfx/angle/src/compiler/translator/depgraph/DependencyGraph.h
new file mode 100644
index 000000000..2f7f7b9ab
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/depgraph/DependencyGraph.h
@@ -0,0 +1,199 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_
+#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_
+
+#include "compiler/translator/IntermNode.h"
+
+#include <set>
+#include <stack>
+
+class TGraphNode;
+class TGraphParentNode;
+class TGraphArgument;
+class TGraphFunctionCall;
+class TGraphSymbol;
+class TGraphSelection;
+class TGraphLoop;
+class TGraphLogicalOp;
+class TDependencyGraphTraverser;
+class TDependencyGraphOutput;
+
+typedef std::set<TGraphNode*> TGraphNodeSet;
+typedef std::vector<TGraphNode*> TGraphNodeVector;
+typedef std::vector<TGraphSymbol*> TGraphSymbolVector;
+typedef std::vector<TGraphFunctionCall*> TFunctionCallVector;
+
+//
+// Base class for all dependency graph nodes.
+//
+class TGraphNode {
+public:
+ TGraphNode(TIntermNode* node) : intermNode(node) {}
+ virtual ~TGraphNode() {}
+ virtual void traverse(TDependencyGraphTraverser* graphTraverser);
+protected:
+ TIntermNode* intermNode;
+};
+
+//
+// Base class for dependency graph nodes that may have children.
+//
+class TGraphParentNode : public TGraphNode {
+public:
+ TGraphParentNode(TIntermNode* node) : TGraphNode(node) {}
+ ~TGraphParentNode() override {}
+ void addDependentNode(TGraphNode* node) { if (node != this) mDependentNodes.insert(node); }
+ void traverse(TDependencyGraphTraverser *graphTraverser) override;
+
+private:
+ TGraphNodeSet mDependentNodes;
+};
+
+//
+// Handle function call arguments.
+//
+class TGraphArgument : public TGraphParentNode {
+public:
+ TGraphArgument(TIntermAggregate* intermFunctionCall, int argumentNumber)
+ : TGraphParentNode(intermFunctionCall)
+ , mArgumentNumber(argumentNumber) {}
+ ~TGraphArgument() override {}
+ const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); }
+ int getArgumentNumber() const { return mArgumentNumber; }
+ void traverse(TDependencyGraphTraverser *graphTraverser) override;
+
+private:
+ int mArgumentNumber;
+};
+
+//
+// Handle function calls.
+//
+class TGraphFunctionCall : public TGraphParentNode {
+public:
+ TGraphFunctionCall(TIntermAggregate* intermFunctionCall)
+ : TGraphParentNode(intermFunctionCall) {}
+ ~TGraphFunctionCall() override {}
+ const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); }
+ void traverse(TDependencyGraphTraverser *graphTraverser) override;
+};
+
+//
+// Handle symbols.
+//
+class TGraphSymbol : public TGraphParentNode {
+public:
+ TGraphSymbol(TIntermSymbol* intermSymbol) : TGraphParentNode(intermSymbol) {}
+ ~TGraphSymbol() override {}
+ const TIntermSymbol* getIntermSymbol() const { return intermNode->getAsSymbolNode(); }
+ void traverse(TDependencyGraphTraverser *graphTraverser) override;
+};
+
+//
+// Handle if statements and ternary operators.
+//
+class TGraphSelection : public TGraphNode {
+public:
+ TGraphSelection(TIntermSelection* intermSelection) : TGraphNode(intermSelection) {}
+ ~TGraphSelection() override {}
+ const TIntermSelection* getIntermSelection() const { return intermNode->getAsSelectionNode(); }
+ void traverse(TDependencyGraphTraverser *graphTraverser) override;
+};
+
+//
+// Handle for, do-while, and while loops.
+//
+class TGraphLoop : public TGraphNode {
+public:
+ TGraphLoop(TIntermLoop* intermLoop) : TGraphNode(intermLoop) {}
+ ~TGraphLoop() override {}
+ const TIntermLoop* getIntermLoop() const { return intermNode->getAsLoopNode(); }
+ void traverse(TDependencyGraphTraverser *graphTraverser) override;
+};
+
+//
+// Handle logical and, or.
+//
+class TGraphLogicalOp : public TGraphNode {
+public:
+ TGraphLogicalOp(TIntermBinary* intermLogicalOp) : TGraphNode(intermLogicalOp) {}
+ ~TGraphLogicalOp() override {}
+ const TIntermBinary* getIntermLogicalOp() const { return intermNode->getAsBinaryNode(); }
+ const char* getOpString() const;
+ void traverse(TDependencyGraphTraverser *graphTraverser) override;
+};
+
+//
+// A dependency graph of symbols, function calls, conditions etc.
+//
+// This class provides an interface to the entry points of the dependency graph.
+//
+// Dependency graph nodes should be created by using one of the provided "create..." methods.
+// This class (and nobody else) manages the memory of the created nodes.
+// Nodes may not be removed after being added, so all created nodes will exist while the
+// TDependencyGraph instance exists.
+//
+class TDependencyGraph {
+public:
+ TDependencyGraph(TIntermNode* intermNode);
+ ~TDependencyGraph();
+ const TGraphNodeVector &allNodes() const { return mAllNodes; }
+ const TGraphSymbolVector &samplerSymbols() const { return mSamplerSymbols; }
+ const TFunctionCallVector &userDefinedFunctionCalls() const
+ {
+ return mUserDefinedFunctionCalls;
+ }
+
+ TGraphArgument* createArgument(TIntermAggregate* intermFunctionCall, int argumentNumber);
+ TGraphFunctionCall* createFunctionCall(TIntermAggregate* intermFunctionCall);
+ TGraphSymbol* getOrCreateSymbol(TIntermSymbol* intermSymbol);
+ TGraphSelection* createSelection(TIntermSelection* intermSelection);
+ TGraphLoop* createLoop(TIntermLoop* intermLoop);
+ TGraphLogicalOp* createLogicalOp(TIntermBinary* intermLogicalOp);
+private:
+ typedef TMap<int, TGraphSymbol*> TSymbolIdMap;
+ typedef std::pair<int, TGraphSymbol*> TSymbolIdPair;
+
+ TGraphNodeVector mAllNodes;
+ TGraphSymbolVector mSamplerSymbols;
+ TFunctionCallVector mUserDefinedFunctionCalls;
+ TSymbolIdMap mSymbolIdMap;
+};
+
+//
+// For traversing the dependency graph. Users should derive from this,
+// put their traversal specific data in it, and then pass it to a
+// traverse method.
+//
+// When using this, just fill in the methods for nodes you want visited.
+//
+class TDependencyGraphTraverser : angle::NonCopyable {
+public:
+ TDependencyGraphTraverser() : mDepth(0) {}
+ virtual ~TDependencyGraphTraverser() {}
+
+ virtual void visitSymbol(TGraphSymbol* symbol) {};
+ virtual void visitArgument(TGraphArgument* selection) {};
+ virtual void visitFunctionCall(TGraphFunctionCall* functionCall) {};
+ virtual void visitSelection(TGraphSelection* selection) {};
+ virtual void visitLoop(TGraphLoop* loop) {};
+ virtual void visitLogicalOp(TGraphLogicalOp* logicalOp) {};
+
+ int getDepth() const { return mDepth; }
+ void incrementDepth() { ++mDepth; }
+ void decrementDepth() { --mDepth; }
+
+ void clearVisited() { mVisited.clear(); }
+ void markVisited(TGraphNode* node) { mVisited.insert(node); }
+ bool isVisited(TGraphNode* node) const { return mVisited.find(node) != mVisited.end(); }
+private:
+ int mDepth;
+ TGraphNodeSet mVisited;
+};
+
+#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_
diff --git a/gfx/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp
new file mode 100644
index 000000000..1aeb822d5
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp
@@ -0,0 +1,255 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/depgraph/DependencyGraphBuilder.h"
+
+void TDependencyGraphBuilder::build(TIntermNode *node, TDependencyGraph *graph)
+{
+ TDependencyGraphBuilder builder(graph);
+ builder.build(node);
+}
+
+bool TDependencyGraphBuilder::visitAggregate(
+ Visit visit, TIntermAggregate *intermAggregate)
+{
+ switch (intermAggregate->getOp())
+ {
+ case EOpFunction:
+ visitFunctionDefinition(intermAggregate);
+ break;
+ case EOpFunctionCall:
+ visitFunctionCall(intermAggregate);
+ break;
+ default:
+ visitAggregateChildren(intermAggregate);
+ break;
+ }
+ return false;
+}
+
+void TDependencyGraphBuilder::visitFunctionDefinition(
+ TIntermAggregate *intermAggregate)
+{
+ // Currently, we do not support user defined functions.
+ if (intermAggregate->getName() != "main(")
+ return;
+
+ visitAggregateChildren(intermAggregate);
+}
+
+// Takes an expression like "f(x)" and creates a dependency graph like
+// "x -> argument 0 -> function call".
+void TDependencyGraphBuilder::visitFunctionCall(
+ TIntermAggregate *intermFunctionCall)
+{
+ TGraphFunctionCall *functionCall =
+ mGraph->createFunctionCall(intermFunctionCall);
+
+ // Run through the function call arguments.
+ int argumentNumber = 0;
+ TIntermSequence *intermArguments = intermFunctionCall->getSequence();
+ for (TIntermSequence::const_iterator iter = intermArguments->begin();
+ iter != intermArguments->end();
+ ++iter, ++argumentNumber)
+ {
+ TNodeSetMaintainer nodeSetMaintainer(this);
+
+ TIntermNode *intermArgument = *iter;
+ intermArgument->traverse(this);
+
+ if (TParentNodeSet *argumentNodes = mNodeSets.getTopSet())
+ {
+ TGraphArgument *argument = mGraph->createArgument(
+ intermFunctionCall, argumentNumber);
+ connectMultipleNodesToSingleNode(argumentNodes, argument);
+ argument->addDependentNode(functionCall);
+ }
+ }
+
+ // Push the leftmost symbol of this function call into the current set of
+ // dependent symbols to represent the result of this function call.
+ // Thus, an expression like "y = f(x)" will yield a dependency graph like
+ // "x -> argument 0 -> function call -> y".
+ // This line essentially passes the function call node back up to an earlier
+ // visitAssignment call, which will create the connection "function call -> y".
+ mNodeSets.insertIntoTopSet(functionCall);
+}
+
+void TDependencyGraphBuilder::visitAggregateChildren(
+ TIntermAggregate *intermAggregate)
+{
+ TIntermSequence *sequence = intermAggregate->getSequence();
+ for (TIntermSequence::const_iterator iter = sequence->begin();
+ iter != sequence->end(); ++iter)
+ {
+ TIntermNode *intermChild = *iter;
+ intermChild->traverse(this);
+ }
+}
+
+void TDependencyGraphBuilder::visitSymbol(TIntermSymbol *intermSymbol)
+{
+ // Push this symbol into the set of dependent symbols for the current
+ // assignment or condition that we are traversing.
+ TGraphSymbol *symbol = mGraph->getOrCreateSymbol(intermSymbol);
+ mNodeSets.insertIntoTopSet(symbol);
+
+ // If this symbol is the current leftmost symbol under an assignment, replace
+ // the previous leftmost symbol with this symbol.
+ if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree)
+ {
+ mLeftmostSymbols.pop();
+ mLeftmostSymbols.push(symbol);
+ }
+}
+
+bool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary *intermBinary)
+{
+ TOperator op = intermBinary->getOp();
+ if (op == EOpInitialize || intermBinary->isAssignment())
+ visitAssignment(intermBinary);
+ else if (op == EOpLogicalAnd || op == EOpLogicalOr)
+ visitLogicalOp(intermBinary);
+ else
+ visitBinaryChildren(intermBinary);
+
+ return false;
+}
+
+void TDependencyGraphBuilder::visitAssignment(TIntermBinary *intermAssignment)
+{
+ TIntermTyped *intermLeft = intermAssignment->getLeft();
+ if (!intermLeft)
+ return;
+
+ TGraphSymbol *leftmostSymbol = NULL;
+
+ {
+ TNodeSetMaintainer nodeSetMaintainer(this);
+
+ {
+ TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mLeftSubtree);
+ intermLeft->traverse(this);
+ leftmostSymbol = mLeftmostSymbols.top();
+
+ // After traversing the left subtree of this assignment, we should
+ // have found a real leftmost symbol, and the leftmost symbol should
+ // not be a placeholder.
+ ASSERT(leftmostSymbol != &mLeftSubtree);
+ ASSERT(leftmostSymbol != &mRightSubtree);
+ }
+
+ if (TIntermTyped *intermRight = intermAssignment->getRight())
+ {
+ TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
+ intermRight->traverse(this);
+ }
+
+ if (TParentNodeSet *assignmentNodes = mNodeSets.getTopSet())
+ connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol);
+ }
+
+ // Push the leftmost symbol of this assignment into the current set of dependent
+ // symbols to represent the result of this assignment.
+ // An expression like "a = (b = c)" will yield a dependency graph like
+ // "c -> b -> a".
+ // This line essentially passes the leftmost symbol of the nested assignment
+ // ("b" in this example) back up to the earlier visitAssignment call for the
+ // outer assignment, which will create the connection "b -> a".
+ mNodeSets.insertIntoTopSet(leftmostSymbol);
+}
+
+void TDependencyGraphBuilder::visitLogicalOp(TIntermBinary *intermLogicalOp)
+{
+ if (TIntermTyped *intermLeft = intermLogicalOp->getLeft())
+ {
+ TNodeSetPropagatingMaintainer nodeSetMaintainer(this);
+
+ intermLeft->traverse(this);
+ if (TParentNodeSet *leftNodes = mNodeSets.getTopSet())
+ {
+ TGraphLogicalOp *logicalOp = mGraph->createLogicalOp(intermLogicalOp);
+ connectMultipleNodesToSingleNode(leftNodes, logicalOp);
+ }
+ }
+
+ if (TIntermTyped *intermRight = intermLogicalOp->getRight())
+ {
+ TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
+ intermRight->traverse(this);
+ }
+}
+
+void TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary *intermBinary)
+{
+ if (TIntermTyped *intermLeft = intermBinary->getLeft())
+ intermLeft->traverse(this);
+
+ if (TIntermTyped *intermRight = intermBinary->getRight())
+ {
+ TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
+ intermRight->traverse(this);
+ }
+}
+
+bool TDependencyGraphBuilder::visitSelection(
+ Visit visit, TIntermSelection *intermSelection)
+{
+ if (TIntermNode *intermCondition = intermSelection->getCondition())
+ {
+ TNodeSetMaintainer nodeSetMaintainer(this);
+
+ intermCondition->traverse(this);
+ if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet())
+ {
+ TGraphSelection *selection = mGraph->createSelection(intermSelection);
+ connectMultipleNodesToSingleNode(conditionNodes, selection);
+ }
+ }
+
+ if (TIntermNode *intermTrueBlock = intermSelection->getTrueBlock())
+ intermTrueBlock->traverse(this);
+
+ if (TIntermNode *intermFalseBlock = intermSelection->getFalseBlock())
+ intermFalseBlock->traverse(this);
+
+ return false;
+}
+
+bool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop *intermLoop)
+{
+ if (TIntermTyped *intermCondition = intermLoop->getCondition())
+ {
+ TNodeSetMaintainer nodeSetMaintainer(this);
+
+ intermCondition->traverse(this);
+ if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet())
+ {
+ TGraphLoop *loop = mGraph->createLoop(intermLoop);
+ connectMultipleNodesToSingleNode(conditionNodes, loop);
+ }
+ }
+
+ if (TIntermNode* intermBody = intermLoop->getBody())
+ intermBody->traverse(this);
+
+ if (TIntermTyped *intermExpression = intermLoop->getExpression())
+ intermExpression->traverse(this);
+
+ return false;
+}
+
+
+void TDependencyGraphBuilder::connectMultipleNodesToSingleNode(
+ TParentNodeSet *nodes, TGraphNode *node) const
+{
+ for (TParentNodeSet::const_iterator iter = nodes->begin();
+ iter != nodes->end(); ++iter)
+ {
+ TGraphParentNode *currentNode = *iter;
+ currentNode->addDependentNode(node);
+ }
+}
diff --git a/gfx/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h
new file mode 100644
index 000000000..c7b54f66b
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h
@@ -0,0 +1,199 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_
+#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_
+
+#include "compiler/translator/depgraph/DependencyGraph.h"
+
+//
+// Creates a dependency graph of symbols, function calls, conditions etc. by
+// traversing a intermediate tree.
+//
+class TDependencyGraphBuilder : public TIntermTraverser
+{
+ public:
+ static void build(TIntermNode *node, TDependencyGraph *graph);
+
+ void visitSymbol(TIntermSymbol *) override;
+ bool visitBinary(Visit visit, TIntermBinary *) override;
+ bool visitSelection(Visit visit, TIntermSelection *) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *) override;
+ bool visitLoop(Visit visit, TIntermLoop *) override;
+
+ private:
+ typedef std::stack<TGraphSymbol *> TSymbolStack;
+ typedef std::set<TGraphParentNode *> TParentNodeSet;
+
+ //
+ // For collecting the dependent nodes of assignments, conditions, etc.
+ // while traversing the intermediate tree.
+ //
+ // This data structure is stack of sets. Each set contains dependency graph
+ // parent nodes.
+ //
+ class TNodeSetStack
+ {
+ public:
+ TNodeSetStack() {};
+ ~TNodeSetStack() { clear(); }
+
+ // This should only be called after a pushSet.
+ // Returns NULL if the top set is empty.
+ TParentNodeSet *getTopSet() const
+ {
+ ASSERT(!mNodeSets.empty());
+ TParentNodeSet *topSet = mNodeSets.top();
+ return !topSet->empty() ? topSet : NULL;
+ }
+
+ void pushSet() { mNodeSets.push(new TParentNodeSet()); }
+ void popSet()
+ {
+ ASSERT(!mNodeSets.empty());
+ delete mNodeSets.top();
+ mNodeSets.pop();
+ }
+
+ // Pops the top set and adds its contents to the new top set.
+ // This should only be called after a pushSet.
+ // If there is no set below the top set, the top set is just deleted.
+ void popSetIntoNext()
+ {
+ ASSERT(!mNodeSets.empty());
+ TParentNodeSet *oldTopSet = mNodeSets.top();
+ mNodeSets.pop();
+
+ if (!mNodeSets.empty())
+ {
+ TParentNodeSet *newTopSet = mNodeSets.top();
+ newTopSet->insert(oldTopSet->begin(), oldTopSet->end());
+ }
+
+ delete oldTopSet;
+ }
+
+ // Does nothing if there is no top set.
+ // This can be called when there is no top set if we are visiting
+ // symbols that are not under an assignment or condition.
+ // We don't need to track those symbols.
+ void insertIntoTopSet(TGraphParentNode *node)
+ {
+ if (mNodeSets.empty())
+ return;
+
+ mNodeSets.top()->insert(node);
+ }
+
+ void clear()
+ {
+ while (!mNodeSets.empty())
+ popSet();
+ }
+
+ private:
+ typedef std::stack<TParentNodeSet *> TParentNodeSetStack;
+
+ TParentNodeSetStack mNodeSets;
+ };
+
+ //
+ // An instance of this class pushes a new node set when instantiated.
+ // When the instance goes out of scope, it and pops the node set.
+ //
+ class TNodeSetMaintainer : angle::NonCopyable
+ {
+ public:
+ TNodeSetMaintainer(TDependencyGraphBuilder *factory)
+ : mSets(factory->mNodeSets)
+ {
+ mSets.pushSet();
+ }
+ ~TNodeSetMaintainer() { mSets.popSet(); }
+ protected:
+ TNodeSetStack &mSets;
+ };
+
+ //
+ // An instance of this class pushes a new node set when instantiated.
+ // When the instance goes out of scope, it and pops the top node set and adds
+ // its contents to the new top node set.
+ //
+ class TNodeSetPropagatingMaintainer : angle::NonCopyable
+ {
+ public:
+ TNodeSetPropagatingMaintainer(TDependencyGraphBuilder *factory)
+ : mSets(factory->mNodeSets)
+ {
+ mSets.pushSet();
+ }
+ ~TNodeSetPropagatingMaintainer() { mSets.popSetIntoNext(); }
+ protected:
+ TNodeSetStack &mSets;
+ };
+
+ //
+ // An instance of this class keeps track of the leftmost symbol while we're
+ // exploring an assignment.
+ // It will push the placeholder symbol kLeftSubtree when instantiated under a
+ // left subtree, and kRightSubtree under a right subtree.
+ // When it goes out of scope, it will pop the leftmost symbol at the top of the
+ // scope.
+ // During traversal, the TDependencyGraphBuilder will replace kLeftSubtree with
+ // a real symbol.
+ // kRightSubtree will never be replaced by a real symbol because we are tracking
+ // the leftmost symbol.
+ //
+ class TLeftmostSymbolMaintainer : angle::NonCopyable
+ {
+ public:
+ TLeftmostSymbolMaintainer(
+ TDependencyGraphBuilder *factory, TGraphSymbol &subtree)
+ : mLeftmostSymbols(factory->mLeftmostSymbols)
+ {
+ mNeedsPlaceholderSymbol =
+ mLeftmostSymbols.empty() || mLeftmostSymbols.top() != &subtree;
+ if (mNeedsPlaceholderSymbol)
+ mLeftmostSymbols.push(&subtree);
+ }
+
+ ~TLeftmostSymbolMaintainer()
+ {
+ if (mNeedsPlaceholderSymbol)
+ mLeftmostSymbols.pop();
+ }
+
+ protected:
+ TSymbolStack& mLeftmostSymbols;
+ bool mNeedsPlaceholderSymbol;
+ };
+
+ TDependencyGraphBuilder(TDependencyGraph *graph)
+ : TIntermTraverser(true, false, false),
+ mLeftSubtree(NULL),
+ mRightSubtree(NULL),
+ mGraph(graph) {}
+ void build(TIntermNode *intermNode) { intermNode->traverse(this); }
+
+ void connectMultipleNodesToSingleNode(
+ TParentNodeSet *nodes, TGraphNode *node) const;
+
+ void visitAssignment(TIntermBinary *);
+ void visitLogicalOp(TIntermBinary *);
+ void visitBinaryChildren(TIntermBinary *);
+ void visitFunctionDefinition(TIntermAggregate *);
+ void visitFunctionCall(TIntermAggregate *intermFunctionCall);
+ void visitAggregateChildren(TIntermAggregate *);
+
+ TGraphSymbol mLeftSubtree;
+ TGraphSymbol mRightSubtree;
+
+ TDependencyGraph *mGraph;
+ TNodeSetStack mNodeSets;
+ TSymbolStack mLeftmostSymbols;
+};
+
+#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_
diff --git a/gfx/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp
new file mode 100644
index 000000000..32a2f3014
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/depgraph/DependencyGraphOutput.h"
+
+void TDependencyGraphOutput::outputIndentation()
+{
+ for (int i = 0; i < getDepth(); ++i)
+ mSink << " ";
+}
+
+void TDependencyGraphOutput::visitArgument(TGraphArgument* parameter)
+{
+ outputIndentation();
+ mSink << "argument " << parameter->getArgumentNumber() << " of call to "
+ << parameter->getIntermFunctionCall()->getName() << "\n";
+}
+
+void TDependencyGraphOutput::visitFunctionCall(TGraphFunctionCall* functionCall)
+{
+ outputIndentation();
+ mSink << "function call " << functionCall->getIntermFunctionCall()->getName() << "\n";
+}
+
+void TDependencyGraphOutput::visitSymbol(TGraphSymbol* symbol)
+{
+ outputIndentation();
+ mSink << symbol->getIntermSymbol()->getSymbol() << " (symbol id: "
+ << symbol->getIntermSymbol()->getId() << ")\n";
+}
+
+void TDependencyGraphOutput::visitSelection(TGraphSelection* selection)
+{
+ outputIndentation();
+ mSink << "selection\n";
+}
+
+void TDependencyGraphOutput::visitLoop(TGraphLoop* loop)
+{
+ outputIndentation();
+ mSink << "loop condition\n";
+}
+
+void TDependencyGraphOutput::visitLogicalOp(TGraphLogicalOp* logicalOp)
+{
+ outputIndentation();
+ mSink << "logical " << logicalOp->getOpString() << "\n";
+}
+
+void TDependencyGraphOutput::outputAllSpanningTrees(TDependencyGraph& graph)
+{
+ mSink << "\n";
+
+ for (auto symbol : graph.allNodes())
+ {
+ mSink << "--- Dependency graph spanning tree ---\n";
+ clearVisited();
+ symbol->traverse(this);
+ mSink << "\n";
+ }
+}
diff --git a/gfx/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h
new file mode 100644
index 000000000..b201e0a67
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h
@@ -0,0 +1,31 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_
+#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_
+
+#include "compiler/translator/depgraph/DependencyGraph.h"
+#include "compiler/translator/InfoSink.h"
+
+class TDependencyGraphOutput : public TDependencyGraphTraverser
+{
+ public:
+ TDependencyGraphOutput(TInfoSinkBase& sink) : mSink(sink) {}
+ void visitSymbol(TGraphSymbol* symbol) override;
+ void visitArgument(TGraphArgument* parameter) override;
+ void visitFunctionCall(TGraphFunctionCall* functionCall) override;
+ void visitSelection(TGraphSelection* selection) override;
+ void visitLoop(TGraphLoop* loop) override;
+ void visitLogicalOp(TGraphLogicalOp* logicalOp) override;
+
+ void outputAllSpanningTrees(TDependencyGraph& graph);
+ private:
+ void outputIndentation();
+
+ TInfoSinkBase& mSink;
+};
+
+#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_
diff --git a/gfx/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp
new file mode 100644
index 000000000..197fde97e
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp
@@ -0,0 +1,69 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/depgraph/DependencyGraph.h"
+
+// These methods do a breadth-first traversal through the graph and mark visited nodes.
+
+void TGraphNode::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+ graphTraverser->markVisited(this);
+}
+
+void TGraphParentNode::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+ TGraphNode::traverse(graphTraverser);
+
+ graphTraverser->incrementDepth();
+
+ // Visit the parent node's children.
+ for (TGraphNodeSet::const_iterator iter = mDependentNodes.begin();
+ iter != mDependentNodes.end();
+ ++iter)
+ {
+ TGraphNode* node = *iter;
+ if (!graphTraverser->isVisited(node))
+ node->traverse(graphTraverser);
+ }
+
+ graphTraverser->decrementDepth();
+}
+
+void TGraphArgument::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+ graphTraverser->visitArgument(this);
+ TGraphParentNode::traverse(graphTraverser);
+}
+
+void TGraphFunctionCall::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+ graphTraverser->visitFunctionCall(this);
+ TGraphParentNode::traverse(graphTraverser);
+}
+
+void TGraphSymbol::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+ graphTraverser->visitSymbol(this);
+ TGraphParentNode::traverse(graphTraverser);
+}
+
+void TGraphSelection::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+ graphTraverser->visitSelection(this);
+ TGraphNode::traverse(graphTraverser);
+}
+
+void TGraphLoop::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+ graphTraverser->visitLoop(this);
+ TGraphNode::traverse(graphTraverser);
+}
+
+void TGraphLogicalOp::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+ graphTraverser->visitLogicalOp(this);
+ TGraphNode::traverse(graphTraverser);
+}
diff --git a/gfx/angle/src/compiler/translator/glslang.h b/gfx/angle/src/compiler/translator/glslang.h
index aaa5dd119..0555e96d4 100755
--- a/gfx/angle/src/compiler/translator/glslang.h
+++ b/gfx/angle/src/compiler/translator/glslang.h
@@ -7,18 +7,14 @@
#ifndef COMPILER_TRANSLATOR_GLSLANG_H_
#define COMPILER_TRANSLATOR_GLSLANG_H_
-namespace sh
-{
class TParseContext;
-}
-
-extern int glslang_initialize(sh::TParseContext *context);
-extern int glslang_finalize(sh::TParseContext *context);
+extern int glslang_initialize(TParseContext* context);
+extern int glslang_finalize(TParseContext* context);
extern int glslang_scan(size_t count,
- const char *const string[],
+ const char* const string[],
const int length[],
- sh::TParseContext *context);
-extern int glslang_parse(sh::TParseContext *context);
+ TParseContext* context);
+extern int glslang_parse(TParseContext* context);
#endif // COMPILER_TRANSLATOR_GLSLANG_H_
diff --git a/gfx/angle/src/compiler/translator/glslang.l b/gfx/angle/src/compiler/translator/glslang.l
index a30f2c33e..7fe289302 100755
--- a/gfx/angle/src/compiler/translator/glslang.l
+++ b/gfx/angle/src/compiler/translator/glslang.l
@@ -22,8 +22,6 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
-/* clang-format off */
-
// Ignore errors in auto-generated code.
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wunused-function"
@@ -46,9 +44,6 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
#include "compiler/preprocessor/Token.h"
#include "compiler/translator/util.h"
#include "compiler/translator/length_limits.h"
-
-using namespace sh;
-
#include "glslang_tab.h"
/* windows only pragma */
@@ -76,8 +71,6 @@ static int reserved_word(yyscan_t yyscanner);
static int ES2_reserved_ES3_keyword(TParseContext *context, int token);
static int ES2_keyword_ES3_reserved(TParseContext *context, int token);
static int ES2_ident_ES3_keyword(TParseContext *context, int token);
-static int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
-static int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
static int uint_constant(TParseContext *context);
static int int_constant(TParseContext *context);
static int float_constant(yyscan_t yyscanner);
@@ -194,25 +187,11 @@ O [0-7]
"layout" { return ES2_ident_ES3_keyword(context, LAYOUT); }
-"image2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2D); }
-"iimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2D); }
-"uimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2D); }
-"image2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY); }
-"iimage2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY); }
-"uimage2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY); }
-"image3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE3D); }
-"uimage3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE3D); }
-"iimage3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE3D); }
-"iimageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGECUBE); }
-"uimageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGECUBE); }
-"imageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGECUBE); }
-"readonly" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, READONLY); }
-"writeonly" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, WRITEONLY); }
-"coherent" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, COHERENT); }
-"restrict" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, RESTRICT); }
-"volatile" { return ES2_and_ES3_reserved_ES3_1_keyword(context, VOLATILE); }
-
/* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
+"coherent" |
+"restrict" |
+"readonly" |
+"writeonly" |
"resource" |
"atomic_uint" |
"noperspective" |
@@ -225,11 +204,23 @@ O [0-7]
"filter" |
"image1D" |
+"image2D" |
+"image3D" |
+"imageCube" |
"iimage1D" |
+"iimage2D" |
+"iimage3D" |
+"iimageCube" |
"uimage1D" |
+"uimage2D" |
+"uimage3D" |
+"uimageCube" |
"image1DArray" |
+"image2DArray" |
"iimage1DArray" |
+"iimage2DArray" |
"uimage1DArray" |
+"uimage2DArray" |
"image1DShadow" |
"image2DShadow" |
"image1DArrayShadow" |
@@ -287,6 +278,7 @@ O [0-7]
"inline" |
"noinline" |
+"volatile" |
"public" |
"static" |
"extern" |
@@ -471,24 +463,6 @@ int ES2_keyword_ES3_reserved(TParseContext *context, int token)
return token;
}
-int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
-{
- struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
- yyscan_t yyscanner = (yyscan_t) context->getScanner();
-
- if (context->getShaderVersion() < 300)
- {
- yylval->lex.string = NewPoolTString(yytext);
- return check_type(yyscanner);
- }
- else if (context->getShaderVersion() == 300)
- {
- return reserved_word(yyscanner);
- }
-
- return token;
-}
-
int ES2_ident_ES3_keyword(TParseContext *context, int token)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
@@ -504,18 +478,6 @@ int ES2_ident_ES3_keyword(TParseContext *context, int token)
return token;
}
-int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
-{
- yyscan_t yyscanner = (yyscan_t) context->getScanner();
-
- if (context->getShaderVersion() < 310)
- {
- return reserved_word(yyscanner);
- }
-
- return token;
-}
-
int uint_constant(TParseContext *context)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
@@ -617,7 +579,8 @@ int glslang_scan(size_t count, const char* const string[], const int length[],
if (context->getFragmentPrecisionHigh())
preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
- preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec()));
+ preprocessor->setMaxTokenSize(GetGlobalMaxTokenSize(context->getShaderSpec()));
return 0;
}
+
diff --git a/gfx/angle/src/compiler/translator/glslang.y b/gfx/angle/src/compiler/translator/glslang.y
index c15dd9d6e..8604d8eb6 100755
--- a/gfx/angle/src/compiler/translator/glslang.y
+++ b/gfx/angle/src/compiler/translator/glslang.y
@@ -46,8 +46,6 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
#define YYENABLE_NLS 0
-using namespace sh;
-
%}
%expect 1 /* One shift reduce conflict because of if | else */
%parse-param {TParseContext* context}
@@ -74,27 +72,22 @@ using namespace sh;
struct {
TOperator op;
union {
- TIntermNode *intermNode;
+ TIntermNode* intermNode;
TIntermNodePair nodePair;
- TIntermTyped *intermTypedNode;
- TIntermAggregate *intermAggregate;
- TIntermBlock *intermBlock;
- TIntermDeclaration *intermDeclaration;
- TIntermSwitch *intermSwitch;
- TIntermCase *intermCase;
+ TIntermTyped* intermTypedNode;
+ TIntermAggregate* intermAggregate;
+ TIntermSwitch* intermSwitch;
+ TIntermCase* intermCase;
};
union {
- TTypeSpecifierNonArray typeSpecifierNonArray;
TPublicType type;
TPrecision precision;
TLayoutQualifier layoutQualifier;
TQualifier qualifier;
- TFunction *function;
+ TFunction* function;
TParameter param;
- TField *field;
- TFieldList *fieldList;
- TQualifierWrapperBase *qualifierWrapper;
- TTypeQualifierBuilder *typeQualifierBuilder;
+ TField* field;
+ TFieldList* fieldList;
};
} interm;
}
@@ -169,14 +162,11 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
%token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3
%token <lex> CENTROID FLAT SMOOTH
-%token <lex> READONLY WRITEONLY COHERENT RESTRICT VOLATILE
%token <lex> STRUCT VOID_TYPE WHILE
%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT SAMPLER2DARRAY
%token <lex> ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY
%token <lex> USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY
%token <lex> SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW
-%token <lex> IMAGE2D IIMAGE2D UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY
-%token <lex> IMAGECUBE IIMAGECUBE UIMAGECUBE
%token <lex> LAYOUT
%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT
@@ -202,9 +192,9 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
%type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
%type <interm.intermTypedNode> function_call initializer condition conditionopt
-%type <interm.intermBlock> translation_unit
-%type <interm.intermNode> function_definition statement simple_statement
-%type <interm.intermBlock> statement_list compound_statement compound_statement_no_new_scope
+%type <interm.intermNode> translation_unit function_definition
+%type <interm.intermNode> statement simple_statement
+%type <interm.intermAggregate> statement_list compound_statement compound_statement_no_new_scope
%type <interm.intermNode> declaration_statement selection_statement expression_statement
%type <interm.intermNode> declaration external_declaration
%type <interm.intermNode> for_init_statement
@@ -215,18 +205,13 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
%type <interm> single_declaration init_declarator_list
%type <interm> parameter_declaration parameter_declarator parameter_type_specifier
-%type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id
-
-%type <interm.type> fully_specified_type type_specifier
+%type <interm.qualifier> parameter_qualifier parameter_type_qualifier
+%type <interm.layoutQualifier> layout_qualifier layout_qualifier_id_list layout_qualifier_id
%type <interm.precision> precision_qualifier
-%type <interm.layoutQualifier> layout_qualifier
-%type <interm.qualifier> interpolation_qualifier
-%type <interm.qualifierWrapper> storage_qualifier single_type_qualifier invariant_qualifier
-%type <interm.typeQualifierBuilder> type_qualifier
-
-%type <interm.typeSpecifierNonArray> type_specifier_nonarray struct_specifier
-%type <interm.type> type_specifier_no_prec
+%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier
+%type <interm.type> type_specifier_no_prec type_specifier_nonarray
+%type <interm.type> struct_specifier
%type <interm.field> struct_declarator
%type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list
%type <interm.function> function_header function_declarator function_identifier
@@ -358,7 +343,7 @@ function_call_header_with_parameters
const TType *type = new TType($2->getType());
$1->addParameter(TConstParameter(type));
$$.function = $1;
- $$.nodePair.node1 = TIntermediate::MakeAggregate($2, @2);
+ $$.nodePair.node1 = context->intermediate.makeAggregate($2, @2);
}
| function_call_header_with_parameters COMMA assignment_expression {
const TType *type = new TType($3->getType());
@@ -609,43 +594,41 @@ declaration
$$ = context->addFunctionPrototypeDeclaration(*($1.function), @1);
}
| init_declarator_list SEMICOLON {
- $$ = $1.intermDeclaration;
+ TIntermAggregate *aggNode = $1.intermAggregate;
+ if (aggNode && aggNode->getOp() == EOpNull)
+ aggNode->setOp(EOpDeclaration);
+ $$ = aggNode;
}
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) {
context->error(@1, "precision is not supported in fragment shader", "highp");
}
if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
- context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.getBasicType()));
+ context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type));
}
$$ = 0;
}
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON {
- ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks");
- $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, NULL, @$, NULL, @$);
+ ES3_OR_NEWER(getQualifierString($1.qualifier), @1, "interface blocks");
+ $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, NULL, @$, NULL, @$);
}
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON {
- ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks");
- $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, NULL, @$);
+ ES3_OR_NEWER(getQualifierString($1.qualifier), @1, "interface blocks");
+ $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, NULL, @$);
}
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON {
- ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks");
- $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, $7, @6);
+ ES3_OR_NEWER(getQualifierString($1.qualifier), @1, "interface blocks");
+ $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, $7, @6);
}
| type_qualifier SEMICOLON {
- context->parseGlobalLayoutQualifier(*$1);
+ context->parseGlobalLayoutQualifier($1);
$$ = 0;
}
- | type_qualifier IDENTIFIER SEMICOLON // e.g. to qualify an existing variable as invariant
- {
- $$ = context->parseInvariantDeclaration(*$1, @2, $2.string, $2.symbol);
- }
;
function_prototype
: function_declarator RIGHT_PAREN {
$$.function = context->parseFunctionDeclarator(@2, $1);
- context->exitFunctionDeclaration();
}
;
@@ -692,14 +675,13 @@ function_header
$$ = context->parseFunctionHeader($1, $2.string, @2);
context->symbolTable.push();
- context->enterFunctionDeclaration();
}
;
parameter_declarator
// Type + name
: type_specifier identifier {
- if ($1.getBasicType() == EbtVoid) {
+ if ($1.type == EbtVoid) {
context->error(@2, "illegal use of type 'void'", $2.string->c_str());
}
context->checkIsNotReserved(@2, *$2.string);
@@ -731,21 +713,41 @@ parameter_declaration
//
// Type + name
//
- : type_qualifier parameter_declarator {
+ : parameter_type_qualifier parameter_qualifier parameter_declarator {
+ $$ = $3;
+ context->checkIsParameterQualifierValid(@3, $1, $2, $$.param.type);
+ }
+ | parameter_qualifier parameter_declarator {
$$ = $2;
- context->checkIsParameterQualifierValid(@2, *$1, $2.param.type);
+ context->checkOutParameterIsNotSampler(@2, $1, *$2.param.type);
+ context->checkIsParameterQualifierValid(@2, EvqTemporary, $1, $$.param.type);
}
- | parameter_declarator {
- $$ = $1;
- $$.param.type->setQualifier(EvqIn);
+ //
+ // Only type
+ //
+ | parameter_type_qualifier parameter_qualifier parameter_type_specifier {
+ $$ = $3;
+ context->checkIsParameterQualifierValid(@3, $1, $2, $$.param.type);
}
- | type_qualifier parameter_type_specifier {
+ | parameter_qualifier parameter_type_specifier {
$$ = $2;
- context->checkIsParameterQualifierValid(@2, *$1, $2.param.type);
+ context->checkOutParameterIsNotSampler(@2, $1, *$2.param.type);
+ context->checkIsParameterQualifierValid(@2, EvqTemporary, $1, $$.param.type);
}
- | parameter_type_specifier {
- $$ = $1;
- $$.param.type->setQualifier(EvqIn);
+ ;
+
+parameter_qualifier
+ : /* empty */ {
+ $$ = EvqIn;
+ }
+ | IN_QUAL {
+ $$ = EvqIn;
+ }
+ | OUT_QUAL {
+ $$ = EvqOut;
+ }
+ | INOUT_QUAL {
+ $$ = EvqInOut;
}
;
@@ -762,209 +764,209 @@ init_declarator_list
}
| init_declarator_list COMMA identifier {
$$ = $1;
- context->parseDeclarator($$.type, @3, *$3.string, $$.intermDeclaration);
+ $$.intermAggregate = context->parseDeclarator($$.type, $1.intermAggregate, @3, *$3.string);
}
| init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$ = $1;
- context->parseArrayDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration);
+ $$.intermAggregate = context->parseArrayDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5);
}
| init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
ES3_OR_NEWER("[]", @3, "implicitly sized array");
$$ = $1;
- context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, nullptr, @6, $7, $$.intermDeclaration);
+ $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, nullptr, @6, $7);
}
| init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
ES3_OR_NEWER("=", @7, "first-class arrays (array initializer)");
$$ = $1;
- context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, $5, @7, $8, $$.intermDeclaration);
+ $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5, @7, $8);
}
| init_declarator_list COMMA identifier EQUAL initializer {
$$ = $1;
- context->parseInitDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration);
+ $$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5);
}
;
single_declaration
: fully_specified_type {
$$.type = $1;
- $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, "");
+ $$.intermAggregate = context->parseSingleDeclaration($$.type, @1, "");
}
| fully_specified_type identifier {
$$.type = $1;
- $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, *$2.string);
+ $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string);
}
| fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$.type = $1;
- $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4);
+ $$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4);
}
| fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
ES3_OR_NEWER("[]", @3, "implicitly sized array");
$$.type = $1;
- $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6);
+ $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6);
}
| fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
ES3_OR_NEWER("=", @6, "first-class arrays (array initializer)");
$$.type = $1;
- $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7);
+ $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7);
}
| fully_specified_type identifier EQUAL initializer {
$$.type = $1;
- $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
+ $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
+ }
+ | INVARIANT IDENTIFIER {
+ // $$.type is not used in invariant declarations.
+ $$.intermAggregate = context->parseInvariantDeclaration(@1, @2, $2.string, $2.symbol);
}
;
fully_specified_type
: type_specifier {
- context->addFullySpecifiedType(&$1);
$$ = $1;
+
+ if ($1.array) {
+ ES3_OR_NEWER("[]", @1, "first-class-array");
+ if (context->getShaderVersion() != 300) {
+ $1.clearArrayness();
+ }
+ }
}
- | type_qualifier type_specifier {
- $$ = context->addFullySpecifiedType(*$1, $2);
+ | type_qualifier type_specifier {
+ $$ = context->addFullySpecifiedType($1.qualifier, $1.invariant, $1.layoutQualifier, $2);
}
;
interpolation_qualifier
: SMOOTH {
- $$ = EvqSmooth;
+ $$.qualifier = EvqSmooth;
}
| FLAT {
- $$ = EvqFlat;
+ $$.qualifier = EvqFlat;
}
;
-type_qualifier
- : single_type_qualifier {
- $$ = context->createTypeQualifierBuilder(@1);
- $$->appendQualifier($1);
- }
- | type_qualifier single_type_qualifier {
- $$ = $1;
- $$->appendQualifier($2);
- }
- ;
-
-invariant_qualifier
- : INVARIANT {
- // empty
+parameter_type_qualifier
+ : CONST_QUAL {
+ $$ = EvqConst;
}
;
-single_type_qualifier
- : storage_qualifier {
- context->checkLocalVariableConstStorageQualifier(*$1);
- $$ = $1;
- }
- | layout_qualifier {
- context->checkIsAtGlobalLevel(@1, "layout");
- $$ = new TLayoutQualifierWrapper($1, @1);
- }
- | precision_qualifier {
- $$ = new TPrecisionQualifierWrapper($1, @1);
- }
- | interpolation_qualifier {
- $$ = new TInterpolationQualifierWrapper($1, @1);
- }
- | invariant_qualifier {
- context->checkIsAtGlobalLevel(@1, "invariant");
- $$ = new TInvariantQualifierWrapper(@1);
- }
- ;
-
-
-storage_qualifier
- :
- ATTRIBUTE {
+type_qualifier
+ : ATTRIBUTE {
VERTEX_ONLY("attribute", @1);
ES2_ONLY("attribute", @1);
context->checkIsAtGlobalLevel(@1, "attribute");
- $$ = new TStorageQualifierWrapper(EvqAttribute, @1);
+ $$.setBasic(EbtVoid, EvqAttribute, @1);
}
| VARYING {
ES2_ONLY("varying", @1);
context->checkIsAtGlobalLevel(@1, "varying");
if (context->getShaderType() == GL_VERTEX_SHADER)
- $$ = new TStorageQualifierWrapper(EvqVaryingOut, @1);
+ $$.setBasic(EbtVoid, EvqVaryingOut, @1);
else
- $$ = new TStorageQualifierWrapper(EvqVaryingIn, @1);
+ $$.setBasic(EbtVoid, EvqVaryingIn, @1);
}
- | CONST_QUAL {
- $$ = new TStorageQualifierWrapper(EvqConst, @1);
+ | INVARIANT VARYING {
+ ES2_ONLY("varying", @1);
+ context->checkIsAtGlobalLevel(@1, "invariant varying");
+ if (context->getShaderType() == GL_VERTEX_SHADER)
+ $$.setBasic(EbtVoid, EvqVaryingOut, @1);
+ else
+ $$.setBasic(EbtVoid, EvqVaryingIn, @1);
+ $$.invariant = true;
}
- | IN_QUAL {
- if (context->declaringFunction())
+ | storage_qualifier {
+ if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel())
{
- $$ = new TStorageQualifierWrapper(EvqIn, @1);
+ context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier));
}
- else if (context->getShaderType() == GL_FRAGMENT_SHADER)
+ $$.setBasic(EbtVoid, $1.qualifier, @1);
+ }
+ | interpolation_qualifier storage_qualifier {
+ $$ = context->joinInterpolationQualifiers(@1, $1.qualifier, @2, $2.qualifier);
+ }
+ | interpolation_qualifier {
+ context->error(@1, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString($1.qualifier));
+
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtVoid, qual, @1);
+ }
+ | layout_qualifier {
+ $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.layoutQualifier = $1;
+ }
+ | layout_qualifier storage_qualifier {
+ $$.setBasic(EbtVoid, $2.qualifier, @2);
+ $$.layoutQualifier = $1;
+ }
+ | INVARIANT storage_qualifier {
+ context->checkInvariantIsOutVariableES3($2.qualifier, @1);
+ $$.setBasic(EbtVoid, $2.qualifier, @2);
+ $$.invariant = true;
+ }
+ | INVARIANT interpolation_qualifier storage_qualifier {
+ context->checkInvariantIsOutVariableES3($3.qualifier, @1);
+ $$ = context->joinInterpolationQualifiers(@2, $2.qualifier, @3, $3.qualifier);
+ $$.invariant = true;
+ }
+ ;
+
+storage_qualifier
+ : CONST_QUAL {
+ $$.qualifier = EvqConst;
+ }
+ | IN_QUAL {
+ if (context->getShaderType() == GL_FRAGMENT_SHADER)
{
ES3_OR_NEWER("in", @1, "storage qualifier");
- $$ = new TStorageQualifierWrapper(EvqFragmentIn, @1);
+ $$.qualifier = EvqFragmentIn;
}
else if (context->getShaderType() == GL_VERTEX_SHADER)
{
ES3_OR_NEWER("in", @1, "storage qualifier");
- $$ = new TStorageQualifierWrapper(EvqVertexIn, @1);
+ $$.qualifier = EvqVertexIn;
}
else
{
- $$ = new TStorageQualifierWrapper(EvqComputeIn, @1);
+ $$.qualifier = EvqComputeIn;
}
}
| OUT_QUAL {
- if (context->declaringFunction())
- {
- $$ = new TStorageQualifierWrapper(EvqOut, @1);
- }
- else
- {
- ES3_OR_NEWER("out", @1, "storage qualifier");
- NON_COMPUTE_ONLY("out", @1);
- if (context->getShaderType() == GL_FRAGMENT_SHADER)
- {
- $$ = new TStorageQualifierWrapper(EvqFragmentOut, @1);
- }
- else
- {
- $$ = new TStorageQualifierWrapper(EvqVertexOut, @1);
- }
- }
+ ES3_OR_NEWER("out", @1, "storage qualifier");
+ NON_COMPUTE_ONLY("out", @1);
+ $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
}
- | INOUT_QUAL {
- if (!context->declaringFunction())
- {
- context->error(@1, "invalid inout qualifier", "'inout' can be only used with function parameters");
- }
- $$ = new TStorageQualifierWrapper(EvqInOut, @1);
+ | CENTROID IN_QUAL {
+ ES3_OR_NEWER("centroid in", @1, "storage qualifier");
+ FRAG_ONLY("centroid in", @1);
+ $$.qualifier = EvqCentroidIn;
}
- | CENTROID {
- ES3_OR_NEWER("centroid", @1, "storage qualifier");
- $$ = new TStorageQualifierWrapper(EvqCentroid, @1);
+ | CENTROID OUT_QUAL {
+ ES3_OR_NEWER("centroid out", @1, "storage qualifier");
+ VERTEX_ONLY("centroid out", @1);
+ $$.qualifier = EvqCentroidOut;
}
| UNIFORM {
context->checkIsAtGlobalLevel(@1, "uniform");
- $$ = new TStorageQualifierWrapper(EvqUniform, @1);
- }
- | READONLY {
- $$ = new TMemoryQualifierWrapper(EvqReadOnly, @1);
- }
- | WRITEONLY {
- $$ = new TMemoryQualifierWrapper(EvqWriteOnly, @1);
- }
- | COHERENT {
- $$ = new TMemoryQualifierWrapper(EvqCoherent, @1);
- }
- | RESTRICT {
- $$ = new TMemoryQualifierWrapper(EvqRestrict, @1);
- }
- | VOLATILE {
- $$ = new TMemoryQualifierWrapper(EvqVolatile, @1);
+ $$.qualifier = EvqUniform;
}
;
type_specifier
: type_specifier_no_prec {
$$ = $1;
- $$.precision = context->symbolTable.getDefaultPrecision($1.getBasicType());
+
+ if ($$.precision == EbpUndefined) {
+ $$.precision = context->symbolTable.getDefaultPrecision($1.type);
+ context->checkPrecisionSpecified(@1, $$.precision, $1.type);
+ }
+ }
+ | precision_qualifier type_specifier_no_prec {
+ $$ = $2;
+ $$.precision = $1;
+
+ if (!SupportsPrecision($2.type)) {
+ context->error(@1, "illegal type for precision qualifier", getBasicString($2.type));
+ }
}
;
@@ -1010,16 +1012,17 @@ layout_qualifier_id
type_specifier_no_prec
: type_specifier_nonarray {
- $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+ $$ = $1;
}
| type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET {
ES3_OR_NEWER("[]", @2, "implicitly sized array");
- $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+ $$ = $1;
$$.setArraySize(0);
}
| type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
- $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
- if (context->checkIsValidTypeForArray(@2, $$))
+ $$ = $1;
+
+ if (context->checkIsValidTypeForArray(@2, $1))
{
unsigned int size = context->checkIsValidArraySize(@2, $3);
$$.setArraySize(size);
@@ -1029,200 +1032,208 @@ type_specifier_no_prec
type_specifier_nonarray
: VOID_TYPE {
- $$.initialize(EbtVoid, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtVoid, qual, @1);
}
| FLOAT_TYPE {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
}
| INT_TYPE {
- $$.initialize(EbtInt, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtInt, qual, @1);
}
| UINT_TYPE {
- $$.initialize(EbtUInt, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtUInt, qual, @1);
}
| BOOL_TYPE {
- $$.initialize(EbtBool, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtBool, qual, @1);
}
| VEC2 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(2);
}
| VEC3 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(3);
}
| VEC4 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setAggregate(4);
}
| BVEC2 {
- $$.initialize(EbtBool, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtBool, qual, @1);
$$.setAggregate(2);
}
| BVEC3 {
- $$.initialize(EbtBool, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtBool, qual, @1);
$$.setAggregate(3);
}
| BVEC4 {
- $$.initialize(EbtBool, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtBool, qual, @1);
$$.setAggregate(4);
}
| IVEC2 {
- $$.initialize(EbtInt, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtInt, qual, @1);
$$.setAggregate(2);
}
| IVEC3 {
- $$.initialize(EbtInt, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtInt, qual, @1);
$$.setAggregate(3);
}
| IVEC4 {
- $$.initialize(EbtInt, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtInt, qual, @1);
$$.setAggregate(4);
}
| UVEC2 {
- $$.initialize(EbtUInt, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtUInt, qual, @1);
$$.setAggregate(2);
}
| UVEC3 {
- $$.initialize(EbtUInt, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtUInt, qual, @1);
$$.setAggregate(3);
}
| UVEC4 {
- $$.initialize(EbtUInt, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtUInt, qual, @1);
$$.setAggregate(4);
}
| MATRIX2 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setMatrix(2, 2);
}
| MATRIX3 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setMatrix(3, 3);
}
| MATRIX4 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setMatrix(4, 4);
}
| MATRIX2x3 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setMatrix(2, 3);
}
| MATRIX3x2 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setMatrix(3, 2);
}
| MATRIX2x4 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setMatrix(2, 4);
}
| MATRIX4x2 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setMatrix(4, 2);
}
| MATRIX3x4 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setMatrix(3, 4);
}
| MATRIX4x3 {
- $$.initialize(EbtFloat, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtFloat, qual, @1);
$$.setMatrix(4, 3);
}
| SAMPLER2D {
- $$.initialize(EbtSampler2D, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSampler2D, qual, @1);
}
| SAMPLER3D {
- $$.initialize(EbtSampler3D, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSampler3D, qual, @1);
}
| SAMPLERCUBE {
- $$.initialize(EbtSamplerCube, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSamplerCube, qual, @1);
}
| SAMPLER2DARRAY {
- $$.initialize(EbtSampler2DArray, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSampler2DArray, qual, @1);
}
| ISAMPLER2D {
- $$.initialize(EbtISampler2D, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtISampler2D, qual, @1);
}
| ISAMPLER3D {
- $$.initialize(EbtISampler3D, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtISampler3D, qual, @1);
}
| ISAMPLERCUBE {
- $$.initialize(EbtISamplerCube, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtISamplerCube, qual, @1);
}
| ISAMPLER2DARRAY {
- $$.initialize(EbtISampler2DArray, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtISampler2DArray, qual, @1);
}
| USAMPLER2D {
- $$.initialize(EbtUSampler2D, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtUSampler2D, qual, @1);
}
| USAMPLER3D {
- $$.initialize(EbtUSampler3D, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtUSampler3D, qual, @1);
}
| USAMPLERCUBE {
- $$.initialize(EbtUSamplerCube, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtUSamplerCube, qual, @1);
}
| USAMPLER2DARRAY {
- $$.initialize(EbtUSampler2DArray, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtUSampler2DArray, qual, @1);
}
| SAMPLER2DSHADOW {
- $$.initialize(EbtSampler2DShadow, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSampler2DShadow, qual, @1);
}
| SAMPLERCUBESHADOW {
- $$.initialize(EbtSamplerCubeShadow, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSamplerCubeShadow, qual, @1);
}
| SAMPLER2DARRAYSHADOW {
- $$.initialize(EbtSampler2DArrayShadow, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSampler2DArrayShadow, qual, @1);
}
| SAMPLER_EXTERNAL_OES {
if (!context->supportsExtension("GL_OES_EGL_image_external") &&
!context->supportsExtension("GL_NV_EGL_stream_consumer_external")) {
context->error(@1, "unsupported type", "samplerExternalOES");
}
- $$.initialize(EbtSamplerExternalOES, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSamplerExternalOES, qual, @1);
}
| SAMPLER2DRECT {
if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
context->error(@1, "unsupported type", "sampler2DRect");
}
- $$.initialize(EbtSampler2DRect, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSampler2DRect, qual, @1);
}
| struct_specifier {
$$ = $1;
- }
- | IMAGE2D {
- $$.initialize(EbtImage2D, @1);
- }
- | IIMAGE2D {
- $$.initialize(EbtIImage2D, @1);
- }
- | UIMAGE2D {
- $$.initialize(EbtUImage2D, @1);
- }
- | IMAGE3D {
- $$.initialize(EbtImage3D, @1);
- }
- | IIMAGE3D {
- $$.initialize(EbtIImage3D, @1);
- }
- | UIMAGE3D {
- $$.initialize(EbtUImage3D, @1);
- }
- | IMAGE2DARRAY {
- $$.initialize(EbtImage2DArray, @1);
- }
- | IIMAGE2DARRAY {
- $$.initialize(EbtIImage2DArray, @1);
- }
- | UIMAGE2DARRAY {
- $$.initialize(EbtUImage2DArray, @1);
- }
- | IMAGECUBE {
- $$.initialize(EbtImageCube, @1);
- }
- | IIMAGECUBE {
- $$.initialize(EbtIImageCube, @1);
- }
- | UIMAGECUBE {
- $$.initialize(EbtUImageCube, @1);
+ $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
}
| TYPE_NAME {
//
@@ -1230,7 +1241,8 @@ type_specifier_nonarray
// type.
//
TType& structure = static_cast<TVariable*>($1.symbol)->getType();
- $$.initialize(EbtStruct, @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtStruct, qual, @1);
$$.userDef = &structure;
}
;
@@ -1268,7 +1280,9 @@ struct_declaration
}
| type_qualifier type_specifier struct_declarator_list SEMICOLON {
// ES3 Only, but errors should be handled elsewhere
- $$ = context->addStructDeclaratorListWithQualifiers(*$1, &$2, $3);
+ $2.qualifier = $1.qualifier;
+ $2.layoutQualifier = $1.layoutQualifier;
+ $$ = context->addStructDeclaratorList($2, $3);
}
;
@@ -1329,6 +1343,7 @@ compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
| LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
if ($3 != 0) {
+ $3->setOp(EOpSequence);
$3->setLine(@$);
}
$$ = $3;
@@ -1352,6 +1367,7 @@ compound_statement_no_new_scope
}
| LEFT_BRACE statement_list RIGHT_BRACE {
if ($2) {
+ $2->setOp(EOpSequence);
$2->setLine(@$);
}
$$ = $2;
@@ -1360,13 +1376,10 @@ compound_statement_no_new_scope
statement_list
: statement {
- $$ = new TIntermBlock();
- $$->setLine(@$);
- $$->appendStatement($1);
+ $$ = context->intermediate.makeAggregate($1, @$);
}
| statement_list statement {
- $$ = $1;
- $$->appendStatement($2);
+ $$ = context->intermediate.growAggregate($1, $2, @$);
}
;
@@ -1378,7 +1391,7 @@ expression_statement
selection_statement
: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
context->checkIsScalarBool(@1, $3);
- $$ = context->intermediate.addIfElse($3, $5, @1);
+ $$ = context->intermediate.addSelection($3, $5, @1);
}
;
@@ -1416,10 +1429,10 @@ condition
context->checkIsScalarBool($1->getLine(), $1);
}
| fully_specified_type identifier EQUAL initializer {
- TIntermBinary *initNode = nullptr;
+ TIntermNode *intermNode;
context->checkIsScalarBool(@2, $1);
- if (!context->executeInitializer(@2, *$2.string, $1, $4, &initNode))
+ if (!context->executeInitializer(@2, *$2.string, $1, $4, &intermNode))
$$ = $4;
else {
$$ = 0;
@@ -1498,13 +1511,12 @@ jump_statement
translation_unit
: external_declaration {
- $$ = new TIntermBlock();
- $$->setLine(@$);
- $$->appendStatement($1);
+ $$ = $1;
context->setTreeRoot($$);
}
| translation_unit external_declaration {
- $$->appendStatement($2);
+ $$ = context->intermediate.growAggregate($1, $2, @$);
+ context->setTreeRoot($$);
}
;
@@ -1519,7 +1531,7 @@ external_declaration
function_definition
: function_prototype {
- context->parseFunctionDefinitionHeader(@1, &($1.function), &$1.intermAggregate);
+ context->parseFunctionPrototype(@1, $1.function, &$1.intermAggregate);
}
compound_statement_no_new_scope {
$$ = context->addFunctionDefinition(*($1.function), $1.intermAggregate, $3, @1);
diff --git a/gfx/angle/src/compiler/translator/glslang_lex.cpp b/gfx/angle/src/compiler/translator/glslang_lex.cpp
index 2dcc1bc0f..8ad7b1464 100755
--- a/gfx/angle/src/compiler/translator/glslang_lex.cpp
+++ b/gfx/angle/src/compiler/translator/glslang_lex.cpp
@@ -1,3 +1,4 @@
+#line 17 "./glslang.l"
//
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -6,8 +7,6 @@
// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
-/* clang-format off */
-
// Ignore errors in auto-generated code.
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wunused-function"
@@ -25,7 +24,7 @@
-#line 30 "./glslang_lex.cpp"
+#line 28 "./glslang_lex.cpp"
#define YY_INT_ALIGNED short int
@@ -221,7 +220,7 @@ typedef size_t yy_size_t;
#define YY_LESS_LINENO(n) \
do { \
yy_size_t yyl;\
- for ( yyl = n; yyl < static_cast<yy_site_t>(yyleng); ++yyl )\
+ for ( yyl = n; yyl < yyleng; ++yyl )\
if ( yytext[yyl] == '\n' )\
--yylineno;\
}while(0)
@@ -396,7 +395,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
+ yyleng = (yy_size_t) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
@@ -429,7 +428,7 @@ static yyconst flex_int16_t yy_accept[820] =
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 199, 203, 235, 0, 189, 185, 0, 188, 182,
- 0, 184, 178, 195, 196, 177, 137, 177, 177, 177,
+ 0, 184, 178, 195, 196, 177, 136, 177, 177, 177,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
13, 177, 177, 177, 177, 177, 177, 177, 177, 177,
@@ -441,67 +440,67 @@ static yyconst flex_int16_t yy_accept[820] =
177, 177, 177, 177, 177, 177, 177, 177, 0, 186,
0, 185, 187, 181, 177, 177, 177, 30, 177, 177,
18, 174, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 16, 140, 177, 177, 177, 177, 21, 177,
- 177, 144, 155, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 16, 139, 177, 177, 177, 177, 21, 177,
+ 177, 143, 155, 177, 177, 177, 177, 177, 177, 177,
177, 177, 177, 177, 177, 152, 4, 35, 36, 37,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 143, 31, 177, 177, 28, 177,
+ 177, 177, 177, 177, 142, 31, 177, 177, 28, 177,
177, 177, 177, 177, 177, 177, 47, 48, 49, 29,
177, 177, 177, 177, 177, 177, 10, 53, 54, 55,
- 177, 138, 177, 177, 7, 177, 177, 177, 177, 164,
+ 177, 137, 177, 177, 7, 177, 177, 177, 177, 164,
165, 166, 177, 32, 177, 156, 26, 167, 168, 169,
2, 161, 162, 163, 177, 177, 177, 25, 159, 177,
177, 177, 50, 51, 52, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 99, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 86, 177, 177, 177,
177, 177, 177, 177, 153, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 139, 177, 177, 176,
- 56, 57, 58, 177, 177, 14, 177, 104, 177, 177,
- 177, 177, 102, 177, 177, 177, 154, 149, 105, 177,
- 177, 177, 177, 177, 177, 145, 177, 177, 177, 78,
+ 177, 177, 177, 177, 177, 177, 138, 177, 177, 176,
+ 56, 57, 58, 177, 177, 14, 177, 91, 177, 177,
+ 177, 177, 89, 177, 177, 177, 154, 149, 92, 177,
+ 177, 177, 177, 177, 177, 144, 177, 177, 177, 78,
38, 41, 43, 42, 39, 45, 44, 46, 40, 177,
- 177, 177, 177, 160, 136, 177, 177, 147, 177, 177,
- 177, 34, 100, 173, 22, 148, 77, 177, 158, 17,
+ 177, 177, 177, 160, 135, 177, 177, 147, 177, 177,
+ 177, 34, 87, 173, 22, 148, 77, 177, 158, 17,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 177, 177, 177, 19, 33, 177, 177, 177, 177,
- 177, 177, 106, 79, 85, 177, 177, 177, 177, 177,
+ 177, 177, 93, 94, 95, 177, 177, 177, 177, 177,
3, 177, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 141, 177, 177, 177, 177, 177, 8, 177,
- 177, 9, 177, 177, 177, 177, 20, 93, 11, 150,
- 107, 80, 87, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 146, 177, 177, 177, 91,
- 96, 94, 177, 177, 177, 177, 177, 177, 177, 142,
- 108, 81, 86, 177, 177, 157, 177, 95, 177, 177,
+ 177, 177, 140, 177, 177, 177, 177, 177, 8, 177,
+ 177, 9, 177, 177, 177, 177, 20, 79, 11, 150,
+ 97, 98, 99, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 145, 177, 177, 177, 81,
+ 83, 80, 177, 177, 177, 177, 177, 177, 177, 141,
+ 101, 102, 103, 177, 177, 157, 177, 146, 177, 177,
6, 177, 177, 177, 177, 177, 177, 177, 177, 177,
- 90, 151, 1, 177, 177, 177, 177, 177, 175, 177,
+ 96, 151, 1, 177, 177, 177, 177, 177, 175, 177,
- 103, 5, 170, 59, 62, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177, 92, 177,
- 177, 177, 177, 88, 177, 177, 177, 177, 177, 121,
+ 90, 5, 170, 59, 62, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 82, 177,
+ 177, 177, 177, 100, 177, 177, 177, 177, 177, 120,
66, 67, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 101, 177, 177, 177, 89,
- 123, 70, 71, 177, 177, 97, 177, 177, 177, 177,
- 177, 177, 177, 116, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 130, 177, 177, 177, 177, 60,
+ 177, 177, 177, 177, 177, 88, 177, 177, 177, 104,
+ 122, 70, 71, 177, 177, 84, 177, 177, 177, 177,
+ 177, 177, 177, 115, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 129, 177, 177, 177, 177, 60,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 117, 109, 177, 82, 177, 177, 177, 131,
+ 177, 177, 116, 105, 177, 106, 177, 177, 177, 130,
177, 177, 68, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 118, 177, 177, 132,
- 177, 177, 72, 110, 83, 177, 112, 177, 113, 177,
- 177, 177, 177, 177, 98, 177, 177, 177, 177, 64,
- 177, 63, 127, 177, 177, 111, 84, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 125, 128, 119,
+ 177, 177, 177, 177, 177, 177, 117, 177, 177, 131,
+ 177, 177, 72, 107, 108, 177, 111, 177, 112, 177,
+ 177, 177, 177, 177, 85, 177, 177, 177, 177, 64,
+ 177, 63, 126, 177, 177, 109, 110, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 124, 127, 118,
177, 65, 177, 177, 177, 177, 177, 177, 177, 177,
- 126, 129, 177, 177, 122, 69, 177, 177, 171, 177,
- 177, 177, 74, 177, 177, 124, 73, 177, 177, 177,
- 177, 177, 177, 133, 177, 177, 177, 177, 177, 177,
+ 125, 128, 177, 177, 121, 69, 177, 177, 171, 177,
+ 177, 177, 74, 177, 177, 123, 73, 177, 177, 177,
+ 177, 177, 177, 132, 177, 177, 177, 177, 177, 177,
- 134, 177, 177, 177, 75, 177, 135, 114, 115, 177,
- 177, 177, 61, 177, 177, 172, 120, 76, 0
+ 133, 177, 177, 177, 75, 177, 134, 113, 114, 177,
+ 177, 177, 61, 177, 177, 172, 119, 76, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
@@ -1028,9 +1027,6 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
#include "compiler/preprocessor/Token.h"
#include "compiler/translator/util.h"
#include "compiler/translator/length_limits.h"
-
-using namespace sh;
-
#include "glslang_tab.h"
/* windows only pragma */
@@ -1058,8 +1054,6 @@ static int reserved_word(yyscan_t yyscanner);
static int ES2_reserved_ES3_keyword(TParseContext *context, int token);
static int ES2_keyword_ES3_reserved(TParseContext *context, int token);
static int ES2_ident_ES3_keyword(TParseContext *context, int token);
-static int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
-static int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
static int uint_constant(TParseContext *context);
static int int_constant(TParseContext *context);
static int float_constant(yyscan_t yyscanner);
@@ -1374,7 +1368,7 @@ yy_find_action:
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
{
yy_size_t yyl;
- for ( yyl = 0; yyl < static_cast<yy_size_t>(yyleng); ++yyl )
+ for ( yyl = 0; yyl < yyleng; ++yyl )
if ( yytext[yyl] == '\n' )
do{ yylineno++;
@@ -1706,75 +1700,24 @@ case 78:
YY_RULE_SETUP
{ return ES2_ident_ES3_keyword(context, LAYOUT); }
YY_BREAK
+/* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
case 79:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2D); }
- YY_BREAK
case 80:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2D); }
- YY_BREAK
case 81:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2D); }
- YY_BREAK
case 82:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY); }
- YY_BREAK
case 83:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY); }
- YY_BREAK
case 84:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY); }
- YY_BREAK
case 85:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE3D); }
- YY_BREAK
case 86:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE3D); }
- YY_BREAK
case 87:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE3D); }
- YY_BREAK
case 88:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGECUBE); }
- YY_BREAK
case 89:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGECUBE); }
- YY_BREAK
case 90:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGECUBE); }
- YY_BREAK
case 91:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, READONLY); }
- YY_BREAK
case 92:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, WRITEONLY); }
- YY_BREAK
case 93:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, COHERENT); }
- YY_BREAK
case 94:
-YY_RULE_SETUP
-{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, RESTRICT); }
- YY_BREAK
case 95:
-YY_RULE_SETUP
-{ return ES2_and_ES3_reserved_ES3_1_keyword(context, VOLATILE); }
- YY_BREAK
-/* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
case 96:
case 97:
case 98:
@@ -1814,7 +1757,6 @@ case 131:
case 132:
case 133:
case 134:
-case 135:
YY_RULE_SETUP
{
if (context->getShaderVersion() < 300) {
@@ -1825,7 +1767,7 @@ YY_RULE_SETUP
}
YY_BREAK
/* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
-case 136:
+case 135:
YY_RULE_SETUP
{
if (context->getShaderVersion() >= 300)
@@ -1838,6 +1780,7 @@ YY_RULE_SETUP
}
YY_BREAK
/* Reserved keywords */
+case 136:
case 137:
case 138:
case 139:
@@ -2338,7 +2281,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{
- int num_to_read =
+ yy_size_t num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -2374,7 +2317,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- static_cast<int>(number_to_move) - 1;
+ number_to_move - 1;
}
@@ -2382,10 +2325,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
num_to_read = YY_READ_BUF_SIZE;
/* Read in more data. */
- size_t result = 0;
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- result, num_to_read );
- yyg->yy_n_chars = static_cast<int>(result);
+ yyg->yy_n_chars, num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
}
@@ -2826,7 +2767,7 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
/* Increase the buffer to prepare for a possible push. */
int grow_size = 8 /* arbitrary grow size */;
- num_to_alloc = static_cast<int>(yyg->yy_buffer_stack_max + grow_size);
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
(yyg->yy_buffer_stack,
num_to_alloc * sizeof(struct yy_buffer_state*)
@@ -2860,7 +2801,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
- b->yy_buf_size = static_cast<int>(size) - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
b->yy_input_file = 0;
@@ -2909,7 +2850,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
- for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i )
+ for ( i = 0; i < _yybytes_len; ++i )
buf[i] = yybytes[i];
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
@@ -3360,24 +3301,6 @@ int ES2_keyword_ES3_reserved(TParseContext *context, int token)
return token;
}
-int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
-{
- struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
- yyscan_t yyscanner = (yyscan_t) context->getScanner();
-
- if (context->getShaderVersion() < 300)
- {
- yylval->lex.string = NewPoolTString(yytext);
- return check_type(yyscanner);
- }
- else if (context->getShaderVersion() == 300)
- {
- return reserved_word(yyscanner);
- }
-
- return token;
-}
-
int ES2_ident_ES3_keyword(TParseContext *context, int token)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
@@ -3393,18 +3316,6 @@ int ES2_ident_ES3_keyword(TParseContext *context, int token)
return token;
}
-int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
-{
- yyscan_t yyscanner = (yyscan_t) context->getScanner();
-
- if (context->getShaderVersion() < 310)
- {
- return reserved_word(yyscanner);
- }
-
- return token;
-}
-
int uint_constant(TParseContext *context)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
@@ -3506,7 +3417,7 @@ int glslang_scan(size_t count, const char* const string[], const int length[],
if (context->getFragmentPrecisionHigh())
preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
- preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec()));
+ preprocessor->setMaxTokenSize(GetGlobalMaxTokenSize(context->getShaderSpec()));
return 0;
}
diff --git a/gfx/angle/src/compiler/translator/glslang_tab.cpp b/gfx/angle/src/compiler/translator/glslang_tab.cpp
index 63a3371dc..ada392497 100755
--- a/gfx/angle/src/compiler/translator/glslang_tab.cpp
+++ b/gfx/angle/src/compiler/translator/glslang_tab.cpp
@@ -96,8 +96,6 @@
#define YYENABLE_NLS 0
-using namespace sh;
-
@@ -192,97 +190,80 @@ extern int yydebug;
CENTROID = 306,
FLAT = 307,
SMOOTH = 308,
- READONLY = 309,
- WRITEONLY = 310,
- COHERENT = 311,
- RESTRICT = 312,
- VOLATILE = 313,
- STRUCT = 314,
- VOID_TYPE = 315,
- WHILE = 316,
- SAMPLER2D = 317,
- SAMPLERCUBE = 318,
- SAMPLER_EXTERNAL_OES = 319,
- SAMPLER2DRECT = 320,
- SAMPLER2DARRAY = 321,
- ISAMPLER2D = 322,
- ISAMPLER3D = 323,
- ISAMPLERCUBE = 324,
- ISAMPLER2DARRAY = 325,
- USAMPLER2D = 326,
- USAMPLER3D = 327,
- USAMPLERCUBE = 328,
- USAMPLER2DARRAY = 329,
- SAMPLER3D = 330,
- SAMPLER3DRECT = 331,
- SAMPLER2DSHADOW = 332,
- SAMPLERCUBESHADOW = 333,
- SAMPLER2DARRAYSHADOW = 334,
- IMAGE2D = 335,
- IIMAGE2D = 336,
- UIMAGE2D = 337,
- IMAGE3D = 338,
- IIMAGE3D = 339,
- UIMAGE3D = 340,
- IMAGE2DARRAY = 341,
- IIMAGE2DARRAY = 342,
- UIMAGE2DARRAY = 343,
- IMAGECUBE = 344,
- IIMAGECUBE = 345,
- UIMAGECUBE = 346,
- LAYOUT = 347,
- IDENTIFIER = 348,
- TYPE_NAME = 349,
- FLOATCONSTANT = 350,
- INTCONSTANT = 351,
- UINTCONSTANT = 352,
- BOOLCONSTANT = 353,
- FIELD_SELECTION = 354,
- LEFT_OP = 355,
- RIGHT_OP = 356,
- INC_OP = 357,
- DEC_OP = 358,
- LE_OP = 359,
- GE_OP = 360,
- EQ_OP = 361,
- NE_OP = 362,
- AND_OP = 363,
- OR_OP = 364,
- XOR_OP = 365,
- MUL_ASSIGN = 366,
- DIV_ASSIGN = 367,
- ADD_ASSIGN = 368,
- MOD_ASSIGN = 369,
- LEFT_ASSIGN = 370,
- RIGHT_ASSIGN = 371,
- AND_ASSIGN = 372,
- XOR_ASSIGN = 373,
- OR_ASSIGN = 374,
- SUB_ASSIGN = 375,
- LEFT_PAREN = 376,
- RIGHT_PAREN = 377,
- LEFT_BRACKET = 378,
- RIGHT_BRACKET = 379,
- LEFT_BRACE = 380,
- RIGHT_BRACE = 381,
- DOT = 382,
- COMMA = 383,
- COLON = 384,
- EQUAL = 385,
- SEMICOLON = 386,
- BANG = 387,
- DASH = 388,
- TILDE = 389,
- PLUS = 390,
- STAR = 391,
- SLASH = 392,
- PERCENT = 393,
- LEFT_ANGLE = 394,
- RIGHT_ANGLE = 395,
- VERTICAL_BAR = 396,
- CARET = 397,
- AMPERSAND = 398,
- QUESTION = 399
+ STRUCT = 309,
+ VOID_TYPE = 310,
+ WHILE = 311,
+ SAMPLER2D = 312,
+ SAMPLERCUBE = 313,
+ SAMPLER_EXTERNAL_OES = 314,
+ SAMPLER2DRECT = 315,
+ SAMPLER2DARRAY = 316,
+ ISAMPLER2D = 317,
+ ISAMPLER3D = 318,
+ ISAMPLERCUBE = 319,
+ ISAMPLER2DARRAY = 320,
+ USAMPLER2D = 321,
+ USAMPLER3D = 322,
+ USAMPLERCUBE = 323,
+ USAMPLER2DARRAY = 324,
+ SAMPLER3D = 325,
+ SAMPLER3DRECT = 326,
+ SAMPLER2DSHADOW = 327,
+ SAMPLERCUBESHADOW = 328,
+ SAMPLER2DARRAYSHADOW = 329,
+ LAYOUT = 330,
+ IDENTIFIER = 331,
+ TYPE_NAME = 332,
+ FLOATCONSTANT = 333,
+ INTCONSTANT = 334,
+ UINTCONSTANT = 335,
+ BOOLCONSTANT = 336,
+ FIELD_SELECTION = 337,
+ LEFT_OP = 338,
+ RIGHT_OP = 339,
+ INC_OP = 340,
+ DEC_OP = 341,
+ LE_OP = 342,
+ GE_OP = 343,
+ EQ_OP = 344,
+ NE_OP = 345,
+ AND_OP = 346,
+ OR_OP = 347,
+ XOR_OP = 348,
+ MUL_ASSIGN = 349,
+ DIV_ASSIGN = 350,
+ ADD_ASSIGN = 351,
+ MOD_ASSIGN = 352,
+ LEFT_ASSIGN = 353,
+ RIGHT_ASSIGN = 354,
+ AND_ASSIGN = 355,
+ XOR_ASSIGN = 356,
+ OR_ASSIGN = 357,
+ SUB_ASSIGN = 358,
+ LEFT_PAREN = 359,
+ RIGHT_PAREN = 360,
+ LEFT_BRACKET = 361,
+ RIGHT_BRACKET = 362,
+ LEFT_BRACE = 363,
+ RIGHT_BRACE = 364,
+ DOT = 365,
+ COMMA = 366,
+ COLON = 367,
+ EQUAL = 368,
+ SEMICOLON = 369,
+ BANG = 370,
+ DASH = 371,
+ TILDE = 372,
+ PLUS = 373,
+ STAR = 374,
+ SLASH = 375,
+ PERCENT = 376,
+ LEFT_ANGLE = 377,
+ RIGHT_ANGLE = 378,
+ VERTICAL_BAR = 379,
+ CARET = 380,
+ AMPERSAND = 381,
+ QUESTION = 382
};
#endif
@@ -306,27 +287,22 @@ union YYSTYPE
struct {
TOperator op;
union {
- TIntermNode *intermNode;
+ TIntermNode* intermNode;
TIntermNodePair nodePair;
- TIntermTyped *intermTypedNode;
- TIntermAggregate *intermAggregate;
- TIntermBlock *intermBlock;
- TIntermDeclaration *intermDeclaration;
- TIntermSwitch *intermSwitch;
- TIntermCase *intermCase;
+ TIntermTyped* intermTypedNode;
+ TIntermAggregate* intermAggregate;
+ TIntermSwitch* intermSwitch;
+ TIntermCase* intermCase;
};
union {
- TTypeSpecifierNonArray typeSpecifierNonArray;
TPublicType type;
TPrecision precision;
TLayoutQualifier layoutQualifier;
TQualifier qualifier;
- TFunction *function;
+ TFunction* function;
TParameter param;
- TField *field;
- TFieldList *fieldList;
- TQualifierWrapperBase *qualifierWrapper;
- TTypeQualifierBuilder *typeQualifierBuilder;
+ TField* field;
+ TFieldList* fieldList;
};
} interm;
@@ -664,23 +640,23 @@ union yyalloc
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 126
+#define YYFINAL 116
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 2825
+#define YYLAST 2516
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 145
+#define YYNTOKENS 128
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 94
/* YYNRULES -- Number of rules. */
-#define YYNRULES 286
+#define YYNRULES 275
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 422
+#define YYNSTATES 417
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 399
+#define YYMAXUTOK 382
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -727,43 +703,41 @@ static const yytype_uint8 yytranslate[] =
95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
- 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
- 135, 136, 137, 138, 139, 140, 141, 142, 143, 144
+ 125, 126, 127
};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 243, 243, 244, 247, 257, 260, 265, 270, 275,
- 280, 286, 289, 292, 295, 298, 301, 307, 314, 325,
- 329, 337, 340, 346, 350, 357, 363, 372, 380, 386,
- 392, 401, 404, 407, 410, 420, 421, 422, 423, 431,
- 432, 435, 438, 445, 446, 449, 455, 456, 460, 467,
- 468, 471, 474, 477, 483, 484, 487, 493, 494, 501,
- 502, 509, 510, 517, 518, 524, 525, 531, 532, 538,
- 539, 545, 546, 553, 554, 555, 556, 560, 561, 562,
- 566, 570, 574, 578, 585, 588, 594, 601, 608, 611,
- 614, 623, 627, 631, 635, 639, 646, 653, 656, 663,
- 671, 691, 701, 709, 734, 738, 742, 746, 753, 760,
- 763, 767, 771, 776, 781, 788, 792, 796, 800, 805,
- 810, 817, 821, 827, 830, 836, 840, 847, 853, 857,
- 861, 864, 867, 876, 882, 890, 893, 913, 932, 939,
- 943, 947, 950, 953, 956, 959, 965, 972, 975, 978,
- 984, 991, 994, 1000, 1003, 1006, 1012, 1015, 1020, 1031,
- 1034, 1037, 1040, 1043, 1046, 1050, 1054, 1058, 1062, 1066,
- 1070, 1074, 1078, 1082, 1086, 1090, 1094, 1098, 1102, 1106,
- 1110, 1114, 1118, 1122, 1126, 1130, 1133, 1136, 1139, 1142,
- 1145, 1148, 1151, 1154, 1157, 1160, 1163, 1166, 1169, 1172,
- 1175, 1182, 1188, 1191, 1194, 1197, 1200, 1203, 1206, 1209,
- 1212, 1215, 1218, 1221, 1224, 1227, 1239, 1239, 1242, 1242,
- 1248, 1251, 1266, 1269, 1276, 1280, 1286, 1292, 1304, 1308,
- 1312, 1313, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1329,
- 1330, 1330, 1330, 1339, 1340, 1344, 1344, 1345, 1345, 1350,
- 1353, 1362, 1367, 1374, 1375, 1379, 1386, 1390, 1397, 1397,
- 1404, 1407, 1414, 1418, 1431, 1431, 1436, 1436, 1442, 1442,
- 1450, 1453, 1459, 1462, 1468, 1472, 1479, 1482, 1485, 1488,
- 1491, 1500, 1506, 1512, 1515, 1521, 1521
+ 0, 228, 228, 229, 232, 242, 245, 250, 255, 260,
+ 265, 271, 274, 277, 280, 283, 286, 292, 299, 310,
+ 314, 322, 325, 331, 335, 342, 348, 357, 365, 371,
+ 377, 386, 389, 392, 395, 405, 406, 407, 408, 416,
+ 417, 420, 423, 430, 431, 434, 440, 441, 445, 452,
+ 453, 456, 459, 462, 468, 469, 472, 478, 479, 486,
+ 487, 494, 495, 502, 503, 509, 510, 516, 517, 523,
+ 524, 530, 531, 538, 539, 540, 541, 545, 546, 547,
+ 551, 555, 559, 563, 570, 573, 579, 586, 593, 596,
+ 602, 611, 615, 619, 623, 630, 636, 639, 646, 654,
+ 674, 683, 691, 716, 720, 728, 732, 740, 743, 746,
+ 749, 755, 762, 765, 769, 773, 778, 783, 790, 794,
+ 798, 802, 807, 812, 816, 823, 833, 839, 842, 848,
+ 854, 860, 868, 877, 884, 887, 893, 897, 901, 906,
+ 914, 917, 933, 938, 943, 948, 955, 963, 974, 977,
+ 980, 986, 993, 996, 1002, 1005, 1008, 1014, 1017, 1022,
+ 1034, 1038, 1042, 1046, 1050, 1054, 1059, 1064, 1069, 1074,
+ 1079, 1084, 1089, 1094, 1099, 1104, 1109, 1114, 1119, 1124,
+ 1129, 1134, 1139, 1144, 1149, 1154, 1159, 1163, 1167, 1171,
+ 1175, 1179, 1183, 1187, 1191, 1195, 1199, 1203, 1207, 1211,
+ 1215, 1219, 1227, 1234, 1238, 1251, 1251, 1254, 1254, 1260,
+ 1263, 1278, 1281, 1290, 1294, 1300, 1306, 1318, 1322, 1326,
+ 1327, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1343, 1344,
+ 1344, 1344, 1354, 1355, 1359, 1359, 1360, 1360, 1365, 1368,
+ 1378, 1381, 1387, 1388, 1392, 1399, 1403, 1410, 1410, 1417,
+ 1420, 1427, 1431, 1444, 1444, 1449, 1449, 1455, 1455, 1463,
+ 1466, 1472, 1475, 1481, 1485, 1492, 1495, 1498, 1501, 1504,
+ 1513, 1517, 1524, 1527, 1533, 1533
};
#endif
@@ -780,28 +754,24 @@ static const char *const yytname[] =
"IVEC4", "VEC2", "VEC3", "VEC4", "UVEC2", "UVEC3", "UVEC4", "MATRIX2",
"MATRIX3", "MATRIX4", "IN_QUAL", "OUT_QUAL", "INOUT_QUAL", "UNIFORM",
"VARYING", "MATRIX2x3", "MATRIX3x2", "MATRIX2x4", "MATRIX4x2",
- "MATRIX3x4", "MATRIX4x3", "CENTROID", "FLAT", "SMOOTH", "READONLY",
- "WRITEONLY", "COHERENT", "RESTRICT", "VOLATILE", "STRUCT", "VOID_TYPE",
- "WHILE", "SAMPLER2D", "SAMPLERCUBE", "SAMPLER_EXTERNAL_OES",
+ "MATRIX3x4", "MATRIX4x3", "CENTROID", "FLAT", "SMOOTH", "STRUCT",
+ "VOID_TYPE", "WHILE", "SAMPLER2D", "SAMPLERCUBE", "SAMPLER_EXTERNAL_OES",
"SAMPLER2DRECT", "SAMPLER2DARRAY", "ISAMPLER2D", "ISAMPLER3D",
"ISAMPLERCUBE", "ISAMPLER2DARRAY", "USAMPLER2D", "USAMPLER3D",
"USAMPLERCUBE", "USAMPLER2DARRAY", "SAMPLER3D", "SAMPLER3DRECT",
- "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", "SAMPLER2DARRAYSHADOW",
- "IMAGE2D", "IIMAGE2D", "UIMAGE2D", "IMAGE3D", "IIMAGE3D", "UIMAGE3D",
- "IMAGE2DARRAY", "IIMAGE2DARRAY", "UIMAGE2DARRAY", "IMAGECUBE",
- "IIMAGECUBE", "UIMAGECUBE", "LAYOUT", "IDENTIFIER", "TYPE_NAME",
- "FLOATCONSTANT", "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT",
- "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP",
- "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN",
- "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN",
- "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "LEFT_PAREN",
- "RIGHT_PAREN", "LEFT_BRACKET", "RIGHT_BRACKET", "LEFT_BRACE",
- "RIGHT_BRACE", "DOT", "COMMA", "COLON", "EQUAL", "SEMICOLON", "BANG",
- "DASH", "TILDE", "PLUS", "STAR", "SLASH", "PERCENT", "LEFT_ANGLE",
- "RIGHT_ANGLE", "VERTICAL_BAR", "CARET", "AMPERSAND", "QUESTION",
- "$accept", "identifier", "variable_identifier", "primary_expression",
- "postfix_expression", "integer_expression", "function_call",
- "function_call_or_method", "function_call_generic",
+ "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", "SAMPLER2DARRAYSHADOW", "LAYOUT",
+ "IDENTIFIER", "TYPE_NAME", "FLOATCONSTANT", "INTCONSTANT",
+ "UINTCONSTANT", "BOOLCONSTANT", "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP",
+ "INC_OP", "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP",
+ "OR_OP", "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN",
+ "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", "AND_ASSIGN", "XOR_ASSIGN",
+ "OR_ASSIGN", "SUB_ASSIGN", "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACKET",
+ "RIGHT_BRACKET", "LEFT_BRACE", "RIGHT_BRACE", "DOT", "COMMA", "COLON",
+ "EQUAL", "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS", "STAR", "SLASH",
+ "PERCENT", "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR", "CARET",
+ "AMPERSAND", "QUESTION", "$accept", "identifier", "variable_identifier",
+ "primary_expression", "postfix_expression", "integer_expression",
+ "function_call", "function_call_or_method", "function_call_generic",
"function_call_header_no_parameters",
"function_call_header_with_parameters", "function_call_header",
"function_identifier", "unary_expression", "unary_operator",
@@ -814,10 +784,10 @@ static const char *const yytname[] =
"constant_expression", "enter_struct", "declaration",
"function_prototype", "function_declarator",
"function_header_with_parameters", "function_header",
- "parameter_declarator", "parameter_declaration",
+ "parameter_declarator", "parameter_declaration", "parameter_qualifier",
"parameter_type_specifier", "init_declarator_list", "single_declaration",
- "fully_specified_type", "interpolation_qualifier", "type_qualifier",
- "invariant_qualifier", "single_type_qualifier", "storage_qualifier",
+ "fully_specified_type", "interpolation_qualifier",
+ "parameter_type_qualifier", "type_qualifier", "storage_qualifier",
"type_specifier", "precision_qualifier", "layout_qualifier",
"layout_qualifier_id_list", "layout_qualifier_id",
"type_specifier_no_prec", "type_specifier_nonarray", "struct_specifier",
@@ -852,18 +822,16 @@ static const yytype_uint16 yytoknum[] =
345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
- 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
- 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
- 395, 396, 397, 398, 399
+ 375, 376, 377, 378, 379, 380, 381, 382
};
# endif
-#define YYPACT_NINF -363
+#define YYPACT_NINF -361
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-363)))
+ (!!((Yystate) == (-361)))
-#define YYTABLE_NINF -246
+#define YYTABLE_NINF -235
#define yytable_value_is_error(Yytable_value) \
0
@@ -872,49 +840,48 @@ static const yytype_uint16 yytoknum[] =
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- 2469, -363, -363, -363, -363, 101, -363, -363, -363, -363,
- -363, -363, -363, -363, -363, -363, -363, -363, -363, -363,
- -363, -363, -363, -363, -363, -363, -363, -363, -363, -363,
- -363, -363, -363, -363, -363, -363, -363, -363, -363, -363,
- -363, -363, -363, -363, -363, -363, -68, -363, -363, -363,
- -363, -363, -363, -363, -363, -363, -363, -363, -363, -363,
- -363, -363, -363, -363, -363, -363, -363, -363, -363, -363,
- -363, -363, -363, -363, -363, -363, -363, -88, -363, -363,
- -77, -35, -13, 2561, -51, -363, 27, -363, 1301, -363,
- -363, -363, -363, -363, -363, -363, 12, -363, 2377, -363,
- -363, 2731, -363, -363, -363, 15, 49, -363, 22, -363,
- 2561, -363, -363, -363, 2561, 51, 51, -363, 16, -103,
- -87, -363, 2561, -363, -363, 1388, -363, -363, 20, 2561,
- -363, 19, -82, -363, 408, -363, -363, -363, -363, 39,
- -91, -363, 1503, 1845, -363, -363, 2561, 51, 2071, -363,
- 47, -363, -363, -363, -363, -363, 1845, 1845, 1845, -363,
- -363, -363, -363, -363, -363, -363, -41, -363, -363, -363,
- 55, -55, 1957, 59, -363, 1845, -5, -90, 64, -81,
- -42, 33, 45, 48, 78, 80, -93, -363, 71, -363,
- -363, 2173, 2561, 70, -363, 49, 57, 63, -363, 79,
- 81, 68, 1618, 83, 1845, 72, 84, 82, -363, -363,
- 41, -363, -363, -36, -363, -77, 85, -363, -363, -363,
- -363, 541, -363, -363, -363, -363, -363, -363, 1845, 1730,
- 1845, 77, 88, -363, -363, 51, 86, -34, -363, -78,
- -363, -363, -363, -50, -363, -363, 1845, 2646, -363, -363,
- 1845, 92, -363, -363, -363, 1845, 1845, 1845, 1845, 1845,
- 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845,
- 1845, 1845, 1845, 1845, 1845, -363, -363, 2275, -363, -363,
- -363, -363, -363, 90, -363, 1845, -363, -363, -29, 1845,
- 87, -363, -363, -363, 674, -363, -363, -363, -363, -363,
- -363, -363, -363, -363, -363, -363, 1845, 1845, -363, -363,
- -363, 93, 89, 94, -363, 1845, 95, -1, 1845, 51,
- -363, -94, -363, -363, 96, 98, -363, 102, -363, -363,
- -363, -363, -363, -5, -5, -90, -90, 64, 64, 64,
- 64, -81, -81, -42, 33, 45, 48, 78, 80, 44,
- -363, 161, 22, 940, 1073, -47, -363, -37, -363, 1187,
- 674, -363, -363, -363, 1845, 103, -363, 1845, -363, 100,
- -363, 1845, -363, -363, 1845, 107, -363, -363, -363, -363,
- 1187, 90, -363, 98, 51, 2561, 109, 106, -363, 1845,
- -363, -363, 111, -363, 1845, -363, 105, 116, 222, -363,
- 115, 112, 807, -363, -363, 110, -32, 1845, 807, 90,
- -363, 1845, -363, -363, -363, -363, 113, 98, -363, -363,
- -363, -363
+ 2154, 224, -361, -361, -361, 130, -361, -361, -361, -361,
+ -361, -361, -361, -361, -361, -361, -361, -361, -361, -361,
+ -361, -361, -361, -361, -361, -361, -361, -361, -361, -361,
+ -361, -361, -361, -361, -361, -361, -361, 145, -361, -361,
+ -46, -361, -361, -361, -361, -361, -361, -361, -361, -361,
+ -361, -361, -361, -361, -361, -361, -361, -361, -361, -82,
+ -361, -361, -68, -41, -45, 9, 7, -361, 117, 16,
+ 1173, -361, -361, 2439, 16, -361, -9, -361, 2079, -361,
+ -361, -361, -361, 16, -361, 2439, -361, -361, -361, -361,
+ -361, -31, 23, -361, 11, -361, 63, -361, -361, -361,
+ -361, -361, 2303, 168, 120, -361, 13, -66, -361, 31,
+ -361, 2229, -361, -361, -361, 1243, -361, -361, -361, 56,
+ 2229, -361, 17, -50, -361, 401, -361, -361, -361, -361,
+ 120, 2303, -18, -361, 1341, 1632, -361, 179, 2303, 120,
+ 1824, -361, 70, -361, -361, -361, -361, -361, 1632, 1632,
+ 1632, -361, -361, -361, -361, -361, -361, -361, 22, -361,
+ -361, -361, 101, -29, 1727, 114, -361, 1632, 96, -97,
+ 128, -54, 111, 118, 102, 115, 154, 153, -69, -361,
+ 140, -361, -361, 1909, 2229, 124, -361, 23, 134, 136,
+ -361, 147, 149, 143, 1439, 155, 1632, 148, 157, 160,
+ -361, -361, 184, -361, -361, 52, -361, -68, 158, -361,
+ -361, -361, -361, 517, -361, -361, -361, -361, -361, -361,
+ 166, -361, -361, 1534, 1632, 150, 159, -361, -361, 120,
+ 167, 61, -361, -62, -361, -361, -361, -5, -361, -361,
+ 1632, 2371, -361, -361, 1632, 185, -361, -361, -361, 1632,
+ 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632,
+ 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, -361,
+ -361, 1994, -361, -361, -361, -361, -361, 181, -361, 1632,
+ -361, -361, 67, 1632, 180, -361, -361, -361, 633, -361,
+ -361, -361, -361, -361, -361, -361, -361, -361, -361, -361,
+ 1632, 1632, -361, -361, -361, 1632, 178, 186, -361, 1632,
+ 182, 68, 1632, 120, -361, -71, -361, -361, 187, 188,
+ -361, 192, -361, -361, -361, -361, -361, 96, 96, -97,
+ -97, 128, 128, 128, 128, -54, -54, 111, 118, 102,
+ 115, 154, 153, 113, -361, 242, 11, 865, 981, 4,
+ -361, 18, -361, 1078, 633, -361, -361, 194, 1632, 189,
+ -361, 1632, -361, 196, -361, 1632, -361, -361, 1632, 200,
+ -361, -361, -361, -361, 1078, 181, -361, 188, 120, 2303,
+ 201, 198, -361, -361, 1632, -361, -361, 202, -361, 1632,
+ -361, 191, 203, 293, -361, 204, 205, 749, -361, -361,
+ 197, 60, 1632, 749, 181, -361, 1632, -361, -361, -361,
+ -361, 199, 188, -361, -361, -361, -361
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -922,79 +889,78 @@ static const yytype_int16 yypact[] =
means the default is an error. */
static const yytype_uint16 yydefact[] =
{
- 0, 127, 147, 148, 149, 0, 133, 135, 163, 160,
- 161, 162, 167, 168, 169, 170, 171, 172, 164, 165,
- 166, 173, 174, 175, 176, 177, 178, 136, 137, 138,
- 140, 134, 179, 180, 181, 182, 183, 184, 139, 124,
- 123, 141, 142, 143, 144, 145, 0, 159, 185, 187,
- 200, 201, 188, 189, 190, 191, 192, 193, 194, 195,
- 196, 186, 197, 198, 199, 203, 204, 205, 206, 207,
- 208, 209, 210, 211, 212, 213, 214, 0, 215, 284,
- 285, 0, 98, 97, 0, 109, 115, 131, 0, 132,
- 125, 128, 121, 130, 129, 146, 156, 202, 0, 281,
- 283, 0, 2, 3, 218, 0, 0, 88, 0, 96,
- 0, 105, 99, 107, 0, 108, 0, 89, 2, 116,
- 0, 94, 0, 126, 122, 0, 1, 282, 0, 0,
- 216, 153, 0, 151, 0, 286, 100, 104, 106, 102,
- 110, 101, 0, 0, 87, 95, 0, 0, 0, 220,
- 4, 8, 6, 7, 9, 30, 0, 0, 0, 157,
- 37, 36, 38, 35, 5, 11, 31, 13, 18, 19,
- 0, 0, 24, 0, 39, 0, 43, 46, 49, 54,
- 57, 59, 61, 63, 65, 67, 69, 86, 0, 28,
- 90, 0, 0, 0, 150, 0, 0, 0, 266, 0,
- 0, 0, 0, 0, 0, 0, 0, 240, 249, 253,
- 39, 71, 84, 0, 229, 0, 146, 232, 251, 231,
- 230, 0, 233, 234, 235, 236, 237, 238, 0, 0,
- 0, 0, 0, 228, 120, 0, 226, 0, 224, 0,
- 221, 32, 33, 0, 15, 16, 0, 0, 22, 21,
- 0, 159, 25, 27, 34, 0, 0, 0, 0, 0,
+ 0, 0, 148, 149, 150, 0, 130, 140, 164, 161,
+ 162, 163, 168, 169, 170, 171, 172, 173, 165, 166,
+ 167, 174, 175, 176, 177, 178, 179, 141, 142, 145,
+ 131, 180, 181, 182, 183, 184, 185, 0, 128, 127,
+ 0, 160, 186, 188, 201, 202, 189, 190, 191, 192,
+ 193, 194, 195, 196, 197, 187, 198, 199, 200, 0,
+ 204, 273, 274, 0, 97, 107, 0, 112, 118, 135,
+ 0, 133, 125, 0, 136, 146, 157, 203, 0, 270,
+ 272, 132, 124, 0, 138, 0, 143, 144, 2, 3,
+ 207, 0, 0, 88, 0, 95, 107, 129, 108, 109,
+ 110, 98, 0, 107, 0, 89, 2, 119, 134, 0,
+ 94, 0, 126, 147, 137, 0, 1, 271, 139, 0,
+ 0, 205, 154, 0, 152, 0, 275, 99, 104, 106,
+ 111, 0, 113, 100, 0, 0, 87, 0, 0, 0,
+ 0, 209, 4, 8, 6, 7, 9, 30, 0, 0,
+ 0, 158, 37, 36, 38, 35, 5, 11, 31, 13,
+ 18, 19, 0, 0, 24, 0, 39, 0, 43, 46,
+ 49, 54, 57, 59, 61, 63, 65, 67, 69, 86,
+ 0, 28, 90, 0, 0, 0, 151, 0, 0, 0,
+ 255, 0, 0, 0, 0, 0, 0, 0, 0, 229,
+ 238, 242, 39, 71, 84, 0, 218, 0, 146, 221,
+ 240, 220, 219, 0, 222, 223, 224, 225, 226, 227,
+ 101, 103, 105, 0, 0, 0, 0, 217, 123, 0,
+ 215, 0, 213, 0, 210, 32, 33, 0, 15, 16,
+ 0, 0, 22, 21, 0, 160, 25, 27, 34, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 158, 219, 0, 154, 155,
- 152, 277, 276, 247, 268, 0, 280, 278, 0, 0,
- 0, 261, 264, 239, 0, 74, 75, 77, 76, 79,
- 80, 81, 82, 83, 78, 73, 0, 0, 254, 250,
- 252, 0, 0, 0, 114, 0, 117, 0, 0, 0,
- 222, 0, 91, 10, 0, 17, 29, 14, 20, 26,
- 40, 41, 42, 45, 44, 47, 48, 52, 53, 50,
- 51, 55, 56, 58, 60, 62, 64, 66, 68, 0,
- 217, 0, 0, 0, 0, 0, 279, 0, 260, 0,
- 241, 72, 85, 103, 0, 111, 118, 0, 223, 0,
- 225, 0, 92, 12, 0, 0, 246, 248, 271, 270,
- 273, 247, 258, 262, 0, 0, 0, 0, 112, 0,
- 119, 227, 0, 70, 0, 272, 0, 0, 257, 255,
- 0, 0, 0, 242, 113, 0, 0, 274, 0, 247,
- 259, 0, 244, 265, 243, 93, 0, 275, 269, 256,
- 263, 267
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 159,
+ 208, 0, 155, 156, 153, 266, 265, 236, 257, 0,
+ 269, 267, 0, 0, 0, 250, 253, 228, 0, 74,
+ 75, 77, 76, 79, 80, 81, 82, 83, 78, 73,
+ 0, 0, 243, 239, 241, 0, 0, 0, 117, 0,
+ 120, 0, 0, 0, 211, 0, 91, 10, 0, 17,
+ 29, 14, 20, 26, 40, 41, 42, 45, 44, 47,
+ 48, 52, 53, 50, 51, 55, 56, 58, 60, 62,
+ 64, 66, 68, 0, 206, 0, 0, 0, 0, 0,
+ 268, 0, 249, 0, 230, 72, 85, 0, 0, 114,
+ 121, 0, 212, 0, 214, 0, 92, 12, 0, 0,
+ 235, 237, 260, 259, 262, 236, 247, 251, 0, 0,
+ 0, 0, 102, 115, 0, 122, 216, 0, 70, 0,
+ 261, 0, 0, 246, 244, 0, 0, 0, 231, 116,
+ 0, 0, 263, 0, 236, 248, 0, 233, 254, 232,
+ 93, 0, 264, 258, 245, 252, 256
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
- -363, -45, -363, -363, -363, -363, -363, -363, -4, -363,
- -363, -363, -363, 54, -363, -84, -79, -139, -83, -23,
- -22, -21, -18, -17, -16, -363, -120, -137, -363, -146,
- -125, -363, 18, 21, -363, -363, -363, 136, 146, 145,
- -363, -363, -328, -363, -74, -363, -86, -363, -80, 255,
- -363, -363, 67, 0, -363, -363, -363, -363, -116, -141,
- 28, -54, -226, -85, -210, -339, -136, -363, -363, -142,
- -362, -363, -363, -98, -27, -76, -363, -363, -363, -363,
- -363, -112, -363, -363, -363, -363, -363, -363, -363, -363,
- -363, 172, -363, -363
+ -361, -39, -361, -361, -361, -361, -361, -361, 73, -361,
+ -361, -361, -361, -107, -361, -15, -20, -67, -19, 53,
+ 54, 55, 51, 57, 58, -361, -110, -132, -361, -146,
+ -125, -361, 6, 12, -361, -361, -361, 190, 228, 217,
+ 195, -361, -361, -336, 25, -361, -104, 27, -57, 322,
+ -361, -361, 141, 0, -361, -361, -361, -361, -109, -130,
+ 100, 19, -185, -17, -193, -310, -65, -361, -361, -70,
+ -360, -361, -361, -92, 46, -13, -361, -361, -361, -361,
+ -361, -38, -361, -361, -361, -361, -361, -361, -361, -361,
+ -361, 259, -361, -361
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] =
{
- -1, 236, 164, 165, 166, 324, 167, 168, 169, 170,
- 171, 172, 173, 210, 175, 176, 177, 178, 179, 180,
- 181, 182, 183, 184, 185, 186, 211, 212, 306, 213,
- 188, 122, 214, 215, 81, 82, 83, 111, 112, 113,
- 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- 94, 132, 133, 189, 96, 97, 192, 129, 148, 149,
- 237, 238, 234, 217, 218, 219, 220, 294, 387, 413,
- 351, 352, 353, 414, 221, 222, 223, 399, 224, 400,
- 225, 386, 226, 359, 283, 354, 380, 396, 397, 227,
- 98, 99, 100, 108
+ -1, 230, 156, 157, 158, 318, 159, 160, 161, 162,
+ 163, 164, 165, 202, 167, 168, 169, 170, 171, 172,
+ 173, 174, 175, 176, 177, 178, 203, 204, 300, 205,
+ 180, 111, 206, 207, 63, 64, 65, 128, 101, 102,
+ 129, 66, 67, 68, 69, 103, 70, 71, 72, 73,
+ 74, 123, 124, 181, 76, 77, 184, 120, 140, 141,
+ 231, 232, 228, 209, 210, 211, 212, 288, 381, 408,
+ 345, 346, 347, 409, 213, 214, 215, 394, 216, 395,
+ 217, 380, 218, 353, 277, 348, 374, 391, 392, 219,
+ 78, 79, 80, 94
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -1002,576 +968,514 @@ static const yytype_int16 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int16 yytable[] =
{
- 95, 105, 123, 115, 314, 187, 233, 240, 124, 114,
- 135, 310, 243, 191, 377, 321, 273, 232, 79, 398,
- 142, 80, 187, 262, 263, 102, 103, 143, 123, 371,
- 115, 384, 229, 106, 115, 252, 114, 372, 144, 230,
- 194, 119, 147, 258, 145, 259, 195, 419, 146, 147,
- 240, 274, 384, 322, 107, 146, 288, 104, 264, 265,
- 123, 244, 245, 412, 266, 267, 235, 249, 147, 412,
- 139, 140, 323, 250, 146, 381, 277, 116, 307, 290,
- 117, 307, 246, 95, 187, 382, 247, 109, 95, 366,
- 416, 307, 307, 233, 319, 308, 307, 320, 95, 307,
- 325, 128, 356, 311, 313, 2, 3, 4, 187, 187,
- 95, 147, 147, 329, 95, 110, 79, 146, 146, 80,
- 118, 103, 95, 337, 338, 339, 340, 319, 349, 95,
- 368, 255, 256, 257, 216, 125, 240, 141, 388, 355,
- 130, 390, 131, 357, 102, 103, 95, 134, 95, 193,
- 310, 190, 295, 296, 297, 298, 299, 300, 301, 302,
- 303, 304, 228, 404, 260, 261, 278, 279, -29, 361,
- 362, 305, 307, 374, 333, 334, 268, 248, 233, 174,
- 253, 335, 336, 341, 342, 420, 271, 269, 281, 270,
- 272, 95, 95, 369, 282, 275, 174, 147, 187, 286,
- 284, 291, 285, 146, 289, 292, -28, 315, 293, 318,
- 241, 242, 316, 383, -23, -245, 358, 363, 365, 364,
- 373, 216, 375, -30, 391, 367, 307, 233, 394, 254,
- 233, 402, 403, 389, 383, 405, 407, 393, 408, 409,
- 207, 415, 411, 328, 421, 343, 392, 344, 406, 345,
- 137, 187, 233, 346, 376, 347, 136, 348, 174, 138,
- 101, 417, 280, 317, 410, 370, 418, 360, 395, 378,
- 127, 0, 0, 0, 233, 0, 0, 95, 379, 0,
- 0, 0, 174, 174, 0, 385, 0, 0, 0, 0,
- 0, 0, 0, 0, 216, 0, 0, 0, 0, 123,
- 0, 0, 0, 0, 0, 124, 385, 0, 0, 330,
- 331, 332, 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 174, 174, 174, 174, 174, 174, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 401,
+ 75, 91, 126, 227, 237, 179, 61, 138, 166, 226,
+ 234, 183, 62, 112, 315, 393, 138, 378, 97, 252,
+ 304, 253, 92, 267, 179, 7, 83, 166, 84, 107,
+ 88, 89, 246, 256, 257, 365, 138, 371, 378, 308,
+ 134, 235, 236, 366, 414, 130, 93, 135, 282, 98,
+ 99, 100, 316, 234, 139, 186, 27, 28, 268, 29,
+ 248, 187, 90, 139, 95, 132, 96, 37, 258, 259,
+ 75, 284, 97, 113, 130, 271, 243, 121, 75, 138,
+ 138, 229, 244, 139, 61, 119, 179, 407, 223, 166,
+ 62, 220, 227, 407, 319, 224, 108, 115, 307, 122,
+ 317, 114, 75, 98, 99, 100, 301, 238, 239, 375,
+ 118, 75, 323, 179, -96, 301, 166, 133, 104, 125,
+ 75, 105, 343, 376, 360, 208, 139, 139, 240, 301,
+ 185, 75, 241, 349, 2, 3, 4, 351, 75, 136,
+ 75, 234, 324, 325, 326, 166, 166, 166, 166, 166,
+ 166, 166, 166, 166, 166, 166, 166, 166, 166, 166,
+ 166, 304, 83, 301, 84, 411, 302, 138, 355, 356,
+ 182, 301, 313, 383, -29, 314, 385, 227, 301, 313,
+ 357, 350, 362, 75, 75, 86, 87, 363, 7, 331,
+ 332, 333, 334, 106, 89, 179, 88, 89, 166, 399,
+ 260, 261, 179, 272, 273, 166, 242, 377, 98, 99,
+ 100, 254, 255, 208, 139, 249, 250, 251, 247, 27,
+ 28, 415, 29, 81, 301, 368, 227, 263, 377, 227,
+ 37, 38, 39, 7, 329, 330, 388, 327, 328, 264,
+ 387, 335, 336, 401, 262, 265, 266, 269, 275, 379,
+ 276, 278, 227, 279, 370, 179, 412, 280, 166, 283,
+ 285, 286, -28, 309, 27, 28, 310, 29, 81, 287,
+ 379, 75, 305, 312, 227, 37, 38, 39, 289, 290,
+ 291, 292, 293, 294, 295, 296, 297, 298, 208, -234,
+ -23, 358, 352, 359, 367, 361, -30, 299, 369, 301,
+ 82, 382, 384, 386, 389, 402, 397, 398, 403, 400,
+ 404, 410, 199, 416, 322, 337, 340, 338, 406, 339,
+ 131, 221, 112, 341, 127, 342, 222, 85, 274, 311,
+ 405, 372, 364, 413, 354, 373, 390, 117, 0, 396,
+ 0, 0, 0, 0, 0, 0, 0, 208, 208, 0,
+ 0, 0, 0, 208, 208, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 216, 216, 0, 0, 0, 0, 216,
- 216, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 174, 0, 0, 0, 0, 0, 0, 0,
- 216, 0, 0, 0, 0, 95, 0, 0, 0, 0,
+ 0, 0, 0, 0, 208, 0, 0, 0, 0, 75,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 216, 0, 0, 0, 0, 0, 216, 0,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 196, 197, 198, 174, 199, 200, 201, 202,
- 203, 204, 205, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 206,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 0, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- 77, 150, 78, 151, 152, 153, 154, 155, 0, 0,
- 156, 157, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 158,
- 0, 0, 0, 207, 208, 0, 0, 0, 0, 209,
- 160, 161, 162, 163, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 196, 197, 198, 0, 199,
- 200, 201, 202, 203, 204, 205, 12, 13, 14, 15,
+ 0, 0, 0, 0, 0, 0, 0, 208, 0, 0,
+ 0, 0, 0, 208, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 188, 189, 190, 0, 191,
+ 192, 193, 194, 195, 196, 197, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 206, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 0, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 76, 77, 150, 78, 151, 152, 153, 154,
- 155, 0, 0, 156, 157, 0, 0, 0, 0, 0,
+ 26, 27, 28, 0, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 198, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 0, 56, 57, 58, 59, 142, 60, 143,
+ 144, 145, 146, 147, 0, 0, 148, 149, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 158, 0, 0, 0, 207, 309, 0, 0,
- 0, 0, 209, 160, 161, 162, 163, 1, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, 196, 197,
- 198, 0, 199, 200, 201, 202, 203, 204, 205, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 206, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- 0, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 150, 78, 151,
- 152, 153, 154, 155, 0, 0, 156, 157, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 158, 0, 0, 0, 207,
- 0, 0, 0, 0, 0, 209, 160, 161, 162, 163,
+ 0, 0, 0, 0, 0, 150, 0, 0, 0, 199,
+ 200, 0, 0, 0, 0, 201, 152, 153, 154, 155,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 196, 197, 198, 0, 199, 200, 201, 202, 203,
- 204, 205, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 206, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, 61, 0, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
- 150, 78, 151, 152, 153, 154, 155, 0, 0, 156,
- 157, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 158, 0,
- 0, 0, 134, 0, 0, 0, 0, 0, 209, 160,
- 161, 162, 163, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 196, 197, 198, 0, 199, 200,
- 201, 202, 203, 204, 205, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 206, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 0, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 150, 78, 151, 152, 153, 154, 155,
- 0, 0, 156, 157, 0, 0, 0, 0, 0, 0,
+ 11, 188, 189, 190, 0, 191, 192, 193, 194, 195,
+ 196, 197, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 0,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 198, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 0, 56,
+ 57, 58, 59, 142, 60, 143, 144, 145, 146, 147,
+ 0, 0, 148, 149, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 158, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 209, 160, 161, 162, 163, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 12, 13,
+ 0, 150, 0, 0, 0, 199, 303, 0, 0, 0,
+ 0, 201, 152, 153, 154, 155, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 188, 189, 190,
+ 0, 191, 192, 193, 194, 195, 196, 197, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 0, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 0,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 150, 78, 151, 152,
- 153, 154, 155, 0, 0, 156, 157, 0, 0, 0,
+ 24, 25, 26, 27, 28, 0, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 198,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 59, 142,
+ 60, 143, 144, 145, 146, 147, 0, 0, 148, 149,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 3, 4, 158, 6, 7, 8, 9, 10,
- 11, 0, 0, 0, 209, 160, 161, 162, 163, 0,
- 0, 0, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 0, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, 61, 0, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
- 150, 78, 151, 152, 153, 154, 155, 0, 0, 156,
- 157, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 2, 3, 4, 158, 6,
- 7, 8, 9, 10, 11, 0, 0, 0, 0, 160,
- 161, 162, 163, 0, 0, 0, 12, 13, 14, 15,
+ 0, 0, 0, 0, 0, 0, 0, 150, 0, 0,
+ 0, 199, 0, 0, 0, 0, 0, 201, 152, 153,
+ 154, 155, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 188, 189, 190, 0, 191, 192, 193,
+ 194, 195, 196, 197, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 0, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 198, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 0, 56, 57, 58, 59, 142, 60, 143, 144, 145,
+ 146, 147, 0, 0, 148, 149, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 150, 0, 0, 0, 125, 0, 0,
+ 0, 0, 0, 201, 152, 153, 154, 155, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 188,
+ 189, 190, 0, 191, 192, 193, 194, 195, 196, 197,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 0, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 198, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 0, 56, 57, 58,
+ 59, 142, 60, 143, 144, 145, 146, 147, 0, 0,
+ 148, 149, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 150,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 201,
+ 152, 153, 154, 155, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 0, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 0, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 76, 77, 120, 78, 0, 0, 8, 9,
- 10, 11, 0, 0, 0, 0, 0, 0, 0, 0,
+ 26, 27, 28, 0, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 0, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 0, 56, 57, 58, 59, 142, 60, 143,
+ 144, 145, 146, 147, 0, 0, 148, 149, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 137, 2, 3, 4, 150, 6, 7, 8, 9,
+ 10, 11, 0, 0, 0, 201, 152, 153, 154, 155,
0, 0, 0, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 0, 0,
- 0, 0, 121, 32, 33, 34, 35, 36, 37, 0,
- 0, 0, 0, 0, 0, 0, 0, 46, 47, 0,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 0, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- 0, 150, 78, 151, 152, 153, 154, 155, 0, 0,
- 156, 157, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 158,
- 0, 0, 159, 8, 9, 10, 11, 0, 0, 0,
- 160, 161, 162, 163, 0, 0, 0, 0, 12, 13,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 0, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 0, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 0,
+ 56, 57, 58, 59, 142, 60, 143, 144, 145, 146,
+ 147, 0, 0, 148, 149, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 3, 4,
+ 0, 0, 150, 8, 9, 10, 11, 0, 0, 0,
+ 0, 0, 0, 152, 153, 154, 155, 0, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 0, 0, 0, 0, 0, 31, 32,
+ 33, 34, 35, 36, 0, 0, 0, 40, 41, 0,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 0, 109,
+ 60, 0, 0, 8, 9, 10, 11, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 0, 0, 0, 0, 0, 32, 33,
- 34, 35, 36, 37, 0, 0, 0, 0, 0, 0,
- 0, 0, 46, 47, 0, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 0,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 0, 150, 78, 151, 152,
- 153, 154, 155, 0, 0, 156, 157, 0, 0, 0,
+ 24, 25, 26, 0, 0, 0, 0, 110, 31, 32,
+ 33, 34, 35, 36, 0, 0, 0, 40, 41, 0,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 0, 142,
+ 60, 143, 144, 145, 146, 147, 0, 0, 148, 149,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 158, 0, 0, 231, 8, 9,
- 10, 11, 0, 0, 0, 160, 161, 162, 163, 0,
- 0, 0, 0, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 0, 0,
- 0, 0, 0, 32, 33, 34, 35, 36, 37, 0,
- 0, 0, 0, 0, 0, 0, 0, 46, 47, 0,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 0, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- 0, 150, 78, 151, 152, 153, 154, 155, 0, 0,
- 156, 157, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 158,
- 8, 9, 10, 11, 0, 0, 0, 0, 0, 287,
- 160, 161, 162, 163, 0, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 0, 0, 0, 0, 0, 32, 33, 34, 35, 36,
- 37, 0, 0, 0, 0, 0, 0, 0, 0, 46,
- 47, 0, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 0, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 0, 150, 78, 151, 152, 153, 154, 155,
- 0, 0, 156, 157, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 150, 0, 0,
+ 151, 8, 9, 10, 11, 0, 0, 0, 152, 153,
+ 154, 155, 0, 0, 0, 0, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 0, 0, 0, 0, 0, 31, 32, 33, 34,
+ 35, 36, 0, 0, 0, 40, 41, 0, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 0, 56, 57, 58, 0, 142, 60, 143,
+ 144, 145, 146, 147, 0, 0, 148, 149, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 158, 0, 0, 312, 8, 9, 10, 11, 0,
- 0, 0, 160, 161, 162, 163, 0, 0, 0, 0,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 0, 0, 0, 0, 0,
- 32, 33, 34, 35, 36, 37, 0, 0, 0, 0,
- 0, 0, 0, 0, 46, 47, 0, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 0, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 76, 0, 150, 78,
- 151, 152, 153, 154, 155, 0, 0, 156, 157, 0,
+ 0, 0, 0, 0, 0, 150, 0, 0, 225, 8,
+ 9, 10, 11, 0, 0, 0, 152, 153, 154, 155,
+ 0, 0, 0, 0, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 0,
+ 0, 0, 0, 0, 31, 32, 33, 34, 35, 36,
+ 0, 0, 0, 40, 41, 0, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 0, 56, 57, 58, 0, 142, 60, 143, 144, 145,
+ 146, 147, 0, 0, 148, 149, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 158, 8, 9, 10,
- 11, 0, 0, 0, 0, 0, 0, 160, 161, 162,
- 163, 0, 12, 13, 14, 15, 16, 17, 18, 19,
+ 0, 0, 0, 150, 8, 9, 10, 11, 0, 0,
+ 0, 0, 0, 281, 152, 153, 154, 155, 0, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 0, 0, 0, 0, 0, 31,
+ 32, 33, 34, 35, 36, 0, 0, 0, 40, 41,
+ 0, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 0, 56, 57, 58, 0,
+ 142, 60, 143, 144, 145, 146, 147, 0, 0, 148,
+ 149, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 150, 0,
+ 0, 306, 8, 9, 10, 11, 0, 0, 0, 152,
+ 153, 154, 155, 0, 0, 0, 0, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 0, 0, 0, 0, 0, 31, 32, 33,
+ 34, 35, 36, 0, 0, 0, 40, 41, 0, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 0, 56, 57, 58, 0, 142, 60,
+ 143, 144, 145, 146, 147, 0, 0, 148, 149, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 150, 8, 9, 10,
+ 11, 0, 0, 0, 0, 0, 0, 152, 153, 154,
+ 155, 0, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 0, 0, 0,
- 0, 0, 32, 33, 34, 35, 36, 37, 0, 0,
- 0, 0, 0, 0, 0, 0, 46, 251, 0, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, 61, 0, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 72, 73, 74, 75, 76, 0,
- 150, 78, 151, 152, 153, 154, 155, 0, 0, 156,
- 157, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 2, 3, 4, 158, 6,
- 7, 8, 9, 10, 11, 0, 0, 0, 0, 160,
- 161, 162, 163, 0, 0, 0, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 0, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 0, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 76, 77, 0, 78, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 2, 3, 4,
- 0, 6, 7, 8, 9, 10, 11, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 239, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 0, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 61, 0,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 0, 78, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
- 3, 4, 0, 6, 7, 8, 9, 10, 11, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 276,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 0, 0, 31, 32, 33, 34, 35, 36, 0, 0,
+ 0, 40, 245, 0, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 0, 56,
+ 57, 58, 0, 142, 60, 143, 144, 145, 146, 147,
+ 0, 0, 148, 149, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 137, 2, 3,
+ 4, 150, 6, 7, 8, 9, 10, 11, 0, 0,
+ 0, 0, 152, 153, 154, 155, 0, 0, 0, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 0, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
- 42, 43, 44, 45, 46, 47, 0, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 0, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 76, 77, 0, 78,
- 0, 0, 0, 0, 0, 0, 0, 126, 0, 0,
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 350, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 0, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, 61, 0, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
- 0, 78, 1, 2, 3, 4, 5, 6, 7, 8,
+ 0, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 0, 56, 57, 58, 59,
+ 0, 60, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 137, 2, 3, 4, 0, 6, 7, 8,
+ 9, 10, 11, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 233, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 0, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 0, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 0, 56, 57, 58, 59, 0, 60, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 137, 2, 3,
+ 4, 0, 6, 7, 8, 9, 10, 11, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 270, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 0, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 0, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 0, 56, 57, 58, 59,
+ 0, 60, 0, 0, 0, 0, 0, 0, 0, 116,
+ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 344, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 0, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 0, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 0, 56, 57, 58, 59, 0, 60, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 0, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 0, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 0, 56, 57, 58, 59,
+ 0, 60, 137, 2, 3, 4, 0, 6, 7, 8,
9, 10, 11, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 0, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 0, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 0, 78, 1, 2, 3, 4, 0, 6,
- 7, 8, 9, 10, 11, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 0, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 0, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 76, 77, 0, 78, 8, 9, 10, 11,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 0, 0, 0, 0,
- 0, 32, 33, 34, 35, 36, 37, 0, 0, 0,
- 0, 0, 0, 0, 0, 46, 47, 0, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 0, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, 75, 76, 0, 326,
- 78, 8, 9, 10, 11, 327, 0, 0, 0, 0,
+ 28, 0, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 0, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 0, 56, 57, 58, 59, 0, 60, 2, 3, 4,
+ 0, 0, 0, 8, 9, 10, 11, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 0, 0, 0, 0, 0, 31, 32,
+ 33, 34, 35, 36, 0, 0, 0, 40, 41, 0,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 0, 0,
+ 60, 8, 9, 10, 11, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 0, 0, 0, 0, 0, 32, 33, 34, 35,
- 36, 37, 0, 0, 0, 0, 0, 0, 0, 0,
- 46, 47, 0, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 0, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 76, 0, 0, 78
+ 26, 0, 0, 0, 0, 0, 31, 32, 33, 34,
+ 35, 36, 0, 0, 0, 40, 41, 0, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 0, 56, 57, 58, 0, 320, 60, 8,
+ 9, 10, 11, 321, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 0,
+ 0, 0, 0, 0, 31, 32, 33, 34, 35, 36,
+ 0, 0, 0, 40, 41, 0, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 0, 56, 57, 58, 0, 0, 60
};
static const yytype_int16 yycheck[] =
{
- 0, 46, 88, 83, 230, 125, 143, 148, 88, 83,
- 108, 221, 158, 129, 353, 93, 109, 142, 0, 381,
- 123, 0, 142, 104, 105, 93, 94, 130, 114, 123,
- 110, 359, 123, 121, 114, 172, 110, 131, 125, 130,
- 122, 86, 122, 133, 131, 135, 128, 409, 122, 129,
- 191, 144, 380, 131, 131, 129, 202, 125, 139, 140,
- 146, 102, 103, 402, 106, 107, 146, 122, 148, 408,
- 115, 116, 122, 128, 148, 122, 192, 128, 128, 204,
- 131, 128, 123, 83, 204, 122, 127, 122, 88, 315,
- 122, 128, 128, 230, 128, 131, 128, 131, 98, 128,
- 246, 101, 131, 228, 229, 4, 5, 6, 228, 229,
- 110, 191, 192, 250, 114, 128, 98, 191, 192, 98,
- 93, 94, 122, 262, 263, 264, 265, 128, 274, 129,
- 131, 136, 137, 138, 134, 123, 277, 121, 364, 285,
- 125, 367, 93, 289, 93, 94, 146, 125, 148, 130,
- 360, 131, 111, 112, 113, 114, 115, 116, 117, 118,
- 119, 120, 123, 389, 100, 101, 96, 97, 121, 306,
- 307, 130, 128, 129, 258, 259, 143, 122, 315, 125,
- 121, 260, 261, 266, 267, 411, 108, 142, 131, 141,
- 110, 191, 192, 318, 131, 124, 142, 277, 318, 131,
- 121, 129, 121, 277, 121, 121, 121, 130, 126, 123,
- 156, 157, 124, 359, 122, 125, 129, 124, 124, 130,
- 124, 221, 61, 121, 124, 130, 128, 364, 121, 175,
- 367, 122, 126, 130, 380, 124, 131, 374, 122, 17,
- 125, 131, 130, 247, 131, 268, 371, 269, 394, 270,
- 114, 371, 389, 271, 352, 272, 110, 273, 204, 114,
- 5, 407, 195, 235, 400, 319, 408, 294, 380, 354,
- 98, -1, -1, -1, 411, -1, -1, 277, 354, -1,
- -1, -1, 228, 229, -1, 359, -1, -1, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, -1, -1, 385,
- -1, -1, -1, -1, -1, 385, 380, -1, -1, 255,
- 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
- 266, 267, 268, 269, 270, 271, 272, 273, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 384,
+ 0, 40, 94, 135, 150, 115, 0, 111, 115, 134,
+ 140, 120, 0, 70, 76, 375, 120, 353, 9, 116,
+ 213, 118, 104, 92, 134, 9, 1, 134, 1, 68,
+ 76, 77, 164, 87, 88, 106, 140, 347, 374, 224,
+ 106, 148, 149, 114, 404, 102, 114, 113, 194, 40,
+ 41, 42, 114, 183, 111, 105, 40, 41, 127, 43,
+ 167, 111, 108, 120, 105, 104, 111, 51, 122, 123,
+ 70, 196, 9, 73, 131, 184, 105, 108, 78, 183,
+ 184, 138, 111, 140, 78, 85, 196, 397, 106, 196,
+ 78, 130, 224, 403, 240, 113, 69, 106, 223, 76,
+ 105, 74, 102, 40, 41, 42, 111, 85, 86, 105,
+ 83, 111, 244, 223, 105, 111, 223, 104, 111, 108,
+ 120, 114, 268, 105, 309, 125, 183, 184, 106, 111,
+ 113, 131, 110, 279, 4, 5, 6, 283, 138, 108,
+ 140, 271, 249, 250, 251, 252, 253, 254, 255, 256,
+ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
+ 267, 354, 137, 111, 137, 105, 114, 271, 300, 301,
+ 114, 111, 111, 358, 104, 114, 361, 309, 111, 111,
+ 305, 114, 114, 183, 184, 40, 41, 312, 9, 256,
+ 257, 258, 259, 76, 77, 305, 76, 77, 305, 384,
+ 89, 90, 312, 79, 80, 312, 105, 353, 40, 41,
+ 42, 83, 84, 213, 271, 119, 120, 121, 104, 40,
+ 41, 406, 43, 44, 111, 112, 358, 125, 374, 361,
+ 51, 52, 53, 9, 254, 255, 368, 252, 253, 124,
+ 365, 260, 261, 389, 126, 91, 93, 107, 114, 353,
+ 114, 104, 384, 104, 346, 365, 402, 114, 365, 104,
+ 112, 104, 104, 113, 40, 41, 107, 43, 44, 109,
+ 374, 271, 106, 106, 406, 51, 52, 53, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 288, 108,
+ 105, 113, 112, 107, 107, 113, 104, 113, 56, 111,
+ 76, 107, 113, 107, 104, 114, 105, 109, 105, 107,
+ 17, 114, 108, 114, 241, 262, 265, 263, 113, 264,
+ 103, 131, 379, 266, 96, 267, 131, 5, 187, 229,
+ 395, 348, 313, 403, 288, 348, 374, 78, -1, 378,
+ -1, -1, -1, -1, -1, -1, -1, 347, 348, -1,
+ -1, -1, -1, 353, 354, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 353, 354, -1, -1, -1, -1, 359,
- 360, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 318, -1, -1, -1, -1, -1, -1, -1,
- 380, -1, -1, -1, -1, 385, -1, -1, -1, -1,
+ -1, -1, -1, -1, 374, -1, -1, -1, -1, 379,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 402, -1, -1, -1, -1, -1, 408, -1,
- -1, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 371, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, -1, 77, 78, 79, 80, 81,
- 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- 92, 93, 94, 95, 96, 97, 98, 99, -1, -1,
- 102, 103, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 121,
- -1, -1, -1, 125, 126, -1, -1, -1, -1, 131,
- 132, 133, 134, 135, 3, 4, 5, 6, 7, 8,
+ -1, -1, -1, -1, -1, -1, -1, 397, -1, -1,
+ -1, -1, -1, 403, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, -1, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 39, 40, 41, -1, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, 75, -1, 77, 78,
- 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
- 99, -1, -1, 102, 103, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 121, -1, -1, -1, 125, 126, -1, -1,
- -1, -1, 131, 132, 133, 134, 135, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, -1, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
- -1, 77, 78, 79, 80, 81, 82, 83, 84, 85,
- 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, -1, -1, 102, 103, -1, -1,
+ 69, 70, -1, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, -1, -1, 85, 86, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 121, -1, -1, -1, 125,
- -1, -1, -1, -1, -1, 131, 132, 133, 134, 135,
+ -1, -1, -1, -1, -1, 104, -1, -1, -1, 108,
+ 109, -1, -1, -1, -1, 114, 115, 116, 117, 118,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, -1, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, -1,
43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, -1, 77, 78, 79, 80, 81, 82,
- 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- 93, 94, 95, 96, 97, 98, 99, -1, -1, 102,
- 103, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 121, -1,
- -1, -1, 125, -1, -1, -1, -1, -1, 131, 132,
- 133, 134, 135, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, -1, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, -1, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- -1, -1, 102, 103, -1, -1, -1, -1, -1, -1,
+ 63, 64, 65, 66, 67, 68, 69, 70, -1, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ -1, -1, 85, 86, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 121, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 131, 132, 133, 134, 135, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 25, 26,
+ -1, 104, -1, -1, -1, 108, 109, -1, -1, -1,
+ -1, 114, 115, 116, 117, 118, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ -1, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 37, 38, 39, 40, 41, -1, 43, 44, 45, 46,
47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, -1, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, -1,
- 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
- 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
- 97, 98, 99, -1, -1, 102, 103, -1, -1, -1,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, -1, 72, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, -1, -1, 85, 86,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 3, 4, 5, 6, 121, 8, 9, 10, 11, 12,
- 13, -1, -1, -1, 131, 132, 133, 134, 135, -1,
- -1, -1, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, -1, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, -1, 77, 78, 79, 80, 81, 82,
- 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- 93, 94, 95, 96, 97, 98, 99, -1, -1, 102,
- 103, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 3, 4, 5, 6, 121, 8,
- 9, 10, 11, 12, 13, -1, -1, -1, -1, 132,
- 133, 134, 135, -1, -1, -1, 25, 26, 27, 28,
+ -1, -1, -1, -1, -1, -1, -1, 104, -1, -1,
+ -1, 108, -1, -1, -1, -1, -1, 114, 115, 116,
+ 117, 118, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, -1, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, -1, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ -1, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, -1, -1, 85, 86, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 104, -1, -1, -1, 108, -1, -1,
+ -1, -1, -1, 114, 115, 116, 117, 118, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, -1, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, -1, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, -1, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, -1, -1,
+ 85, 86, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 104,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 114,
+ 115, 116, 117, 118, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, -1, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, 75, -1, 77, 78,
- 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 94, -1, -1, 10, 11,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
+ 39, 40, 41, -1, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, -1, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, -1, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, -1, -1, 85, 86, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 3, 4, 5, 6, 104, 8, 9, 10, 11,
+ 12, 13, -1, -1, -1, 114, 115, 116, 117, 118,
-1, -1, -1, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, -1, -1,
- -1, -1, 131, 45, 46, 47, 48, 49, 50, -1,
- -1, -1, -1, -1, -1, -1, -1, 59, 60, -1,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, -1, 77, 78, 79, 80, 81,
- 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- -1, 93, 94, 95, 96, 97, 98, 99, -1, -1,
- 102, 103, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 121,
- -1, -1, 124, 10, 11, 12, 13, -1, -1, -1,
- 132, 133, 134, 135, -1, -1, -1, -1, 25, 26,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ -1, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, -1, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, 70, -1,
+ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, -1, -1, 85, 86, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 4, 5, 6,
+ -1, -1, 104, 10, 11, 12, 13, -1, -1, -1,
+ -1, -1, -1, 115, 116, 117, 118, -1, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, -1, -1, -1, -1, -1, 45, 46,
- 47, 48, 49, 50, -1, -1, -1, -1, -1, -1,
- -1, -1, 59, 60, -1, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, -1,
- 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
- 87, 88, 89, 90, 91, -1, 93, 94, 95, 96,
- 97, 98, 99, -1, -1, 102, 103, -1, -1, -1,
+ 47, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, -1, 72, 73, 74, -1, 76,
+ 77, -1, -1, 10, 11, 12, 13, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, -1, -1, -1, -1, 114, 45, 46,
+ 47, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, -1, 72, 73, 74, -1, 76,
+ 77, 78, 79, 80, 81, 82, -1, -1, 85, 86,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 121, -1, -1, 124, 10, 11,
- 12, 13, -1, -1, -1, 132, 133, 134, 135, -1,
- -1, -1, -1, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, -1, -1,
- -1, -1, -1, 45, 46, 47, 48, 49, 50, -1,
- -1, -1, -1, -1, -1, -1, -1, 59, 60, -1,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, -1, 77, 78, 79, 80, 81,
- 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- -1, 93, 94, 95, 96, 97, 98, 99, -1, -1,
- 102, 103, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 121,
- 10, 11, 12, 13, -1, -1, -1, -1, -1, 131,
- 132, 133, 134, 135, -1, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- -1, -1, -1, -1, -1, 45, 46, 47, 48, 49,
- 50, -1, -1, -1, -1, -1, -1, -1, -1, 59,
- 60, -1, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, -1, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 91, -1, 93, 94, 95, 96, 97, 98, 99,
- -1, -1, 102, 103, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 104, -1, -1,
+ 107, 10, 11, 12, 13, -1, -1, -1, 115, 116,
+ 117, 118, -1, -1, -1, -1, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, -1, -1, -1, -1, -1, 45, 46, 47, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, -1, 72, 73, 74, -1, 76, 77, 78,
+ 79, 80, 81, 82, -1, -1, 85, 86, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 121, -1, -1, 124, 10, 11, 12, 13, -1,
- -1, -1, 132, 133, 134, 135, -1, -1, -1, -1,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, -1, -1, -1, -1, -1,
- 45, 46, 47, 48, 49, 50, -1, -1, -1, -1,
- -1, -1, -1, -1, 59, 60, -1, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, -1, 77, 78, 79, 80, 81, 82, 83, 84,
- 85, 86, 87, 88, 89, 90, 91, -1, 93, 94,
- 95, 96, 97, 98, 99, -1, -1, 102, 103, -1,
+ -1, -1, -1, -1, -1, 104, -1, -1, 107, 10,
+ 11, 12, 13, -1, -1, -1, 115, 116, 117, 118,
+ -1, -1, -1, -1, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, -1,
+ -1, -1, -1, -1, 45, 46, 47, 48, 49, 50,
+ -1, -1, -1, 54, 55, -1, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ -1, 72, 73, 74, -1, 76, 77, 78, 79, 80,
+ 81, 82, -1, -1, 85, 86, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 121, 10, 11, 12,
- 13, -1, -1, -1, -1, -1, -1, 132, 133, 134,
- 135, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ -1, -1, -1, 104, 10, 11, 12, 13, -1, -1,
+ -1, -1, -1, 114, 115, 116, 117, 118, -1, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, -1, -1, -1, -1, -1, 45,
+ 46, 47, 48, 49, 50, -1, -1, -1, 54, 55,
+ -1, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, -1, 72, 73, 74, -1,
+ 76, 77, 78, 79, 80, 81, 82, -1, -1, 85,
+ 86, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 104, -1,
+ -1, 107, 10, 11, 12, 13, -1, -1, -1, 115,
+ 116, 117, 118, -1, -1, -1, -1, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, -1, -1, -1, -1, -1, 45, 46, 47,
+ 48, 49, 50, -1, -1, -1, 54, 55, -1, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, -1, 72, 73, 74, -1, 76, 77,
+ 78, 79, 80, 81, 82, -1, -1, 85, 86, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 104, 10, 11, 12,
+ 13, -1, -1, -1, -1, -1, -1, 115, 116, 117,
+ 118, -1, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, -1, -1, -1,
-1, -1, 45, 46, 47, 48, 49, 50, -1, -1,
- -1, -1, -1, -1, -1, -1, 59, 60, -1, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, -1, 77, 78, 79, 80, 81, 82,
- 83, 84, 85, 86, 87, 88, 89, 90, 91, -1,
- 93, 94, 95, 96, 97, 98, 99, -1, -1, 102,
- 103, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 3, 4, 5, 6, 121, 8,
- 9, 10, 11, 12, 13, -1, -1, -1, -1, 132,
- 133, 134, 135, -1, -1, -1, 25, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, -1, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, 75, -1, 77, 78,
- 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, -1, 94, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 3, 4, 5, 6,
- -1, 8, 9, 10, 11, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 126, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, -1, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, -1,
- 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
- 87, 88, 89, 90, 91, 92, -1, 94, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 3, 4,
- 5, 6, -1, 8, 9, 10, 11, 12, 13, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 126,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, -1, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, -1, 77, 78, 79, 80, 81, 82, 83, 84,
- 85, 86, 87, 88, 89, 90, 91, 92, -1, 94,
- -1, -1, -1, -1, -1, -1, -1, 0, -1, -1,
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 126, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, -1, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, -1, 77, 78, 79, 80, 81, 82,
- 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- -1, 94, 3, 4, 5, 6, 7, 8, 9, 10,
+ -1, 54, 55, -1, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, -1, 72,
+ 73, 74, -1, 76, 77, 78, 79, 80, 81, 82,
+ -1, -1, 85, 86, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
+ 6, 104, 8, 9, 10, 11, 12, 13, -1, -1,
+ -1, -1, 115, 116, 117, 118, -1, -1, -1, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, -1, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ -1, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, -1, 72, 73, 74, 75,
+ -1, 77, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 3, 4, 5, 6, -1, 8, 9, 10,
+ 11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 109, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, -1, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, -1, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ -1, 72, 73, 74, 75, -1, 77, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
+ 6, -1, 8, 9, 10, 11, 12, 13, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 109, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, -1, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ -1, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, -1, 72, 73, 74, 75,
+ -1, 77, -1, -1, -1, -1, -1, -1, -1, 0,
+ -1, -1, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 109, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, -1, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, -1, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ -1, 72, 73, 74, 75, -1, 77, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, -1, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ -1, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, -1, 72, 73, 74, 75,
+ -1, 77, 3, 4, 5, 6, -1, 8, 9, 10,
11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- -1, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, -1, 77, 78, 79, 80,
- 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- 91, 92, -1, 94, 3, 4, 5, 6, -1, 8,
- 9, 10, 11, 12, 13, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 25, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 59, 60, -1, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, 75, -1, 77, 78,
- 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, -1, 94, 10, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 38, 39, -1, -1, -1, -1,
- -1, 45, 46, 47, 48, 49, 50, -1, -1, -1,
- -1, -1, -1, -1, -1, 59, 60, -1, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, -1, 77, 78, 79, 80, 81, 82, 83,
- 84, 85, 86, 87, 88, 89, 90, 91, -1, 93,
- 94, 10, 11, 12, 13, 99, -1, -1, -1, -1,
+ 41, -1, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, -1, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ -1, 72, 73, 74, 75, -1, 77, 4, 5, 6,
+ -1, -1, -1, 10, 11, 12, 13, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, -1, -1, -1, -1, -1, 45, 46,
+ 47, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, -1, 72, 73, 74, -1, -1,
+ 77, 10, 11, 12, 13, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, -1, -1, -1, -1, -1, 45, 46, 47, 48,
- 49, 50, -1, -1, -1, -1, -1, -1, -1, -1,
- 59, 60, -1, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, 75, -1, 77, 78,
- 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, -1, -1, 94
+ 49, 50, -1, -1, -1, 54, 55, -1, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, -1, 72, 73, 74, -1, 76, 77, 10,
+ 11, 12, 13, 82, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, -1,
+ -1, -1, -1, -1, 45, 46, 47, 48, 49, 50,
+ -1, -1, -1, 54, 55, -1, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ -1, 72, 73, 74, -1, -1, 77
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1580,81 +1484,79 @@ static const yytype_uint8 yystos[] =
{
0, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 59, 60, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 77, 78, 79, 80, 81, 82, 83, 84,
- 85, 86, 87, 88, 89, 90, 91, 92, 94, 177,
- 178, 179, 180, 181, 185, 186, 187, 188, 189, 190,
- 191, 192, 193, 194, 195, 198, 199, 200, 235, 236,
- 237, 194, 93, 94, 125, 146, 121, 131, 238, 122,
- 128, 182, 183, 184, 189, 193, 128, 131, 93, 146,
- 93, 131, 176, 191, 193, 123, 0, 236, 198, 202,
- 125, 93, 196, 197, 125, 218, 183, 182, 184, 146,
- 146, 121, 123, 130, 125, 131, 189, 193, 203, 204,
- 93, 95, 96, 97, 98, 99, 102, 103, 121, 124,
- 132, 133, 134, 135, 147, 148, 149, 151, 152, 153,
- 154, 155, 156, 157, 158, 159, 160, 161, 162, 163,
- 164, 165, 166, 167, 168, 169, 170, 171, 175, 198,
- 131, 203, 201, 130, 122, 128, 14, 15, 16, 18,
- 19, 20, 21, 22, 23, 24, 61, 125, 126, 131,
- 158, 171, 172, 174, 177, 178, 198, 208, 209, 210,
- 211, 219, 220, 221, 223, 225, 227, 234, 123, 123,
- 130, 124, 175, 172, 207, 193, 146, 205, 206, 126,
- 204, 158, 158, 174, 102, 103, 123, 127, 122, 122,
- 128, 60, 172, 121, 158, 136, 137, 138, 133, 135,
- 100, 101, 104, 105, 139, 140, 106, 107, 143, 142,
- 141, 108, 110, 109, 144, 124, 126, 203, 96, 97,
- 197, 131, 131, 229, 121, 121, 131, 131, 174, 121,
- 175, 129, 121, 126, 212, 111, 112, 113, 114, 115,
- 116, 117, 118, 119, 120, 130, 173, 128, 131, 126,
- 209, 175, 124, 175, 207, 130, 124, 205, 123, 128,
- 131, 93, 131, 122, 150, 174, 93, 99, 153, 172,
- 158, 158, 158, 160, 160, 161, 161, 162, 162, 162,
- 162, 163, 163, 164, 165, 166, 167, 168, 169, 174,
- 126, 215, 216, 217, 230, 174, 131, 174, 129, 228,
- 219, 172, 172, 124, 130, 124, 207, 130, 131, 175,
- 206, 123, 131, 124, 129, 61, 218, 210, 208, 220,
- 231, 122, 122, 174, 187, 189, 226, 213, 207, 130,
- 207, 124, 175, 172, 121, 226, 232, 233, 215, 222,
- 224, 146, 122, 126, 207, 124, 174, 131, 122, 17,
- 211, 130, 210, 214, 218, 131, 122, 174, 214, 215,
- 207, 131
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 72, 73, 74, 75,
+ 77, 160, 161, 162, 163, 164, 169, 170, 171, 172,
+ 174, 175, 176, 177, 178, 181, 182, 183, 218, 219,
+ 220, 44, 76, 172, 175, 177, 40, 41, 76, 77,
+ 108, 129, 104, 114, 221, 105, 111, 9, 40, 41,
+ 42, 166, 167, 173, 111, 114, 76, 129, 175, 76,
+ 114, 159, 176, 181, 175, 106, 0, 219, 175, 181,
+ 185, 108, 76, 179, 180, 108, 201, 166, 165, 168,
+ 176, 167, 129, 104, 106, 113, 108, 3, 174, 176,
+ 186, 187, 76, 78, 79, 80, 81, 82, 85, 86,
+ 104, 107, 115, 116, 117, 118, 130, 131, 132, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+ 158, 181, 114, 186, 184, 113, 105, 111, 14, 15,
+ 16, 18, 19, 20, 21, 22, 23, 24, 56, 108,
+ 109, 114, 141, 154, 155, 157, 160, 161, 181, 191,
+ 192, 193, 194, 202, 203, 204, 206, 208, 210, 217,
+ 129, 165, 168, 106, 113, 107, 158, 155, 190, 176,
+ 129, 188, 189, 109, 187, 141, 141, 157, 85, 86,
+ 106, 110, 105, 105, 111, 55, 155, 104, 141, 119,
+ 120, 121, 116, 118, 83, 84, 87, 88, 122, 123,
+ 89, 90, 126, 125, 124, 91, 93, 92, 127, 107,
+ 109, 186, 79, 80, 180, 114, 114, 212, 104, 104,
+ 114, 114, 157, 104, 158, 112, 104, 109, 195, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 113,
+ 156, 111, 114, 109, 192, 106, 107, 158, 190, 113,
+ 107, 188, 106, 111, 114, 76, 114, 105, 133, 157,
+ 76, 82, 136, 155, 141, 141, 141, 143, 143, 144,
+ 144, 145, 145, 145, 145, 146, 146, 147, 148, 149,
+ 150, 151, 152, 157, 109, 198, 199, 200, 213, 157,
+ 114, 157, 112, 211, 202, 155, 155, 158, 113, 107,
+ 190, 113, 114, 158, 189, 106, 114, 107, 112, 56,
+ 201, 193, 191, 203, 214, 105, 105, 157, 171, 174,
+ 209, 196, 107, 190, 113, 190, 107, 158, 155, 104,
+ 209, 215, 216, 198, 205, 207, 129, 105, 109, 190,
+ 107, 157, 114, 105, 17, 194, 113, 193, 197, 201,
+ 114, 105, 157, 197, 198, 190, 114
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 145, 146, 146, 147, 148, 148, 148, 148, 148,
- 148, 149, 149, 149, 149, 149, 149, 150, 151, 152,
- 152, 153, 153, 154, 154, 155, 155, 156, 157, 157,
- 157, 158, 158, 158, 158, 159, 159, 159, 159, 160,
- 160, 160, 160, 161, 161, 161, 162, 162, 162, 163,
- 163, 163, 163, 163, 164, 164, 164, 165, 165, 166,
- 166, 167, 167, 168, 168, 169, 169, 170, 170, 171,
- 171, 172, 172, 173, 173, 173, 173, 173, 173, 173,
- 173, 173, 173, 173, 174, 174, 175, 176, 177, 177,
- 177, 177, 177, 177, 177, 177, 178, 179, 179, 180,
- 180, 181, 182, 182, 183, 183, 183, 183, 184, 185,
- 185, 185, 185, 185, 185, 186, 186, 186, 186, 186,
- 186, 187, 187, 188, 188, 189, 189, 190, 191, 191,
- 191, 191, 191, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 193, 194, 194, 194,
- 195, 196, 196, 197, 197, 197, 198, 198, 198, 199,
- 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
- 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
- 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
- 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
- 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
- 199, 199, 199, 199, 199, 199, 201, 200, 202, 200,
- 203, 203, 204, 204, 205, 205, 206, 206, 207, 208,
- 209, 209, 210, 210, 210, 210, 210, 210, 210, 211,
- 212, 213, 211, 214, 214, 216, 215, 217, 215, 218,
- 218, 219, 219, 220, 220, 221, 222, 222, 224, 223,
- 225, 225, 226, 226, 228, 227, 229, 227, 230, 227,
- 231, 231, 232, 232, 233, 233, 234, 234, 234, 234,
- 234, 235, 235, 236, 236, 238, 237
+ 0, 128, 129, 129, 130, 131, 131, 131, 131, 131,
+ 131, 132, 132, 132, 132, 132, 132, 133, 134, 135,
+ 135, 136, 136, 137, 137, 138, 138, 139, 140, 140,
+ 140, 141, 141, 141, 141, 142, 142, 142, 142, 143,
+ 143, 143, 143, 144, 144, 144, 145, 145, 145, 146,
+ 146, 146, 146, 146, 147, 147, 147, 148, 148, 149,
+ 149, 150, 150, 151, 151, 152, 152, 153, 153, 154,
+ 154, 155, 155, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 157, 157, 158, 159, 160, 160,
+ 160, 160, 160, 160, 160, 161, 162, 162, 163, 163,
+ 164, 165, 165, 166, 166, 166, 166, 167, 167, 167,
+ 167, 168, 169, 169, 169, 169, 169, 169, 170, 170,
+ 170, 170, 170, 170, 170, 171, 171, 172, 172, 173,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 175, 175, 175, 175, 175, 175, 176, 176, 177, 177,
+ 177, 178, 179, 179, 180, 180, 180, 181, 181, 181,
+ 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 184, 183, 185, 183, 186,
+ 186, 187, 187, 188, 188, 189, 189, 190, 191, 192,
+ 192, 193, 193, 193, 193, 193, 193, 193, 194, 195,
+ 196, 194, 197, 197, 199, 198, 200, 198, 201, 201,
+ 202, 202, 203, 203, 204, 205, 205, 207, 206, 208,
+ 208, 209, 209, 211, 210, 212, 210, 213, 210, 214,
+ 214, 215, 215, 216, 216, 217, 217, 217, 217, 217,
+ 218, 218, 219, 219, 221, 220
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -1669,26 +1571,25 @@ static const yytype_uint8 yyr2[] =
3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
5, 1, 3, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 3, 1, 2, 2, 2,
- 4, 5, 6, 9, 2, 3, 2, 1, 1, 2,
- 3, 3, 2, 5, 2, 1, 2, 1, 1, 1,
- 3, 6, 7, 8, 5, 1, 2, 5, 6, 7,
- 4, 1, 2, 1, 1, 1, 2, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 4, 1, 3, 1, 3, 3, 1, 3, 4, 1,
+ 4, 5, 6, 9, 2, 2, 1, 1, 2, 3,
+ 3, 2, 5, 3, 2, 3, 2, 0, 1, 1,
+ 1, 1, 1, 3, 6, 7, 8, 5, 1, 2,
+ 5, 6, 7, 4, 2, 1, 2, 1, 1, 1,
+ 1, 1, 2, 1, 2, 1, 1, 2, 2, 3,
+ 1, 1, 1, 2, 2, 1, 1, 2, 1, 1,
+ 1, 4, 1, 3, 1, 3, 3, 1, 3, 4,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 0, 6, 0, 5,
- 1, 2, 3, 4, 1, 3, 1, 4, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
- 0, 0, 5, 1, 1, 0, 2, 0, 2, 2,
- 3, 1, 2, 1, 2, 5, 3, 1, 0, 6,
- 3, 2, 1, 4, 0, 6, 0, 8, 0, 7,
- 1, 1, 1, 0, 2, 3, 2, 2, 2, 3,
- 2, 1, 2, 1, 1, 0, 3
+ 1, 1, 1, 1, 1, 0, 6, 0, 5, 1,
+ 2, 3, 4, 1, 3, 1, 4, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 0,
+ 0, 5, 1, 1, 0, 2, 0, 2, 2, 3,
+ 1, 2, 1, 2, 5, 3, 1, 0, 6, 3,
+ 2, 1, 4, 0, 6, 0, 8, 0, 7, 1,
+ 1, 1, 0, 2, 3, 2, 2, 2, 3, 2,
+ 1, 2, 1, 1, 0, 3
};
@@ -2664,7 +2565,7 @@ yyreduce:
const TType *type = new TType((yyvsp[0].interm.intermTypedNode)->getType());
(yyvsp[-1].interm.function)->addParameter(TConstParameter(type));
(yyval.interm).function = (yyvsp[-1].interm.function);
- (yyval.interm).nodePair.node1 = TIntermediate::MakeAggregate((yyvsp[0].interm.intermTypedNode), (yylsp[0]));
+ (yyval.interm).nodePair.node1 = context->intermediate.makeAggregate((yyvsp[0].interm.intermTypedNode), (yylsp[0]));
}
break;
@@ -3165,7 +3066,10 @@ yyreduce:
case 89:
{
- (yyval.interm.intermNode) = (yyvsp[-1].interm).intermDeclaration;
+ TIntermAggregate *aggNode = (yyvsp[-1].interm).intermAggregate;
+ if (aggNode && aggNode->getOp() == EOpNull)
+ aggNode->setOp(EOpDeclaration);
+ (yyval.interm.intermNode) = aggNode;
}
break;
@@ -3177,7 +3081,7 @@ yyreduce:
context->error((yylsp[-3]), "precision is not supported in fragment shader", "highp");
}
if (!context->symbolTable.setDefaultPrecision( (yyvsp[-1].interm.type), (yyvsp[-2].interm.precision) )) {
- context->error((yylsp[-3]), "illegal type argument for default precision qualifier", getBasicString((yyvsp[-1].interm.type).getBasicType()));
+ context->error((yylsp[-3]), "illegal type argument for default precision qualifier", getBasicString((yyvsp[-1].interm.type).type));
}
(yyval.interm.intermNode) = 0;
}
@@ -3187,8 +3091,8 @@ yyreduce:
case 91:
{
- ES3_OR_NEWER((yyvsp[-3].lex).string->c_str(), (yylsp[-4]), "interface blocks");
- (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-4].interm.typeQualifierBuilder), (yylsp[-3]), *(yyvsp[-3].lex).string, (yyvsp[-2].interm.fieldList), NULL, (yyloc), NULL, (yyloc));
+ ES3_OR_NEWER(getQualifierString((yyvsp[-4].interm.type).qualifier), (yylsp[-4]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[-4].interm.type), (yylsp[-3]), *(yyvsp[-3].lex).string, (yyvsp[-2].interm.fieldList), NULL, (yyloc), NULL, (yyloc));
}
break;
@@ -3196,8 +3100,8 @@ yyreduce:
case 92:
{
- ES3_OR_NEWER((yyvsp[-4].lex).string->c_str(), (yylsp[-5]), "interface blocks");
- (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-5].interm.typeQualifierBuilder), (yylsp[-4]), *(yyvsp[-4].lex).string, (yyvsp[-3].interm.fieldList), (yyvsp[-1].lex).string, (yylsp[-1]), NULL, (yyloc));
+ ES3_OR_NEWER(getQualifierString((yyvsp[-5].interm.type).qualifier), (yylsp[-5]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[-5].interm.type), (yylsp[-4]), *(yyvsp[-4].lex).string, (yyvsp[-3].interm.fieldList), (yyvsp[-1].lex).string, (yylsp[-1]), NULL, (yyloc));
}
break;
@@ -3205,8 +3109,8 @@ yyreduce:
case 93:
{
- ES3_OR_NEWER((yyvsp[-7].lex).string->c_str(), (yylsp[-8]), "interface blocks");
- (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-8].interm.typeQualifierBuilder), (yylsp[-7]), *(yyvsp[-7].lex).string, (yyvsp[-6].interm.fieldList), (yyvsp[-4].lex).string, (yylsp[-4]), (yyvsp[-2].interm.intermTypedNode), (yylsp[-3]));
+ ES3_OR_NEWER(getQualifierString((yyvsp[-8].interm.type).qualifier), (yylsp[-8]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[-8].interm.type), (yylsp[-7]), *(yyvsp[-7].lex).string, (yyvsp[-6].interm.fieldList), (yyvsp[-4].lex).string, (yylsp[-4]), (yyvsp[-2].interm.intermTypedNode), (yylsp[-3]));
}
break;
@@ -3214,7 +3118,7 @@ yyreduce:
case 94:
{
- context->parseGlobalLayoutQualifier(*(yyvsp[-1].interm.typeQualifierBuilder));
+ context->parseGlobalLayoutQualifier((yyvsp[-1].interm.type));
(yyval.interm.intermNode) = 0;
}
@@ -3223,7 +3127,7 @@ yyreduce:
case 95:
{
- (yyval.interm.intermNode) = context->parseInvariantDeclaration(*(yyvsp[-2].interm.typeQualifierBuilder), (yylsp[-1]), (yyvsp[-1].lex).string, (yyvsp[-1].lex).symbol);
+ (yyval.interm).function = context->parseFunctionDeclarator((yylsp[0]), (yyvsp[-1].interm.function));
}
break;
@@ -3231,8 +3135,7 @@ yyreduce:
case 96:
{
- (yyval.interm).function = context->parseFunctionDeclarator((yylsp[0]), (yyvsp[-1].interm.function));
- context->exitFunctionDeclaration();
+ (yyval.interm.function) = (yyvsp[0].interm.function);
}
break;
@@ -3248,14 +3151,6 @@ yyreduce:
case 98:
{
- (yyval.interm.function) = (yyvsp[0].interm.function);
- }
-
- break;
-
- case 99:
-
- {
// Add the parameter
(yyval.interm.function) = (yyvsp[-1].interm.function);
if ((yyvsp[0].interm).param.type->getBasicType() != EbtVoid)
@@ -3266,7 +3161,7 @@ yyreduce:
break;
- case 100:
+ case 99:
{
//
@@ -3288,21 +3183,20 @@ yyreduce:
break;
- case 101:
+ case 100:
{
(yyval.interm.function) = context->parseFunctionHeader((yyvsp[-2].interm.type), (yyvsp[-1].lex).string, (yylsp[-1]));
context->symbolTable.push();
- context->enterFunctionDeclaration();
}
break;
- case 102:
+ case 101:
{
- if ((yyvsp[-1].interm.type).getBasicType() == EbtVoid) {
+ if ((yyvsp[-1].interm.type).type == EbtVoid) {
context->error((yylsp[0]), "illegal use of type 'void'", (yyvsp[0].lex).string->c_str());
}
context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string);
@@ -3312,7 +3206,7 @@ yyreduce:
break;
- case 103:
+ case 102:
{
// Check that we can make an array out of this type
@@ -3331,11 +3225,21 @@ yyreduce:
break;
+ case 103:
+
+ {
+ (yyval.interm) = (yyvsp[0].interm);
+ context->checkIsParameterQualifierValid((yylsp[0]), (yyvsp[-2].interm.qualifier), (yyvsp[-1].interm.qualifier), (yyval.interm).param.type);
+ }
+
+ break;
+
case 104:
{
(yyval.interm) = (yyvsp[0].interm);
- context->checkIsParameterQualifierValid((yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm).param.type);
+ context->checkOutParameterIsNotSampler((yylsp[0]), (yyvsp[-1].interm.qualifier), *(yyvsp[0].interm).param.type);
+ context->checkIsParameterQualifierValid((yylsp[0]), EvqTemporary, (yyvsp[-1].interm.qualifier), (yyval.interm).param.type);
}
break;
@@ -3344,7 +3248,7 @@ yyreduce:
{
(yyval.interm) = (yyvsp[0].interm);
- (yyval.interm).param.type->setQualifier(EvqIn);
+ context->checkIsParameterQualifierValid((yylsp[0]), (yyvsp[-2].interm.qualifier), (yyvsp[-1].interm.qualifier), (yyval.interm).param.type);
}
break;
@@ -3353,7 +3257,8 @@ yyreduce:
{
(yyval.interm) = (yyvsp[0].interm);
- context->checkIsParameterQualifierValid((yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm).param.type);
+ context->checkOutParameterIsNotSampler((yylsp[0]), (yyvsp[-1].interm.qualifier), *(yyvsp[0].interm).param.type);
+ context->checkIsParameterQualifierValid((yylsp[0]), EvqTemporary, (yyvsp[-1].interm.qualifier), (yyval.interm).param.type);
}
break;
@@ -3361,8 +3266,7 @@ yyreduce:
case 107:
{
- (yyval.interm) = (yyvsp[0].interm);
- (yyval.interm).param.type->setQualifier(EvqIn);
+ (yyval.interm.qualifier) = EvqIn;
}
break;
@@ -3370,8 +3274,7 @@ yyreduce:
case 108:
{
- TParameter param = { 0, new TType((yyvsp[0].interm.type)) };
- (yyval.interm).param = param;
+ (yyval.interm.qualifier) = EvqIn;
}
break;
@@ -3379,7 +3282,7 @@ yyreduce:
case 109:
{
- (yyval.interm) = (yyvsp[0].interm);
+ (yyval.interm.qualifier) = EvqOut;
}
break;
@@ -3387,8 +3290,7 @@ yyreduce:
case 110:
{
- (yyval.interm) = (yyvsp[-2].interm);
- context->parseDeclarator((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string, (yyval.interm).intermDeclaration);
+ (yyval.interm.qualifier) = EvqInOut;
}
break;
@@ -3396,8 +3298,8 @@ yyreduce:
case 111:
{
- (yyval.interm) = (yyvsp[-5].interm);
- context->parseArrayDeclarator((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ TParameter param = { 0, new TType((yyvsp[0].interm.type)) };
+ (yyval.interm).param = param;
}
break;
@@ -3405,9 +3307,7 @@ yyreduce:
case 112:
{
- ES3_OR_NEWER("[]", (yylsp[-4]), "implicitly sized array");
- (yyval.interm) = (yyvsp[-6].interm);
- context->parseArrayInitDeclarator((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ (yyval.interm) = (yyvsp[0].interm);
}
break;
@@ -3415,9 +3315,8 @@ yyreduce:
case 113:
{
- ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
- (yyval.interm) = (yyvsp[-7].interm);
- context->parseArrayInitDeclarator((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ (yyval.interm) = (yyvsp[-2].interm);
+ (yyval.interm).intermAggregate = context->parseDeclarator((yyval.interm).type, (yyvsp[-2].interm).intermAggregate, (yylsp[0]), *(yyvsp[0].lex).string);
}
break;
@@ -3425,8 +3324,8 @@ yyreduce:
case 114:
{
- (yyval.interm) = (yyvsp[-4].interm);
- context->parseInitDeclarator((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ (yyval.interm) = (yyvsp[-5].interm);
+ (yyval.interm).intermAggregate = context->parseArrayDeclarator((yyval.interm).type, (yyvsp[-5].interm).intermAggregate, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
}
break;
@@ -3434,8 +3333,9 @@ yyreduce:
case 115:
{
- (yyval.interm).type = (yyvsp[0].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), "");
+ ES3_OR_NEWER("[]", (yylsp[-4]), "implicitly sized array");
+ (yyval.interm) = (yyvsp[-6].interm);
+ (yyval.interm).intermAggregate = context->parseArrayInitDeclarator((yyval.interm).type, (yyvsp[-6].interm).intermAggregate, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3443,8 +3343,9 @@ yyreduce:
case 116:
{
- (yyval.interm).type = (yyvsp[-1].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string);
+ ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
+ (yyval.interm) = (yyvsp[-7].interm);
+ (yyval.interm).intermAggregate = context->parseArrayInitDeclarator((yyval.interm).type, (yyvsp[-7].interm).intermAggregate, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3452,8 +3353,8 @@ yyreduce:
case 117:
{
- (yyval.interm).type = (yyvsp[-4].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+ (yyval.interm) = (yyvsp[-4].interm);
+ (yyval.interm).intermAggregate = context->parseInitDeclarator((yyval.interm).type, (yyvsp[-4].interm).intermAggregate, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3461,9 +3362,8 @@ yyreduce:
case 118:
{
- ES3_OR_NEWER("[]", (yylsp[-3]), "implicitly sized array");
- (yyval.interm).type = (yyvsp[-5].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).type = (yyvsp[0].interm.type);
+ (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), "");
}
break;
@@ -3471,9 +3371,8 @@ yyreduce:
case 119:
{
- ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
- (yyval.interm).type = (yyvsp[-6].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).type = (yyvsp[-1].interm.type);
+ (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string);
}
break;
@@ -3481,8 +3380,8 @@ yyreduce:
case 120:
{
- (yyval.interm).type = (yyvsp[-3].interm.type);
- (yyval.interm).intermDeclaration = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ (yyval.interm).type = (yyvsp[-4].interm.type);
+ (yyval.interm).intermAggregate = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
}
break;
@@ -3490,8 +3389,9 @@ yyreduce:
case 121:
{
- context->addFullySpecifiedType(&(yyvsp[0].interm.type));
- (yyval.interm.type) = (yyvsp[0].interm.type);
+ ES3_OR_NEWER("[]", (yylsp[-3]), "implicitly sized array");
+ (yyval.interm).type = (yyvsp[-5].interm.type);
+ (yyval.interm).intermAggregate = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3499,7 +3399,9 @@ yyreduce:
case 122:
{
- (yyval.interm.type) = context->addFullySpecifiedType(*(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.type));
+ ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
+ (yyval.interm).type = (yyvsp[-6].interm.type);
+ (yyval.interm).intermAggregate = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3507,7 +3409,8 @@ yyreduce:
case 123:
{
- (yyval.interm.qualifier) = EvqSmooth;
+ (yyval.interm).type = (yyvsp[-3].interm.type);
+ (yyval.interm).intermAggregate = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
}
break;
@@ -3515,7 +3418,8 @@ yyreduce:
case 124:
{
- (yyval.interm.qualifier) = EvqFlat;
+ // $$.type is not used in invariant declarations.
+ (yyval.interm).intermAggregate = context->parseInvariantDeclaration((yylsp[-1]), (yylsp[0]), (yyvsp[0].lex).string, (yyvsp[0].lex).symbol);
}
break;
@@ -3523,8 +3427,14 @@ yyreduce:
case 125:
{
- (yyval.interm.typeQualifierBuilder) = context->createTypeQualifierBuilder((yylsp[0]));
- (yyval.interm.typeQualifierBuilder)->appendQualifier((yyvsp[0].interm.qualifierWrapper));
+ (yyval.interm.type) = (yyvsp[0].interm.type);
+
+ if ((yyvsp[0].interm.type).array) {
+ ES3_OR_NEWER("[]", (yylsp[0]), "first-class-array");
+ if (context->getShaderVersion() != 300) {
+ (yyvsp[0].interm.type).clearArrayness();
+ }
+ }
}
break;
@@ -3532,8 +3442,7 @@ yyreduce:
case 126:
{
- (yyval.interm.typeQualifierBuilder) = (yyvsp[-1].interm.typeQualifierBuilder);
- (yyval.interm.typeQualifierBuilder)->appendQualifier((yyvsp[0].interm.qualifierWrapper));
+ (yyval.interm.type) = context->addFullySpecifiedType((yyvsp[-1].interm.type).qualifier, (yyvsp[-1].interm.type).invariant, (yyvsp[-1].interm.type).layoutQualifier, (yyvsp[0].interm.type));
}
break;
@@ -3541,7 +3450,7 @@ yyreduce:
case 127:
{
- // empty
+ (yyval.interm.type).qualifier = EvqSmooth;
}
break;
@@ -3549,8 +3458,7 @@ yyreduce:
case 128:
{
- context->checkLocalVariableConstStorageQualifier(*(yyvsp[0].interm.qualifierWrapper));
- (yyval.interm.qualifierWrapper) = (yyvsp[0].interm.qualifierWrapper);
+ (yyval.interm.type).qualifier = EvqFlat;
}
break;
@@ -3558,8 +3466,7 @@ yyreduce:
case 129:
{
- context->checkIsAtGlobalLevel((yylsp[0]), "layout");
- (yyval.interm.qualifierWrapper) = new TLayoutQualifierWrapper((yyvsp[0].interm.layoutQualifier), (yylsp[0]));
+ (yyval.interm.qualifier) = EvqConst;
}
break;
@@ -3567,7 +3474,10 @@ yyreduce:
case 130:
{
- (yyval.interm.qualifierWrapper) = new TPrecisionQualifierWrapper((yyvsp[0].interm.precision), (yylsp[0]));
+ VERTEX_ONLY("attribute", (yylsp[0]));
+ ES2_ONLY("attribute", (yylsp[0]));
+ context->checkIsAtGlobalLevel((yylsp[0]), "attribute");
+ (yyval.interm.type).setBasic(EbtVoid, EvqAttribute, (yylsp[0]));
}
break;
@@ -3575,7 +3485,12 @@ yyreduce:
case 131:
{
- (yyval.interm.qualifierWrapper) = new TInterpolationQualifierWrapper((yyvsp[0].interm.qualifier), (yylsp[0]));
+ ES2_ONLY("varying", (yylsp[0]));
+ context->checkIsAtGlobalLevel((yylsp[0]), "varying");
+ if (context->getShaderType() == GL_VERTEX_SHADER)
+ (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[0]));
+ else
+ (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[0]));
}
break;
@@ -3583,8 +3498,13 @@ yyreduce:
case 132:
{
- context->checkIsAtGlobalLevel((yylsp[0]), "invariant");
- (yyval.interm.qualifierWrapper) = new TInvariantQualifierWrapper((yylsp[0]));
+ ES2_ONLY("varying", (yylsp[-1]));
+ context->checkIsAtGlobalLevel((yylsp[-1]), "invariant varying");
+ if (context->getShaderType() == GL_VERTEX_SHADER)
+ (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[-1]));
+ else
+ (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[-1]));
+ (yyval.interm.type).invariant = true;
}
break;
@@ -3592,10 +3512,11 @@ yyreduce:
case 133:
{
- VERTEX_ONLY("attribute", (yylsp[0]));
- ES2_ONLY("attribute", (yylsp[0]));
- context->checkIsAtGlobalLevel((yylsp[0]), "attribute");
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqAttribute, (yylsp[0]));
+ if ((yyvsp[0].interm.type).qualifier != EvqConst && !context->symbolTable.atGlobalLevel())
+ {
+ context->error((yylsp[0]), "Local variables can only use the const storage qualifier.", getQualifierString((yyvsp[0].interm.type).qualifier));
+ }
+ (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0]));
}
break;
@@ -3603,12 +3524,7 @@ yyreduce:
case 134:
{
- ES2_ONLY("varying", (yylsp[0]));
- context->checkIsAtGlobalLevel((yylsp[0]), "varying");
- if (context->getShaderType() == GL_VERTEX_SHADER)
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqVaryingOut, (yylsp[0]));
- else
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqVaryingIn, (yylsp[0]));
+ (yyval.interm.type) = context->joinInterpolationQualifiers((yylsp[-1]), (yyvsp[-1].interm.type).qualifier, (yylsp[0]), (yyvsp[0].interm.type).qualifier);
}
break;
@@ -3616,7 +3532,10 @@ yyreduce:
case 135:
{
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqConst, (yylsp[0]));
+ context->error((yylsp[0]), "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString((yyvsp[0].interm.type).qualifier));
+
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtVoid, qual, (yylsp[0]));
}
break;
@@ -3624,24 +3543,8 @@ yyreduce:
case 136:
{
- if (context->declaringFunction())
- {
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqIn, (yylsp[0]));
- }
- else if (context->getShaderType() == GL_FRAGMENT_SHADER)
- {
- ES3_OR_NEWER("in", (yylsp[0]), "storage qualifier");
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqFragmentIn, (yylsp[0]));
- }
- else if (context->getShaderType() == GL_VERTEX_SHADER)
- {
- ES3_OR_NEWER("in", (yylsp[0]), "storage qualifier");
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqVertexIn, (yylsp[0]));
- }
- else
- {
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqComputeIn, (yylsp[0]));
- }
+ (yyval.interm.type).qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).layoutQualifier = (yyvsp[0].interm.layoutQualifier);
}
break;
@@ -3649,23 +3552,8 @@ yyreduce:
case 137:
{
- if (context->declaringFunction())
- {
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqOut, (yylsp[0]));
- }
- else
- {
- ES3_OR_NEWER("out", (yylsp[0]), "storage qualifier");
- NON_COMPUTE_ONLY("out", (yylsp[0]));
- if (context->getShaderType() == GL_FRAGMENT_SHADER)
- {
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqFragmentOut, (yylsp[0]));
- }
- else
- {
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqVertexOut, (yylsp[0]));
- }
- }
+ (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0]));
+ (yyval.interm.type).layoutQualifier = (yyvsp[-1].interm.layoutQualifier);
}
break;
@@ -3673,11 +3561,9 @@ yyreduce:
case 138:
{
- if (!context->declaringFunction())
- {
- context->error((yylsp[0]), "invalid inout qualifier", "'inout' can be only used with function parameters");
- }
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqInOut, (yylsp[0]));
+ context->checkInvariantIsOutVariableES3((yyvsp[0].interm.type).qualifier, (yylsp[-1]));
+ (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0]));
+ (yyval.interm.type).invariant = true;
}
break;
@@ -3685,8 +3571,9 @@ yyreduce:
case 139:
{
- ES3_OR_NEWER("centroid", (yylsp[0]), "storage qualifier");
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqCentroid, (yylsp[0]));
+ context->checkInvariantIsOutVariableES3((yyvsp[0].interm.type).qualifier, (yylsp[-2]));
+ (yyval.interm.type) = context->joinInterpolationQualifiers((yylsp[-1]), (yyvsp[-1].interm.type).qualifier, (yylsp[0]), (yyvsp[0].interm.type).qualifier);
+ (yyval.interm.type).invariant = true;
}
break;
@@ -3694,8 +3581,7 @@ yyreduce:
case 140:
{
- context->checkIsAtGlobalLevel((yylsp[0]), "uniform");
- (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqUniform, (yylsp[0]));
+ (yyval.interm.type).qualifier = EvqConst;
}
break;
@@ -3703,7 +3589,20 @@ yyreduce:
case 141:
{
- (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqReadOnly, (yylsp[0]));
+ if (context->getShaderType() == GL_FRAGMENT_SHADER)
+ {
+ ES3_OR_NEWER("in", (yylsp[0]), "storage qualifier");
+ (yyval.interm.type).qualifier = EvqFragmentIn;
+ }
+ else if (context->getShaderType() == GL_VERTEX_SHADER)
+ {
+ ES3_OR_NEWER("in", (yylsp[0]), "storage qualifier");
+ (yyval.interm.type).qualifier = EvqVertexIn;
+ }
+ else
+ {
+ (yyval.interm.type).qualifier = EvqComputeIn;
+ }
}
break;
@@ -3711,7 +3610,9 @@ yyreduce:
case 142:
{
- (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqWriteOnly, (yylsp[0]));
+ ES3_OR_NEWER("out", (yylsp[0]), "storage qualifier");
+ NON_COMPUTE_ONLY("out", (yylsp[0]));
+ (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
}
break;
@@ -3719,7 +3620,9 @@ yyreduce:
case 143:
{
- (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqCoherent, (yylsp[0]));
+ ES3_OR_NEWER("centroid in", (yylsp[-1]), "storage qualifier");
+ FRAG_ONLY("centroid in", (yylsp[-1]));
+ (yyval.interm.type).qualifier = EvqCentroidIn;
}
break;
@@ -3727,7 +3630,9 @@ yyreduce:
case 144:
{
- (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqRestrict, (yylsp[0]));
+ ES3_OR_NEWER("centroid out", (yylsp[-1]), "storage qualifier");
+ VERTEX_ONLY("centroid out", (yylsp[-1]));
+ (yyval.interm.type).qualifier = EvqCentroidOut;
}
break;
@@ -3735,7 +3640,8 @@ yyreduce:
case 145:
{
- (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqVolatile, (yylsp[0]));
+ context->checkIsAtGlobalLevel((yylsp[0]), "uniform");
+ (yyval.interm.type).qualifier = EvqUniform;
}
break;
@@ -3744,7 +3650,11 @@ yyreduce:
{
(yyval.interm.type) = (yyvsp[0].interm.type);
- (yyval.interm.type).precision = context->symbolTable.getDefaultPrecision((yyvsp[0].interm.type).getBasicType());
+
+ if ((yyval.interm.type).precision == EbpUndefined) {
+ (yyval.interm.type).precision = context->symbolTable.getDefaultPrecision((yyvsp[0].interm.type).type);
+ context->checkPrecisionSpecified((yylsp[0]), (yyval.interm.type).precision, (yyvsp[0].interm.type).type);
+ }
}
break;
@@ -3752,7 +3662,12 @@ yyreduce:
case 147:
{
- (yyval.interm.precision) = EbpHigh;
+ (yyval.interm.type) = (yyvsp[0].interm.type);
+ (yyval.interm.type).precision = (yyvsp[-1].interm.precision);
+
+ if (!SupportsPrecision((yyvsp[0].interm.type).type)) {
+ context->error((yylsp[-1]), "illegal type for precision qualifier", getBasicString((yyvsp[0].interm.type).type));
+ }
}
break;
@@ -3760,7 +3675,7 @@ yyreduce:
case 148:
{
- (yyval.interm.precision) = EbpMedium;
+ (yyval.interm.precision) = EbpHigh;
}
break;
@@ -3768,7 +3683,7 @@ yyreduce:
case 149:
{
- (yyval.interm.precision) = EbpLow;
+ (yyval.interm.precision) = EbpMedium;
}
break;
@@ -3776,8 +3691,7 @@ yyreduce:
case 150:
{
- ES3_OR_NEWER("layout", (yylsp[-3]), "qualifier");
- (yyval.interm.layoutQualifier) = (yyvsp[-1].interm.layoutQualifier);
+ (yyval.interm.precision) = EbpLow;
}
break;
@@ -3785,7 +3699,8 @@ yyreduce:
case 151:
{
- (yyval.interm.layoutQualifier) = (yyvsp[0].interm.layoutQualifier);
+ ES3_OR_NEWER("layout", (yylsp[-3]), "qualifier");
+ (yyval.interm.layoutQualifier) = (yyvsp[-1].interm.layoutQualifier);
}
break;
@@ -3793,7 +3708,7 @@ yyreduce:
case 152:
{
- (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers((yyvsp[-2].interm.layoutQualifier), (yyvsp[0].interm.layoutQualifier), (yylsp[0]));
+ (yyval.interm.layoutQualifier) = (yyvsp[0].interm.layoutQualifier);
}
break;
@@ -3801,7 +3716,7 @@ yyreduce:
case 153:
{
- (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[0].lex).string, (yylsp[0]));
+ (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers((yyvsp[-2].interm.layoutQualifier), (yyvsp[0].interm.layoutQualifier), (yylsp[0]));
}
break;
@@ -3809,7 +3724,7 @@ yyreduce:
case 154:
{
- (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[0].lex).string, (yylsp[0]));
}
break;
@@ -3825,7 +3740,7 @@ yyreduce:
case 156:
{
- (yyval.interm.type).initialize((yyvsp[0].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
}
break;
@@ -3833,9 +3748,7 @@ yyreduce:
case 157:
{
- ES3_OR_NEWER("[]", (yylsp[-1]), "implicitly sized array");
- (yyval.interm.type).initialize((yyvsp[-2].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
- (yyval.interm.type).setArraySize(0);
+ (yyval.interm.type) = (yyvsp[0].interm.type);
}
break;
@@ -3843,12 +3756,9 @@ yyreduce:
case 158:
{
- (yyval.interm.type).initialize((yyvsp[-3].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
- if (context->checkIsValidTypeForArray((yylsp[-2]), (yyval.interm.type)))
- {
- unsigned int size = context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
- (yyval.interm.type).setArraySize(size);
- }
+ ES3_OR_NEWER("[]", (yylsp[-1]), "implicitly sized array");
+ (yyval.interm.type) = (yyvsp[-2].interm.type);
+ (yyval.interm.type).setArraySize(0);
}
break;
@@ -3856,7 +3766,13 @@ yyreduce:
case 159:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtVoid, (yylsp[0]));
+ (yyval.interm.type) = (yyvsp[-3].interm.type);
+
+ if (context->checkIsValidTypeForArray((yylsp[-2]), (yyvsp[-3].interm.type)))
+ {
+ unsigned int size = context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+ (yyval.interm.type).setArraySize(size);
+ }
}
break;
@@ -3864,7 +3780,8 @@ yyreduce:
case 160:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtVoid, qual, (yylsp[0]));
}
break;
@@ -3872,7 +3789,8 @@ yyreduce:
case 161:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
}
break;
@@ -3880,7 +3798,8 @@ yyreduce:
case 162:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[0]));
}
break;
@@ -3888,7 +3807,8 @@ yyreduce:
case 163:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[0]));
}
break;
@@ -3896,8 +3816,8 @@ yyreduce:
case 164:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[0]));
}
break;
@@ -3905,8 +3825,9 @@ yyreduce:
case 165:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(2);
}
break;
@@ -3914,8 +3835,9 @@ yyreduce:
case 166:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(3);
}
break;
@@ -3923,8 +3845,9 @@ yyreduce:
case 167:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(4);
}
break;
@@ -3932,8 +3855,9 @@ yyreduce:
case 168:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(2);
}
break;
@@ -3941,8 +3865,9 @@ yyreduce:
case 169:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(3);
}
break;
@@ -3950,8 +3875,9 @@ yyreduce:
case 170:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(4);
}
break;
@@ -3959,8 +3885,9 @@ yyreduce:
case 171:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(2);
}
break;
@@ -3968,8 +3895,9 @@ yyreduce:
case 172:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(3);
}
break;
@@ -3977,8 +3905,9 @@ yyreduce:
case 173:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(4);
}
break;
@@ -3986,8 +3915,9 @@ yyreduce:
case 174:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(2);
}
break;
@@ -3995,8 +3925,9 @@ yyreduce:
case 175:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(3);
}
break;
@@ -4004,8 +3935,9 @@ yyreduce:
case 176:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setMatrix(2, 2);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[0]));
+ (yyval.interm.type).setAggregate(4);
}
break;
@@ -4013,8 +3945,9 @@ yyreduce:
case 177:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setMatrix(3, 3);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setMatrix(2, 2);
}
break;
@@ -4022,8 +3955,9 @@ yyreduce:
case 178:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setMatrix(4, 4);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setMatrix(3, 3);
}
break;
@@ -4031,8 +3965,9 @@ yyreduce:
case 179:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setMatrix(2, 3);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setMatrix(4, 4);
}
break;
@@ -4040,8 +3975,9 @@ yyreduce:
case 180:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setMatrix(3, 2);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setMatrix(2, 3);
}
break;
@@ -4049,8 +3985,9 @@ yyreduce:
case 181:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setMatrix(2, 4);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setMatrix(3, 2);
}
break;
@@ -4058,8 +3995,9 @@ yyreduce:
case 182:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setMatrix(4, 2);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setMatrix(2, 4);
}
break;
@@ -4067,8 +4005,9 @@ yyreduce:
case 183:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setMatrix(3, 4);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setMatrix(4, 2);
}
break;
@@ -4076,8 +4015,9 @@ yyreduce:
case 184:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).setMatrix(4, 3);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setMatrix(3, 4);
}
break;
@@ -4085,7 +4025,9 @@ yyreduce:
case 185:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2D, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0]));
+ (yyval.interm.type).setMatrix(4, 3);
}
break;
@@ -4093,7 +4035,8 @@ yyreduce:
case 186:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler3D, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSampler2D, qual, (yylsp[0]));
}
break;
@@ -4101,7 +4044,8 @@ yyreduce:
case 187:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCube, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSampler3D, qual, (yylsp[0]));
}
break;
@@ -4109,7 +4053,8 @@ yyreduce:
case 188:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArray, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSamplerCube, qual, (yylsp[0]));
}
break;
@@ -4117,7 +4062,8 @@ yyreduce:
case 189:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2D, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSampler2DArray, qual, (yylsp[0]));
}
break;
@@ -4125,7 +4071,8 @@ yyreduce:
case 190:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler3D, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtISampler2D, qual, (yylsp[0]));
}
break;
@@ -4133,7 +4080,8 @@ yyreduce:
case 191:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCube, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtISampler3D, qual, (yylsp[0]));
}
break;
@@ -4141,7 +4089,8 @@ yyreduce:
case 192:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DArray, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtISamplerCube, qual, (yylsp[0]));
}
break;
@@ -4149,7 +4098,8 @@ yyreduce:
case 193:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2D, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtISampler2DArray, qual, (yylsp[0]));
}
break;
@@ -4157,7 +4107,8 @@ yyreduce:
case 194:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler3D, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtUSampler2D, qual, (yylsp[0]));
}
break;
@@ -4165,7 +4116,8 @@ yyreduce:
case 195:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCube, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtUSampler3D, qual, (yylsp[0]));
}
break;
@@ -4173,7 +4125,8 @@ yyreduce:
case 196:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DArray, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtUSamplerCube, qual, (yylsp[0]));
}
break;
@@ -4181,7 +4134,8 @@ yyreduce:
case 197:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DShadow, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtUSampler2DArray, qual, (yylsp[0]));
}
break;
@@ -4189,7 +4143,8 @@ yyreduce:
case 198:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeShadow, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSampler2DShadow, qual, (yylsp[0]));
}
break;
@@ -4197,7 +4152,8 @@ yyreduce:
case 199:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArrayShadow, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSamplerCubeShadow, qual, (yylsp[0]));
}
break;
@@ -4205,11 +4161,8 @@ yyreduce:
case 200:
{
- if (!context->supportsExtension("GL_OES_EGL_image_external") &&
- !context->supportsExtension("GL_NV_EGL_stream_consumer_external")) {
- context->error((yylsp[0]), "unsupported type", "samplerExternalOES");
- }
- (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternalOES, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSampler2DArrayShadow, qual, (yylsp[0]));
}
break;
@@ -4217,10 +4170,12 @@ yyreduce:
case 201:
{
- if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
- context->error((yylsp[0]), "unsupported type", "sampler2DRect");
+ if (!context->supportsExtension("GL_OES_EGL_image_external") &&
+ !context->supportsExtension("GL_NV_EGL_stream_consumer_external")) {
+ context->error((yylsp[0]), "unsupported type", "samplerExternalOES");
}
- (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DRect, (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSamplerExternalOES, qual, (yylsp[0]));
}
break;
@@ -4228,7 +4183,11 @@ yyreduce:
case 202:
{
- (yyval.interm.typeSpecifierNonArray) = (yyvsp[0].interm.typeSpecifierNonArray);
+ if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
+ context->error((yylsp[0]), "unsupported type", "sampler2DRect");
+ }
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSampler2DRect, qual, (yylsp[0]));
}
break;
@@ -4236,7 +4195,8 @@ yyreduce:
case 203:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtImage2D, (yylsp[0]));
+ (yyval.interm.type) = (yyvsp[0].interm.type);
+ (yyval.interm.type).qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
}
break;
@@ -4244,134 +4204,47 @@ yyreduce:
case 204:
{
- (yyval.interm.typeSpecifierNonArray).initialize(EbtIImage2D, (yylsp[0]));
- }
-
- break;
-
- case 205:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUImage2D, (yylsp[0]));
- }
-
- break;
-
- case 206:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtImage3D, (yylsp[0]));
- }
-
- break;
-
- case 207:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtIImage3D, (yylsp[0]));
- }
-
- break;
-
- case 208:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUImage3D, (yylsp[0]));
- }
-
- break;
-
- case 209:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtImage2DArray, (yylsp[0]));
- }
-
- break;
-
- case 210:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtIImage2DArray, (yylsp[0]));
- }
-
- break;
-
- case 211:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUImage2DArray, (yylsp[0]));
- }
-
- break;
-
- case 212:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtImageCube, (yylsp[0]));
- }
-
- break;
-
- case 213:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtIImageCube, (yylsp[0]));
- }
-
- break;
-
- case 214:
-
- {
- (yyval.interm.typeSpecifierNonArray).initialize(EbtUImageCube, (yylsp[0]));
- }
-
- break;
-
- case 215:
-
- {
//
// This is for user defined type names. The lexical phase looked up the
// type.
//
TType& structure = static_cast<TVariable*>((yyvsp[0].lex).symbol)->getType();
- (yyval.interm.typeSpecifierNonArray).initialize(EbtStruct, (yylsp[0]));
- (yyval.interm.typeSpecifierNonArray).userDef = &structure;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtStruct, qual, (yylsp[0]));
+ (yyval.interm.type).userDef = &structure;
}
break;
- case 216:
+ case 205:
{ context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string); }
break;
- case 217:
+ case 206:
{
- (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-5]), (yylsp[-4]), (yyvsp[-4].lex).string, (yyvsp[-1].interm.fieldList));
+ (yyval.interm.type) = context->addStructure((yylsp[-5]), (yylsp[-4]), (yyvsp[-4].lex).string, (yyvsp[-1].interm.fieldList));
}
break;
- case 218:
+ case 207:
{ context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string); }
break;
- case 219:
+ case 208:
{
- (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-4]), (yyloc), NewPoolTString(""), (yyvsp[-1].interm.fieldList));
+ (yyval.interm.type) = context->addStructure((yylsp[-4]), (yyloc), NewPoolTString(""), (yyvsp[-1].interm.fieldList));
}
break;
- case 220:
+ case 209:
{
(yyval.interm.fieldList) = (yyvsp[0].interm.fieldList);
@@ -4379,7 +4252,7 @@ yyreduce:
break;
- case 221:
+ case 210:
{
(yyval.interm.fieldList) = (yyvsp[-1].interm.fieldList);
@@ -4396,7 +4269,7 @@ yyreduce:
break;
- case 222:
+ case 211:
{
(yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList));
@@ -4404,16 +4277,18 @@ yyreduce:
break;
- case 223:
+ case 212:
{
// ES3 Only, but errors should be handled elsewhere
- (yyval.interm.fieldList) = context->addStructDeclaratorListWithQualifiers(*(yyvsp[-3].interm.typeQualifierBuilder), &(yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList));
+ (yyvsp[-2].interm.type).qualifier = (yyvsp[-3].interm.type).qualifier;
+ (yyvsp[-2].interm.type).layoutQualifier = (yyvsp[-3].interm.type).layoutQualifier;
+ (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList));
}
break;
- case 224:
+ case 213:
{
(yyval.interm.fieldList) = NewPoolTFieldList();
@@ -4422,7 +4297,7 @@ yyreduce:
break;
- case 225:
+ case 214:
{
(yyval.interm.fieldList)->push_back((yyvsp[0].interm.field));
@@ -4430,7 +4305,7 @@ yyreduce:
break;
- case 226:
+ case 215:
{
context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string);
@@ -4441,7 +4316,7 @@ yyreduce:
break;
- case 227:
+ case 216:
{
context->checkIsNotReserved((yylsp[-3]), *(yyvsp[-3].lex).string);
@@ -4455,197 +4330,196 @@ yyreduce:
break;
- case 228:
+ case 217:
{ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); }
break;
- case 229:
+ case 218:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 230:
+ case 219:
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
break;
- case 231:
+ case 220:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 232:
+ case 221:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 233:
+ case 222:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 234:
+ case 223:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 235:
+ case 224:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermSwitch); }
break;
- case 236:
+ case 225:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermCase); }
break;
- case 237:
+ case 226:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 238:
+ case 227:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 239:
+ case 228:
- { (yyval.interm.intermBlock) = 0; }
+ { (yyval.interm.intermAggregate) = 0; }
break;
- case 240:
+ case 229:
{ context->symbolTable.push(); }
break;
- case 241:
+ case 230:
{ context->symbolTable.pop(); }
break;
- case 242:
+ case 231:
{
- if ((yyvsp[-2].interm.intermBlock) != 0) {
- (yyvsp[-2].interm.intermBlock)->setLine((yyloc));
+ if ((yyvsp[-2].interm.intermAggregate) != 0) {
+ (yyvsp[-2].interm.intermAggregate)->setOp(EOpSequence);
+ (yyvsp[-2].interm.intermAggregate)->setLine((yyloc));
}
- (yyval.interm.intermBlock) = (yyvsp[-2].interm.intermBlock);
+ (yyval.interm.intermAggregate) = (yyvsp[-2].interm.intermAggregate);
}
break;
- case 243:
+ case 232:
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
break;
- case 244:
+ case 233:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 245:
+ case 234:
{ context->symbolTable.push(); }
break;
- case 246:
+ case 235:
- { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock); }
+ { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
break;
- case 247:
+ case 236:
{ context->symbolTable.push(); }
break;
- case 248:
+ case 237:
{ context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 249:
+ case 238:
{
- (yyval.interm.intermBlock) = 0;
+ (yyval.interm.intermAggregate) = 0;
}
break;
- case 250:
+ case 239:
{
- if ((yyvsp[-1].interm.intermBlock)) {
- (yyvsp[-1].interm.intermBlock)->setLine((yyloc));
+ if ((yyvsp[-1].interm.intermAggregate)) {
+ (yyvsp[-1].interm.intermAggregate)->setOp(EOpSequence);
+ (yyvsp[-1].interm.intermAggregate)->setLine((yyloc));
}
- (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
+ (yyval.interm.intermAggregate) = (yyvsp[-1].interm.intermAggregate);
}
break;
- case 251:
+ case 240:
{
- (yyval.interm.intermBlock) = new TIntermBlock();
- (yyval.interm.intermBlock)->setLine((yyloc));
- (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+ (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[0].interm.intermNode), (yyloc));
}
break;
- case 252:
+ case 241:
{
- (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
- (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+ (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[-1].interm.intermAggregate), (yyvsp[0].interm.intermNode), (yyloc));
}
break;
- case 253:
+ case 242:
{ (yyval.interm.intermNode) = 0; }
break;
- case 254:
+ case 243:
{ (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[-1].interm.intermTypedNode)); }
break;
- case 255:
+ case 244:
{
context->checkIsScalarBool((yylsp[-4]), (yyvsp[-2].interm.intermTypedNode));
- (yyval.interm.intermNode) = context->intermediate.addIfElse((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yylsp[-4]));
+ (yyval.interm.intermNode) = context->intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yylsp[-4]));
}
break;
- case 256:
+ case 245:
{
(yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
@@ -4654,7 +4528,7 @@ yyreduce:
break;
- case 257:
+ case 246:
{
(yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode);
@@ -4663,22 +4537,22 @@ yyreduce:
break;
- case 258:
+ case 247:
{ context->incrSwitchNestingLevel(); }
break;
- case 259:
+ case 248:
{
- (yyval.interm.intermSwitch) = context->addSwitch((yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermBlock), (yylsp[-5]));
+ (yyval.interm.intermSwitch) = context->addSwitch((yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermAggregate), (yylsp[-5]));
context->decrSwitchNestingLevel();
}
break;
- case 260:
+ case 249:
{
(yyval.interm.intermCase) = context->addCase((yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
@@ -4686,7 +4560,7 @@ yyreduce:
break;
- case 261:
+ case 250:
{
(yyval.interm.intermCase) = context->addDefault((yylsp[-1]));
@@ -4694,7 +4568,7 @@ yyreduce:
break;
- case 262:
+ case 251:
{
(yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
@@ -4703,13 +4577,13 @@ yyreduce:
break;
- case 263:
+ case 252:
{
- TIntermBinary *initNode = nullptr;
+ TIntermNode *intermNode;
context->checkIsScalarBool((yylsp[-2]), (yyvsp[-3].interm.type));
- if (!context->executeInitializer((yylsp[-2]), *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), (yyvsp[0].interm.intermTypedNode), &initNode))
+ if (!context->executeInitializer((yylsp[-2]), *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), (yyvsp[0].interm.intermTypedNode), &intermNode))
(yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
else {
(yyval.interm.intermTypedNode) = 0;
@@ -4718,13 +4592,13 @@ yyreduce:
break;
- case 264:
+ case 253:
{ context->symbolTable.push(); context->incrLoopNestingLevel(); }
break;
- case 265:
+ case 254:
{
context->symbolTable.pop();
@@ -4734,13 +4608,13 @@ yyreduce:
break;
- case 266:
+ case 255:
{ context->incrLoopNestingLevel(); }
break;
- case 267:
+ case 256:
{
context->checkIsScalarBool((yylsp[0]), (yyvsp[-2].interm.intermTypedNode));
@@ -4751,13 +4625,13 @@ yyreduce:
break;
- case 268:
+ case 257:
{ context->symbolTable.push(); context->incrLoopNestingLevel(); }
break;
- case 269:
+ case 258:
{
context->symbolTable.pop();
@@ -4767,7 +4641,7 @@ yyreduce:
break;
- case 270:
+ case 259:
{
(yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
@@ -4775,7 +4649,7 @@ yyreduce:
break;
- case 271:
+ case 260:
{
(yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
@@ -4783,7 +4657,7 @@ yyreduce:
break;
- case 272:
+ case 261:
{
(yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
@@ -4791,7 +4665,7 @@ yyreduce:
break;
- case 273:
+ case 262:
{
(yyval.interm.intermTypedNode) = 0;
@@ -4799,7 +4673,7 @@ yyreduce:
break;
- case 274:
+ case 263:
{
(yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode);
@@ -4808,7 +4682,7 @@ yyreduce:
break;
- case 275:
+ case 264:
{
(yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode);
@@ -4817,7 +4691,7 @@ yyreduce:
break;
- case 276:
+ case 265:
{
(yyval.interm.intermNode) = context->addBranch(EOpContinue, (yylsp[-1]));
@@ -4825,7 +4699,7 @@ yyreduce:
break;
- case 277:
+ case 266:
{
(yyval.interm.intermNode) = context->addBranch(EOpBreak, (yylsp[-1]));
@@ -4833,7 +4707,7 @@ yyreduce:
break;
- case 278:
+ case 267:
{
(yyval.interm.intermNode) = context->addBranch(EOpReturn, (yylsp[-1]));
@@ -4841,7 +4715,7 @@ yyreduce:
break;
- case 279:
+ case 268:
{
(yyval.interm.intermNode) = context->addBranch(EOpReturn, (yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
@@ -4849,7 +4723,7 @@ yyreduce:
break;
- case 280:
+ case 269:
{
FRAG_ONLY("discard", (yylsp[-1]));
@@ -4858,26 +4732,25 @@ yyreduce:
break;
- case 281:
+ case 270:
{
- (yyval.interm.intermBlock) = new TIntermBlock();
- (yyval.interm.intermBlock)->setLine((yyloc));
- (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
- context->setTreeRoot((yyval.interm.intermBlock));
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ context->setTreeRoot((yyval.interm.intermNode));
}
break;
- case 282:
+ case 271:
{
- (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+ (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode), (yyloc));
+ context->setTreeRoot((yyval.interm.intermNode));
}
break;
- case 283:
+ case 272:
{
(yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
@@ -4885,7 +4758,7 @@ yyreduce:
break;
- case 284:
+ case 273:
{
(yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
@@ -4893,18 +4766,18 @@ yyreduce:
break;
- case 285:
+ case 274:
{
- context->parseFunctionDefinitionHeader((yylsp[0]), &((yyvsp[0].interm).function), &(yyvsp[0].interm).intermAggregate);
+ context->parseFunctionPrototype((yylsp[0]), (yyvsp[0].interm).function, &(yyvsp[0].interm).intermAggregate);
}
break;
- case 286:
+ case 275:
{
- (yyval.interm.intermNode) = context->addFunctionDefinition(*((yyvsp[-2].interm).function), (yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermBlock), (yylsp[-2]));
+ (yyval.interm.intermNode) = context->addFunctionDefinition(*((yyvsp[-2].interm).function), (yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermAggregate), (yylsp[-2]));
}
break;
diff --git a/gfx/angle/src/compiler/translator/glslang_tab.h b/gfx/angle/src/compiler/translator/glslang_tab.h
index 8b043c01d..7331594a4 100755
--- a/gfx/angle/src/compiler/translator/glslang_tab.h
+++ b/gfx/angle/src/compiler/translator/glslang_tab.h
@@ -50,151 +50,134 @@ extern int yydebug;
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
-enum yytokentype
-{
- INVARIANT = 258,
- HIGH_PRECISION = 259,
- MEDIUM_PRECISION = 260,
- LOW_PRECISION = 261,
- PRECISION = 262,
- ATTRIBUTE = 263,
- CONST_QUAL = 264,
- BOOL_TYPE = 265,
- FLOAT_TYPE = 266,
- INT_TYPE = 267,
- UINT_TYPE = 268,
- BREAK = 269,
- CONTINUE = 270,
- DO = 271,
- ELSE = 272,
- FOR = 273,
- IF = 274,
- DISCARD = 275,
- RETURN = 276,
- SWITCH = 277,
- CASE = 278,
- DEFAULT = 279,
- BVEC2 = 280,
- BVEC3 = 281,
- BVEC4 = 282,
- IVEC2 = 283,
- IVEC3 = 284,
- IVEC4 = 285,
- VEC2 = 286,
- VEC3 = 287,
- VEC4 = 288,
- UVEC2 = 289,
- UVEC3 = 290,
- UVEC4 = 291,
- MATRIX2 = 292,
- MATRIX3 = 293,
- MATRIX4 = 294,
- IN_QUAL = 295,
- OUT_QUAL = 296,
- INOUT_QUAL = 297,
- UNIFORM = 298,
- VARYING = 299,
- MATRIX2x3 = 300,
- MATRIX3x2 = 301,
- MATRIX2x4 = 302,
- MATRIX4x2 = 303,
- MATRIX3x4 = 304,
- MATRIX4x3 = 305,
- CENTROID = 306,
- FLAT = 307,
- SMOOTH = 308,
- READONLY = 309,
- WRITEONLY = 310,
- COHERENT = 311,
- RESTRICT = 312,
- VOLATILE = 313,
- STRUCT = 314,
- VOID_TYPE = 315,
- WHILE = 316,
- SAMPLER2D = 317,
- SAMPLERCUBE = 318,
- SAMPLER_EXTERNAL_OES = 319,
- SAMPLER2DRECT = 320,
- SAMPLER2DARRAY = 321,
- ISAMPLER2D = 322,
- ISAMPLER3D = 323,
- ISAMPLERCUBE = 324,
- ISAMPLER2DARRAY = 325,
- USAMPLER2D = 326,
- USAMPLER3D = 327,
- USAMPLERCUBE = 328,
- USAMPLER2DARRAY = 329,
- SAMPLER3D = 330,
- SAMPLER3DRECT = 331,
- SAMPLER2DSHADOW = 332,
- SAMPLERCUBESHADOW = 333,
- SAMPLER2DARRAYSHADOW = 334,
- IMAGE2D = 335,
- IIMAGE2D = 336,
- UIMAGE2D = 337,
- IMAGE3D = 338,
- IIMAGE3D = 339,
- UIMAGE3D = 340,
- IMAGE2DARRAY = 341,
- IIMAGE2DARRAY = 342,
- UIMAGE2DARRAY = 343,
- IMAGECUBE = 344,
- IIMAGECUBE = 345,
- UIMAGECUBE = 346,
- LAYOUT = 347,
- IDENTIFIER = 348,
- TYPE_NAME = 349,
- FLOATCONSTANT = 350,
- INTCONSTANT = 351,
- UINTCONSTANT = 352,
- BOOLCONSTANT = 353,
- FIELD_SELECTION = 354,
- LEFT_OP = 355,
- RIGHT_OP = 356,
- INC_OP = 357,
- DEC_OP = 358,
- LE_OP = 359,
- GE_OP = 360,
- EQ_OP = 361,
- NE_OP = 362,
- AND_OP = 363,
- OR_OP = 364,
- XOR_OP = 365,
- MUL_ASSIGN = 366,
- DIV_ASSIGN = 367,
- ADD_ASSIGN = 368,
- MOD_ASSIGN = 369,
- LEFT_ASSIGN = 370,
- RIGHT_ASSIGN = 371,
- AND_ASSIGN = 372,
- XOR_ASSIGN = 373,
- OR_ASSIGN = 374,
- SUB_ASSIGN = 375,
- LEFT_PAREN = 376,
- RIGHT_PAREN = 377,
- LEFT_BRACKET = 378,
- RIGHT_BRACKET = 379,
- LEFT_BRACE = 380,
- RIGHT_BRACE = 381,
- DOT = 382,
- COMMA = 383,
- COLON = 384,
- EQUAL = 385,
- SEMICOLON = 386,
- BANG = 387,
- DASH = 388,
- TILDE = 389,
- PLUS = 390,
- STAR = 391,
- SLASH = 392,
- PERCENT = 393,
- LEFT_ANGLE = 394,
- RIGHT_ANGLE = 395,
- VERTICAL_BAR = 396,
- CARET = 397,
- AMPERSAND = 398,
- QUESTION = 399
-};
+ enum yytokentype
+ {
+ INVARIANT = 258,
+ HIGH_PRECISION = 259,
+ MEDIUM_PRECISION = 260,
+ LOW_PRECISION = 261,
+ PRECISION = 262,
+ ATTRIBUTE = 263,
+ CONST_QUAL = 264,
+ BOOL_TYPE = 265,
+ FLOAT_TYPE = 266,
+ INT_TYPE = 267,
+ UINT_TYPE = 268,
+ BREAK = 269,
+ CONTINUE = 270,
+ DO = 271,
+ ELSE = 272,
+ FOR = 273,
+ IF = 274,
+ DISCARD = 275,
+ RETURN = 276,
+ SWITCH = 277,
+ CASE = 278,
+ DEFAULT = 279,
+ BVEC2 = 280,
+ BVEC3 = 281,
+ BVEC4 = 282,
+ IVEC2 = 283,
+ IVEC3 = 284,
+ IVEC4 = 285,
+ VEC2 = 286,
+ VEC3 = 287,
+ VEC4 = 288,
+ UVEC2 = 289,
+ UVEC3 = 290,
+ UVEC4 = 291,
+ MATRIX2 = 292,
+ MATRIX3 = 293,
+ MATRIX4 = 294,
+ IN_QUAL = 295,
+ OUT_QUAL = 296,
+ INOUT_QUAL = 297,
+ UNIFORM = 298,
+ VARYING = 299,
+ MATRIX2x3 = 300,
+ MATRIX3x2 = 301,
+ MATRIX2x4 = 302,
+ MATRIX4x2 = 303,
+ MATRIX3x4 = 304,
+ MATRIX4x3 = 305,
+ CENTROID = 306,
+ FLAT = 307,
+ SMOOTH = 308,
+ STRUCT = 309,
+ VOID_TYPE = 310,
+ WHILE = 311,
+ SAMPLER2D = 312,
+ SAMPLERCUBE = 313,
+ SAMPLER_EXTERNAL_OES = 314,
+ SAMPLER2DRECT = 315,
+ SAMPLER2DARRAY = 316,
+ ISAMPLER2D = 317,
+ ISAMPLER3D = 318,
+ ISAMPLERCUBE = 319,
+ ISAMPLER2DARRAY = 320,
+ USAMPLER2D = 321,
+ USAMPLER3D = 322,
+ USAMPLERCUBE = 323,
+ USAMPLER2DARRAY = 324,
+ SAMPLER3D = 325,
+ SAMPLER3DRECT = 326,
+ SAMPLER2DSHADOW = 327,
+ SAMPLERCUBESHADOW = 328,
+ SAMPLER2DARRAYSHADOW = 329,
+ LAYOUT = 330,
+ IDENTIFIER = 331,
+ TYPE_NAME = 332,
+ FLOATCONSTANT = 333,
+ INTCONSTANT = 334,
+ UINTCONSTANT = 335,
+ BOOLCONSTANT = 336,
+ FIELD_SELECTION = 337,
+ LEFT_OP = 338,
+ RIGHT_OP = 339,
+ INC_OP = 340,
+ DEC_OP = 341,
+ LE_OP = 342,
+ GE_OP = 343,
+ EQ_OP = 344,
+ NE_OP = 345,
+ AND_OP = 346,
+ OR_OP = 347,
+ XOR_OP = 348,
+ MUL_ASSIGN = 349,
+ DIV_ASSIGN = 350,
+ ADD_ASSIGN = 351,
+ MOD_ASSIGN = 352,
+ LEFT_ASSIGN = 353,
+ RIGHT_ASSIGN = 354,
+ AND_ASSIGN = 355,
+ XOR_ASSIGN = 356,
+ OR_ASSIGN = 357,
+ SUB_ASSIGN = 358,
+ LEFT_PAREN = 359,
+ RIGHT_PAREN = 360,
+ LEFT_BRACKET = 361,
+ RIGHT_BRACKET = 362,
+ LEFT_BRACE = 363,
+ RIGHT_BRACE = 364,
+ DOT = 365,
+ COMMA = 366,
+ COLON = 367,
+ EQUAL = 368,
+ SEMICOLON = 369,
+ BANG = 370,
+ DASH = 371,
+ TILDE = 372,
+ PLUS = 373,
+ STAR = 374,
+ SLASH = 375,
+ PERCENT = 376,
+ LEFT_ANGLE = 377,
+ RIGHT_ANGLE = 378,
+ VERTICAL_BAR = 379,
+ CARET = 380,
+ AMPERSAND = 381,
+ QUESTION = 382
+ };
#endif
/* Value type. */
@@ -217,27 +200,22 @@ union YYSTYPE
struct {
TOperator op;
union {
- TIntermNode *intermNode;
+ TIntermNode* intermNode;
TIntermNodePair nodePair;
- TIntermTyped *intermTypedNode;
- TIntermAggregate *intermAggregate;
- TIntermBlock *intermBlock;
- TIntermDeclaration *intermDeclaration;
- TIntermSwitch *intermSwitch;
- TIntermCase *intermCase;
+ TIntermTyped* intermTypedNode;
+ TIntermAggregate* intermAggregate;
+ TIntermSwitch* intermSwitch;
+ TIntermCase* intermCase;
};
union {
- TTypeSpecifierNonArray typeSpecifierNonArray;
TPublicType type;
TPrecision precision;
TLayoutQualifier layoutQualifier;
TQualifier qualifier;
- TFunction *function;
+ TFunction* function;
TParameter param;
- TField *field;
- TFieldList *fieldList;
- TQualifierWrapperBase *qualifierWrapper;
- TTypeQualifierBuilder *typeQualifierBuilder;
+ TField* field;
+ TFieldList* fieldList;
};
} interm;
diff --git a/gfx/angle/src/compiler/translator/intermOut.cpp b/gfx/angle/src/compiler/translator/intermOut.cpp
index 53ee1d02a..6dca547f0 100755
--- a/gfx/angle/src/compiler/translator/intermOut.cpp
+++ b/gfx/angle/src/compiler/translator/intermOut.cpp
@@ -7,17 +7,13 @@
#include "compiler/translator/Intermediate.h"
#include "compiler/translator/SymbolTable.h"
-namespace sh
-{
-
namespace
{
-void OutputFunction(TInfoSinkBase &out, const char *str, TFunctionSymbolInfo *info)
+void OutputFunction(TInfoSinkBase &out, const char *str, TIntermAggregate *node)
{
- const char *internal = info->getNameObj().isInternal() ? " (internal function)" : "";
- out << str << internal << ": " << info->getNameObj().getString() << " (symbol id "
- << info->getId() << ")";
+ const char *internal = node->getNameObj().isInternal() ? " (internal function)" : "";
+ out << str << internal << ": " << node->getNameObj().getString();
}
//
@@ -46,17 +42,10 @@ class TOutputTraverser : public TIntermTraverser
protected:
void visitSymbol(TIntermSymbol *) override;
void visitConstantUnion(TIntermConstantUnion *) override;
- bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
bool visitBinary(Visit visit, TIntermBinary *) override;
bool visitUnary(Visit visit, TIntermUnary *) override;
- bool visitTernary(Visit visit, TIntermTernary *node) override;
- bool visitIfElse(Visit visit, TIntermIfElse *node) override;
- bool visitSwitch(Visit visit, TIntermSwitch *node) override;
- bool visitCase(Visit visit, TIntermCase *node) override;
- bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitSelection(Visit visit, TIntermSelection *) override;
bool visitAggregate(Visit visit, TIntermAggregate *) override;
- bool visitBlock(Visit visit, TIntermBlock *) override;
- bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
bool visitLoop(Visit visit, TIntermLoop *) override;
bool visitBranch(Visit visit, TIntermBranch *) override;
};
@@ -93,14 +82,6 @@ void TOutputTraverser::visitSymbol(TIntermSymbol *node)
sink << "(" << node->getCompleteString() << ")\n";
}
-bool TOutputTraverser::visitSwizzle(Visit visit, TIntermSwizzle *node)
-{
- TInfoSinkBase &out = sink;
- OutputTreeText(out, node, mDepth);
- out << "vector swizzle";
- return true;
-}
-
bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node)
{
TInfoSinkBase& out = sink;
@@ -109,148 +90,148 @@ bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node)
switch (node->getOp())
{
- case EOpComma:
- out << "comma";
- break;
- case EOpAssign:
- out << "move second child to first child";
- break;
- case EOpInitialize:
- out << "initialize first child with second child";
- break;
- case EOpAddAssign:
- out << "add second child into first child";
- break;
- case EOpSubAssign:
- out << "subtract second child into first child";
- break;
- case EOpMulAssign:
- out << "multiply second child into first child";
- break;
- case EOpVectorTimesMatrixAssign:
- out << "matrix mult second child into first child";
- break;
- case EOpVectorTimesScalarAssign:
- out << "vector scale second child into first child";
- break;
- case EOpMatrixTimesScalarAssign:
- out << "matrix scale second child into first child";
- break;
- case EOpMatrixTimesMatrixAssign:
- out << "matrix mult second child into first child";
- break;
- case EOpDivAssign:
- out << "divide second child into first child";
- break;
- case EOpIModAssign:
- out << "modulo second child into first child";
- break;
- case EOpBitShiftLeftAssign:
- out << "bit-wise shift first child left by second child";
- break;
- case EOpBitShiftRightAssign:
- out << "bit-wise shift first child right by second child";
- break;
- case EOpBitwiseAndAssign:
- out << "bit-wise and second child into first child";
- break;
- case EOpBitwiseXorAssign:
- out << "bit-wise xor second child into first child";
- break;
- case EOpBitwiseOrAssign:
- out << "bit-wise or second child into first child";
- break;
-
- case EOpIndexDirect:
- out << "direct index";
- break;
- case EOpIndexIndirect:
- out << "indirect index";
- break;
- case EOpIndexDirectStruct:
- out << "direct index for structure";
- break;
- case EOpIndexDirectInterfaceBlock:
- out << "direct index for interface block";
- break;
-
- case EOpAdd:
- out << "add";
- break;
- case EOpSub:
- out << "subtract";
- break;
- case EOpMul:
- out << "component-wise multiply";
- break;
- case EOpDiv:
- out << "divide";
- break;
- case EOpIMod:
- out << "modulo";
- break;
- case EOpBitShiftLeft:
- out << "bit-wise shift left";
- break;
- case EOpBitShiftRight:
- out << "bit-wise shift right";
- break;
- case EOpBitwiseAnd:
- out << "bit-wise and";
- break;
- case EOpBitwiseXor:
- out << "bit-wise xor";
- break;
- case EOpBitwiseOr:
- out << "bit-wise or";
- break;
-
- case EOpEqual:
- out << "Compare Equal";
- break;
- case EOpNotEqual:
- out << "Compare Not Equal";
- break;
- case EOpLessThan:
- out << "Compare Less Than";
- break;
- case EOpGreaterThan:
- out << "Compare Greater Than";
- break;
- case EOpLessThanEqual:
- out << "Compare Less Than or Equal";
- break;
- case EOpGreaterThanEqual:
- out << "Compare Greater Than or Equal";
- break;
-
- case EOpVectorTimesScalar:
- out << "vector-scale";
- break;
- case EOpVectorTimesMatrix:
- out << "vector-times-matrix";
- break;
- case EOpMatrixTimesVector:
- out << "matrix-times-vector";
- break;
- case EOpMatrixTimesScalar:
- out << "matrix-scale";
- break;
- case EOpMatrixTimesMatrix:
- out << "matrix-multiply";
- break;
-
- case EOpLogicalOr:
- out << "logical-or";
- break;
- case EOpLogicalXor:
- out << "logical-xor";
- break;
- case EOpLogicalAnd:
- out << "logical-and";
- break;
- default:
- out << "<unknown op>";
+ case EOpAssign:
+ out << "move second child to first child";
+ break;
+ case EOpInitialize:
+ out << "initialize first child with second child";
+ break;
+ case EOpAddAssign:
+ out << "add second child into first child";
+ break;
+ case EOpSubAssign:
+ out << "subtract second child into first child";
+ break;
+ case EOpMulAssign:
+ out << "multiply second child into first child";
+ break;
+ case EOpVectorTimesMatrixAssign:
+ out << "matrix mult second child into first child";
+ break;
+ case EOpVectorTimesScalarAssign:
+ out << "vector scale second child into first child";
+ break;
+ case EOpMatrixTimesScalarAssign:
+ out << "matrix scale second child into first child";
+ break;
+ case EOpMatrixTimesMatrixAssign:
+ out << "matrix mult second child into first child";
+ break;
+ case EOpDivAssign:
+ out << "divide second child into first child";
+ break;
+ case EOpIModAssign:
+ out << "modulo second child into first child";
+ break;
+ case EOpBitShiftLeftAssign:
+ out << "bit-wise shift first child left by second child";
+ break;
+ case EOpBitShiftRightAssign:
+ out << "bit-wise shift first child right by second child";
+ break;
+ case EOpBitwiseAndAssign:
+ out << "bit-wise and second child into first child";
+ break;
+ case EOpBitwiseXorAssign:
+ out << "bit-wise xor second child into first child";
+ break;
+ case EOpBitwiseOrAssign:
+ out << "bit-wise or second child into first child";
+ break;
+
+ case EOpIndexDirect:
+ out << "direct index";
+ break;
+ case EOpIndexIndirect:
+ out << "indirect index";
+ break;
+ case EOpIndexDirectStruct:
+ out << "direct index for structure";
+ break;
+ case EOpIndexDirectInterfaceBlock:
+ out << "direct index for interface block";
+ break;
+ case EOpVectorSwizzle:
+ out << "vector swizzle";
+ break;
+
+ case EOpAdd:
+ out << "add";
+ break;
+ case EOpSub:
+ out << "subtract";
+ break;
+ case EOpMul:
+ out << "component-wise multiply";
+ break;
+ case EOpDiv:
+ out << "divide";
+ break;
+ case EOpIMod:
+ out << "modulo";
+ break;
+ case EOpBitShiftLeft:
+ out << "bit-wise shift left";
+ break;
+ case EOpBitShiftRight:
+ out << "bit-wise shift right";
+ break;
+ case EOpBitwiseAnd:
+ out << "bit-wise and";
+ break;
+ case EOpBitwiseXor:
+ out << "bit-wise xor";
+ break;
+ case EOpBitwiseOr:
+ out << "bit-wise or";
+ break;
+
+ case EOpEqual:
+ out << "Compare Equal";
+ break;
+ case EOpNotEqual:
+ out << "Compare Not Equal";
+ break;
+ case EOpLessThan:
+ out << "Compare Less Than";
+ break;
+ case EOpGreaterThan:
+ out << "Compare Greater Than";
+ break;
+ case EOpLessThanEqual:
+ out << "Compare Less Than or Equal";
+ break;
+ case EOpGreaterThanEqual:
+ out << "Compare Greater Than or Equal";
+ break;
+
+ case EOpVectorTimesScalar:
+ out << "vector-scale";
+ break;
+ case EOpVectorTimesMatrix:
+ out << "vector-times-matrix";
+ break;
+ case EOpMatrixTimesVector:
+ out << "matrix-times-vector";
+ break;
+ case EOpMatrixTimesScalar:
+ out << "matrix-scale";
+ break;
+ case EOpMatrixTimesMatrix:
+ out << "matrix-multiply";
+ break;
+
+ case EOpLogicalOr:
+ out << "logical-or";
+ break;
+ case EOpLogicalXor:
+ out << "logical-xor";
+ break;
+ case EOpLogicalAnd:
+ out << "logical-and";
+ break;
+ default:
+ out << "<unknown op>";
}
out << " (" << node->getCompleteString() << ")";
@@ -381,38 +362,27 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
return true;
}
-bool TOutputTraverser::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
-{
- TInfoSinkBase &out = sink;
- OutputTreeText(out, node, mDepth);
- OutputFunction(out, "Function Definition", node->getFunctionSymbolInfo());
- out << "\n";
- return true;
-}
-
bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
{
TInfoSinkBase &out = sink;
- OutputTreeText(out, node, mDepth);
-
if (node->getOp() == EOpNull)
{
out.prefix(EPrefixError);
- out << "node is still EOpNull!\n";
+ out << "node is still EOpNull!";
return true;
}
+ OutputTreeText(out, node, mDepth);
switch (node->getOp())
{
- case EOpFunctionCall:
- OutputFunction(out, "Function Call", node->getFunctionSymbolInfo());
- break;
+ case EOpSequence: out << "Sequence\n"; return true;
+ case EOpComma: out << "Comma\n"; return true;
+ case EOpFunction: OutputFunction(out, "Function Definition", node); break;
+ case EOpFunctionCall: OutputFunction(out, "Function Call", node); break;
case EOpParameters: out << "Function Parameters: "; break;
- case EOpPrototype:
- OutputFunction(out, "Function Prototype", node->getFunctionSymbolInfo());
- break;
+ case EOpPrototype: OutputFunction(out, "Function Prototype", node); break;
case EOpConstructFloat: out << "Construct float"; break;
case EOpConstructVec2: out << "Construct vec2"; break;
@@ -471,6 +441,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpOuterProduct: out << "outer product"; break;
+ case EOpDeclaration: out << "Declaration: "; break;
case EOpInvariantDeclaration: out << "Invariant Declaration: "; break;
default:
@@ -478,7 +449,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
out << "Bad aggregation op";
}
- if (node->getOp() != EOpParameters)
+ if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
out << " (" << node->getCompleteString() << ")";
out << "\n";
@@ -486,33 +457,13 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
return true;
}
-bool TOutputTraverser::visitBlock(Visit visit, TIntermBlock *node)
-{
- TInfoSinkBase &out = sink;
-
- OutputTreeText(out, node, mDepth);
- out << "Code block\n";
-
- return true;
-}
-
-bool TOutputTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
-{
- TInfoSinkBase &out = sink;
-
- OutputTreeText(out, node, mDepth);
- out << "Declaration\n";
-
- return true;
-}
-
-bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node)
+bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection *node)
{
TInfoSinkBase &out = sink;
OutputTreeText(out, node, mDepth);
- out << "Ternary selection";
+ out << "Test condition and select";
out << " (" << node->getCompleteString() << ")\n";
++mDepth;
@@ -522,38 +473,6 @@ bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node)
node->getCondition()->traverse(this);
OutputTreeText(sink, node, mDepth);
- if (node->getTrueExpression())
- {
- out << "true case\n";
- node->getTrueExpression()->traverse(this);
- }
- if (node->getFalseExpression())
- {
- OutputTreeText(sink, node, mDepth);
- out << "false case\n";
- node->getFalseExpression()->traverse(this);
- }
-
- --mDepth;
-
- return false;
-}
-
-bool TOutputTraverser::visitIfElse(Visit visit, TIntermIfElse *node)
-{
- TInfoSinkBase &out = sink;
-
- OutputTreeText(out, node, mDepth);
-
- out << "If test\n";
-
- ++mDepth;
-
- OutputTreeText(sink, node, mDepth);
- out << "Condition\n";
- node->getCondition()->traverse(this);
-
- OutputTreeText(sink, node, mDepth);
if (node->getTrueBlock())
{
out << "true case\n";
@@ -576,35 +495,6 @@ bool TOutputTraverser::visitIfElse(Visit visit, TIntermIfElse *node)
return false;
}
-bool TOutputTraverser::visitSwitch(Visit visit, TIntermSwitch *node)
-{
- TInfoSinkBase &out = sink;
-
- OutputTreeText(out, node, mDepth);
-
- out << "Switch\n";
-
- return true;
-}
-
-bool TOutputTraverser::visitCase(Visit visit, TIntermCase *node)
-{
- TInfoSinkBase &out = sink;
-
- OutputTreeText(out, node, mDepth);
-
- if (node->getCondition() == nullptr)
- {
- out << "Default\n";
- }
- else
- {
- out << "Case\n";
- }
-
- return true;
-}
-
void TOutputTraverser::visitConstantUnion(TIntermConstantUnion *node)
{
TInfoSinkBase &out = sink;
@@ -734,5 +624,3 @@ void TIntermediate::outputTree(TIntermNode *root, TInfoSinkBase &infoSink)
root->traverse(&it);
}
-
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/length_limits.h b/gfx/angle/src/compiler/translator/length_limits.h
index 607157f4a..88634381f 100755
--- a/gfx/angle/src/compiler/translator/length_limits.h
+++ b/gfx/angle/src/compiler/translator/length_limits.h
@@ -16,11 +16,6 @@
// These constants are factored out from the rest of the headers to
// make it easier to reference them from the compiler sources.
-namespace sh
-{
-
size_t GetGlobalMaxTokenSize(ShShaderSpec spec);
-} // namespace sh
-
#endif // COMPILER_TRANSLATOR_LENGTHLIMITS_H_
diff --git a/gfx/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp b/gfx/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp
new file mode 100644
index 000000000..790974a2b
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp
@@ -0,0 +1,130 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/depgraph/DependencyGraphOutput.h"
+#include "compiler/translator/timing/RestrictFragmentShaderTiming.h"
+
+RestrictFragmentShaderTiming::RestrictFragmentShaderTiming(TInfoSinkBase& sink)
+ : mSink(sink)
+ , mNumErrors(0)
+{
+ // Sampling ops found only in fragment shaders.
+ mSamplingOps.insert("texture2D(s21;vf2;f1;");
+ mSamplingOps.insert("texture2DProj(s21;vf3;f1;");
+ mSamplingOps.insert("texture2DProj(s21;vf4;f1;");
+ mSamplingOps.insert("textureCube(sC1;vf3;f1;");
+ // Sampling ops found in both vertex and fragment shaders.
+ mSamplingOps.insert("texture2D(s21;vf2;");
+ mSamplingOps.insert("texture2DProj(s21;vf3;");
+ mSamplingOps.insert("texture2DProj(s21;vf4;");
+ mSamplingOps.insert("textureCube(sC1;vf3;");
+ // Sampling ops provided by OES_EGL_image_external.
+ mSamplingOps.insert("texture2D(1;vf2;");
+ mSamplingOps.insert("texture2DProj(1;vf3;");
+ mSamplingOps.insert("texture2DProj(1;vf4;");
+ // Sampling ops provided by ARB_texture_rectangle.
+ mSamplingOps.insert("texture2DRect(1;vf2;");
+ mSamplingOps.insert("texture2DRectProj(1;vf3;");
+ mSamplingOps.insert("texture2DRectProj(1;vf4;");
+ // Sampling ops provided by EXT_shader_texture_lod.
+ mSamplingOps.insert("texture2DLodEXT(1;vf2;f1;");
+ mSamplingOps.insert("texture2DProjLodEXT(1;vf3;f1;");
+ mSamplingOps.insert("texture2DProjLodEXT(1;vf4;f1;");
+ mSamplingOps.insert("textureCubeLodEXT(1;vf4;f1;");
+ mSamplingOps.insert("texture2DGradEXT(1;vf2;vf2;vf2;");
+ mSamplingOps.insert("texture2DProjGradEXT(1;vf3;vf2;vf2;");
+ mSamplingOps.insert("texture2DProjGradEXT(1;vf4;vf2;vf2;");
+ mSamplingOps.insert("textureCubeGradEXT(1;vf3;vf3;vf3;");
+}
+
+// FIXME(mvujovic): We do not know if the execution time of built-in operations like sin, pow, etc.
+// can vary based on the value of the input arguments. If so, we should restrict those as well.
+void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& graph)
+{
+ mNumErrors = 0;
+
+ // FIXME(mvujovic): The dependency graph does not support user defined function calls right now,
+ // so we generate errors for them.
+ validateUserDefinedFunctionCallUsage(graph);
+
+ // Starting from each sampler, traverse the dependency graph and generate an error each time we
+ // hit a node where sampler dependent values are not allowed.
+ for (auto samplerSymbol : graph.samplerSymbols())
+ {
+ clearVisited();
+ samplerSymbol->traverse(this);
+ }
+}
+
+void RestrictFragmentShaderTiming::validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph)
+{
+ for (const auto* functionCall : graph.userDefinedFunctionCalls())
+ {
+ beginError(functionCall->getIntermFunctionCall());
+ mSink << "A call to a user defined function is not permitted.\n";
+ }
+}
+
+void RestrictFragmentShaderTiming::beginError(const TIntermNode* node)
+{
+ ++mNumErrors;
+ mSink.prefix(EPrefixError);
+ mSink.location(node->getLine());
+}
+
+bool RestrictFragmentShaderTiming::isSamplingOp(const TIntermAggregate* intermFunctionCall) const
+{
+ return !intermFunctionCall->isUserDefined() &&
+ mSamplingOps.find(intermFunctionCall->getName()) != mSamplingOps.end();
+}
+
+void RestrictFragmentShaderTiming::visitArgument(TGraphArgument* parameter)
+{
+ // Texture cache access time might leak sensitive information.
+ // Thus, we restrict sampler dependent values from affecting the coordinate or LOD bias of a
+ // sampling operation.
+ if (isSamplingOp(parameter->getIntermFunctionCall())) {
+ switch (parameter->getArgumentNumber()) {
+ case 1:
+ // Second argument (coord)
+ beginError(parameter->getIntermFunctionCall());
+ mSink << "An expression dependent on a sampler is not permitted to be the"
+ << " coordinate argument of a sampling operation.\n";
+ break;
+ case 2:
+ // Third argument (bias)
+ beginError(parameter->getIntermFunctionCall());
+ mSink << "An expression dependent on a sampler is not permitted to be the"
+ << " bias argument of a sampling operation.\n";
+ break;
+ default:
+ // First argument (sampler)
+ break;
+ }
+ }
+}
+
+void RestrictFragmentShaderTiming::visitSelection(TGraphSelection* selection)
+{
+ beginError(selection->getIntermSelection());
+ mSink << "An expression dependent on a sampler is not permitted in a conditional statement.\n";
+}
+
+void RestrictFragmentShaderTiming::visitLoop(TGraphLoop* loop)
+{
+ beginError(loop->getIntermLoop());
+ mSink << "An expression dependent on a sampler is not permitted in a loop condition.\n";
+}
+
+void RestrictFragmentShaderTiming::visitLogicalOp(TGraphLogicalOp* logicalOp)
+{
+ beginError(logicalOp->getIntermLogicalOp());
+ mSink << "An expression dependent on a sampler is not permitted on the left hand side of a logical "
+ << logicalOp->getOpString()
+ << " operator.\n";
+}
diff --git a/gfx/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h b/gfx/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h
new file mode 100644
index 000000000..b8c7e8295
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_
+#define COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/depgraph/DependencyGraph.h"
+
+class TInfoSinkBase;
+
+class RestrictFragmentShaderTiming : TDependencyGraphTraverser
+{
+ public:
+ RestrictFragmentShaderTiming(TInfoSinkBase &sink);
+ void enforceRestrictions(const TDependencyGraph &graph);
+ int numErrors() const { return mNumErrors; }
+
+ void visitArgument(TGraphArgument *parameter) override;
+ void visitSelection(TGraphSelection *selection) override;
+ void visitLoop(TGraphLoop *loop) override;
+ void visitLogicalOp(TGraphLogicalOp *logicalOp) override;
+
+ private:
+ void beginError(const TIntermNode *node);
+ void validateUserDefinedFunctionCallUsage(const TDependencyGraph &graph);
+ bool isSamplingOp(const TIntermAggregate *intermFunctionCall) const;
+
+ TInfoSinkBase &mSink;
+ int mNumErrors;
+
+ typedef std::set<TString> StringSet;
+ StringSet mSamplingOps;
+};
+
+#endif // COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_
diff --git a/gfx/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp b/gfx/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp
new file mode 100644
index 000000000..7c1208a29
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp
@@ -0,0 +1,17 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/timing/RestrictVertexShaderTiming.h"
+
+void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node)
+{
+ if (IsSampler(node->getBasicType())) {
+ ++mNumErrors;
+ mSink.message(EPrefixError,
+ node->getLine(),
+ "Samplers are not permitted in vertex shaders.\n");
+ }
+}
diff --git a/gfx/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h b/gfx/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h
new file mode 100644
index 000000000..23a821772
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h
@@ -0,0 +1,32 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_
+#define COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/InfoSink.h"
+
+class TInfoSinkBase;
+
+class RestrictVertexShaderTiming : public TIntermTraverser {
+public:
+ RestrictVertexShaderTiming(TInfoSinkBase& sink)
+ : TIntermTraverser(true, false, false)
+ , mSink(sink)
+ , mNumErrors(0) {}
+
+ void enforceRestrictions(TIntermNode* root) { root->traverse(this); }
+ int numErrors() { return mNumErrors; }
+
+ void visitSymbol(TIntermSymbol *) override;
+
+private:
+ TInfoSinkBase& mSink;
+ int mNumErrors;
+};
+
+#endif // COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_
diff --git a/gfx/angle/src/compiler/translator/util.cpp b/gfx/angle/src/compiler/translator/util.cpp
index 89f237ceb..bd3e484eb 100755
--- a/gfx/angle/src/compiler/translator/util.cpp
+++ b/gfx/angle/src/compiler/translator/util.cpp
@@ -159,30 +159,6 @@ GLenum GLVariableType(const TType &type)
case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW;
case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW;
case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW;
- case EbtImage2D:
- return GL_IMAGE_2D;
- case EbtIImage2D:
- return GL_INT_IMAGE_2D;
- case EbtUImage2D:
- return GL_UNSIGNED_INT_IMAGE_2D;
- case EbtImage2DArray:
- return GL_IMAGE_2D_ARRAY;
- case EbtIImage2DArray:
- return GL_INT_IMAGE_2D_ARRAY;
- case EbtUImage2DArray:
- return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
- case EbtImage3D:
- return GL_IMAGE_3D;
- case EbtIImage3D:
- return GL_INT_IMAGE_3D;
- case EbtUImage3D:
- return GL_UNSIGNED_INT_IMAGE_3D;
- case EbtImageCube:
- return GL_IMAGE_CUBE;
- case EbtIImageCube:
- return GL_INT_IMAGE_CUBE;
- case EbtUImageCube:
- return GL_UNSIGNED_INT_IMAGE_CUBE;
default: UNREACHABLE();
}
@@ -302,18 +278,10 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
}
}
-TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
+TType ConvertShaderVariableTypeToTType(sh::GLenum type)
{
- switch (var.type)
+ switch (type)
{
- case GL_BOOL:
- return TType(EbtBool);
- case GL_BOOL_VEC2:
- return TType(EbtBool, 2);
- case GL_BOOL_VEC3:
- return TType(EbtBool, 3);
- case GL_BOOL_VEC4:
- return TType(EbtBool, 4);
case GL_FLOAT:
return TType(EbtFloat);
case GL_FLOAT_VEC2:
@@ -569,52 +537,4 @@ template void GetVariableTraverser::traverse(const TType &, const TString &, std
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
-// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
-bool CanBeInvariantESSL1(TQualifier qualifier)
-{
- return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
- IsBuiltinOutputVariable(qualifier) ||
- (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
-}
-
-// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
-// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
-bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
-{
- return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
- IsBuiltinOutputVariable(qualifier);
-}
-
-bool IsBuiltinOutputVariable(TQualifier qualifier)
-{
- switch (qualifier)
- {
- case EvqPosition:
- case EvqPointSize:
- case EvqFragDepth:
- case EvqFragDepthEXT:
- case EvqFragColor:
- case EvqSecondaryFragColorEXT:
- case EvqFragData:
- case EvqSecondaryFragDataEXT:
- return true;
- default:
- break;
- }
- return false;
-}
-
-bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
-{
- switch (qualifier)
- {
- case EvqFragCoord:
- case EvqPointCoord:
- case EvqFrontFacing:
- return true;
- default:
- break;
- }
- return false;
}
-} // namespace sh
diff --git a/gfx/angle/src/compiler/translator/util.h b/gfx/angle/src/compiler/translator/util.h
index bfad5fb4c..4e577b111 100755
--- a/gfx/angle/src/compiler/translator/util.h
+++ b/gfx/angle/src/compiler/translator/util.h
@@ -25,9 +25,10 @@ bool strtof_clamp(const std::string &str, float *value);
// Return false if overflow happens.
bool atoi_clamp(const char *str, unsigned int *value);
+class TSymbolTable;
+
namespace sh
{
-class TSymbolTable;
GLenum GLVariableType(const TType &type);
GLenum GLVariablePrecision(const TType &type);
@@ -36,8 +37,8 @@ bool IsVaryingOut(TQualifier qualifier);
bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier);
TString ArrayString(const TType &type);
-
-TType GetShaderVariableBasicType(const sh::ShaderVariable &var);
+// Handles only basic output variable types.
+TType ConvertShaderVariableTypeToTType(sh::GLenum type);
TOperator TypeToConstructorOperator(const TType &type);
@@ -64,10 +65,6 @@ class GetVariableTraverser : angle::NonCopyable
const TSymbolTable &mSymbolTable;
};
-bool IsBuiltinOutputVariable(TQualifier qualifier);
-bool IsBuiltinFragmentInputVariable(TQualifier qualifier);
-bool CanBeInvariantESSL1(TQualifier qualifier);
-bool CanBeInvariantESSL3OrGreater(TQualifier qualifier);
-} // namespace sh
+}
#endif // COMPILER_TRANSLATOR_UTIL_H_