From 026b85e62b3d8812afb5f04df29aeac28c52b331 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 12 Feb 2011 15:47:35 +0000 Subject: xkeyboard-config pixman xkbcompt mesa git update 12 Feb 2011 --- mesalib/src/SConscript | 56 +- mesalib/src/glsl/Makefile | 396 +- mesalib/src/glsl/SConscript | 287 +- mesalib/src/glsl/ast_function.cpp | 2569 ++--- mesalib/src/glsl/glcpp/glcpp-parse.c | 8431 ++++++++------- mesalib/src/glsl/glcpp/glcpp-parse.h | 201 +- mesalib/src/glsl/glsl_lexer.cpp | 7439 ++++++------- mesalib/src/glsl/glsl_lexer.lpp | 893 +- mesalib/src/glsl/glsl_parser.cpp | 10826 ++++++++++--------- mesalib/src/glsl/glsl_parser.h | 598 +- mesalib/src/glsl/glsl_parser.ypp | 3436 +++--- mesalib/src/mesa/Makefile | 412 +- mesalib/src/mesa/drivers/dri/Makefile.template | 12 +- .../windows/gldirect/dx9/gld_primitive_dx9.c | 1 - .../windows/gldirect/mesasw/gld_wgl_mesasw.c | 1 - mesalib/src/mesa/main/mtypes.h | 6740 ++++++------ mesalib/src/mesa/program/ir_to_mesa.cpp | 6537 +++++------ mesalib/src/mesa/state_tracker/st_cb_fbo.c | 1259 +-- mesalib/src/mesa/state_tracker/st_manager.c | 15 +- mesalib/src/mesa/swrast/s_trispan.h | 31 - mesalib/src/mesa/x86/read_rgba_span_x86.S | 1364 +-- 21 files changed, 25891 insertions(+), 25613 deletions(-) delete mode 100644 mesalib/src/mesa/swrast/s_trispan.h (limited to 'mesalib/src') diff --git a/mesalib/src/SConscript b/mesalib/src/SConscript index d5cde1c96..f5951fc9d 100644 --- a/mesalib/src/SConscript +++ b/mesalib/src/SConscript @@ -1,24 +1,32 @@ -Import('*') - -if env['platform'] == 'windows': - SConscript('getopt/SConscript') - -SConscript('glsl/SConscript') -# When env['gles'] is set, the targets defined in mapi/glapi/SConscript are not -# used. libgl-xlib and libgl-gdi adapt themselves to use the targets defined -# in mapi/glapi-shared/SConscript. mesa/SConscript also adapts itself to -# enable OpenGL ES support. -SConscript('mapi/glapi/SConscript') -SConscript('mesa/SConscript') - -SConscript('mapi/vgapi/SConscript') - -if env['platform'] != 'embedded': - SConscript('egl/main/SConscript') - SConscript('glut/glx/SConscript') - - if env['gles']: - SConscript('mapi/shared-glapi/SConscript') - -SConscript('gallium/SConscript') - +Import('*') + + +if env['platform'] == 'windows': + SConscript('getopt/SConscript') + +SConscript('glsl/SConscript') + +if env['hostonly']: + # We are just compiling the things necessary on the host for cross + # compilation + Return() + + +# When env['gles'] is set, the targets defined in mapi/glapi/SConscript are not +# used. libgl-xlib and libgl-gdi adapt themselves to use the targets defined +# in mapi/glapi-shared/SConscript. mesa/SConscript also adapts itself to +# enable OpenGL ES support. +SConscript('mapi/glapi/SConscript') +SConscript('mesa/SConscript') + +SConscript('mapi/vgapi/SConscript') + +if env['platform'] != 'embedded': + SConscript('egl/main/SConscript') + SConscript('glut/glx/SConscript') + + if env['gles']: + SConscript('mapi/shared-glapi/SConscript') + +SConscript('gallium/SConscript') + diff --git a/mesalib/src/glsl/Makefile b/mesalib/src/glsl/Makefile index ec11c8a7b..a017894ac 100644 --- a/mesalib/src/glsl/Makefile +++ b/mesalib/src/glsl/Makefile @@ -1,183 +1,213 @@ -#src/glsl/pp/Makefile - -TOP = ../.. - -include $(TOP)/configs/current - -LIBNAME = glsl - -LIBGLCPP_SOURCES = \ - glcpp/glcpp-lex.c \ - glcpp/glcpp-parse.c \ - glcpp/pp.c - -GLCPP_SOURCES = \ - $(LIBGLCPP_SOURCES) \ - glcpp/glcpp.c - -C_SOURCES = \ - strtod.c \ - ralloc.c \ - $(LIBGLCPP_SOURCES) - -CXX_SOURCES = \ - ast_expr.cpp \ - ast_function.cpp \ - ast_to_hir.cpp \ - ast_type.cpp \ - glsl_lexer.cpp \ - glsl_parser.cpp \ - glsl_parser_extras.cpp \ - glsl_types.cpp \ - glsl_symbol_table.cpp \ - hir_field_selection.cpp \ - ir_basic_block.cpp \ - ir_clone.cpp \ - ir_constant_expression.cpp \ - ir.cpp \ - ir_expression_flattening.cpp \ - ir_function_can_inline.cpp \ - ir_function.cpp \ - ir_hierarchical_visitor.cpp \ - ir_hv_accept.cpp \ - ir_import_prototypes.cpp \ - ir_print_visitor.cpp \ - ir_reader.cpp \ - ir_rvalue_visitor.cpp \ - ir_set_program_inouts.cpp \ - ir_validate.cpp \ - ir_variable.cpp \ - ir_variable_refcount.cpp \ - linker.cpp \ - link_functions.cpp \ - loop_analysis.cpp \ - loop_controls.cpp \ - loop_unroll.cpp \ - lower_discard.cpp \ - lower_if_to_cond_assign.cpp \ - lower_instructions.cpp \ - lower_jumps.cpp \ - lower_mat_op_to_vec.cpp \ - lower_noise.cpp \ - lower_texture_projection.cpp \ - lower_variable_index_to_cond_assign.cpp \ - lower_vec_index_to_cond_assign.cpp \ - lower_vec_index_to_swizzle.cpp \ - lower_vector.cpp \ - opt_algebraic.cpp \ - opt_constant_folding.cpp \ - opt_constant_propagation.cpp \ - opt_constant_variable.cpp \ - opt_copy_propagation.cpp \ - opt_copy_propagation_elements.cpp \ - opt_dead_code.cpp \ - opt_dead_code_local.cpp \ - opt_dead_functions.cpp \ - opt_discard_simplification.cpp \ - opt_function_inlining.cpp \ - opt_if_simplification.cpp \ - opt_noop_swizzle.cpp \ - opt_redundant_jumps.cpp \ - opt_structure_splitting.cpp \ - opt_swizzle_swizzle.cpp \ - opt_tree_grafting.cpp \ - s_expression.cpp - -LIBS = \ - $(TOP)/src/glsl/libglsl.a - -APPS = glsl_compiler glcpp/glcpp - -GLSL2_C_SOURCES = \ - ../mesa/program/hash_table.c \ - ../mesa/program/symbol_table.c -GLSL2_CXX_SOURCES = \ - main.cpp - -GLSL2_OBJECTS = \ - $(GLSL2_C_SOURCES:.c=.o) \ - $(GLSL2_CXX_SOURCES:.cpp=.o) - -### Basic defines ### - -DEFINES += \ - $(LIBRARY_DEFINES) \ - $(API_DEFINES) - -GLCPP_OBJECTS = \ - $(GLCPP_SOURCES:.c=.o) \ - ../mesa/program/hash_table.o - -OBJECTS = \ - $(C_SOURCES:.c=.o) \ - $(CXX_SOURCES:.cpp=.o) - -INCLUDES = \ - -I. \ - -I../mesa \ - -I../mapi \ - -I../../include \ - $(LIBRARY_INCLUDES) - -ALL_SOURCES = \ - $(C_SOURCES) \ - $(CXX_SOURCES) \ - $(GLSL2_CXX_SOURCES) \ - $(GLSL2_C_SOURCES) - -##### TARGETS ##### - -default: depend lib$(LIBNAME).a $(APPS) - -lib$(LIBNAME).a: $(OBJECTS) builtin_function.o Makefile $(TOP)/src/glsl/Makefile.template - $(MKLIB) -cplusplus -o $(LIBNAME) -static $(OBJECTS) builtin_function.o - -depend: $(ALL_SOURCES) Makefile - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(ALL_SOURCES) 2> /dev/null - -# Remove .o and backup files -clean: - rm -f $(GLCPP_OBJECTS) $(GLSL2_OBJECTS) $(OBJECTS) lib$(LIBNAME).a depend depend.bak builtin_function.cpp builtin_function.o builtin_stubs.o builtin_compiler - -rm -f $(APPS) - -# Dummy target -install: - @echo -n "" - - -##### RULES ##### - -glsl_compiler: $(GLSL2_OBJECTS) libglsl.a builtin_stubs.o - $(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLSL2_OBJECTS) builtin_stubs.o $(LIBS) -o $@ - -glcpp/glcpp: $(GLCPP_OBJECTS) libglsl.a - $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLCPP_OBJECTS) $(LIBS) -o $@ - -.cpp.o: - $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DEFINES) $< -o $@ - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ - -glsl_lexer.cpp: glsl_lexer.lpp - flex --nounistd -o$@ $< - -glsl_parser.cpp: glsl_parser.ypp - bison -v -o "$@" -p "_mesa_glsl_" --defines=glsl_parser.h $< - -glcpp/glcpp-lex.c: glcpp/glcpp-lex.l - flex --nounistd -o$@ $< - -glcpp/glcpp-parse.c: glcpp/glcpp-parse.y - bison -v -o "$@" --defines=glcpp/glcpp-parse.h $< - -builtin_compiler: $(GLSL2_OBJECTS) $(OBJECTS) builtin_stubs.o - $(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $(GLSL2_OBJECTS) builtin_stubs.o -o $@ - -builtin_function.cpp: builtins/profiles/* builtins/ir/* builtins/tools/generate_builtins.py builtins/tools/texture_builtins.py builtin_compiler - @echo Regenerating builtin_function.cpp... - $(PYTHON2) $(PYTHON_FLAGS) builtins/tools/generate_builtins.py $(PWD)/builtin_compiler > builtin_function.cpp - --include depend + +#src/glsl/pp/Makefile + +TOP = ../.. + +include $(TOP)/configs/current + +LIBNAME = glsl + +LIBGLCPP_SOURCES = \ + glcpp/glcpp-lex.c \ + glcpp/glcpp-parse.c \ + glcpp/pp.c + +GLCPP_SOURCES = \ + $(LIBGLCPP_SOURCES) \ + ralloc.c \ + glcpp/glcpp.c + +C_SOURCES = \ + strtod.c \ + ralloc.c \ + $(LIBGLCPP_SOURCES) + +CXX_SOURCES = \ + ast_expr.cpp \ + ast_function.cpp \ + ast_to_hir.cpp \ + ast_type.cpp \ + glsl_lexer.cpp \ + glsl_parser.cpp \ + glsl_parser_extras.cpp \ + glsl_types.cpp \ + glsl_symbol_table.cpp \ + hir_field_selection.cpp \ + ir_basic_block.cpp \ + ir_clone.cpp \ + ir_constant_expression.cpp \ + ir.cpp \ + ir_expression_flattening.cpp \ + ir_function_can_inline.cpp \ + ir_function.cpp \ + ir_hierarchical_visitor.cpp \ + ir_hv_accept.cpp \ + ir_import_prototypes.cpp \ + ir_print_visitor.cpp \ + ir_reader.cpp \ + ir_rvalue_visitor.cpp \ + ir_set_program_inouts.cpp \ + ir_validate.cpp \ + ir_variable.cpp \ + ir_variable_refcount.cpp \ + linker.cpp \ + link_functions.cpp \ + loop_analysis.cpp \ + loop_controls.cpp \ + loop_unroll.cpp \ + lower_discard.cpp \ + lower_if_to_cond_assign.cpp \ + lower_instructions.cpp \ + lower_jumps.cpp \ + lower_mat_op_to_vec.cpp \ + lower_noise.cpp \ + lower_texture_projection.cpp \ + lower_variable_index_to_cond_assign.cpp \ + lower_vec_index_to_cond_assign.cpp \ + lower_vec_index_to_swizzle.cpp \ + lower_vector.cpp \ + opt_algebraic.cpp \ + opt_constant_folding.cpp \ + opt_constant_propagation.cpp \ + opt_constant_variable.cpp \ + opt_copy_propagation.cpp \ + opt_copy_propagation_elements.cpp \ + opt_dead_code.cpp \ + opt_dead_code_local.cpp \ + opt_dead_functions.cpp \ + opt_discard_simplification.cpp \ + opt_function_inlining.cpp \ + opt_if_simplification.cpp \ + opt_noop_swizzle.cpp \ + opt_redundant_jumps.cpp \ + opt_structure_splitting.cpp \ + opt_swizzle_swizzle.cpp \ + opt_tree_grafting.cpp \ + s_expression.cpp + +LIBS = \ + $(TOP)/src/glsl/libglsl.a + +APPS = glsl_compiler glcpp/glcpp + +GLSL2_C_SOURCES = \ + ../mesa/program/hash_table.c \ + ../mesa/program/symbol_table.c +GLSL2_CXX_SOURCES = \ + main.cpp + +GLSL2_OBJECTS = \ + $(GLSL2_C_SOURCES:.c=.o) \ + $(GLSL2_CXX_SOURCES:.cpp=.o) + +### Basic defines ### + +DEFINES += \ + $(LIBRARY_DEFINES) \ + $(API_DEFINES) + +GLCPP_OBJECTS = \ + $(GLCPP_SOURCES:.c=.o) \ + ../mesa/program/hash_table.o + +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(CXX_SOURCES:.cpp=.o) + +DRICORE_OBJ_DIR = obj-visible +OBJECTS_DRICORE = $(addprefix $(DRICORE_OBJ_DIR)/,$(OBJECTS)) + +INCLUDES = \ + -I. \ + -I../mesa \ + -I../mapi \ + -I../../include \ + $(LIBRARY_INCLUDES) + +ALL_SOURCES = \ + $(C_SOURCES) \ + $(CXX_SOURCES) \ + $(GLSL2_CXX_SOURCES) \ + $(GLSL2_C_SOURCES) + +##### TARGETS ##### + +default: depend lib$(LIBNAME).a $(APPS) $(DRICORE_GLSL_LIBS) + +$(TOP)/$(LIB_DIR)/libglsl.so: $(OBJECTS_DRICORE) builtin_function.o Makefile $(TOP)/src/glsl/Makefile.template + $(MKLIB) -o $@ -linker '$(CXX)' -ldflags '$(LDFLAGS)' \ + -cplusplus -noprefix \ + -install $(TOP)/$(LIB_DIR) -id $(INSTALL_LIB_DIR)/$@.dylib \ + $(OBJECTS_DRICORE) builtin_function.o + +lib$(LIBNAME).a: $(OBJECTS) builtin_function.o Makefile $(TOP)/src/glsl/Makefile.template + $(MKLIB) -cplusplus -o $(LIBNAME) -static $(OBJECTS) builtin_function.o + +depend: $(ALL_SOURCES) Makefile + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(ALL_SOURCES) 2> /dev/null + +# Remove .o and backup files +clean: clean-dricore + rm -f $(GLCPP_OBJECTS) $(GLSL2_OBJECTS) $(OBJECTS) lib$(LIBNAME).a depend depend.bak builtin_function.cpp builtin_function.o builtin_stubs.o builtin_compiler + -rm -f $(APPS) + +clean-dricore: + -rm -f $(DRICORE_OBJ_DIR) $(TOP)/$(LIB_DIR)/libglsl.so libglsl.so + +ifneq (,$(DRICORE_GLSL_LIBS)) +DRICORE_INSTALL_TARGET = install-dricore +endif + +# Dummy target +install: $(DRICORE_INSTALL_TARGET) + @echo -n "" + +install-dricore: default + $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(DRICORE_GLSL_LIBS) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + +##### RULES ##### + +glsl_compiler: $(GLSL2_OBJECTS) libglsl.a builtin_stubs.o + $(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLSL2_OBJECTS) builtin_stubs.o $(LIBS) -o $@ + +glcpp: glcpp/glcpp +glcpp/glcpp: $(GLCPP_OBJECTS) + $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLCPP_OBJECTS) -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DEFINES) $< -o $@ + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + +$(DRICORE_OBJ_DIR)/%.o : %.cpp + @mkdir -p $(dir $@) + $(CXX) -c $(INCLUDES) $(DRI_CXXFLAGS) $(DEFINES) $< -o $@ + +$(DRICORE_OBJ_DIR)/%.o : %.c + @mkdir -p $(dir $@) + $(CC) -c $(INCLUDES) $(DRI_CFLAGS) $(DEFINES) $< -o $@ + +glsl_lexer.cpp: glsl_lexer.lpp + flex --nounistd -o$@ $< + +glsl_parser.cpp: glsl_parser.ypp + bison -v -o "$@" -p "_mesa_glsl_" --defines=glsl_parser.h $< + +glcpp/glcpp-lex.c: glcpp/glcpp-lex.l + flex --nounistd -o$@ $< + +glcpp/glcpp-parse.c: glcpp/glcpp-parse.y + bison -v -o "$@" --defines=glcpp/glcpp-parse.h $< + +builtin_compiler: $(GLSL2_OBJECTS) $(OBJECTS) builtin_stubs.o + $(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $(GLSL2_OBJECTS) builtin_stubs.o -o $@ + +builtin_function.cpp: builtins/profiles/* builtins/ir/* builtins/tools/generate_builtins.py builtins/tools/texture_builtins.py builtin_compiler + @echo Regenerating builtin_function.cpp... + $(PYTHON2) $(PYTHON_FLAGS) builtins/tools/generate_builtins.py $(PWD)/builtin_compiler > builtin_function.cpp + +-include depend diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript index f55d7de74..3e1d0a84e 100644 --- a/mesalib/src/glsl/SConscript +++ b/mesalib/src/glsl/SConscript @@ -1,142 +1,145 @@ -import common - -Import('*') - -from sys import executable as python_cmd - -env = env.Clone() - -env.Prepend(CPPPATH = [ - '#include', - '#src/mapi', - '#src/mesa', - '#src/glsl', -]) - -sources = [ - 'glcpp/glcpp-lex.c', - 'glcpp/glcpp-parse.c', - 'glcpp/pp.c', - 'ast_expr.cpp', - 'ast_function.cpp', - 'ast_to_hir.cpp', - 'ast_type.cpp', - 'glsl_lexer.cpp', - 'glsl_parser.cpp', - 'glsl_parser_extras.cpp', - 'glsl_types.cpp', - 'glsl_symbol_table.cpp', - 'hir_field_selection.cpp', - 'ir_basic_block.cpp', - 'ir_clone.cpp', - 'ir_constant_expression.cpp', - 'ir.cpp', - 'ir_expression_flattening.cpp', - 'ir_function_can_inline.cpp', - 'ir_function.cpp', - 'ir_hierarchical_visitor.cpp', - 'ir_hv_accept.cpp', - 'ir_import_prototypes.cpp', - 'ir_print_visitor.cpp', - 'ir_reader.cpp', - 'ir_rvalue_visitor.cpp', - 'ir_set_program_inouts.cpp', - 'ir_validate.cpp', - 'ir_variable.cpp', - 'ir_variable_refcount.cpp', - 'linker.cpp', - 'link_functions.cpp', - 'loop_analysis.cpp', - 'loop_controls.cpp', - 'loop_unroll.cpp', - 'lower_discard.cpp', - 'lower_if_to_cond_assign.cpp', - 'lower_instructions.cpp', - 'lower_jumps.cpp', - 'lower_mat_op_to_vec.cpp', - 'lower_noise.cpp', - 'lower_variable_index_to_cond_assign.cpp', - 'lower_vec_index_to_cond_assign.cpp', - 'lower_vec_index_to_swizzle.cpp', - 'lower_vector.cpp', - 'opt_algebraic.cpp', - 'opt_constant_folding.cpp', - 'opt_constant_propagation.cpp', - 'opt_constant_variable.cpp', - 'opt_copy_propagation.cpp', - 'opt_copy_propagation_elements.cpp', - 'opt_dead_code.cpp', - 'opt_dead_code_local.cpp', - 'opt_dead_functions.cpp', - 'opt_discard_simplification.cpp', - 'opt_function_inlining.cpp', - 'opt_if_simplification.cpp', - 'opt_noop_swizzle.cpp', - 'opt_redundant_jumps.cpp', - 'opt_structure_splitting.cpp', - 'opt_swizzle_swizzle.cpp', - 'opt_tree_grafting.cpp', - 'ralloc.c', - 's_expression.cpp', - 'strtod.c', -] - - -if env['platform'] == common.host_platform: - if env['msvc']: - env.Prepend(CPPPATH = ['#/src/getopt']) - env.PrependUnique(LIBS = [getopt]) - - builtin_compiler = env.Program( - target = 'builtin_compiler', - source = sources + ['main.cpp', 'builtin_stubs.cpp', - '#src/mesa/program/hash_table.c', - '#src/mesa/program/symbol_table.c'], - ) - - builtin_glsl_function = env.CodeGenerate( - target = 'builtin_function.cpp', - script = 'builtins/tools/generate_builtins.py', - source = builtin_compiler, - command = python_cmd + ' $SCRIPT $SOURCE > $TARGET' - ) - - env.Depends(builtin_glsl_function, ['builtins/tools/generate_builtins.py', 'builtins/tools/texture_builtins.py'] + Glob('builtins/ir/*')) - - Export('builtin_glsl_function') - - if common.cross_compiling: - Return() - -sources += builtin_glsl_function - -glsl = env.ConvenienceLibrary( - target = 'glsl', - source = sources, -) - -Export('glsl') - -# FIXME: We can't build the programs because there's a cyclic dependency between tis directory and src/mesa -Return() - -env = env.Clone() - -if env['platform'] == 'windows': - env.PrependUnique(LIBS = [ - 'user32', - ]) - -env.Prepend(LIBS = [glsl]) - -env.Program( - target = 'glsl2', - source = [ - 'main.cpp', - ] -) - -env.Program( - target = 'glcpp', - source = ['glcpp/glcpp.c'], -) +import common + +Import('*') + +from sys import executable as python_cmd + +env = env.Clone() + +env.Prepend(CPPPATH = [ + '#include', + '#src/mapi', + '#src/mesa', + '#src/glsl', +]) + +sources = [ + 'glcpp/glcpp-lex.c', + 'glcpp/glcpp-parse.c', + 'glcpp/pp.c', + 'ast_expr.cpp', + 'ast_function.cpp', + 'ast_to_hir.cpp', + 'ast_type.cpp', + 'glsl_lexer.cpp', + 'glsl_parser.cpp', + 'glsl_parser_extras.cpp', + 'glsl_types.cpp', + 'glsl_symbol_table.cpp', + 'hir_field_selection.cpp', + 'ir_basic_block.cpp', + 'ir_clone.cpp', + 'ir_constant_expression.cpp', + 'ir.cpp', + 'ir_expression_flattening.cpp', + 'ir_function_can_inline.cpp', + 'ir_function.cpp', + 'ir_hierarchical_visitor.cpp', + 'ir_hv_accept.cpp', + 'ir_import_prototypes.cpp', + 'ir_print_visitor.cpp', + 'ir_reader.cpp', + 'ir_rvalue_visitor.cpp', + 'ir_set_program_inouts.cpp', + 'ir_validate.cpp', + 'ir_variable.cpp', + 'ir_variable_refcount.cpp', + 'linker.cpp', + 'link_functions.cpp', + 'loop_analysis.cpp', + 'loop_controls.cpp', + 'loop_unroll.cpp', + 'lower_discard.cpp', + 'lower_if_to_cond_assign.cpp', + 'lower_instructions.cpp', + 'lower_jumps.cpp', + 'lower_mat_op_to_vec.cpp', + 'lower_noise.cpp', + 'lower_variable_index_to_cond_assign.cpp', + 'lower_vec_index_to_cond_assign.cpp', + 'lower_vec_index_to_swizzle.cpp', + 'lower_vector.cpp', + 'opt_algebraic.cpp', + 'opt_constant_folding.cpp', + 'opt_constant_propagation.cpp', + 'opt_constant_variable.cpp', + 'opt_copy_propagation.cpp', + 'opt_copy_propagation_elements.cpp', + 'opt_dead_code.cpp', + 'opt_dead_code_local.cpp', + 'opt_dead_functions.cpp', + 'opt_discard_simplification.cpp', + 'opt_function_inlining.cpp', + 'opt_if_simplification.cpp', + 'opt_noop_swizzle.cpp', + 'opt_redundant_jumps.cpp', + 'opt_structure_splitting.cpp', + 'opt_swizzle_swizzle.cpp', + 'opt_tree_grafting.cpp', + 'ralloc.c', + 's_expression.cpp', + 'strtod.c', +] + + +if env['crosscompile'] and env['platform'] != 'embedded': + Import('builtin_glsl_function') +else: + if env['msvc']: + env.Prepend(CPPPATH = ['#/src/getopt']) + env.PrependUnique(LIBS = [getopt]) + + builtin_compiler = env.Program( + target = 'builtin_compiler', + source = sources + ['main.cpp', 'builtin_stubs.cpp', + '#src/mesa/program/hash_table.c', + '#src/mesa/program/symbol_table.c'], + ) + + builtin_glsl_function = env.CodeGenerate( + target = 'builtin_function.cpp', + script = 'builtins/tools/generate_builtins.py', + source = builtin_compiler, + command = python_cmd + ' $SCRIPT $SOURCE > $TARGET' + ) + + env.Depends(builtin_glsl_function, ['builtins/tools/generate_builtins.py', 'builtins/tools/texture_builtins.py'] + Glob('builtins/ir/*')) + + Export('builtin_glsl_function') + + if env['hostonly']: + Return() + + +sources += builtin_glsl_function + +glsl = env.ConvenienceLibrary( + target = 'glsl', + source = sources, +) + +Export('glsl') + +# FIXME: We can't build the programs because there's a cyclic dependency between tis directory and src/mesa +Return() + +env = env.Clone() + +if env['platform'] == 'windows': + env.PrependUnique(LIBS = [ + 'user32', + ]) + +env.Prepend(LIBS = [glsl]) + +env.Program( + target = 'glsl2', + source = [ + 'main.cpp', + ] +) + +env.Program( + target = 'glcpp', + source = ['glcpp/glcpp.c'], +) diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index 7611617df..8247ceffd 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -1,1278 +1,1291 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "glsl_symbol_table.h" -#include "ast.h" -#include "glsl_types.h" -#include "ir.h" -#include "main/core.h" /* for MIN2 */ - -static ir_rvalue * -convert_component(ir_rvalue *src, const glsl_type *desired_type); - -bool -apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, - struct _mesa_glsl_parse_state *state); - -static unsigned -process_parameters(exec_list *instructions, exec_list *actual_parameters, - exec_list *parameters, - struct _mesa_glsl_parse_state *state) -{ - unsigned count = 0; - - foreach_list (n, parameters) { - ast_node *const ast = exec_node_data(ast_node, n, link); - ir_rvalue *result = ast->hir(instructions, state); - - ir_constant *const constant = result->constant_expression_value(); - if (constant != NULL) - result = constant; - - actual_parameters->push_tail(result); - count++; - } - - return count; -} - - -/** - * Generate a source prototype for a function signature - * - * \param return_type Return type of the function. May be \c NULL. - * \param name Name of the function. - * \param parameters Parameter list for the function. This may be either a - * formal or actual parameter list. Only the type is used. - * - * \return - * A ralloced string representing the prototype of the function. - */ -char * -prototype_string(const glsl_type *return_type, const char *name, - exec_list *parameters) -{ - char *str = NULL; - - if (return_type != NULL) - str = ralloc_asprintf(NULL, "%s ", return_type->name); - - ralloc_asprintf_append(&str, "%s(", name); - - const char *comma = ""; - foreach_list(node, parameters) { - const ir_instruction *const param = (ir_instruction *) node; - - ralloc_asprintf_append(&str, "%s%s", comma, param->type->name); - comma = ", "; - } - - ralloc_strcat(&str, ")"); - return str; -} - - -static ir_rvalue * -match_function_by_name(exec_list *instructions, const char *name, - YYLTYPE *loc, exec_list *actual_parameters, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - ir_function *f = state->symbols->get_function(name); - ir_function_signature *sig; - - sig = f ? f->matching_signature(actual_parameters) : NULL; - - /* FINISHME: This doesn't handle the case where shader X contains a - * FINISHME: matching signature but shader X + N contains an _exact_ - * FINISHME: matching signature. - */ - if (sig == NULL && (f == NULL || state->es_shader || !f->has_user_signature()) && state->symbols->get_type(name) == NULL && (state->language_version == 110 || state->symbols->get_variable(name) == NULL)) { - /* The current shader doesn't contain a matching function or signature. - * Before giving up, look for the prototype in the built-in functions. - */ - for (unsigned i = 0; i < state->num_builtins_to_link; i++) { - ir_function *builtin; - builtin = state->builtins_to_link[i]->symbols->get_function(name); - sig = builtin ? builtin->matching_signature(actual_parameters) : NULL; - if (sig != NULL) { - if (f == NULL) { - f = new(ctx) ir_function(name); - state->symbols->add_global_function(f); - emit_function(state, instructions, f); - } - - f->add_signature(sig->clone_prototype(f, NULL)); - break; - } - } - } - - if (sig != NULL) { - /* Verify that 'out' and 'inout' actual parameters are lvalues. This - * isn't done in ir_function::matching_signature because that function - * cannot generate the necessary diagnostics. - * - * Also, validate that 'const_in' formal parameters (an extension of our - * IR) correspond to ir_constant actual parameters. - */ - exec_list_iterator actual_iter = actual_parameters->iterator(); - exec_list_iterator formal_iter = sig->parameters.iterator(); - - while (actual_iter.has_next()) { - ir_rvalue *actual = (ir_rvalue *) actual_iter.get(); - ir_variable *formal = (ir_variable *) formal_iter.get(); - - assert(actual != NULL); - assert(formal != NULL); - - if (formal->mode == ir_var_const_in && !actual->as_constant()) { - _mesa_glsl_error(loc, state, - "parameter `%s' must be a constant expression", - formal->name); - } - - if ((formal->mode == ir_var_out) - || (formal->mode == ir_var_inout)) { - const char *mode = NULL; - switch (formal->mode) { - case ir_var_out: mode = "out"; break; - case ir_var_inout: mode = "inout"; break; - default: assert(false); break; - } - /* FIXME: 'loc' is incorrect (as of 2011-01-21). It is always - * FIXME: 0:0(0). - */ - if (actual->variable_referenced() - && actual->variable_referenced()->read_only) { - _mesa_glsl_error(loc, state, - "function parameter '%s %s' references the " - "read-only variable '%s'", - mode, formal->name, - actual->variable_referenced()->name); - - } else if (!actual->is_lvalue()) { - _mesa_glsl_error(loc, state, - "function parameter '%s %s' is not an lvalue", - mode, formal->name); - } - } - - if (formal->type->is_numeric() || formal->type->is_boolean()) { - ir_rvalue *converted = convert_component(actual, formal->type); - actual->replace_with(converted); - } - - actual_iter.next(); - formal_iter.next(); - } - - /* Always insert the call in the instruction stream, and return a deref - * of its return val if it returns a value, since we don't know if - * the rvalue is going to be assigned to anything or not. - */ - ir_call *call = new(ctx) ir_call(sig, actual_parameters); - if (!sig->return_type->is_void()) { - ir_variable *var; - ir_dereference_variable *deref; - - var = new(ctx) ir_variable(sig->return_type, - ralloc_asprintf(ctx, "%s_retval", - sig->function_name()), - ir_var_temporary); - instructions->push_tail(var); - - deref = new(ctx) ir_dereference_variable(var); - ir_assignment *assign = new(ctx) ir_assignment(deref, call, NULL); - instructions->push_tail(assign); - if (state->language_version >= 120) - var->constant_value = call->constant_expression_value(); - - deref = new(ctx) ir_dereference_variable(var); - return deref; - } else { - instructions->push_tail(call); - return NULL; - } - } else { - char *str = prototype_string(NULL, name, actual_parameters); - - _mesa_glsl_error(loc, state, "no matching function for call to `%s'", - str); - ralloc_free(str); - - const char *prefix = "candidates are: "; - - for (int i = -1; i < (int) state->num_builtins_to_link; i++) { - glsl_symbol_table *syms = i >= 0 ? state->builtins_to_link[i]->symbols - : state->symbols; - f = syms->get_function(name); - if (f == NULL) - continue; - - foreach_list (node, &f->signatures) { - ir_function_signature *sig = (ir_function_signature *) node; - - str = prototype_string(sig->return_type, f->name, &sig->parameters); - _mesa_glsl_error(loc, state, "%s%s\n", prefix, str); - ralloc_free(str); - - prefix = " "; - } - - } - - return ir_call::get_error_instruction(ctx); - } -} - - -/** - * Perform automatic type conversion of constructor parameters - * - * This implements the rules in the "Conversion and Scalar Constructors" - * section (GLSL 1.10 section 5.4.1), not the "Implicit Conversions" rules. - */ -static ir_rvalue * -convert_component(ir_rvalue *src, const glsl_type *desired_type) -{ - void *ctx = ralloc_parent(src); - const unsigned a = desired_type->base_type; - const unsigned b = src->type->base_type; - ir_expression *result = NULL; - - if (src->type->is_error()) - return src; - - assert(a <= GLSL_TYPE_BOOL); - assert(b <= GLSL_TYPE_BOOL); - - if ((a == b) || (src->type->is_integer() && desired_type->is_integer())) - return src; - - switch (a) { - case GLSL_TYPE_UINT: - case GLSL_TYPE_INT: - if (b == GLSL_TYPE_FLOAT) - result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL); - else { - assert(b == GLSL_TYPE_BOOL); - result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL); - } - break; - case GLSL_TYPE_FLOAT: - switch (b) { - case GLSL_TYPE_UINT: - result = new(ctx) ir_expression(ir_unop_u2f, desired_type, src, NULL); - break; - case GLSL_TYPE_INT: - result = new(ctx) ir_expression(ir_unop_i2f, desired_type, src, NULL); - break; - case GLSL_TYPE_BOOL: - result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL); - break; - } - break; - case GLSL_TYPE_BOOL: - switch (b) { - case GLSL_TYPE_UINT: - case GLSL_TYPE_INT: - result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL); - break; - case GLSL_TYPE_FLOAT: - result = new(ctx) ir_expression(ir_unop_f2b, desired_type, src, NULL); - break; - } - break; - } - - assert(result != NULL); - - /* Try constant folding; it may fold in the conversion we just added. */ - ir_constant *const constant = result->constant_expression_value(); - return (constant != NULL) ? (ir_rvalue *) constant : (ir_rvalue *) result; -} - -/** - * Dereference a specific component from a scalar, vector, or matrix - */ -static ir_rvalue * -dereference_component(ir_rvalue *src, unsigned component) -{ - void *ctx = ralloc_parent(src); - assert(component < src->type->components()); - - /* If the source is a constant, just create a new constant instead of a - * dereference of the existing constant. - */ - ir_constant *constant = src->as_constant(); - if (constant) - return new(ctx) ir_constant(constant, component); - - if (src->type->is_scalar()) { - return src; - } else if (src->type->is_vector()) { - return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1); - } else { - assert(src->type->is_matrix()); - - /* Dereference a row of the matrix, then call this function again to get - * a specific element from that row. - */ - const int c = component / src->type->column_type()->vector_elements; - const int r = component % src->type->column_type()->vector_elements; - ir_constant *const col_index = new(ctx) ir_constant(c); - ir_dereference *const col = new(ctx) ir_dereference_array(src, col_index); - - col->type = src->type->column_type(); - - return dereference_component(col, r); - } - - assert(!"Should not get here."); - return NULL; -} - - -static ir_rvalue * -process_array_constructor(exec_list *instructions, - const glsl_type *constructor_type, - YYLTYPE *loc, exec_list *parameters, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - /* Array constructors come in two forms: sized and unsized. Sized array - * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4 - * variables. In this case the number of parameters must exactly match the - * specified size of the array. - * - * Unsized array constructors look like 'vec4[](a, b)', where 'a' and 'b' - * are vec4 variables. In this case the size of the array being constructed - * is determined by the number of parameters. - * - * From page 52 (page 58 of the PDF) of the GLSL 1.50 spec: - * - * "There must be exactly the same number of arguments as the size of - * the array being constructed. If no size is present in the - * constructor, then the array is explicitly sized to the number of - * arguments provided. The arguments are assigned in order, starting at - * element 0, to the elements of the constructed array. Each argument - * must be the same type as the element type of the array, or be a type - * that can be converted to the element type of the array according to - * Section 4.1.10 "Implicit Conversions."" - */ - exec_list actual_parameters; - const unsigned parameter_count = - process_parameters(instructions, &actual_parameters, parameters, state); - - if ((parameter_count == 0) - || ((constructor_type->length != 0) - && (constructor_type->length != parameter_count))) { - const unsigned min_param = (constructor_type->length == 0) - ? 1 : constructor_type->length; - - _mesa_glsl_error(loc, state, "array constructor must have %s %u " - "parameter%s", - (constructor_type->length != 0) ? "at least" : "exactly", - min_param, (min_param <= 1) ? "" : "s"); - return ir_call::get_error_instruction(ctx); - } - - if (constructor_type->length == 0) { - constructor_type = - glsl_type::get_array_instance(constructor_type->element_type(), - parameter_count); - assert(constructor_type != NULL); - assert(constructor_type->length == parameter_count); - } - - bool all_parameters_are_constant = true; - - /* Type cast each parameter and, if possible, fold constants. */ - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *ir = (ir_rvalue *) n; - ir_rvalue *result = ir; - - /* Apply implicit conversions (not the scalar constructor rules!) */ - if (constructor_type->element_type()->is_float()) { - const glsl_type *desired_type = - glsl_type::get_instance(GLSL_TYPE_FLOAT, - ir->type->vector_elements, - ir->type->matrix_columns); - result = convert_component(ir, desired_type); - } - - if (result->type != constructor_type->element_type()) { - _mesa_glsl_error(loc, state, "type error in array constructor: " - "expected: %s, found %s", - constructor_type->element_type()->name, - result->type->name); - } - - /* Attempt to convert the parameter to a constant valued expression. - * After doing so, track whether or not all the parameters to the - * constructor are trivially constant valued expressions. - */ - ir_rvalue *const constant = result->constant_expression_value(); - - if (constant != NULL) - result = constant; - else - all_parameters_are_constant = false; - - ir->replace_with(result); - } - - if (all_parameters_are_constant) - return new(ctx) ir_constant(constructor_type, &actual_parameters); - - ir_variable *var = new(ctx) ir_variable(constructor_type, "array_ctor", - ir_var_temporary); - instructions->push_tail(var); - - int i = 0; - foreach_list(node, &actual_parameters) { - ir_rvalue *rhs = (ir_rvalue *) node; - ir_rvalue *lhs = new(ctx) ir_dereference_array(var, - new(ctx) ir_constant(i)); - - ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs, NULL); - instructions->push_tail(assignment); - - i++; - } - - return new(ctx) ir_dereference_variable(var); -} - - -/** - * Try to convert a record constructor to a constant expression - */ -static ir_constant * -constant_record_constructor(const glsl_type *constructor_type, - exec_list *parameters, void *mem_ctx) -{ - foreach_list(node, parameters) { - ir_constant *constant = ((ir_instruction *) node)->as_constant(); - if (constant == NULL) - return NULL; - node->replace_with(constant); - } - - return new(mem_ctx) ir_constant(constructor_type, parameters); -} - - -/** - * Determine if a list consists of a single scalar r-value - */ -bool -single_scalar_parameter(exec_list *parameters) -{ - const ir_rvalue *const p = (ir_rvalue *) parameters->head; - assert(((ir_rvalue *)p)->as_rvalue() != NULL); - - return (p->type->is_scalar() && p->next->is_tail_sentinel()); -} - - -/** - * Generate inline code for a vector constructor - * - * The generated constructor code will consist of a temporary variable - * declaration of the same type as the constructor. A sequence of assignments - * from constructor parameters to the temporary will follow. - * - * \return - * An \c ir_dereference_variable of the temprorary generated in the constructor - * body. - */ -ir_rvalue * -emit_inline_vector_constructor(const glsl_type *type, - exec_list *instructions, - exec_list *parameters, - void *ctx) -{ - assert(!parameters->is_empty()); - - ir_variable *var = new(ctx) ir_variable(type, "vec_ctor", ir_var_temporary); - instructions->push_tail(var); - - /* There are two kinds of vector constructors. - * - * - Construct a vector from a single scalar by replicating that scalar to - * all components of the vector. - * - * - Construct a vector from an arbirary combination of vectors and - * scalars. The components of the constructor parameters are assigned - * to the vector in order until the vector is full. - */ - const unsigned lhs_components = type->components(); - if (single_scalar_parameter(parameters)) { - ir_rvalue *first_param = (ir_rvalue *)parameters->head; - ir_rvalue *rhs = new(ctx) ir_swizzle(first_param, 0, 0, 0, 0, - lhs_components); - ir_dereference_variable *lhs = new(ctx) ir_dereference_variable(var); - const unsigned mask = (1U << lhs_components) - 1; - - assert(rhs->type == lhs->type); - - ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL, mask); - instructions->push_tail(inst); - } else { - unsigned base_component = 0; - unsigned base_lhs_component = 0; - ir_constant_data data; - unsigned constant_mask = 0, constant_components = 0; - - memset(&data, 0, sizeof(data)); - - foreach_list(node, parameters) { - ir_rvalue *param = (ir_rvalue *) node; - unsigned rhs_components = param->type->components(); - - /* Do not try to assign more components to the vector than it has! - */ - if ((rhs_components + base_lhs_component) > lhs_components) { - rhs_components = lhs_components - base_lhs_component; - } - - const ir_constant *const c = param->as_constant(); - if (c != NULL) { - for (unsigned i = 0; i < rhs_components; i++) { - switch (c->type->base_type) { - case GLSL_TYPE_UINT: - data.u[i + base_component] = c->get_uint_component(i); - break; - case GLSL_TYPE_INT: - data.i[i + base_component] = c->get_int_component(i); - break; - case GLSL_TYPE_FLOAT: - data.f[i + base_component] = c->get_float_component(i); - break; - case GLSL_TYPE_BOOL: - data.b[i + base_component] = c->get_bool_component(i); - break; - default: - assert(!"Should not get here."); - break; - } - } - - /* Mask of fields to be written in the assignment. - */ - constant_mask |= ((1U << rhs_components) - 1) << base_lhs_component; - constant_components += rhs_components; - - base_component += rhs_components; - } - /* Advance the component index by the number of components - * that were just assigned. - */ - base_lhs_component += rhs_components; - } - - if (constant_mask != 0) { - ir_dereference *lhs = new(ctx) ir_dereference_variable(var); - const glsl_type *rhs_type = glsl_type::get_instance(var->type->base_type, - constant_components, - 1); - ir_rvalue *rhs = new(ctx) ir_constant(rhs_type, &data); - - ir_instruction *inst = - new(ctx) ir_assignment(lhs, rhs, NULL, constant_mask); - instructions->push_tail(inst); - } - - base_component = 0; - foreach_list(node, parameters) { - ir_rvalue *param = (ir_rvalue *) node; - unsigned rhs_components = param->type->components(); - - /* Do not try to assign more components to the vector than it has! - */ - if ((rhs_components + base_component) > lhs_components) { - rhs_components = lhs_components - base_component; - } - - const ir_constant *const c = param->as_constant(); - if (c == NULL) { - /* Mask of fields to be written in the assignment. - */ - const unsigned write_mask = ((1U << rhs_components) - 1) - << base_component; - - ir_dereference *lhs = new(ctx) ir_dereference_variable(var); - - /* Generate a swizzle so that LHS and RHS sizes match. - */ - ir_rvalue *rhs = - new(ctx) ir_swizzle(param, 0, 1, 2, 3, rhs_components); - - ir_instruction *inst = - new(ctx) ir_assignment(lhs, rhs, NULL, write_mask); - instructions->push_tail(inst); - } - - /* Advance the component index by the number of components that were - * just assigned. - */ - base_component += rhs_components; - } - } - return new(ctx) ir_dereference_variable(var); -} - - -/** - * Generate assignment of a portion of a vector to a portion of a matrix column - * - * \param src_base First component of the source to be used in assignment - * \param column Column of destination to be assiged - * \param row_base First component of the destination column to be assigned - * \param count Number of components to be assigned - * - * \note - * \c src_base + \c count must be less than or equal to the number of components - * in the source vector. - */ -ir_instruction * -assign_to_matrix_column(ir_variable *var, unsigned column, unsigned row_base, - ir_rvalue *src, unsigned src_base, unsigned count, - void *mem_ctx) -{ - ir_constant *col_idx = new(mem_ctx) ir_constant(column); - ir_dereference *column_ref = new(mem_ctx) ir_dereference_array(var, col_idx); - - assert(column_ref->type->components() >= (row_base + count)); - assert(src->type->components() >= (src_base + count)); - - /* Generate a swizzle that extracts the number of components from the source - * that are to be assigned to the column of the matrix. - */ - if (count < src->type->vector_elements) { - src = new(mem_ctx) ir_swizzle(src, - src_base + 0, src_base + 1, - src_base + 2, src_base + 3, - count); - } - - /* Mask of fields to be written in the assignment. - */ - const unsigned write_mask = ((1U << count) - 1) << row_base; - - return new(mem_ctx) ir_assignment(column_ref, src, NULL, write_mask); -} - - -/** - * Generate inline code for a matrix constructor - * - * The generated constructor code will consist of a temporary variable - * declaration of the same type as the constructor. A sequence of assignments - * from constructor parameters to the temporary will follow. - * - * \return - * An \c ir_dereference_variable of the temprorary generated in the constructor - * body. - */ -ir_rvalue * -emit_inline_matrix_constructor(const glsl_type *type, - exec_list *instructions, - exec_list *parameters, - void *ctx) -{ - assert(!parameters->is_empty()); - - ir_variable *var = new(ctx) ir_variable(type, "mat_ctor", ir_var_temporary); - instructions->push_tail(var); - - /* There are three kinds of matrix constructors. - * - * - Construct a matrix from a single scalar by replicating that scalar to - * along the diagonal of the matrix and setting all other components to - * zero. - * - * - Construct a matrix from an arbirary combination of vectors and - * scalars. The components of the constructor parameters are assigned - * to the matrix in colum-major order until the matrix is full. - * - * - Construct a matrix from a single matrix. The source matrix is copied - * to the upper left portion of the constructed matrix, and the remaining - * elements take values from the identity matrix. - */ - ir_rvalue *const first_param = (ir_rvalue *) parameters->head; - if (single_scalar_parameter(parameters)) { - /* Assign the scalar to the X component of a vec4, and fill the remaining - * components with zero. - */ - ir_variable *rhs_var = - new(ctx) ir_variable(glsl_type::vec4_type, "mat_ctor_vec", - ir_var_temporary); - instructions->push_tail(rhs_var); - - ir_constant_data zero; - zero.f[0] = 0.0; - zero.f[1] = 0.0; - zero.f[2] = 0.0; - zero.f[3] = 0.0; - - ir_instruction *inst = - new(ctx) ir_assignment(new(ctx) ir_dereference_variable(rhs_var), - new(ctx) ir_constant(rhs_var->type, &zero), - NULL); - instructions->push_tail(inst); - - ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); - - inst = new(ctx) ir_assignment(rhs_ref, first_param, NULL, 0x01); - instructions->push_tail(inst); - - /* Assign the temporary vector to each column of the destination matrix - * with a swizzle that puts the X component on the diagonal of the - * matrix. In some cases this may mean that the X component does not - * get assigned into the column at all (i.e., when the matrix has more - * columns than rows). - */ - static const unsigned rhs_swiz[4][4] = { - { 0, 1, 1, 1 }, - { 1, 0, 1, 1 }, - { 1, 1, 0, 1 }, - { 1, 1, 1, 0 } - }; - - const unsigned cols_to_init = MIN2(type->matrix_columns, - type->vector_elements); - for (unsigned i = 0; i < cols_to_init; i++) { - ir_constant *const col_idx = new(ctx) ir_constant(i); - ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx); - - ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); - ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, rhs_swiz[i], - type->vector_elements); - - inst = new(ctx) ir_assignment(col_ref, rhs, NULL); - instructions->push_tail(inst); - } - - for (unsigned i = cols_to_init; i < type->matrix_columns; i++) { - ir_constant *const col_idx = new(ctx) ir_constant(i); - ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx); - - ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); - ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, 1, 1, 1, 1, - type->vector_elements); - - inst = new(ctx) ir_assignment(col_ref, rhs, NULL); - instructions->push_tail(inst); - } - } else if (first_param->type->is_matrix()) { - /* From page 50 (56 of the PDF) of the GLSL 1.50 spec: - * - * "If a matrix is constructed from a matrix, then each component - * (column i, row j) in the result that has a corresponding - * component (column i, row j) in the argument will be initialized - * from there. All other components will be initialized to the - * identity matrix. If a matrix argument is given to a matrix - * constructor, it is an error to have any other arguments." - */ - assert(first_param->next->is_tail_sentinel()); - ir_rvalue *const src_matrix = first_param; - - /* If the source matrix is smaller, pre-initialize the relavent parts of - * the destination matrix to the identity matrix. - */ - if ((src_matrix->type->matrix_columns < var->type->matrix_columns) - || (src_matrix->type->vector_elements < var->type->vector_elements)) { - - /* If the source matrix has fewer rows, every column of the destination - * must be initialized. Otherwise only the columns in the destination - * that do not exist in the source must be initialized. - */ - unsigned col = - (src_matrix->type->vector_elements < var->type->vector_elements) - ? 0 : src_matrix->type->matrix_columns; - - const glsl_type *const col_type = var->type->column_type(); - for (/* empty */; col < var->type->matrix_columns; col++) { - ir_constant_data ident; - - ident.f[0] = 0.0; - ident.f[1] = 0.0; - ident.f[2] = 0.0; - ident.f[3] = 0.0; - - ident.f[col] = 1.0; - - ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident); - - ir_rvalue *const lhs = - new(ctx) ir_dereference_array(var, new(ctx) ir_constant(col)); - - ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL); - instructions->push_tail(inst); - } - } - - /* Assign columns from the source matrix to the destination matrix. - * - * Since the parameter will be used in the RHS of multiple assignments, - * generate a temporary and copy the paramter there. - */ - ir_variable *const rhs_var = - new(ctx) ir_variable(first_param->type, "mat_ctor_mat", - ir_var_temporary); - instructions->push_tail(rhs_var); - - ir_dereference *const rhs_var_ref = - new(ctx) ir_dereference_variable(rhs_var); - ir_instruction *const inst = - new(ctx) ir_assignment(rhs_var_ref, first_param, NULL); - instructions->push_tail(inst); - - const unsigned last_row = MIN2(src_matrix->type->vector_elements, - var->type->vector_elements); - const unsigned last_col = MIN2(src_matrix->type->matrix_columns, - var->type->matrix_columns); - - unsigned swiz[4] = { 0, 0, 0, 0 }; - for (unsigned i = 1; i < last_row; i++) - swiz[i] = i; - - const unsigned write_mask = (1U << last_row) - 1; - - for (unsigned i = 0; i < last_col; i++) { - ir_dereference *const lhs = - new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i)); - ir_rvalue *const rhs_col = - new(ctx) ir_dereference_array(rhs_var, new(ctx) ir_constant(i)); - - /* If one matrix has columns that are smaller than the columns of the - * other matrix, wrap the column access of the larger with a swizzle - * so that the LHS and RHS of the assignment have the same size (and - * therefore have the same type). - * - * It would be perfectly valid to unconditionally generate the - * swizzles, this this will typically result in a more compact IR tree. - */ - ir_rvalue *rhs; - if (lhs->type->vector_elements != rhs_col->type->vector_elements) { - rhs = new(ctx) ir_swizzle(rhs_col, swiz, last_row); - } else { - rhs = rhs_col; - } - - ir_instruction *inst = - new(ctx) ir_assignment(lhs, rhs, NULL, write_mask); - instructions->push_tail(inst); - } - } else { - const unsigned cols = type->matrix_columns; - const unsigned rows = type->vector_elements; - unsigned col_idx = 0; - unsigned row_idx = 0; - - foreach_list (node, parameters) { - ir_rvalue *const rhs = (ir_rvalue *) node; - const unsigned components_remaining_this_column = rows - row_idx; - unsigned rhs_components = rhs->type->components(); - unsigned rhs_base = 0; - - /* Since the parameter might be used in the RHS of two assignments, - * generate a temporary and copy the paramter there. - */ - ir_variable *rhs_var = - new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary); - instructions->push_tail(rhs_var); - - ir_dereference *rhs_var_ref = - new(ctx) ir_dereference_variable(rhs_var); - ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs, NULL); - instructions->push_tail(inst); - - /* Assign the current parameter to as many components of the matrix - * as it will fill. - * - * NOTE: A single vector parameter can span two matrix columns. A - * single vec4, for example, can completely fill a mat2. - */ - if (rhs_components >= components_remaining_this_column) { - const unsigned count = MIN2(rhs_components, - components_remaining_this_column); - - rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var); - - ir_instruction *inst = assign_to_matrix_column(var, col_idx, - row_idx, - rhs_var_ref, 0, - count, ctx); - instructions->push_tail(inst); - - rhs_base = count; - - col_idx++; - row_idx = 0; - } - - /* If there is data left in the parameter and components left to be - * set in the destination, emit another assignment. It is possible - * that the assignment could be of a vec4 to the last element of the - * matrix. In this case col_idx==cols, but there is still data - * left in the source parameter. Obviously, don't emit an assignment - * to data outside the destination matrix. - */ - if ((col_idx < cols) && (rhs_base < rhs_components)) { - const unsigned count = rhs_components - rhs_base; - - rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var); - - ir_instruction *inst = assign_to_matrix_column(var, col_idx, - row_idx, - rhs_var_ref, - rhs_base, - count, ctx); - instructions->push_tail(inst); - - row_idx += count; - } - } - } - - return new(ctx) ir_dereference_variable(var); -} - - -ir_rvalue * -emit_inline_record_constructor(const glsl_type *type, - exec_list *instructions, - exec_list *parameters, - void *mem_ctx) -{ - ir_variable *const var = - new(mem_ctx) ir_variable(type, "record_ctor", ir_var_temporary); - ir_dereference_variable *const d = new(mem_ctx) ir_dereference_variable(var); - - instructions->push_tail(var); - - exec_node *node = parameters->head; - for (unsigned i = 0; i < type->length; i++) { - assert(!node->is_tail_sentinel()); - - ir_dereference *const lhs = - new(mem_ctx) ir_dereference_record(d->clone(mem_ctx, NULL), - type->fields.structure[i].name); - - ir_rvalue *const rhs = ((ir_instruction *) node)->as_rvalue(); - assert(rhs != NULL); - - ir_instruction *const assign = new(mem_ctx) ir_assignment(lhs, rhs, NULL); - - instructions->push_tail(assign); - node = node->next; - } - - return d; -} - - -ir_rvalue * -ast_function_expression::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - /* There are three sorts of function calls. - * - * 1. constructors - The first subexpression is an ast_type_specifier. - * 2. methods - Only the .length() method of array types. - * 3. functions - Calls to regular old functions. - * - * Method calls are actually detected when the ast_field_selection - * expression is handled. - */ - if (is_constructor()) { - const ast_type_specifier *type = (ast_type_specifier *) subexpressions[0]; - YYLTYPE loc = type->get_location(); - const char *name; - - const glsl_type *const constructor_type = type->glsl_type(& name, state); - - - /* Constructors for samplers are illegal. - */ - if (constructor_type->is_sampler()) { - _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'", - constructor_type->name); - return ir_call::get_error_instruction(ctx); - } - - if (constructor_type->is_array()) { - if (state->language_version <= 110) { - _mesa_glsl_error(& loc, state, - "array constructors forbidden in GLSL 1.10"); - return ir_call::get_error_instruction(ctx); - } - - return process_array_constructor(instructions, constructor_type, - & loc, &this->expressions, state); - } - - - /* There are two kinds of constructor call. Constructors for built-in - * language types, such as mat4 and vec2, are free form. The only - * requirement is that the parameters must provide enough values of the - * correct scalar type. Constructors for arrays and structures must - * have the exact number of parameters with matching types in the - * correct order. These constructors follow essentially the same type - * matching rules as functions. - */ - if (!constructor_type->is_numeric() && !constructor_type->is_boolean()) - return ir_call::get_error_instruction(ctx); - - /* Total number of components of the type being constructed. */ - const unsigned type_components = constructor_type->components(); - - /* Number of components from parameters that have actually been - * consumed. This is used to perform several kinds of error checking. - */ - unsigned components_used = 0; - - unsigned matrix_parameters = 0; - unsigned nonmatrix_parameters = 0; - exec_list actual_parameters; - - foreach_list (n, &this->expressions) { - ast_node *ast = exec_node_data(ast_node, n, link); - ir_rvalue *result = ast->hir(instructions, state)->as_rvalue(); - - /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: - * - * "It is an error to provide extra arguments beyond this - * last used argument." - */ - if (components_used >= type_components) { - _mesa_glsl_error(& loc, state, "too many parameters to `%s' " - "constructor", - constructor_type->name); - return ir_call::get_error_instruction(ctx); - } - - if (!result->type->is_numeric() && !result->type->is_boolean()) { - _mesa_glsl_error(& loc, state, "cannot construct `%s' from a " - "non-numeric data type", - constructor_type->name); - return ir_call::get_error_instruction(ctx); - } - - /* Count the number of matrix and nonmatrix parameters. This - * is used below to enforce some of the constructor rules. - */ - if (result->type->is_matrix()) - matrix_parameters++; - else - nonmatrix_parameters++; - - actual_parameters.push_tail(result); - components_used += result->type->components(); - } - - /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec: - * - * "It is an error to construct matrices from other matrices. This - * is reserved for future use." - */ - if (state->language_version == 110 && matrix_parameters > 0 - && constructor_type->is_matrix()) { - _mesa_glsl_error(& loc, state, "cannot construct `%s' from a " - "matrix in GLSL 1.10", - constructor_type->name); - return ir_call::get_error_instruction(ctx); - } - - /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: - * - * "If a matrix argument is given to a matrix constructor, it is - * an error to have any other arguments." - */ - if ((matrix_parameters > 0) - && ((matrix_parameters + nonmatrix_parameters) > 1) - && constructor_type->is_matrix()) { - _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, " - "matrix must be only parameter", - constructor_type->name); - return ir_call::get_error_instruction(ctx); - } - - /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec: - * - * "In these cases, there must be enough components provided in the - * arguments to provide an initializer for every component in the - * constructed value." - */ - if (components_used < type_components && components_used != 1 - && matrix_parameters == 0) { - _mesa_glsl_error(& loc, state, "too few components to construct " - "`%s'", - constructor_type->name); - return ir_call::get_error_instruction(ctx); - } - - /* Later, we cast each parameter to the same base type as the - * constructor. Since there are no non-floating point matrices, we - * need to break them up into a series of column vectors. - */ - if (constructor_type->base_type != GLSL_TYPE_FLOAT) { - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *matrix = (ir_rvalue *) n; - - if (!matrix->type->is_matrix()) - continue; - - /* Create a temporary containing the matrix. */ - ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp", - ir_var_temporary); - instructions->push_tail(var); - instructions->push_tail(new(ctx) ir_assignment(new(ctx) - ir_dereference_variable(var), matrix, NULL)); - var->constant_value = matrix->constant_expression_value(); - - /* Replace the matrix with dereferences of its columns. */ - for (int i = 0; i < matrix->type->matrix_columns; i++) { - matrix->insert_before(new (ctx) ir_dereference_array(var, - new(ctx) ir_constant(i))); - } - matrix->remove(); - } - } - - bool all_parameters_are_constant = true; - - /* Type cast each parameter and, if possible, fold constants.*/ - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *ir = (ir_rvalue *) n; - - const glsl_type *desired_type = - glsl_type::get_instance(constructor_type->base_type, - ir->type->vector_elements, - ir->type->matrix_columns); - ir_rvalue *result = convert_component(ir, desired_type); - - /* Attempt to convert the parameter to a constant valued expression. - * After doing so, track whether or not all the parameters to the - * constructor are trivially constant valued expressions. - */ - ir_rvalue *const constant = result->constant_expression_value(); - - if (constant != NULL) - result = constant; - else - all_parameters_are_constant = false; - - if (result != ir) { - ir->replace_with(result); - } - } - - /* If all of the parameters are trivially constant, create a - * constant representing the complete collection of parameters. - */ - if (all_parameters_are_constant) { - return new(ctx) ir_constant(constructor_type, &actual_parameters); - } else if (constructor_type->is_scalar()) { - return dereference_component((ir_rvalue *) actual_parameters.head, - 0); - } else if (constructor_type->is_vector()) { - return emit_inline_vector_constructor(constructor_type, - instructions, - &actual_parameters, - ctx); - } else { - assert(constructor_type->is_matrix()); - return emit_inline_matrix_constructor(constructor_type, - instructions, - &actual_parameters, - ctx); - } - } else { - const ast_expression *id = subexpressions[0]; - YYLTYPE loc = id->get_location(); - exec_list actual_parameters; - - process_parameters(instructions, &actual_parameters, &this->expressions, - state); - - const glsl_type *const type = - state->symbols->get_type(id->primary_expression.identifier); - - if ((type != NULL) && type->is_record()) { - exec_node *node = actual_parameters.head; - for (unsigned i = 0; i < type->length; i++) { - ir_rvalue *ir = (ir_rvalue *) node; - - if (node->is_tail_sentinel()) { - _mesa_glsl_error(&loc, state, - "insufficient parameters to constructor " - "for `%s'", - type->name); - return ir_call::get_error_instruction(ctx); - } - - if (apply_implicit_conversion(type->fields.structure[i].type, ir, - state)) { - node->replace_with(ir); - } else { - _mesa_glsl_error(&loc, state, - "parameter type mismatch in constructor " - "for `%s.%s' (%s vs %s)", - type->name, - type->fields.structure[i].name, - ir->type->name, - type->fields.structure[i].type->name); - return ir_call::get_error_instruction(ctx);; - } - - node = node->next; - } - - if (!node->is_tail_sentinel()) { - _mesa_glsl_error(&loc, state, "too many parameters in constructor " - "for `%s'", type->name); - return ir_call::get_error_instruction(ctx); - } - - ir_rvalue *const constant = - constant_record_constructor(type, &actual_parameters, state); - - return (constant != NULL) - ? constant - : emit_inline_record_constructor(type, instructions, - &actual_parameters, state); - } - - return match_function_by_name(instructions, - id->primary_expression.identifier, & loc, - &actual_parameters, state); - } - - return ir_call::get_error_instruction(ctx); -} +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "glsl_symbol_table.h" +#include "ast.h" +#include "glsl_types.h" +#include "ir.h" +#include "main/core.h" /* for MIN2 */ + +static ir_rvalue * +convert_component(ir_rvalue *src, const glsl_type *desired_type); + +bool +apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, + struct _mesa_glsl_parse_state *state); + +static unsigned +process_parameters(exec_list *instructions, exec_list *actual_parameters, + exec_list *parameters, + struct _mesa_glsl_parse_state *state) +{ + unsigned count = 0; + + foreach_list (n, parameters) { + ast_node *const ast = exec_node_data(ast_node, n, link); + ir_rvalue *result = ast->hir(instructions, state); + + ir_constant *const constant = result->constant_expression_value(); + if (constant != NULL) + result = constant; + + actual_parameters->push_tail(result); + count++; + } + + return count; +} + + +/** + * Generate a source prototype for a function signature + * + * \param return_type Return type of the function. May be \c NULL. + * \param name Name of the function. + * \param parameters Parameter list for the function. This may be either a + * formal or actual parameter list. Only the type is used. + * + * \return + * A ralloced string representing the prototype of the function. + */ +char * +prototype_string(const glsl_type *return_type, const char *name, + exec_list *parameters) +{ + char *str = NULL; + + if (return_type != NULL) + str = ralloc_asprintf(NULL, "%s ", return_type->name); + + ralloc_asprintf_append(&str, "%s(", name); + + const char *comma = ""; + foreach_list(node, parameters) { + const ir_instruction *const param = (ir_instruction *) node; + + ralloc_asprintf_append(&str, "%s%s", comma, param->type->name); + comma = ", "; + } + + ralloc_strcat(&str, ")"); + return str; +} + + +static ir_rvalue * +match_function_by_name(exec_list *instructions, const char *name, + YYLTYPE *loc, exec_list *actual_parameters, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = state; + ir_function *f = state->symbols->get_function(name); + ir_function_signature *sig; + + sig = f ? f->matching_signature(actual_parameters) : NULL; + + /* FINISHME: This doesn't handle the case where shader X contains a + * FINISHME: matching signature but shader X + N contains an _exact_ + * FINISHME: matching signature. + */ + if (sig == NULL && (f == NULL || state->es_shader || !f->has_user_signature()) && state->symbols->get_type(name) == NULL && (state->language_version == 110 || state->symbols->get_variable(name) == NULL)) { + /* The current shader doesn't contain a matching function or signature. + * Before giving up, look for the prototype in the built-in functions. + */ + for (unsigned i = 0; i < state->num_builtins_to_link; i++) { + ir_function *builtin; + builtin = state->builtins_to_link[i]->symbols->get_function(name); + sig = builtin ? builtin->matching_signature(actual_parameters) : NULL; + if (sig != NULL) { + if (f == NULL) { + f = new(ctx) ir_function(name); + state->symbols->add_global_function(f); + emit_function(state, instructions, f); + } + + f->add_signature(sig->clone_prototype(f, NULL)); + break; + } + } + } + + if (sig != NULL) { + /* Verify that 'out' and 'inout' actual parameters are lvalues. This + * isn't done in ir_function::matching_signature because that function + * cannot generate the necessary diagnostics. + * + * Also, validate that 'const_in' formal parameters (an extension of our + * IR) correspond to ir_constant actual parameters. + */ + exec_list_iterator actual_iter = actual_parameters->iterator(); + exec_list_iterator formal_iter = sig->parameters.iterator(); + + while (actual_iter.has_next()) { + ir_rvalue *actual = (ir_rvalue *) actual_iter.get(); + ir_variable *formal = (ir_variable *) formal_iter.get(); + + assert(actual != NULL); + assert(formal != NULL); + + if (formal->mode == ir_var_const_in && !actual->as_constant()) { + _mesa_glsl_error(loc, state, + "parameter `%s' must be a constant expression", + formal->name); + } + + if ((formal->mode == ir_var_out) + || (formal->mode == ir_var_inout)) { + const char *mode = NULL; + switch (formal->mode) { + case ir_var_out: mode = "out"; break; + case ir_var_inout: mode = "inout"; break; + default: assert(false); break; + } + /* FIXME: 'loc' is incorrect (as of 2011-01-21). It is always + * FIXME: 0:0(0). + */ + if (actual->variable_referenced() + && actual->variable_referenced()->read_only) { + _mesa_glsl_error(loc, state, + "function parameter '%s %s' references the " + "read-only variable '%s'", + mode, formal->name, + actual->variable_referenced()->name); + + } else if (!actual->is_lvalue()) { + _mesa_glsl_error(loc, state, + "function parameter '%s %s' is not an lvalue", + mode, formal->name); + } + } + + if (formal->type->is_numeric() || formal->type->is_boolean()) { + ir_rvalue *converted = convert_component(actual, formal->type); + actual->replace_with(converted); + } + + actual_iter.next(); + formal_iter.next(); + } + + /* Always insert the call in the instruction stream, and return a deref + * of its return val if it returns a value, since we don't know if + * the rvalue is going to be assigned to anything or not. + */ + ir_call *call = new(ctx) ir_call(sig, actual_parameters); + if (!sig->return_type->is_void()) { + ir_variable *var; + ir_dereference_variable *deref; + + var = new(ctx) ir_variable(sig->return_type, + ralloc_asprintf(ctx, "%s_retval", + sig->function_name()), + ir_var_temporary); + instructions->push_tail(var); + + deref = new(ctx) ir_dereference_variable(var); + ir_assignment *assign = new(ctx) ir_assignment(deref, call, NULL); + instructions->push_tail(assign); + if (state->language_version >= 120) + var->constant_value = call->constant_expression_value(); + + deref = new(ctx) ir_dereference_variable(var); + return deref; + } else { + instructions->push_tail(call); + return NULL; + } + } else { + char *str = prototype_string(NULL, name, actual_parameters); + + _mesa_glsl_error(loc, state, "no matching function for call to `%s'", + str); + ralloc_free(str); + + const char *prefix = "candidates are: "; + + for (int i = -1; i < (int) state->num_builtins_to_link; i++) { + glsl_symbol_table *syms = i >= 0 ? state->builtins_to_link[i]->symbols + : state->symbols; + f = syms->get_function(name); + if (f == NULL) + continue; + + foreach_list (node, &f->signatures) { + ir_function_signature *sig = (ir_function_signature *) node; + + str = prototype_string(sig->return_type, f->name, &sig->parameters); + _mesa_glsl_error(loc, state, "%s%s\n", prefix, str); + ralloc_free(str); + + prefix = " "; + } + + } + + return ir_call::get_error_instruction(ctx); + } +} + + +/** + * Perform automatic type conversion of constructor parameters + * + * This implements the rules in the "Conversion and Scalar Constructors" + * section (GLSL 1.10 section 5.4.1), not the "Implicit Conversions" rules. + */ +static ir_rvalue * +convert_component(ir_rvalue *src, const glsl_type *desired_type) +{ + void *ctx = ralloc_parent(src); + const unsigned a = desired_type->base_type; + const unsigned b = src->type->base_type; + ir_expression *result = NULL; + + if (src->type->is_error()) + return src; + + assert(a <= GLSL_TYPE_BOOL); + assert(b <= GLSL_TYPE_BOOL); + + if ((a == b) || (src->type->is_integer() && desired_type->is_integer())) + return src; + + switch (a) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + if (b == GLSL_TYPE_FLOAT) + result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL); + else { + assert(b == GLSL_TYPE_BOOL); + result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL); + } + break; + case GLSL_TYPE_FLOAT: + switch (b) { + case GLSL_TYPE_UINT: + result = new(ctx) ir_expression(ir_unop_u2f, desired_type, src, NULL); + break; + case GLSL_TYPE_INT: + result = new(ctx) ir_expression(ir_unop_i2f, desired_type, src, NULL); + break; + case GLSL_TYPE_BOOL: + result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL); + break; + } + break; + case GLSL_TYPE_BOOL: + switch (b) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL); + break; + case GLSL_TYPE_FLOAT: + result = new(ctx) ir_expression(ir_unop_f2b, desired_type, src, NULL); + break; + } + break; + } + + assert(result != NULL); + + /* Try constant folding; it may fold in the conversion we just added. */ + ir_constant *const constant = result->constant_expression_value(); + return (constant != NULL) ? (ir_rvalue *) constant : (ir_rvalue *) result; +} + +/** + * Dereference a specific component from a scalar, vector, or matrix + */ +static ir_rvalue * +dereference_component(ir_rvalue *src, unsigned component) +{ + void *ctx = ralloc_parent(src); + assert(component < src->type->components()); + + /* If the source is a constant, just create a new constant instead of a + * dereference of the existing constant. + */ + ir_constant *constant = src->as_constant(); + if (constant) + return new(ctx) ir_constant(constant, component); + + if (src->type->is_scalar()) { + return src; + } else if (src->type->is_vector()) { + return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1); + } else { + assert(src->type->is_matrix()); + + /* Dereference a row of the matrix, then call this function again to get + * a specific element from that row. + */ + const int c = component / src->type->column_type()->vector_elements; + const int r = component % src->type->column_type()->vector_elements; + ir_constant *const col_index = new(ctx) ir_constant(c); + ir_dereference *const col = new(ctx) ir_dereference_array(src, col_index); + + col->type = src->type->column_type(); + + return dereference_component(col, r); + } + + assert(!"Should not get here."); + return NULL; +} + + +static ir_rvalue * +process_array_constructor(exec_list *instructions, + const glsl_type *constructor_type, + YYLTYPE *loc, exec_list *parameters, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = state; + /* Array constructors come in two forms: sized and unsized. Sized array + * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4 + * variables. In this case the number of parameters must exactly match the + * specified size of the array. + * + * Unsized array constructors look like 'vec4[](a, b)', where 'a' and 'b' + * are vec4 variables. In this case the size of the array being constructed + * is determined by the number of parameters. + * + * From page 52 (page 58 of the PDF) of the GLSL 1.50 spec: + * + * "There must be exactly the same number of arguments as the size of + * the array being constructed. If no size is present in the + * constructor, then the array is explicitly sized to the number of + * arguments provided. The arguments are assigned in order, starting at + * element 0, to the elements of the constructed array. Each argument + * must be the same type as the element type of the array, or be a type + * that can be converted to the element type of the array according to + * Section 4.1.10 "Implicit Conversions."" + */ + exec_list actual_parameters; + const unsigned parameter_count = + process_parameters(instructions, &actual_parameters, parameters, state); + + if ((parameter_count == 0) + || ((constructor_type->length != 0) + && (constructor_type->length != parameter_count))) { + const unsigned min_param = (constructor_type->length == 0) + ? 1 : constructor_type->length; + + _mesa_glsl_error(loc, state, "array constructor must have %s %u " + "parameter%s", + (constructor_type->length != 0) ? "at least" : "exactly", + min_param, (min_param <= 1) ? "" : "s"); + return ir_call::get_error_instruction(ctx); + } + + if (constructor_type->length == 0) { + constructor_type = + glsl_type::get_array_instance(constructor_type->element_type(), + parameter_count); + assert(constructor_type != NULL); + assert(constructor_type->length == parameter_count); + } + + bool all_parameters_are_constant = true; + + /* Type cast each parameter and, if possible, fold constants. */ + foreach_list_safe(n, &actual_parameters) { + ir_rvalue *ir = (ir_rvalue *) n; + ir_rvalue *result = ir; + + /* Apply implicit conversions (not the scalar constructor rules!) */ + if (constructor_type->element_type()->is_float()) { + const glsl_type *desired_type = + glsl_type::get_instance(GLSL_TYPE_FLOAT, + ir->type->vector_elements, + ir->type->matrix_columns); + result = convert_component(ir, desired_type); + } + + if (result->type != constructor_type->element_type()) { + _mesa_glsl_error(loc, state, "type error in array constructor: " + "expected: %s, found %s", + constructor_type->element_type()->name, + result->type->name); + } + + /* Attempt to convert the parameter to a constant valued expression. + * After doing so, track whether or not all the parameters to the + * constructor are trivially constant valued expressions. + */ + ir_rvalue *const constant = result->constant_expression_value(); + + if (constant != NULL) + result = constant; + else + all_parameters_are_constant = false; + + ir->replace_with(result); + } + + if (all_parameters_are_constant) + return new(ctx) ir_constant(constructor_type, &actual_parameters); + + ir_variable *var = new(ctx) ir_variable(constructor_type, "array_ctor", + ir_var_temporary); + instructions->push_tail(var); + + int i = 0; + foreach_list(node, &actual_parameters) { + ir_rvalue *rhs = (ir_rvalue *) node; + ir_rvalue *lhs = new(ctx) ir_dereference_array(var, + new(ctx) ir_constant(i)); + + ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs, NULL); + instructions->push_tail(assignment); + + i++; + } + + return new(ctx) ir_dereference_variable(var); +} + + +/** + * Try to convert a record constructor to a constant expression + */ +static ir_constant * +constant_record_constructor(const glsl_type *constructor_type, + exec_list *parameters, void *mem_ctx) +{ + foreach_list(node, parameters) { + ir_constant *constant = ((ir_instruction *) node)->as_constant(); + if (constant == NULL) + return NULL; + node->replace_with(constant); + } + + return new(mem_ctx) ir_constant(constructor_type, parameters); +} + + +/** + * Determine if a list consists of a single scalar r-value + */ +bool +single_scalar_parameter(exec_list *parameters) +{ + const ir_rvalue *const p = (ir_rvalue *) parameters->head; + assert(((ir_rvalue *)p)->as_rvalue() != NULL); + + return (p->type->is_scalar() && p->next->is_tail_sentinel()); +} + + +/** + * Generate inline code for a vector constructor + * + * The generated constructor code will consist of a temporary variable + * declaration of the same type as the constructor. A sequence of assignments + * from constructor parameters to the temporary will follow. + * + * \return + * An \c ir_dereference_variable of the temprorary generated in the constructor + * body. + */ +ir_rvalue * +emit_inline_vector_constructor(const glsl_type *type, + exec_list *instructions, + exec_list *parameters, + void *ctx) +{ + assert(!parameters->is_empty()); + + ir_variable *var = new(ctx) ir_variable(type, "vec_ctor", ir_var_temporary); + instructions->push_tail(var); + + /* There are two kinds of vector constructors. + * + * - Construct a vector from a single scalar by replicating that scalar to + * all components of the vector. + * + * - Construct a vector from an arbirary combination of vectors and + * scalars. The components of the constructor parameters are assigned + * to the vector in order until the vector is full. + */ + const unsigned lhs_components = type->components(); + if (single_scalar_parameter(parameters)) { + ir_rvalue *first_param = (ir_rvalue *)parameters->head; + ir_rvalue *rhs = new(ctx) ir_swizzle(first_param, 0, 0, 0, 0, + lhs_components); + ir_dereference_variable *lhs = new(ctx) ir_dereference_variable(var); + const unsigned mask = (1U << lhs_components) - 1; + + assert(rhs->type == lhs->type); + + ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL, mask); + instructions->push_tail(inst); + } else { + unsigned base_component = 0; + unsigned base_lhs_component = 0; + ir_constant_data data; + unsigned constant_mask = 0, constant_components = 0; + + memset(&data, 0, sizeof(data)); + + foreach_list(node, parameters) { + ir_rvalue *param = (ir_rvalue *) node; + unsigned rhs_components = param->type->components(); + + /* Do not try to assign more components to the vector than it has! + */ + if ((rhs_components + base_lhs_component) > lhs_components) { + rhs_components = lhs_components - base_lhs_component; + } + + const ir_constant *const c = param->as_constant(); + if (c != NULL) { + for (unsigned i = 0; i < rhs_components; i++) { + switch (c->type->base_type) { + case GLSL_TYPE_UINT: + data.u[i + base_component] = c->get_uint_component(i); + break; + case GLSL_TYPE_INT: + data.i[i + base_component] = c->get_int_component(i); + break; + case GLSL_TYPE_FLOAT: + data.f[i + base_component] = c->get_float_component(i); + break; + case GLSL_TYPE_BOOL: + data.b[i + base_component] = c->get_bool_component(i); + break; + default: + assert(!"Should not get here."); + break; + } + } + + /* Mask of fields to be written in the assignment. + */ + constant_mask |= ((1U << rhs_components) - 1) << base_lhs_component; + constant_components += rhs_components; + + base_component += rhs_components; + } + /* Advance the component index by the number of components + * that were just assigned. + */ + base_lhs_component += rhs_components; + } + + if (constant_mask != 0) { + ir_dereference *lhs = new(ctx) ir_dereference_variable(var); + const glsl_type *rhs_type = glsl_type::get_instance(var->type->base_type, + constant_components, + 1); + ir_rvalue *rhs = new(ctx) ir_constant(rhs_type, &data); + + ir_instruction *inst = + new(ctx) ir_assignment(lhs, rhs, NULL, constant_mask); + instructions->push_tail(inst); + } + + base_component = 0; + foreach_list(node, parameters) { + ir_rvalue *param = (ir_rvalue *) node; + unsigned rhs_components = param->type->components(); + + /* Do not try to assign more components to the vector than it has! + */ + if ((rhs_components + base_component) > lhs_components) { + rhs_components = lhs_components - base_component; + } + + const ir_constant *const c = param->as_constant(); + if (c == NULL) { + /* Mask of fields to be written in the assignment. + */ + const unsigned write_mask = ((1U << rhs_components) - 1) + << base_component; + + ir_dereference *lhs = new(ctx) ir_dereference_variable(var); + + /* Generate a swizzle so that LHS and RHS sizes match. + */ + ir_rvalue *rhs = + new(ctx) ir_swizzle(param, 0, 1, 2, 3, rhs_components); + + ir_instruction *inst = + new(ctx) ir_assignment(lhs, rhs, NULL, write_mask); + instructions->push_tail(inst); + } + + /* Advance the component index by the number of components that were + * just assigned. + */ + base_component += rhs_components; + } + } + return new(ctx) ir_dereference_variable(var); +} + + +/** + * Generate assignment of a portion of a vector to a portion of a matrix column + * + * \param src_base First component of the source to be used in assignment + * \param column Column of destination to be assiged + * \param row_base First component of the destination column to be assigned + * \param count Number of components to be assigned + * + * \note + * \c src_base + \c count must be less than or equal to the number of components + * in the source vector. + */ +ir_instruction * +assign_to_matrix_column(ir_variable *var, unsigned column, unsigned row_base, + ir_rvalue *src, unsigned src_base, unsigned count, + void *mem_ctx) +{ + ir_constant *col_idx = new(mem_ctx) ir_constant(column); + ir_dereference *column_ref = new(mem_ctx) ir_dereference_array(var, col_idx); + + assert(column_ref->type->components() >= (row_base + count)); + assert(src->type->components() >= (src_base + count)); + + /* Generate a swizzle that extracts the number of components from the source + * that are to be assigned to the column of the matrix. + */ + if (count < src->type->vector_elements) { + src = new(mem_ctx) ir_swizzle(src, + src_base + 0, src_base + 1, + src_base + 2, src_base + 3, + count); + } + + /* Mask of fields to be written in the assignment. + */ + const unsigned write_mask = ((1U << count) - 1) << row_base; + + return new(mem_ctx) ir_assignment(column_ref, src, NULL, write_mask); +} + + +/** + * Generate inline code for a matrix constructor + * + * The generated constructor code will consist of a temporary variable + * declaration of the same type as the constructor. A sequence of assignments + * from constructor parameters to the temporary will follow. + * + * \return + * An \c ir_dereference_variable of the temprorary generated in the constructor + * body. + */ +ir_rvalue * +emit_inline_matrix_constructor(const glsl_type *type, + exec_list *instructions, + exec_list *parameters, + void *ctx) +{ + assert(!parameters->is_empty()); + + ir_variable *var = new(ctx) ir_variable(type, "mat_ctor", ir_var_temporary); + instructions->push_tail(var); + + /* There are three kinds of matrix constructors. + * + * - Construct a matrix from a single scalar by replicating that scalar to + * along the diagonal of the matrix and setting all other components to + * zero. + * + * - Construct a matrix from an arbirary combination of vectors and + * scalars. The components of the constructor parameters are assigned + * to the matrix in colum-major order until the matrix is full. + * + * - Construct a matrix from a single matrix. The source matrix is copied + * to the upper left portion of the constructed matrix, and the remaining + * elements take values from the identity matrix. + */ + ir_rvalue *const first_param = (ir_rvalue *) parameters->head; + if (single_scalar_parameter(parameters)) { + /* Assign the scalar to the X component of a vec4, and fill the remaining + * components with zero. + */ + ir_variable *rhs_var = + new(ctx) ir_variable(glsl_type::vec4_type, "mat_ctor_vec", + ir_var_temporary); + instructions->push_tail(rhs_var); + + ir_constant_data zero; + zero.f[0] = 0.0; + zero.f[1] = 0.0; + zero.f[2] = 0.0; + zero.f[3] = 0.0; + + ir_instruction *inst = + new(ctx) ir_assignment(new(ctx) ir_dereference_variable(rhs_var), + new(ctx) ir_constant(rhs_var->type, &zero), + NULL); + instructions->push_tail(inst); + + ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); + + inst = new(ctx) ir_assignment(rhs_ref, first_param, NULL, 0x01); + instructions->push_tail(inst); + + /* Assign the temporary vector to each column of the destination matrix + * with a swizzle that puts the X component on the diagonal of the + * matrix. In some cases this may mean that the X component does not + * get assigned into the column at all (i.e., when the matrix has more + * columns than rows). + */ + static const unsigned rhs_swiz[4][4] = { + { 0, 1, 1, 1 }, + { 1, 0, 1, 1 }, + { 1, 1, 0, 1 }, + { 1, 1, 1, 0 } + }; + + const unsigned cols_to_init = MIN2(type->matrix_columns, + type->vector_elements); + for (unsigned i = 0; i < cols_to_init; i++) { + ir_constant *const col_idx = new(ctx) ir_constant(i); + ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx); + + ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); + ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, rhs_swiz[i], + type->vector_elements); + + inst = new(ctx) ir_assignment(col_ref, rhs, NULL); + instructions->push_tail(inst); + } + + for (unsigned i = cols_to_init; i < type->matrix_columns; i++) { + ir_constant *const col_idx = new(ctx) ir_constant(i); + ir_rvalue *const col_ref = new(ctx) ir_dereference_array(var, col_idx); + + ir_rvalue *const rhs_ref = new(ctx) ir_dereference_variable(rhs_var); + ir_rvalue *const rhs = new(ctx) ir_swizzle(rhs_ref, 1, 1, 1, 1, + type->vector_elements); + + inst = new(ctx) ir_assignment(col_ref, rhs, NULL); + instructions->push_tail(inst); + } + } else if (first_param->type->is_matrix()) { + /* From page 50 (56 of the PDF) of the GLSL 1.50 spec: + * + * "If a matrix is constructed from a matrix, then each component + * (column i, row j) in the result that has a corresponding + * component (column i, row j) in the argument will be initialized + * from there. All other components will be initialized to the + * identity matrix. If a matrix argument is given to a matrix + * constructor, it is an error to have any other arguments." + */ + assert(first_param->next->is_tail_sentinel()); + ir_rvalue *const src_matrix = first_param; + + /* If the source matrix is smaller, pre-initialize the relavent parts of + * the destination matrix to the identity matrix. + */ + if ((src_matrix->type->matrix_columns < var->type->matrix_columns) + || (src_matrix->type->vector_elements < var->type->vector_elements)) { + + /* If the source matrix has fewer rows, every column of the destination + * must be initialized. Otherwise only the columns in the destination + * that do not exist in the source must be initialized. + */ + unsigned col = + (src_matrix->type->vector_elements < var->type->vector_elements) + ? 0 : src_matrix->type->matrix_columns; + + const glsl_type *const col_type = var->type->column_type(); + for (/* empty */; col < var->type->matrix_columns; col++) { + ir_constant_data ident; + + ident.f[0] = 0.0; + ident.f[1] = 0.0; + ident.f[2] = 0.0; + ident.f[3] = 0.0; + + ident.f[col] = 1.0; + + ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident); + + ir_rvalue *const lhs = + new(ctx) ir_dereference_array(var, new(ctx) ir_constant(col)); + + ir_instruction *inst = new(ctx) ir_assignment(lhs, rhs, NULL); + instructions->push_tail(inst); + } + } + + /* Assign columns from the source matrix to the destination matrix. + * + * Since the parameter will be used in the RHS of multiple assignments, + * generate a temporary and copy the paramter there. + */ + ir_variable *const rhs_var = + new(ctx) ir_variable(first_param->type, "mat_ctor_mat", + ir_var_temporary); + instructions->push_tail(rhs_var); + + ir_dereference *const rhs_var_ref = + new(ctx) ir_dereference_variable(rhs_var); + ir_instruction *const inst = + new(ctx) ir_assignment(rhs_var_ref, first_param, NULL); + instructions->push_tail(inst); + + const unsigned last_row = MIN2(src_matrix->type->vector_elements, + var->type->vector_elements); + const unsigned last_col = MIN2(src_matrix->type->matrix_columns, + var->type->matrix_columns); + + unsigned swiz[4] = { 0, 0, 0, 0 }; + for (unsigned i = 1; i < last_row; i++) + swiz[i] = i; + + const unsigned write_mask = (1U << last_row) - 1; + + for (unsigned i = 0; i < last_col; i++) { + ir_dereference *const lhs = + new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i)); + ir_rvalue *const rhs_col = + new(ctx) ir_dereference_array(rhs_var, new(ctx) ir_constant(i)); + + /* If one matrix has columns that are smaller than the columns of the + * other matrix, wrap the column access of the larger with a swizzle + * so that the LHS and RHS of the assignment have the same size (and + * therefore have the same type). + * + * It would be perfectly valid to unconditionally generate the + * swizzles, this this will typically result in a more compact IR tree. + */ + ir_rvalue *rhs; + if (lhs->type->vector_elements != rhs_col->type->vector_elements) { + rhs = new(ctx) ir_swizzle(rhs_col, swiz, last_row); + } else { + rhs = rhs_col; + } + + ir_instruction *inst = + new(ctx) ir_assignment(lhs, rhs, NULL, write_mask); + instructions->push_tail(inst); + } + } else { + const unsigned cols = type->matrix_columns; + const unsigned rows = type->vector_elements; + unsigned col_idx = 0; + unsigned row_idx = 0; + + foreach_list (node, parameters) { + ir_rvalue *const rhs = (ir_rvalue *) node; + const unsigned components_remaining_this_column = rows - row_idx; + unsigned rhs_components = rhs->type->components(); + unsigned rhs_base = 0; + + /* Since the parameter might be used in the RHS of two assignments, + * generate a temporary and copy the paramter there. + */ + ir_variable *rhs_var = + new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary); + instructions->push_tail(rhs_var); + + ir_dereference *rhs_var_ref = + new(ctx) ir_dereference_variable(rhs_var); + ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs, NULL); + instructions->push_tail(inst); + + /* Assign the current parameter to as many components of the matrix + * as it will fill. + * + * NOTE: A single vector parameter can span two matrix columns. A + * single vec4, for example, can completely fill a mat2. + */ + if (rhs_components >= components_remaining_this_column) { + const unsigned count = MIN2(rhs_components, + components_remaining_this_column); + + rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var); + + ir_instruction *inst = assign_to_matrix_column(var, col_idx, + row_idx, + rhs_var_ref, 0, + count, ctx); + instructions->push_tail(inst); + + rhs_base = count; + + col_idx++; + row_idx = 0; + } + + /* If there is data left in the parameter and components left to be + * set in the destination, emit another assignment. It is possible + * that the assignment could be of a vec4 to the last element of the + * matrix. In this case col_idx==cols, but there is still data + * left in the source parameter. Obviously, don't emit an assignment + * to data outside the destination matrix. + */ + if ((col_idx < cols) && (rhs_base < rhs_components)) { + const unsigned count = rhs_components - rhs_base; + + rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var); + + ir_instruction *inst = assign_to_matrix_column(var, col_idx, + row_idx, + rhs_var_ref, + rhs_base, + count, ctx); + instructions->push_tail(inst); + + row_idx += count; + } + } + } + + return new(ctx) ir_dereference_variable(var); +} + + +ir_rvalue * +emit_inline_record_constructor(const glsl_type *type, + exec_list *instructions, + exec_list *parameters, + void *mem_ctx) +{ + ir_variable *const var = + new(mem_ctx) ir_variable(type, "record_ctor", ir_var_temporary); + ir_dereference_variable *const d = new(mem_ctx) ir_dereference_variable(var); + + instructions->push_tail(var); + + exec_node *node = parameters->head; + for (unsigned i = 0; i < type->length; i++) { + assert(!node->is_tail_sentinel()); + + ir_dereference *const lhs = + new(mem_ctx) ir_dereference_record(d->clone(mem_ctx, NULL), + type->fields.structure[i].name); + + ir_rvalue *const rhs = ((ir_instruction *) node)->as_rvalue(); + assert(rhs != NULL); + + ir_instruction *const assign = new(mem_ctx) ir_assignment(lhs, rhs, NULL); + + instructions->push_tail(assign); + node = node->next; + } + + return d; +} + + +ir_rvalue * +ast_function_expression::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = state; + /* There are three sorts of function calls. + * + * 1. constructors - The first subexpression is an ast_type_specifier. + * 2. methods - Only the .length() method of array types. + * 3. functions - Calls to regular old functions. + * + * Method calls are actually detected when the ast_field_selection + * expression is handled. + */ + if (is_constructor()) { + const ast_type_specifier *type = (ast_type_specifier *) subexpressions[0]; + YYLTYPE loc = type->get_location(); + const char *name; + + const glsl_type *const constructor_type = type->glsl_type(& name, state); + + /* constructor_type can be NULL if a variable with the same name as the + * structure has come into scope. + */ + if (constructor_type == NULL) { + _mesa_glsl_error(& loc, state, "unknown type `%s' (structure name " + "may be shadowed by a variable with the same name)", + type->type_name); + return ir_call::get_error_instruction(ctx); + } + + + /* Constructors for samplers are illegal. + */ + if (constructor_type->is_sampler()) { + _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'", + constructor_type->name); + return ir_call::get_error_instruction(ctx); + } + + if (constructor_type->is_array()) { + if (state->language_version <= 110) { + _mesa_glsl_error(& loc, state, + "array constructors forbidden in GLSL 1.10"); + return ir_call::get_error_instruction(ctx); + } + + return process_array_constructor(instructions, constructor_type, + & loc, &this->expressions, state); + } + + + /* There are two kinds of constructor call. Constructors for built-in + * language types, such as mat4 and vec2, are free form. The only + * requirement is that the parameters must provide enough values of the + * correct scalar type. Constructors for arrays and structures must + * have the exact number of parameters with matching types in the + * correct order. These constructors follow essentially the same type + * matching rules as functions. + */ + if (constructor_type->is_record()) { + exec_list actual_parameters; + + process_parameters(instructions, &actual_parameters, + &this->expressions, state); + + exec_node *node = actual_parameters.head; + for (unsigned i = 0; i < constructor_type->length; i++) { + ir_rvalue *ir = (ir_rvalue *) node; + + if (node->is_tail_sentinel()) { + _mesa_glsl_error(&loc, state, + "insufficient parameters to constructor " + "for `%s'", + constructor_type->name); + return ir_call::get_error_instruction(ctx); + } + + if (apply_implicit_conversion(constructor_type->fields.structure[i].type, + ir, state)) { + node->replace_with(ir); + } else { + _mesa_glsl_error(&loc, state, + "parameter type mismatch in constructor " + "for `%s.%s' (%s vs %s)", + constructor_type->name, + constructor_type->fields.structure[i].name, + ir->type->name, + constructor_type->fields.structure[i].type->name); + return ir_call::get_error_instruction(ctx);; + } + + node = node->next; + } + + if (!node->is_tail_sentinel()) { + _mesa_glsl_error(&loc, state, "too many parameters in constructor " + "for `%s'", constructor_type->name); + return ir_call::get_error_instruction(ctx); + } + + ir_rvalue *const constant = + constant_record_constructor(constructor_type, &actual_parameters, + state); + + return (constant != NULL) + ? constant + : emit_inline_record_constructor(constructor_type, instructions, + &actual_parameters, state); + } + + if (!constructor_type->is_numeric() && !constructor_type->is_boolean()) + return ir_call::get_error_instruction(ctx); + + /* Total number of components of the type being constructed. */ + const unsigned type_components = constructor_type->components(); + + /* Number of components from parameters that have actually been + * consumed. This is used to perform several kinds of error checking. + */ + unsigned components_used = 0; + + unsigned matrix_parameters = 0; + unsigned nonmatrix_parameters = 0; + exec_list actual_parameters; + + foreach_list (n, &this->expressions) { + ast_node *ast = exec_node_data(ast_node, n, link); + ir_rvalue *result = ast->hir(instructions, state)->as_rvalue(); + + /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: + * + * "It is an error to provide extra arguments beyond this + * last used argument." + */ + if (components_used >= type_components) { + _mesa_glsl_error(& loc, state, "too many parameters to `%s' " + "constructor", + constructor_type->name); + return ir_call::get_error_instruction(ctx); + } + + if (!result->type->is_numeric() && !result->type->is_boolean()) { + _mesa_glsl_error(& loc, state, "cannot construct `%s' from a " + "non-numeric data type", + constructor_type->name); + return ir_call::get_error_instruction(ctx); + } + + /* Count the number of matrix and nonmatrix parameters. This + * is used below to enforce some of the constructor rules. + */ + if (result->type->is_matrix()) + matrix_parameters++; + else + nonmatrix_parameters++; + + actual_parameters.push_tail(result); + components_used += result->type->components(); + } + + /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec: + * + * "It is an error to construct matrices from other matrices. This + * is reserved for future use." + */ + if (state->language_version == 110 && matrix_parameters > 0 + && constructor_type->is_matrix()) { + _mesa_glsl_error(& loc, state, "cannot construct `%s' from a " + "matrix in GLSL 1.10", + constructor_type->name); + return ir_call::get_error_instruction(ctx); + } + + /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: + * + * "If a matrix argument is given to a matrix constructor, it is + * an error to have any other arguments." + */ + if ((matrix_parameters > 0) + && ((matrix_parameters + nonmatrix_parameters) > 1) + && constructor_type->is_matrix()) { + _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, " + "matrix must be only parameter", + constructor_type->name); + return ir_call::get_error_instruction(ctx); + } + + /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec: + * + * "In these cases, there must be enough components provided in the + * arguments to provide an initializer for every component in the + * constructed value." + */ + if (components_used < type_components && components_used != 1 + && matrix_parameters == 0) { + _mesa_glsl_error(& loc, state, "too few components to construct " + "`%s'", + constructor_type->name); + return ir_call::get_error_instruction(ctx); + } + + /* Later, we cast each parameter to the same base type as the + * constructor. Since there are no non-floating point matrices, we + * need to break them up into a series of column vectors. + */ + if (constructor_type->base_type != GLSL_TYPE_FLOAT) { + foreach_list_safe(n, &actual_parameters) { + ir_rvalue *matrix = (ir_rvalue *) n; + + if (!matrix->type->is_matrix()) + continue; + + /* Create a temporary containing the matrix. */ + ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp", + ir_var_temporary); + instructions->push_tail(var); + instructions->push_tail(new(ctx) ir_assignment(new(ctx) + ir_dereference_variable(var), matrix, NULL)); + var->constant_value = matrix->constant_expression_value(); + + /* Replace the matrix with dereferences of its columns. */ + for (int i = 0; i < matrix->type->matrix_columns; i++) { + matrix->insert_before(new (ctx) ir_dereference_array(var, + new(ctx) ir_constant(i))); + } + matrix->remove(); + } + } + + bool all_parameters_are_constant = true; + + /* Type cast each parameter and, if possible, fold constants.*/ + foreach_list_safe(n, &actual_parameters) { + ir_rvalue *ir = (ir_rvalue *) n; + + const glsl_type *desired_type = + glsl_type::get_instance(constructor_type->base_type, + ir->type->vector_elements, + ir->type->matrix_columns); + ir_rvalue *result = convert_component(ir, desired_type); + + /* Attempt to convert the parameter to a constant valued expression. + * After doing so, track whether or not all the parameters to the + * constructor are trivially constant valued expressions. + */ + ir_rvalue *const constant = result->constant_expression_value(); + + if (constant != NULL) + result = constant; + else + all_parameters_are_constant = false; + + if (result != ir) { + ir->replace_with(result); + } + } + + /* If all of the parameters are trivially constant, create a + * constant representing the complete collection of parameters. + */ + if (all_parameters_are_constant) { + return new(ctx) ir_constant(constructor_type, &actual_parameters); + } else if (constructor_type->is_scalar()) { + return dereference_component((ir_rvalue *) actual_parameters.head, + 0); + } else if (constructor_type->is_vector()) { + return emit_inline_vector_constructor(constructor_type, + instructions, + &actual_parameters, + ctx); + } else { + assert(constructor_type->is_matrix()); + return emit_inline_matrix_constructor(constructor_type, + instructions, + &actual_parameters, + ctx); + } + } else { + const ast_expression *id = subexpressions[0]; + YYLTYPE loc = id->get_location(); + exec_list actual_parameters; + + process_parameters(instructions, &actual_parameters, &this->expressions, + state); + + return match_function_by_name(instructions, + id->primary_expression.identifier, & loc, + &actual_parameters, state); + } + + return ir_call::get_error_instruction(ctx); +} diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.c b/mesalib/src/glsl/glcpp/glcpp-parse.c index 3e51792e9..0be33a645 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.c +++ b/mesalib/src/glsl/glcpp/glcpp-parse.c @@ -1,4209 +1,4222 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.4.1" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* Using locations. */ -#define YYLSP_NEEDED 1 - - - -/* Copy the first part of user declarations. */ - -/* Line 189 of yacc.c */ -#line 1 "glcpp/glcpp-parse.y" - -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include - -#include "glcpp.h" -#include "main/core.h" /* for struct gl_extensions */ -#include "main/mtypes.h" /* for gl_api enum */ - -static void -yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error); - -static void -_define_object_macro (glcpp_parser_t *parser, - YYLTYPE *loc, - const char *macro, - token_list_t *replacements); - -static void -_define_function_macro (glcpp_parser_t *parser, - YYLTYPE *loc, - const char *macro, - string_list_t *parameters, - token_list_t *replacements); - -static string_list_t * -_string_list_create (void *ctx); - -static void -_string_list_append_item (string_list_t *list, const char *str); - -static int -_string_list_contains (string_list_t *list, const char *member, int *index); - -static int -_string_list_length (string_list_t *list); - -static int -_string_list_equal (string_list_t *a, string_list_t *b); - -static argument_list_t * -_argument_list_create (void *ctx); - -static void -_argument_list_append (argument_list_t *list, token_list_t *argument); - -static int -_argument_list_length (argument_list_t *list); - -static token_list_t * -_argument_list_member_at (argument_list_t *list, int index); - -/* Note: This function ralloc_steal()s the str pointer. */ -static token_t * -_token_create_str (void *ctx, int type, char *str); - -static token_t * -_token_create_ival (void *ctx, int type, int ival); - -static token_list_t * -_token_list_create (void *ctx); - -/* Note: This function calls ralloc_steal on token. */ -static void -_token_list_append (token_list_t *list, token_t *token); - -static void -_token_list_append_list (token_list_t *list, token_list_t *tail); - -static int -_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b); - -static active_list_t * -_active_list_push (active_list_t *list, - const char *identifier, - token_node_t *marker); - -static active_list_t * -_active_list_pop (active_list_t *list); - -int -_active_list_contains (active_list_t *list, const char *identifier); - -static void -_glcpp_parser_expand_if (glcpp_parser_t *parser, int type, token_list_t *list); - -static void -_glcpp_parser_expand_token_list (glcpp_parser_t *parser, - token_list_t *list); - -static void -_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, - token_list_t *list); - -static void -_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc, - int condition); - -static void -_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, - const char *type, int condition); - -static void -_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc); - -#define yylex glcpp_parser_lex - -static int -glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser); - -static void -glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list); - -static void -add_builtin_define(glcpp_parser_t *parser, const char *name, int value); - - - -/* Line 189 of yacc.c */ -#line 217 "glcpp/glcpp-parse.c" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - COMMA_FINAL = 258, - DEFINED = 259, - ELIF_EXPANDED = 260, - HASH = 261, - HASH_DEFINE_FUNC = 262, - HASH_DEFINE_OBJ = 263, - HASH_ELIF = 264, - HASH_ELSE = 265, - HASH_ENDIF = 266, - HASH_IF = 267, - HASH_IFDEF = 268, - HASH_IFNDEF = 269, - HASH_UNDEF = 270, - HASH_VERSION = 271, - IDENTIFIER = 272, - IF_EXPANDED = 273, - INTEGER = 274, - INTEGER_STRING = 275, - NEWLINE = 276, - OTHER = 277, - PLACEHOLDER = 278, - SPACE = 279, - PASTE = 280, - OR = 281, - AND = 282, - NOT_EQUAL = 283, - EQUAL = 284, - GREATER_OR_EQUAL = 285, - LESS_OR_EQUAL = 286, - RIGHT_SHIFT = 287, - LEFT_SHIFT = 288, - UNARY = 289 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -/* Copy the second part of user declarations. */ - - -/* Line 264 of yacc.c */ -#line 305 "glcpp/glcpp-parse.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 2 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 606 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 57 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 17 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 101 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 162 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 289 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 47, 2, 2, 2, 43, 30, 2, - 45, 46, 41, 39, 49, 40, 54, 42, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, - 33, 56, 34, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 50, 2, 51, 29, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 52, 28, 53, 48, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 31, 32, 35, 36, 37, 38, 44 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 4, 7, 9, 11, 13, 16, 20, - 24, 29, 36, 44, 48, 52, 55, 60, 65, 69, - 72, 75, 78, 82, 85, 87, 89, 91, 95, 99, - 103, 107, 111, 115, 119, 123, 127, 131, 135, 139, - 143, 147, 151, 155, 159, 163, 166, 169, 172, 175, - 179, 181, 185, 187, 190, 193, 194, 196, 197, 199, - 202, 207, 209, 211, 214, 216, 219, 221, 223, 225, - 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, - 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, - 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, - 287, 289 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 58, 0, -1, -1, 58, 59, -1, 61, -1, 65, - -1, 60, -1, 6, 66, -1, 18, 63, 21, -1, - 5, 63, 21, -1, 8, 17, 67, 21, -1, 7, - 17, 45, 46, 67, 21, -1, 7, 17, 45, 64, - 46, 67, 21, -1, 15, 17, 21, -1, 12, 70, - 21, -1, 12, 21, -1, 13, 17, 68, 21, -1, - 14, 17, 68, 21, -1, 9, 70, 21, -1, 9, - 21, -1, 10, 21, -1, 11, 21, -1, 16, 62, - 21, -1, 6, 21, -1, 20, -1, 19, -1, 62, - -1, 63, 26, 63, -1, 63, 27, 63, -1, 63, - 28, 63, -1, 63, 29, 63, -1, 63, 30, 63, - -1, 63, 31, 63, -1, 63, 32, 63, -1, 63, - 35, 63, -1, 63, 36, 63, -1, 63, 34, 63, - -1, 63, 33, 63, -1, 63, 37, 63, -1, 63, - 38, 63, -1, 63, 40, 63, -1, 63, 39, 63, - -1, 63, 43, 63, -1, 63, 42, 63, -1, 63, - 41, 63, -1, 47, 63, -1, 48, 63, -1, 40, - 63, -1, 39, 63, -1, 45, 63, 46, -1, 17, - -1, 64, 49, 17, -1, 21, -1, 71, 21, -1, - 71, 21, -1, -1, 71, -1, -1, 71, -1, 4, - 17, -1, 4, 45, 17, 46, -1, 72, -1, 69, - -1, 70, 69, -1, 72, -1, 71, 72, -1, 17, - -1, 20, -1, 73, -1, 22, -1, 24, -1, 50, - -1, 51, -1, 45, -1, 46, -1, 52, -1, 53, - -1, 54, -1, 30, -1, 41, -1, 39, -1, 40, - -1, 48, -1, 47, -1, 42, -1, 43, -1, 38, - -1, 37, -1, 33, -1, 34, -1, 36, -1, 35, - -1, 32, -1, 31, -1, 29, -1, 28, -1, 27, - -1, 26, -1, 55, -1, 49, -1, 56, -1, 25, - -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 181, 181, 183, 187, 190, 195, 196, 200, 203, - 209, 212, 215, 218, 226, 245, 255, 260, 265, 284, - 299, 302, 305, 326, 330, 339, 344, 345, 348, 351, - 354, 357, 360, 363, 366, 369, 372, 375, 378, 381, - 384, 387, 390, 393, 401, 404, 407, 410, 413, 416, - 422, 427, 435, 436, 440, 446, 447, 450, 452, 459, - 463, 467, 472, 476, 483, 488, 495, 499, 503, 507, - 511, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, - 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, - 547, 548 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "COMMA_FINAL", "DEFINED", - "ELIF_EXPANDED", "HASH", "HASH_DEFINE_FUNC", "HASH_DEFINE_OBJ", - "HASH_ELIF", "HASH_ELSE", "HASH_ENDIF", "HASH_IF", "HASH_IFDEF", - "HASH_IFNDEF", "HASH_UNDEF", "HASH_VERSION", "IDENTIFIER", "IF_EXPANDED", - "INTEGER", "INTEGER_STRING", "NEWLINE", "OTHER", "PLACEHOLDER", "SPACE", - "PASTE", "OR", "AND", "'|'", "'^'", "'&'", "NOT_EQUAL", "EQUAL", "'<'", - "'>'", "GREATER_OR_EQUAL", "LESS_OR_EQUAL", "RIGHT_SHIFT", "LEFT_SHIFT", - "'+'", "'-'", "'*'", "'/'", "'%'", "UNARY", "'('", "')'", "'!'", "'~'", - "','", "'['", "']'", "'{'", "'}'", "'.'", "';'", "'='", "$accept", - "input", "line", "expanded_line", "control_line", "integer_constant", - "expression", "identifier_list", "text_line", "non_directive", - "replacement_list", "junk", "conditional_token", "conditional_tokens", - "pp_tokens", "preprocessing_token", "operator", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 124, 94, - 38, 283, 284, 60, 62, 285, 286, 287, 288, 43, - 45, 42, 47, 37, 289, 40, 41, 33, 126, 44, - 91, 93, 123, 125, 46, 59, 61 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 57, 58, 58, 59, 59, 59, 59, 60, 60, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 62, 62, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 64, 64, 65, 65, 66, 67, 67, 68, 68, 69, - 69, 69, 70, 70, 71, 71, 72, 72, 72, 72, - 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 0, 2, 1, 1, 1, 2, 3, 3, - 4, 6, 7, 3, 3, 2, 4, 4, 3, 2, - 2, 2, 3, 2, 1, 1, 1, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, - 1, 3, 1, 2, 2, 0, 1, 0, 1, 2, - 4, 1, 1, 2, 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, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 66, 0, 67, 52, 69, - 70, 101, 97, 96, 95, 94, 78, 93, 92, 88, - 89, 91, 90, 87, 86, 80, 81, 79, 84, 85, - 73, 74, 83, 82, 99, 71, 72, 75, 76, 77, - 98, 100, 3, 6, 4, 5, 0, 64, 68, 25, - 24, 0, 0, 0, 0, 0, 26, 0, 23, 7, - 0, 0, 55, 0, 19, 62, 0, 61, 20, 21, - 15, 0, 57, 57, 0, 0, 0, 53, 65, 48, - 47, 0, 45, 46, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 54, 0, 0, 56, 59, 0, 18, - 63, 14, 0, 58, 0, 13, 22, 8, 49, 27, - 28, 29, 30, 31, 32, 33, 37, 36, 34, 35, - 38, 39, 41, 40, 44, 43, 42, 50, 55, 0, - 10, 0, 16, 17, 0, 55, 0, 60, 11, 0, - 51, 12 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 1, 52, 53, 54, 66, 67, 149, 55, 69, - 115, 122, 75, 76, 116, 57, 58 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -147 -static const yytype_int16 yypact[] = -{ - -147, 112, -147, 28, -10, 55, 62, 152, -15, 59, - 192, 85, 86, 87, 51, -147, 28, -147, -147, -147, - -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, - -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, - -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, - -147, -147, -147, -147, -147, -147, 312, -147, -147, -147, - -147, 28, 28, 28, 28, 28, -147, 428, -147, -147, - 352, 63, 392, 17, -147, -147, 232, -147, -147, -147, - -147, 272, 392, 392, 84, 89, 451, -147, -147, -147, - -147, 469, -147, -147, -147, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, -147, 60, 90, 392, -147, 96, -147, - -147, -147, 93, 392, 94, -147, -147, -147, -147, 489, - 505, 520, 534, 547, 558, 558, 18, 18, 18, 18, - 563, 563, 23, 23, -147, -147, -147, -147, 392, 32, - -147, 61, -147, -147, 110, 392, 118, -147, -147, 149, - -147, -147 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -147, -147, -147, -147, -147, 157, -11, -147, -147, -147, - -146, 92, -68, 200, 0, -7, -147 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 77, 56, 154, 77, 70, 86, 78, 15, 120, 159, - 17, 68, 19, 120, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 117, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 59, 60, 88, - 89, 90, 91, 92, 93, 106, 107, 108, 109, 110, - 111, 112, 118, 88, 110, 111, 112, 61, 62, 77, - 59, 60, 71, 63, 77, 64, 65, 147, 155, 72, - 79, 156, 123, 123, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 82, 83, 84, 125, 148, 157, 114, 88, - 126, 150, 2, 151, 152, 153, 88, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 158, 17, 18, 19, 160, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 161, 85, 17, 74, 19, 124, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 81, 0, 17, 80, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 119, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 121, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 87, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 113, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, - 0, 0, 17, 0, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 94, - 0, 0, 0, 0, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 127, 0, 0, 0, 0, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 0, 0, 128, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 108, 109, 110, 111, 112 -}; - -static const yytype_int16 yycheck[] = -{ - 7, 1, 148, 10, 4, 16, 21, 17, 76, 155, - 20, 21, 22, 81, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 17, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 19, 20, 56, - 61, 62, 63, 64, 65, 37, 38, 39, 40, 41, - 42, 43, 45, 70, 41, 42, 43, 39, 40, 76, - 19, 20, 17, 45, 81, 47, 48, 17, 46, 17, - 21, 49, 82, 83, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 17, 17, 17, 21, 46, 46, 45, 116, - 21, 21, 0, 17, 21, 21, 123, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 21, 20, 21, 22, 17, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - 21, 14, 20, 21, 22, 83, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - 10, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, - -1, -1, 20, -1, 22, -1, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 21, - -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 21, -1, -1, -1, -1, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, -1, -1, 46, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 39, 40, 41, 42, 43 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 58, 0, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 59, 60, 61, 65, 71, 72, 73, 19, - 20, 39, 40, 45, 47, 48, 62, 63, 21, 66, - 71, 17, 17, 4, 21, 69, 70, 72, 21, 21, - 21, 70, 17, 17, 17, 62, 63, 21, 72, 63, - 63, 63, 63, 63, 21, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 21, 45, 67, 71, 17, 45, 21, - 69, 21, 68, 71, 68, 21, 21, 21, 46, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 17, 46, 64, - 21, 17, 21, 21, 67, 46, 49, 46, 21, 67, - 17, 21 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, parser, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc, parser) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, parser); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - glcpp_parser_t *parser; -#endif -{ - if (!yyvaluep) - return; - YYUSE (yylocationp); - YYUSE (parser); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, parser) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - glcpp_parser_t *parser; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, glcpp_parser_t *parser) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, parser) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - glcpp_parser_t *parser; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , parser); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, parser); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, glcpp_parser_t *parser) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, parser) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - glcpp_parser_t *parser; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (parser); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (glcpp_parser_t *parser); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (glcpp_parser_t *parser) -#else -int -yyparse (parser) - glcpp_parser_t *parser; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc; - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - yylsp = yyls; - -#if YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 1; -#endif - -/* User initialization code. */ - -/* Line 1242 of yacc.c */ -#line 148 "glcpp/glcpp-parse.y" -{ - yylloc.first_line = 1; - yylloc.first_column = 1; - yylloc.last_line = 1; - yylloc.last_column = 1; - yylloc.source = 0; -} - -/* Line 1242 of yacc.c */ -#line 1610 "glcpp/glcpp-parse.c" - yylsp[0] = yylloc; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 4: - -/* Line 1455 of yacc.c */ -#line 187 "glcpp/glcpp-parse.y" - { - ralloc_strcat (&parser->output, "\n"); - ;} - break; - - case 5: - -/* Line 1455 of yacc.c */ -#line 190 "glcpp/glcpp-parse.y" - { - _glcpp_parser_print_expanded_token_list (parser, (yyvsp[(1) - (1)].token_list)); - ralloc_strcat (&parser->output, "\n"); - ralloc_free ((yyvsp[(1) - (1)].token_list)); - ;} - break; - - case 8: - -/* Line 1455 of yacc.c */ -#line 200 "glcpp/glcpp-parse.y" - { - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (3)]), (yyvsp[(2) - (3)].ival)); - ;} - break; - - case 9: - -/* Line 1455 of yacc.c */ -#line 203 "glcpp/glcpp-parse.y" - { - _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (3)]), "elif", (yyvsp[(2) - (3)].ival)); - ;} - break; - - case 10: - -/* Line 1455 of yacc.c */ -#line 209 "glcpp/glcpp-parse.y" - { - _define_object_macro (parser, & (yylsp[(2) - (4)]), (yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].token_list)); - ;} - break; - - case 11: - -/* Line 1455 of yacc.c */ -#line 212 "glcpp/glcpp-parse.y" - { - _define_function_macro (parser, & (yylsp[(2) - (6)]), (yyvsp[(2) - (6)].str), NULL, (yyvsp[(5) - (6)].token_list)); - ;} - break; - - case 12: - -/* Line 1455 of yacc.c */ -#line 215 "glcpp/glcpp-parse.y" - { - _define_function_macro (parser, & (yylsp[(2) - (7)]), (yyvsp[(2) - (7)].str), (yyvsp[(4) - (7)].string_list), (yyvsp[(6) - (7)].token_list)); - ;} - break; - - case 13: - -/* Line 1455 of yacc.c */ -#line 218 "glcpp/glcpp-parse.y" - { - macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (3)].str)); - if (macro) { - hash_table_remove (parser->defines, (yyvsp[(2) - (3)].str)); - ralloc_free (macro); - } - ralloc_free ((yyvsp[(2) - (3)].str)); - ;} - break; - - case 14: - -/* Line 1455 of yacc.c */ -#line 226 "glcpp/glcpp-parse.y" - { - /* Be careful to only evaluate the 'if' expression if - * we are not skipping. When we are skipping, we - * simply push a new 0-valued 'if' onto the skip - * stack. - * - * This avoids generating diagnostics for invalid - * expressions that are being skipped. */ - if (parser->skip_stack == NULL || - parser->skip_stack->type == SKIP_NO_SKIP) - { - _glcpp_parser_expand_if (parser, IF_EXPANDED, (yyvsp[(2) - (3)].token_list)); - } - else - { - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (3)]), 0); - parser->skip_stack->type = SKIP_TO_ENDIF; - } - ;} - break; - - case 15: - -/* Line 1455 of yacc.c */ -#line 245 "glcpp/glcpp-parse.y" - { - /* #if without an expression is only an error if we - * are not skipping */ - if (parser->skip_stack == NULL || - parser->skip_stack->type == SKIP_NO_SKIP) - { - glcpp_error(& (yylsp[(1) - (2)]), parser, "#if with no expression"); - } - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (2)]), 0); - ;} - break; - - case 16: - -/* Line 1455 of yacc.c */ -#line 255 "glcpp/glcpp-parse.y" - { - macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (4)].str)); - ralloc_free ((yyvsp[(2) - (4)].str)); - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (4)]), macro != NULL); - ;} - break; - - case 17: - -/* Line 1455 of yacc.c */ -#line 260 "glcpp/glcpp-parse.y" - { - macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (4)].str)); - ralloc_free ((yyvsp[(2) - (4)].str)); - _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (4)]), macro == NULL); - ;} - break; - - case 18: - -/* Line 1455 of yacc.c */ -#line 265 "glcpp/glcpp-parse.y" - { - /* Be careful to only evaluate the 'elif' expression - * if we are not skipping. When we are skipping, we - * simply change to a 0-valued 'elif' on the skip - * stack. - * - * This avoids generating diagnostics for invalid - * expressions that are being skipped. */ - if (parser->skip_stack && - parser->skip_stack->type == SKIP_TO_ELSE) - { - _glcpp_parser_expand_if (parser, ELIF_EXPANDED, (yyvsp[(2) - (3)].token_list)); - } - else - { - _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (3)]), - "elif", 0); - } - ;} - break; - - case 19: - -/* Line 1455 of yacc.c */ -#line 284 "glcpp/glcpp-parse.y" - { - /* #elif without an expression is an error unless we - * are skipping. */ - if (parser->skip_stack && - parser->skip_stack->type == SKIP_TO_ELSE) - { - glcpp_error(& (yylsp[(1) - (2)]), parser, "#elif with no expression"); - } - else - { - _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (2)]), - "elif", 0); - glcpp_warning(& (yylsp[(1) - (2)]), parser, "ignoring illegal #elif without expression"); - } - ;} - break; - - case 20: - -/* Line 1455 of yacc.c */ -#line 299 "glcpp/glcpp-parse.y" - { - _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (2)]), "else", 1); - ;} - break; - - case 21: - -/* Line 1455 of yacc.c */ -#line 302 "glcpp/glcpp-parse.y" - { - _glcpp_parser_skip_stack_pop (parser, & (yylsp[(1) - (2)])); - ;} - break; - - case 22: - -/* Line 1455 of yacc.c */ -#line 305 "glcpp/glcpp-parse.y" - { - macro_t *macro = hash_table_find (parser->defines, "__VERSION__"); - if (macro) { - hash_table_remove (parser->defines, "__VERSION__"); - ralloc_free (macro); - } - add_builtin_define (parser, "__VERSION__", (yyvsp[(2) - (3)].ival)); - - if ((yyvsp[(2) - (3)].ival) == 100) - add_builtin_define (parser, "GL_ES", 1); - - /* Currently, all ES2 implementations support highp in the - * fragment shader, so we always define this macro in ES2. - * If we ever get a driver that doesn't support highp, we'll - * need to add a flag to the gl_context and check that here. - */ - if ((yyvsp[(2) - (3)].ival) >= 130 || (yyvsp[(2) - (3)].ival) == 100) - add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1); - - ralloc_asprintf_append (&parser->output, "#version %" PRIiMAX, (yyvsp[(2) - (3)].ival)); - ;} - break; - - case 24: - -/* Line 1455 of yacc.c */ -#line 330 "glcpp/glcpp-parse.y" - { - if (strlen ((yyvsp[(1) - (1)].str)) >= 3 && strncmp ((yyvsp[(1) - (1)].str), "0x", 2) == 0) { - (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str) + 2, NULL, 16); - } else if ((yyvsp[(1) - (1)].str)[0] == '0') { - (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str), NULL, 8); - } else { - (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str), NULL, 10); - } - ;} - break; - - case 25: - -/* Line 1455 of yacc.c */ -#line 339 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (1)].ival); - ;} - break; - - case 27: - -/* Line 1455 of yacc.c */ -#line 345 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) || (yyvsp[(3) - (3)].ival); - ;} - break; - - case 28: - -/* Line 1455 of yacc.c */ -#line 348 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) && (yyvsp[(3) - (3)].ival); - ;} - break; - - case 29: - -/* Line 1455 of yacc.c */ -#line 351 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); - ;} - break; - - case 30: - -/* Line 1455 of yacc.c */ -#line 354 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) ^ (yyvsp[(3) - (3)].ival); - ;} - break; - - case 31: - -/* Line 1455 of yacc.c */ -#line 357 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) & (yyvsp[(3) - (3)].ival); - ;} - break; - - case 32: - -/* Line 1455 of yacc.c */ -#line 360 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) != (yyvsp[(3) - (3)].ival); - ;} - break; - - case 33: - -/* Line 1455 of yacc.c */ -#line 363 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) == (yyvsp[(3) - (3)].ival); - ;} - break; - - case 34: - -/* Line 1455 of yacc.c */ -#line 366 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) >= (yyvsp[(3) - (3)].ival); - ;} - break; - - case 35: - -/* Line 1455 of yacc.c */ -#line 369 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) <= (yyvsp[(3) - (3)].ival); - ;} - break; - - case 36: - -/* Line 1455 of yacc.c */ -#line 372 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) > (yyvsp[(3) - (3)].ival); - ;} - break; - - case 37: - -/* Line 1455 of yacc.c */ -#line 375 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) < (yyvsp[(3) - (3)].ival); - ;} - break; - - case 38: - -/* Line 1455 of yacc.c */ -#line 378 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) >> (yyvsp[(3) - (3)].ival); - ;} - break; - - case 39: - -/* Line 1455 of yacc.c */ -#line 381 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) << (yyvsp[(3) - (3)].ival); - ;} - break; - - case 40: - -/* Line 1455 of yacc.c */ -#line 384 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) - (yyvsp[(3) - (3)].ival); - ;} - break; - - case 41: - -/* Line 1455 of yacc.c */ -#line 387 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) + (yyvsp[(3) - (3)].ival); - ;} - break; - - case 42: - -/* Line 1455 of yacc.c */ -#line 390 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) % (yyvsp[(3) - (3)].ival); - ;} - break; - - case 43: - -/* Line 1455 of yacc.c */ -#line 393 "glcpp/glcpp-parse.y" - { - if ((yyvsp[(3) - (3)].ival) == 0) { - yyerror (& (yylsp[(1) - (3)]), parser, - "division by 0 in preprocessor directive"); - } else { - (yyval.ival) = (yyvsp[(1) - (3)].ival) / (yyvsp[(3) - (3)].ival); - } - ;} - break; - - case 44: - -/* Line 1455 of yacc.c */ -#line 401 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(1) - (3)].ival) * (yyvsp[(3) - (3)].ival); - ;} - break; - - case 45: - -/* Line 1455 of yacc.c */ -#line 404 "glcpp/glcpp-parse.y" - { - (yyval.ival) = ! (yyvsp[(2) - (2)].ival); - ;} - break; - - case 46: - -/* Line 1455 of yacc.c */ -#line 407 "glcpp/glcpp-parse.y" - { - (yyval.ival) = ~ (yyvsp[(2) - (2)].ival); - ;} - break; - - case 47: - -/* Line 1455 of yacc.c */ -#line 410 "glcpp/glcpp-parse.y" - { - (yyval.ival) = - (yyvsp[(2) - (2)].ival); - ;} - break; - - case 48: - -/* Line 1455 of yacc.c */ -#line 413 "glcpp/glcpp-parse.y" - { - (yyval.ival) = + (yyvsp[(2) - (2)].ival); - ;} - break; - - case 49: - -/* Line 1455 of yacc.c */ -#line 416 "glcpp/glcpp-parse.y" - { - (yyval.ival) = (yyvsp[(2) - (3)].ival); - ;} - break; - - case 50: - -/* Line 1455 of yacc.c */ -#line 422 "glcpp/glcpp-parse.y" - { - (yyval.string_list) = _string_list_create (parser); - _string_list_append_item ((yyval.string_list), (yyvsp[(1) - (1)].str)); - ralloc_steal ((yyval.string_list), (yyvsp[(1) - (1)].str)); - ;} - break; - - case 51: - -/* Line 1455 of yacc.c */ -#line 427 "glcpp/glcpp-parse.y" - { - (yyval.string_list) = (yyvsp[(1) - (3)].string_list); - _string_list_append_item ((yyval.string_list), (yyvsp[(3) - (3)].str)); - ralloc_steal ((yyval.string_list), (yyvsp[(3) - (3)].str)); - ;} - break; - - case 52: - -/* Line 1455 of yacc.c */ -#line 435 "glcpp/glcpp-parse.y" - { (yyval.token_list) = NULL; ;} - break; - - case 54: - -/* Line 1455 of yacc.c */ -#line 440 "glcpp/glcpp-parse.y" - { - yyerror (& (yylsp[(1) - (2)]), parser, "Invalid tokens after #"); - ;} - break; - - case 55: - -/* Line 1455 of yacc.c */ -#line 446 "glcpp/glcpp-parse.y" - { (yyval.token_list) = NULL; ;} - break; - - case 58: - -/* Line 1455 of yacc.c */ -#line 452 "glcpp/glcpp-parse.y" - { - glcpp_warning(&(yylsp[(1) - (1)]), parser, "extra tokens at end of directive"); - ;} - break; - - case 59: - -/* Line 1455 of yacc.c */ -#line 459 "glcpp/glcpp-parse.y" - { - int v = hash_table_find (parser->defines, (yyvsp[(2) - (2)].str)) ? 1 : 0; - (yyval.token) = _token_create_ival (parser, INTEGER, v); - ;} - break; - - case 60: - -/* Line 1455 of yacc.c */ -#line 463 "glcpp/glcpp-parse.y" - { - int v = hash_table_find (parser->defines, (yyvsp[(3) - (4)].str)) ? 1 : 0; - (yyval.token) = _token_create_ival (parser, INTEGER, v); - ;} - break; - - case 62: - -/* Line 1455 of yacc.c */ -#line 472 "glcpp/glcpp-parse.y" - { - (yyval.token_list) = _token_list_create (parser); - _token_list_append ((yyval.token_list), (yyvsp[(1) - (1)].token)); - ;} - break; - - case 63: - -/* Line 1455 of yacc.c */ -#line 476 "glcpp/glcpp-parse.y" - { - (yyval.token_list) = (yyvsp[(1) - (2)].token_list); - _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token)); - ;} - break; - - case 64: - -/* Line 1455 of yacc.c */ -#line 483 "glcpp/glcpp-parse.y" - { - parser->space_tokens = 1; - (yyval.token_list) = _token_list_create (parser); - _token_list_append ((yyval.token_list), (yyvsp[(1) - (1)].token)); - ;} - break; - - case 65: - -/* Line 1455 of yacc.c */ -#line 488 "glcpp/glcpp-parse.y" - { - (yyval.token_list) = (yyvsp[(1) - (2)].token_list); - _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token)); - ;} - break; - - case 66: - -/* Line 1455 of yacc.c */ -#line 495 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_str (parser, IDENTIFIER, (yyvsp[(1) - (1)].str)); - (yyval.token)->location = yylloc; - ;} - break; - - case 67: - -/* Line 1455 of yacc.c */ -#line 499 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_str (parser, INTEGER_STRING, (yyvsp[(1) - (1)].str)); - (yyval.token)->location = yylloc; - ;} - break; - - case 68: - -/* Line 1455 of yacc.c */ -#line 503 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_ival (parser, (yyvsp[(1) - (1)].ival), (yyvsp[(1) - (1)].ival)); - (yyval.token)->location = yylloc; - ;} - break; - - case 69: - -/* Line 1455 of yacc.c */ -#line 507 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_str (parser, OTHER, (yyvsp[(1) - (1)].str)); - (yyval.token)->location = yylloc; - ;} - break; - - case 70: - -/* Line 1455 of yacc.c */ -#line 511 "glcpp/glcpp-parse.y" - { - (yyval.token) = _token_create_ival (parser, SPACE, SPACE); - (yyval.token)->location = yylloc; - ;} - break; - - case 71: - -/* Line 1455 of yacc.c */ -#line 518 "glcpp/glcpp-parse.y" - { (yyval.ival) = '['; ;} - break; - - case 72: - -/* Line 1455 of yacc.c */ -#line 519 "glcpp/glcpp-parse.y" - { (yyval.ival) = ']'; ;} - break; - - case 73: - -/* Line 1455 of yacc.c */ -#line 520 "glcpp/glcpp-parse.y" - { (yyval.ival) = '('; ;} - break; - - case 74: - -/* Line 1455 of yacc.c */ -#line 521 "glcpp/glcpp-parse.y" - { (yyval.ival) = ')'; ;} - break; - - case 75: - -/* Line 1455 of yacc.c */ -#line 522 "glcpp/glcpp-parse.y" - { (yyval.ival) = '{'; ;} - break; - - case 76: - -/* Line 1455 of yacc.c */ -#line 523 "glcpp/glcpp-parse.y" - { (yyval.ival) = '}'; ;} - break; - - case 77: - -/* Line 1455 of yacc.c */ -#line 524 "glcpp/glcpp-parse.y" - { (yyval.ival) = '.'; ;} - break; - - case 78: - -/* Line 1455 of yacc.c */ -#line 525 "glcpp/glcpp-parse.y" - { (yyval.ival) = '&'; ;} - break; - - case 79: - -/* Line 1455 of yacc.c */ -#line 526 "glcpp/glcpp-parse.y" - { (yyval.ival) = '*'; ;} - break; - - case 80: - -/* Line 1455 of yacc.c */ -#line 527 "glcpp/glcpp-parse.y" - { (yyval.ival) = '+'; ;} - break; - - case 81: - -/* Line 1455 of yacc.c */ -#line 528 "glcpp/glcpp-parse.y" - { (yyval.ival) = '-'; ;} - break; - - case 82: - -/* Line 1455 of yacc.c */ -#line 529 "glcpp/glcpp-parse.y" - { (yyval.ival) = '~'; ;} - break; - - case 83: - -/* Line 1455 of yacc.c */ -#line 530 "glcpp/glcpp-parse.y" - { (yyval.ival) = '!'; ;} - break; - - case 84: - -/* Line 1455 of yacc.c */ -#line 531 "glcpp/glcpp-parse.y" - { (yyval.ival) = '/'; ;} - break; - - case 85: - -/* Line 1455 of yacc.c */ -#line 532 "glcpp/glcpp-parse.y" - { (yyval.ival) = '%'; ;} - break; - - case 86: - -/* Line 1455 of yacc.c */ -#line 533 "glcpp/glcpp-parse.y" - { (yyval.ival) = LEFT_SHIFT; ;} - break; - - case 87: - -/* Line 1455 of yacc.c */ -#line 534 "glcpp/glcpp-parse.y" - { (yyval.ival) = RIGHT_SHIFT; ;} - break; - - case 88: - -/* Line 1455 of yacc.c */ -#line 535 "glcpp/glcpp-parse.y" - { (yyval.ival) = '<'; ;} - break; - - case 89: - -/* Line 1455 of yacc.c */ -#line 536 "glcpp/glcpp-parse.y" - { (yyval.ival) = '>'; ;} - break; - - case 90: - -/* Line 1455 of yacc.c */ -#line 537 "glcpp/glcpp-parse.y" - { (yyval.ival) = LESS_OR_EQUAL; ;} - break; - - case 91: - -/* Line 1455 of yacc.c */ -#line 538 "glcpp/glcpp-parse.y" - { (yyval.ival) = GREATER_OR_EQUAL; ;} - break; - - case 92: - -/* Line 1455 of yacc.c */ -#line 539 "glcpp/glcpp-parse.y" - { (yyval.ival) = EQUAL; ;} - break; - - case 93: - -/* Line 1455 of yacc.c */ -#line 540 "glcpp/glcpp-parse.y" - { (yyval.ival) = NOT_EQUAL; ;} - break; - - case 94: - -/* Line 1455 of yacc.c */ -#line 541 "glcpp/glcpp-parse.y" - { (yyval.ival) = '^'; ;} - break; - - case 95: - -/* Line 1455 of yacc.c */ -#line 542 "glcpp/glcpp-parse.y" - { (yyval.ival) = '|'; ;} - break; - - case 96: - -/* Line 1455 of yacc.c */ -#line 543 "glcpp/glcpp-parse.y" - { (yyval.ival) = AND; ;} - break; - - case 97: - -/* Line 1455 of yacc.c */ -#line 544 "glcpp/glcpp-parse.y" - { (yyval.ival) = OR; ;} - break; - - case 98: - -/* Line 1455 of yacc.c */ -#line 545 "glcpp/glcpp-parse.y" - { (yyval.ival) = ';'; ;} - break; - - case 99: - -/* Line 1455 of yacc.c */ -#line 546 "glcpp/glcpp-parse.y" - { (yyval.ival) = ','; ;} - break; - - case 100: - -/* Line 1455 of yacc.c */ -#line 547 "glcpp/glcpp-parse.y" - { (yyval.ival) = '='; ;} - break; - - case 101: - -/* Line 1455 of yacc.c */ -#line 548 "glcpp/glcpp-parse.y" - { (yyval.ival) = PASTE; ;} - break; - - - -/* Line 1455 of yacc.c */ -#line 2649 "glcpp/glcpp-parse.c" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (&yylloc, parser, YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (&yylloc, parser, yymsg); - } - else - { - yyerror (&yylloc, parser, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - yyerror_range[0] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, parser); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[0] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[0] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, parser); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - yyerror_range[1] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, parser, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, parser); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, parser); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - -/* Line 1675 of yacc.c */ -#line 551 "glcpp/glcpp-parse.y" - - -string_list_t * -_string_list_create (void *ctx) -{ - string_list_t *list; - - list = ralloc (ctx, string_list_t); - list->head = NULL; - list->tail = NULL; - - return list; -} - -void -_string_list_append_item (string_list_t *list, const char *str) -{ - string_node_t *node; - - node = ralloc (list, string_node_t); - node->str = ralloc_strdup (node, str); - - node->next = NULL; - - if (list->head == NULL) { - list->head = node; - } else { - list->tail->next = node; - } - - list->tail = node; -} - -int -_string_list_contains (string_list_t *list, const char *member, int *index) -{ - string_node_t *node; - int i; - - if (list == NULL) - return 0; - - for (i = 0, node = list->head; node; i++, node = node->next) { - if (strcmp (node->str, member) == 0) { - if (index) - *index = i; - return 1; - } - } - - return 0; -} - -int -_string_list_length (string_list_t *list) -{ - int length = 0; - string_node_t *node; - - if (list == NULL) - return 0; - - for (node = list->head; node; node = node->next) - length++; - - return length; -} - -int -_string_list_equal (string_list_t *a, string_list_t *b) -{ - string_node_t *node_a, *node_b; - - if (a == NULL && b == NULL) - return 1; - - if (a == NULL || b == NULL) - return 0; - - for (node_a = a->head, node_b = b->head; - node_a && node_b; - node_a = node_a->next, node_b = node_b->next) - { - if (strcmp (node_a->str, node_b->str)) - return 0; - } - - /* Catch the case of lists being different lengths, (which - * would cause the loop above to terminate after the shorter - * list). */ - return node_a == node_b; -} - -argument_list_t * -_argument_list_create (void *ctx) -{ - argument_list_t *list; - - list = ralloc (ctx, argument_list_t); - list->head = NULL; - list->tail = NULL; - - return list; -} - -void -_argument_list_append (argument_list_t *list, token_list_t *argument) -{ - argument_node_t *node; - - node = ralloc (list, argument_node_t); - node->argument = argument; - - node->next = NULL; - - if (list->head == NULL) { - list->head = node; - } else { - list->tail->next = node; - } - - list->tail = node; -} - -int -_argument_list_length (argument_list_t *list) -{ - int length = 0; - argument_node_t *node; - - if (list == NULL) - return 0; - - for (node = list->head; node; node = node->next) - length++; - - return length; -} - -token_list_t * -_argument_list_member_at (argument_list_t *list, int index) -{ - argument_node_t *node; - int i; - - if (list == NULL) - return NULL; - - node = list->head; - for (i = 0; i < index; i++) { - node = node->next; - if (node == NULL) - break; - } - - if (node) - return node->argument; - - return NULL; -} - -/* Note: This function ralloc_steal()s the str pointer. */ -token_t * -_token_create_str (void *ctx, int type, char *str) -{ - token_t *token; - - token = ralloc (ctx, token_t); - token->type = type; - token->value.str = str; - - ralloc_steal (token, str); - - return token; -} - -token_t * -_token_create_ival (void *ctx, int type, int ival) -{ - token_t *token; - - token = ralloc (ctx, token_t); - token->type = type; - token->value.ival = ival; - - return token; -} - -token_list_t * -_token_list_create (void *ctx) -{ - token_list_t *list; - - list = ralloc (ctx, token_list_t); - list->head = NULL; - list->tail = NULL; - list->non_space_tail = NULL; - - return list; -} - -void -_token_list_append (token_list_t *list, token_t *token) -{ - token_node_t *node; - - node = ralloc (list, token_node_t); - node->token = token; - node->next = NULL; - - ralloc_steal (list, token); - - if (list->head == NULL) { - list->head = node; - } else { - list->tail->next = node; - } - - list->tail = node; - if (token->type != SPACE) - list->non_space_tail = node; -} - -void -_token_list_append_list (token_list_t *list, token_list_t *tail) -{ - if (tail == NULL || tail->head == NULL) - return; - - if (list->head == NULL) { - list->head = tail->head; - } else { - list->tail->next = tail->head; - } - - list->tail = tail->tail; - list->non_space_tail = tail->non_space_tail; -} - -static token_list_t * -_token_list_copy (void *ctx, token_list_t *other) -{ - token_list_t *copy; - token_node_t *node; - - if (other == NULL) - return NULL; - - copy = _token_list_create (ctx); - for (node = other->head; node; node = node->next) { - token_t *new_token = ralloc (copy, token_t); - *new_token = *node->token; - _token_list_append (copy, new_token); - } - - return copy; -} - -static void -_token_list_trim_trailing_space (token_list_t *list) -{ - token_node_t *tail, *next; - - if (list->non_space_tail) { - tail = list->non_space_tail->next; - list->non_space_tail->next = NULL; - list->tail = list->non_space_tail; - - while (tail) { - next = tail->next; - ralloc_free (tail); - tail = next; - } - } -} - -static int -_token_list_is_empty_ignoring_space (token_list_t *l) -{ - token_node_t *n; - - if (l == NULL) - return 1; - - n = l->head; - while (n != NULL && n->token->type == SPACE) - n = n->next; - - return n == NULL; -} - -int -_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b) -{ - token_node_t *node_a, *node_b; - - if (a == NULL || b == NULL) { - int a_empty = _token_list_is_empty_ignoring_space(a); - int b_empty = _token_list_is_empty_ignoring_space(b); - return a_empty == b_empty; - } - - node_a = a->head; - node_b = b->head; - - while (1) - { - if (node_a == NULL && node_b == NULL) - break; - - if (node_a == NULL || node_b == NULL) - return 0; - - if (node_a->token->type == SPACE) { - node_a = node_a->next; - continue; - } - - if (node_b->token->type == SPACE) { - node_b = node_b->next; - continue; - } - - if (node_a->token->type != node_b->token->type) - return 0; - - switch (node_a->token->type) { - case INTEGER: - if (node_a->token->value.ival != - node_b->token->value.ival) - { - return 0; - } - break; - case IDENTIFIER: - case INTEGER_STRING: - case OTHER: - if (strcmp (node_a->token->value.str, - node_b->token->value.str)) - { - return 0; - } - break; - } - - node_a = node_a->next; - node_b = node_b->next; - } - - return 1; -} - -static void -_token_print (char **out, token_t *token) -{ - if (token->type < 256) { - ralloc_asprintf_append (out, "%c", token->type); - return; - } - - switch (token->type) { - case INTEGER: - ralloc_asprintf_append (out, "%" PRIiMAX, token->value.ival); - break; - case IDENTIFIER: - case INTEGER_STRING: - case OTHER: - ralloc_strcat (out, token->value.str); - break; - case SPACE: - ralloc_strcat (out, " "); - break; - case LEFT_SHIFT: - ralloc_strcat (out, "<<"); - break; - case RIGHT_SHIFT: - ralloc_strcat (out, ">>"); - break; - case LESS_OR_EQUAL: - ralloc_strcat (out, "<="); - break; - case GREATER_OR_EQUAL: - ralloc_strcat (out, ">="); - break; - case EQUAL: - ralloc_strcat (out, "=="); - break; - case NOT_EQUAL: - ralloc_strcat (out, "!="); - break; - case AND: - ralloc_strcat (out, "&&"); - break; - case OR: - ralloc_strcat (out, "||"); - break; - case PASTE: - ralloc_strcat (out, "##"); - break; - case COMMA_FINAL: - ralloc_strcat (out, ","); - break; - case PLACEHOLDER: - /* Nothing to print. */ - break; - default: - assert(!"Error: Don't know how to print token."); - break; - } -} - -/* Return a new token (ralloc()ed off of 'token') formed by pasting - * 'token' and 'other'. Note that this function may return 'token' or - * 'other' directly rather than allocating anything new. - * - * Caution: Only very cursory error-checking is performed to see if - * the final result is a valid single token. */ -static token_t * -_token_paste (glcpp_parser_t *parser, token_t *token, token_t *other) -{ - token_t *combined = NULL; - - /* Pasting a placeholder onto anything makes no change. */ - if (other->type == PLACEHOLDER) - return token; - - /* When 'token' is a placeholder, just return 'other'. */ - if (token->type == PLACEHOLDER) - return other; - - /* A very few single-character punctuators can be combined - * with another to form a multi-character punctuator. */ - switch (token->type) { - case '<': - if (other->type == '<') - combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT); - else if (other->type == '=') - combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL); - break; - case '>': - if (other->type == '>') - combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT); - else if (other->type == '=') - combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL); - break; - case '=': - if (other->type == '=') - combined = _token_create_ival (token, EQUAL, EQUAL); - break; - case '!': - if (other->type == '=') - combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL); - break; - case '&': - if (other->type == '&') - combined = _token_create_ival (token, AND, AND); - break; - case '|': - if (other->type == '|') - combined = _token_create_ival (token, OR, OR); - break; - } - - if (combined != NULL) { - /* Inherit the location from the first token */ - combined->location = token->location; - return combined; - } - - /* Two string-valued tokens can usually just be mashed - * together. - * - * XXX: This isn't actually legitimate. Several things here - * should result in a diagnostic since the result cannot be a - * valid, single pre-processing token. For example, pasting - * "123" and "abc" is not legal, but we don't catch that - * here. */ - if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING) && - (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING)) - { - char *str; - - str = ralloc_asprintf (token, "%s%s", token->value.str, - other->value.str); - combined = _token_create_str (token, token->type, str); - combined->location = token->location; - return combined; - } - - glcpp_error (&token->location, parser, ""); - ralloc_strcat (&parser->info_log, "Pasting \""); - _token_print (&parser->info_log, token); - ralloc_strcat (&parser->info_log, "\" and \""); - _token_print (&parser->info_log, other); - ralloc_strcat (&parser->info_log, "\" does not give a valid preprocessing token.\n"); - - return token; -} - -static void -_token_list_print (glcpp_parser_t *parser, token_list_t *list) -{ - token_node_t *node; - - if (list == NULL) - return; - - for (node = list->head; node; node = node->next) - _token_print (&parser->output, node->token); -} - -void -yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error) -{ - glcpp_error(locp, parser, "%s", error); -} - -static void add_builtin_define(glcpp_parser_t *parser, - const char *name, int value) -{ - token_t *tok; - token_list_t *list; - - tok = _token_create_ival (parser, INTEGER, value); - - list = _token_list_create(parser); - _token_list_append(list, tok); - _define_object_macro(parser, NULL, name, list); -} - -glcpp_parser_t * -glcpp_parser_create (const struct gl_extensions *extensions, int api) -{ - glcpp_parser_t *parser; - int language_version; - - parser = ralloc (NULL, glcpp_parser_t); - - glcpp_lex_init_extra (parser, &parser->scanner); - parser->defines = hash_table_ctor (32, hash_table_string_hash, - hash_table_string_compare); - parser->active = NULL; - parser->lexing_if = 0; - parser->space_tokens = 1; - parser->newline_as_space = 0; - parser->in_control_line = 0; - parser->paren_count = 0; - - parser->skip_stack = NULL; - - parser->lex_from_list = NULL; - parser->lex_from_node = NULL; - - parser->output = ralloc_strdup(parser, ""); - parser->info_log = ralloc_strdup(parser, ""); - parser->error = 0; - - /* Add pre-defined macros. */ - add_builtin_define(parser, "GL_ARB_draw_buffers", 1); - add_builtin_define(parser, "GL_ARB_texture_rectangle", 1); - - if (api == API_OPENGLES2) - add_builtin_define(parser, "GL_ES", 1); - - if (extensions != NULL) { - if (extensions->EXT_texture_array) { - add_builtin_define(parser, "GL_EXT_texture_array", 1); - } - - if (extensions->ARB_fragment_coord_conventions) - add_builtin_define(parser, "GL_ARB_fragment_coord_conventions", - 1); - - if (extensions->ARB_explicit_attrib_location) - add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1); - if (extensions->AMD_conservative_depth) - add_builtin_define(parser, "GL_AMD_conservative_depth", 1); - } - - language_version = 110; - add_builtin_define(parser, "__VERSION__", language_version); - - return parser; -} - -int -glcpp_parser_parse (glcpp_parser_t *parser) -{ - return yyparse (parser); -} - -void -glcpp_parser_destroy (glcpp_parser_t *parser) -{ - glcpp_lex_destroy (parser->scanner); - hash_table_dtor (parser->defines); - ralloc_free (parser); -} - -typedef enum function_status -{ - FUNCTION_STATUS_SUCCESS, - FUNCTION_NOT_A_FUNCTION, - FUNCTION_UNBALANCED_PARENTHESES -} function_status_t; - -/* Find a set of function-like macro arguments by looking for a - * balanced set of parentheses. - * - * When called, 'node' should be the opening-parenthesis token, (or - * perhaps preceeding SPACE tokens). Upon successful return *last will - * be the last consumed node, (corresponding to the closing right - * parenthesis). - * - * Return values: - * - * FUNCTION_STATUS_SUCCESS: - * - * Successfully parsed a set of function arguments. - * - * FUNCTION_NOT_A_FUNCTION: - * - * Macro name not followed by a '('. This is not an error, but - * simply that the macro name should be treated as a non-macro. - * - * FUNCTION_UNBALANCED_PARENTHESES - * - * Macro name is not followed by a balanced set of parentheses. - */ -static function_status_t -_arguments_parse (argument_list_t *arguments, - token_node_t *node, - token_node_t **last) -{ - token_list_t *argument; - int paren_count; - - node = node->next; - - /* Ignore whitespace before first parenthesis. */ - while (node && node->token->type == SPACE) - node = node->next; - - if (node == NULL || node->token->type != '(') - return FUNCTION_NOT_A_FUNCTION; - - node = node->next; - - argument = _token_list_create (arguments); - _argument_list_append (arguments, argument); - - for (paren_count = 1; node; node = node->next) { - if (node->token->type == '(') - { - paren_count++; - } - else if (node->token->type == ')') - { - paren_count--; - if (paren_count == 0) - break; - } - - if (node->token->type == ',' && - paren_count == 1) - { - _token_list_trim_trailing_space (argument); - argument = _token_list_create (arguments); - _argument_list_append (arguments, argument); - } - else { - if (argument->head == NULL) { - /* Don't treat initial whitespace as - * part of the arguement. */ - if (node->token->type == SPACE) - continue; - } - _token_list_append (argument, node->token); - } - } - - if (paren_count) - return FUNCTION_UNBALANCED_PARENTHESES; - - *last = node; - - return FUNCTION_STATUS_SUCCESS; -} - -static token_list_t * -_token_list_create_with_one_space (void *ctx) -{ - token_list_t *list; - token_t *space; - - list = _token_list_create (ctx); - space = _token_create_ival (list, SPACE, SPACE); - _token_list_append (list, space); - - return list; -} - -static void -_glcpp_parser_expand_if (glcpp_parser_t *parser, int type, token_list_t *list) -{ - token_list_t *expanded; - token_t *token; - - expanded = _token_list_create (parser); - token = _token_create_ival (parser, type, type); - _token_list_append (expanded, token); - _glcpp_parser_expand_token_list (parser, list); - _token_list_append_list (expanded, list); - glcpp_parser_lex_from (parser, expanded); -} - -/* This is a helper function that's essentially part of the - * implementation of _glcpp_parser_expand_node. It shouldn't be called - * except for by that function. - * - * Returns NULL if node is a simple token with no expansion, (that is, - * although 'node' corresponds to an identifier defined as a - * function-like macro, it is not followed with a parenthesized - * argument list). - * - * Compute the complete expansion of node (which is a function-like - * macro) and subsequent nodes which are arguments. - * - * Returns the token list that results from the expansion and sets - * *last to the last node in the list that was consumed by the - * expansion. Specifically, *last will be set as follows: as the - * token of the closing right parenthesis. - */ -static token_list_t * -_glcpp_parser_expand_function (glcpp_parser_t *parser, - token_node_t *node, - token_node_t **last) - -{ - macro_t *macro; - const char *identifier; - argument_list_t *arguments; - function_status_t status; - token_list_t *substituted; - int parameter_index; - - identifier = node->token->value.str; - - macro = hash_table_find (parser->defines, identifier); - - assert (macro->is_function); - - arguments = _argument_list_create (parser); - status = _arguments_parse (arguments, node, last); - - switch (status) { - case FUNCTION_STATUS_SUCCESS: - break; - case FUNCTION_NOT_A_FUNCTION: - return NULL; - case FUNCTION_UNBALANCED_PARENTHESES: - glcpp_error (&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier); - return NULL; - } - - /* Replace a macro defined as empty with a SPACE token. */ - if (macro->replacements == NULL) { - ralloc_free (arguments); - return _token_list_create_with_one_space (parser); - } - - if (! ((_argument_list_length (arguments) == - _string_list_length (macro->parameters)) || - (_string_list_length (macro->parameters) == 0 && - _argument_list_length (arguments) == 1 && - arguments->head->argument->head == NULL))) - { - glcpp_error (&node->token->location, parser, - "Error: macro %s invoked with %d arguments (expected %d)\n", - identifier, - _argument_list_length (arguments), - _string_list_length (macro->parameters)); - return NULL; - } - - /* Perform argument substitution on the replacement list. */ - substituted = _token_list_create (arguments); - - for (node = macro->replacements->head; node; node = node->next) - { - if (node->token->type == IDENTIFIER && - _string_list_contains (macro->parameters, - node->token->value.str, - ¶meter_index)) - { - token_list_t *argument; - argument = _argument_list_member_at (arguments, - parameter_index); - /* Before substituting, we expand the argument - * tokens, or append a placeholder token for - * an empty argument. */ - if (argument->head) { - token_list_t *expanded_argument; - expanded_argument = _token_list_copy (parser, - argument); - _glcpp_parser_expand_token_list (parser, - expanded_argument); - _token_list_append_list (substituted, - expanded_argument); - } else { - token_t *new_token; - - new_token = _token_create_ival (substituted, - PLACEHOLDER, - PLACEHOLDER); - _token_list_append (substituted, new_token); - } - } else { - _token_list_append (substituted, node->token); - } - } - - /* After argument substitution, and before further expansion - * below, implement token pasting. */ - - _token_list_trim_trailing_space (substituted); - - node = substituted->head; - while (node) - { - token_node_t *next_non_space; - - /* Look ahead for a PASTE token, skipping space. */ - next_non_space = node->next; - while (next_non_space && next_non_space->token->type == SPACE) - next_non_space = next_non_space->next; - - if (next_non_space == NULL) - break; - - if (next_non_space->token->type != PASTE) { - node = next_non_space; - continue; - } - - /* Now find the next non-space token after the PASTE. */ - next_non_space = next_non_space->next; - while (next_non_space && next_non_space->token->type == SPACE) - next_non_space = next_non_space->next; - - if (next_non_space == NULL) { - yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n"); - return NULL; - } - - node->token = _token_paste (parser, node->token, next_non_space->token); - node->next = next_non_space->next; - if (next_non_space == substituted->tail) - substituted->tail = node; - - node = node->next; - } - - substituted->non_space_tail = substituted->tail; - - return substituted; -} - -/* Compute the complete expansion of node, (and subsequent nodes after - * 'node' in the case that 'node' is a function-like macro and - * subsequent nodes are arguments). - * - * Returns NULL if node is a simple token with no expansion. - * - * Otherwise, returns the token list that results from the expansion - * and sets *last to the last node in the list that was consumed by - * the expansion. Specifically, *last will be set as follows: - * - * As 'node' in the case of object-like macro expansion. - * - * As the token of the closing right parenthesis in the case of - * function-like macro expansion. - */ -static token_list_t * -_glcpp_parser_expand_node (glcpp_parser_t *parser, - token_node_t *node, - token_node_t **last) -{ - token_t *token = node->token; - const char *identifier; - macro_t *macro; - - /* We only expand identifiers */ - if (token->type != IDENTIFIER) { - /* We change any COMMA into a COMMA_FINAL to prevent - * it being mistaken for an argument separator - * later. */ - if (token->type == ',') { - token->type = COMMA_FINAL; - token->value.ival = COMMA_FINAL; - } - - return NULL; - } - - /* Look up this identifier in the hash table. */ - identifier = token->value.str; - macro = hash_table_find (parser->defines, identifier); - - /* Not a macro, so no expansion needed. */ - if (macro == NULL) - return NULL; - - /* Finally, don't expand this macro if we're already actively - * expanding it, (to avoid infinite recursion). */ - if (_active_list_contains (parser->active, identifier)) { - /* We change the token type here from IDENTIFIER to - * OTHER to prevent any future expansion of this - * unexpanded token. */ - char *str; - token_list_t *expansion; - token_t *final; - - str = ralloc_strdup (parser, token->value.str); - final = _token_create_str (parser, OTHER, str); - expansion = _token_list_create (parser); - _token_list_append (expansion, final); - *last = node; - return expansion; - } - - if (! macro->is_function) - { - *last = node; - - /* Replace a macro defined as empty with a SPACE token. */ - if (macro->replacements == NULL) - return _token_list_create_with_one_space (parser); - - return _token_list_copy (parser, macro->replacements); - } - - return _glcpp_parser_expand_function (parser, node, last); -} - -/* Push a new identifier onto the active list, returning the new list. - * - * Here, 'marker' is the token node that appears in the list after the - * expansion of 'identifier'. That is, when the list iterator begins - * examinging 'marker', then it is time to pop this node from the - * active stack. - */ -active_list_t * -_active_list_push (active_list_t *list, - const char *identifier, - token_node_t *marker) -{ - active_list_t *node; - - node = ralloc (list, active_list_t); - node->identifier = ralloc_strdup (node, identifier); - node->marker = marker; - node->next = list; - - return node; -} - -active_list_t * -_active_list_pop (active_list_t *list) -{ - active_list_t *node = list; - - if (node == NULL) - return NULL; - - node = list->next; - ralloc_free (list); - - return node; -} - -int -_active_list_contains (active_list_t *list, const char *identifier) -{ - active_list_t *node; - - if (list == NULL) - return 0; - - for (node = list; node; node = node->next) - if (strcmp (node->identifier, identifier) == 0) - return 1; - - return 0; -} - -/* Walk over the token list replacing nodes with their expansion. - * Whenever nodes are expanded the walking will walk over the new - * nodes, continuing to expand as necessary. The results are placed in - * 'list' itself; - */ -static void -_glcpp_parser_expand_token_list (glcpp_parser_t *parser, - token_list_t *list) -{ - token_node_t *node_prev; - token_node_t *node, *last = NULL; - token_list_t *expansion; - - if (list == NULL) - return; - - _token_list_trim_trailing_space (list); - - node_prev = NULL; - node = list->head; - - while (node) { - - while (parser->active && parser->active->marker == node) - parser->active = _active_list_pop (parser->active); - - /* Find the expansion for node, which will replace all - * nodes from node to last, inclusive. */ - expansion = _glcpp_parser_expand_node (parser, node, &last); - if (expansion) { - token_node_t *n; - - for (n = node; n != last->next; n = n->next) - while (parser->active && - parser->active->marker == n) - { - parser->active = _active_list_pop (parser->active); - } - - parser->active = _active_list_push (parser->active, - node->token->value.str, - last->next); - - /* Splice expansion into list, supporting a - * simple deletion if the expansion is - * empty. */ - if (expansion->head) { - if (node_prev) - node_prev->next = expansion->head; - else - list->head = expansion->head; - expansion->tail->next = last->next; - if (last == list->tail) - list->tail = expansion->tail; - } else { - if (node_prev) - node_prev->next = last->next; - else - list->head = last->next; - if (last == list->tail) - list->tail = NULL; - } - } else { - node_prev = node; - } - node = node_prev ? node_prev->next : list->head; - } - - while (parser->active) - parser->active = _active_list_pop (parser->active); - - list->non_space_tail = list->tail; -} - -void -_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, - token_list_t *list) -{ - if (list == NULL) - return; - - _glcpp_parser_expand_token_list (parser, list); - - _token_list_trim_trailing_space (list); - - _token_list_print (parser, list); -} - -static void -_check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc, - const char *identifier) -{ - /* According to the GLSL specification, macro names starting with "__" - * or "GL_" are reserved for future use. So, don't allow them. - */ - if (strncmp(identifier, "__", 2) == 0) { - glcpp_error (loc, parser, "Macro names starting with \"__\" are reserved.\n"); - } - if (strncmp(identifier, "GL_", 3) == 0) { - glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n"); - } -} - -static int -_macro_equal (macro_t *a, macro_t *b) -{ - if (a->is_function != b->is_function) - return 0; - - if (a->is_function) { - if (! _string_list_equal (a->parameters, b->parameters)) - return 0; - } - - return _token_list_equal_ignoring_space (a->replacements, - b->replacements); -} - -void -_define_object_macro (glcpp_parser_t *parser, - YYLTYPE *loc, - const char *identifier, - token_list_t *replacements) -{ - macro_t *macro, *previous; - - if (loc != NULL) - _check_for_reserved_macro_name(parser, loc, identifier); - - macro = ralloc (parser, macro_t); - - macro->is_function = 0; - macro->parameters = NULL; - macro->identifier = ralloc_strdup (macro, identifier); - macro->replacements = replacements; - ralloc_steal (macro, replacements); - - previous = hash_table_find (parser->defines, identifier); - if (previous) { - if (_macro_equal (macro, previous)) { - ralloc_free (macro); - return; - } - glcpp_error (loc, parser, "Redefinition of macro %s\n", - identifier); - } - - hash_table_insert (parser->defines, macro, identifier); -} - -void -_define_function_macro (glcpp_parser_t *parser, - YYLTYPE *loc, - const char *identifier, - string_list_t *parameters, - token_list_t *replacements) -{ - macro_t *macro, *previous; - - _check_for_reserved_macro_name(parser, loc, identifier); - - macro = ralloc (parser, macro_t); - ralloc_steal (macro, parameters); - ralloc_steal (macro, replacements); - - macro->is_function = 1; - macro->parameters = parameters; - macro->identifier = ralloc_strdup (macro, identifier); - macro->replacements = replacements; - previous = hash_table_find (parser->defines, identifier); - if (previous) { - if (_macro_equal (macro, previous)) { - ralloc_free (macro); - return; - } - glcpp_error (loc, parser, "Redefinition of macro %s\n", - identifier); - } - - hash_table_insert (parser->defines, macro, identifier); -} - -static int -glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) -{ - token_node_t *node; - int ret; - - if (parser->lex_from_list == NULL) { - ret = glcpp_lex (yylval, yylloc, parser->scanner); - - /* XXX: This ugly block of code exists for the sole - * purpose of converting a NEWLINE token into a SPACE - * token, but only in the case where we have seen a - * function-like macro name, but have not yet seen its - * closing parenthesis. - * - * There's perhaps a more compact way to do this with - * mid-rule actions in the grammar. - * - * I'm definitely not pleased with the complexity of - * this code here. - */ - if (parser->newline_as_space) - { - if (ret == '(') { - parser->paren_count++; - } else if (ret == ')') { - parser->paren_count--; - if (parser->paren_count == 0) - parser->newline_as_space = 0; - } else if (ret == NEWLINE) { - ret = SPACE; - } else if (ret != SPACE) { - if (parser->paren_count == 0) - parser->newline_as_space = 0; - } - } - else if (parser->in_control_line) - { - if (ret == NEWLINE) - parser->in_control_line = 0; - } - else if (ret == HASH_DEFINE_OBJ || ret == HASH_DEFINE_FUNC || - ret == HASH_UNDEF || ret == HASH_IF || - ret == HASH_IFDEF || ret == HASH_IFNDEF || - ret == HASH_ELIF || ret == HASH_ELSE || - ret == HASH_ENDIF || ret == HASH) - { - parser->in_control_line = 1; - } - else if (ret == IDENTIFIER) - { - macro_t *macro; - macro = hash_table_find (parser->defines, - yylval->str); - if (macro && macro->is_function) { - parser->newline_as_space = 1; - parser->paren_count = 0; - } - } - - return ret; - } - - node = parser->lex_from_node; - - if (node == NULL) { - ralloc_free (parser->lex_from_list); - parser->lex_from_list = NULL; - return NEWLINE; - } - - *yylval = node->token->value; - ret = node->token->type; - - parser->lex_from_node = node->next; - - return ret; -} - -static void -glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list) -{ - token_node_t *node; - - assert (parser->lex_from_list == NULL); - - /* Copy list, eliminating any space tokens. */ - parser->lex_from_list = _token_list_create (parser); - - for (node = list->head; node; node = node->next) { - if (node->token->type == SPACE) - continue; - _token_list_append (parser->lex_from_list, node->token); - } - - ralloc_free (list); - - parser->lex_from_node = parser->lex_from_list->head; - - /* It's possible the list consisted of nothing but whitespace. */ - if (parser->lex_from_node == NULL) { - ralloc_free (parser->lex_from_list); - parser->lex_from_list = NULL; - } -} - -static void -_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc, - int condition) -{ - skip_type_t current = SKIP_NO_SKIP; - skip_node_t *node; - - if (parser->skip_stack) - current = parser->skip_stack->type; - - node = ralloc (parser, skip_node_t); - node->loc = *loc; - - if (current == SKIP_NO_SKIP) { - if (condition) - node->type = SKIP_NO_SKIP; - else - node->type = SKIP_TO_ELSE; - } else { - node->type = SKIP_TO_ENDIF; - } - - node->next = parser->skip_stack; - parser->skip_stack = node; -} - -static void -_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, - const char *type, int condition) -{ - if (parser->skip_stack == NULL) { - glcpp_error (loc, parser, "%s without #if\n", type); - return; - } - - if (parser->skip_stack->type == SKIP_TO_ELSE) { - if (condition) - parser->skip_stack->type = SKIP_NO_SKIP; - } else { - parser->skip_stack->type = SKIP_TO_ENDIF; - } -} - -static void -_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc) -{ - skip_node_t *node; - - if (parser->skip_stack == NULL) { - glcpp_error (loc, parser, "#endif without #if\n"); - return; - } - - node = parser->skip_stack; - parser->skip_stack = node->next; - ralloc_free (node); -} - +/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 1 + + + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 1 "glcpp/glcpp-parse.y" + +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "glcpp.h" +#include "main/core.h" /* for struct gl_extensions */ +#include "main/mtypes.h" /* for gl_api enum */ + +static void +yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error); + +static void +_define_object_macro (glcpp_parser_t *parser, + YYLTYPE *loc, + const char *macro, + token_list_t *replacements); + +static void +_define_function_macro (glcpp_parser_t *parser, + YYLTYPE *loc, + const char *macro, + string_list_t *parameters, + token_list_t *replacements); + +static string_list_t * +_string_list_create (void *ctx); + +static void +_string_list_append_item (string_list_t *list, const char *str); + +static int +_string_list_contains (string_list_t *list, const char *member, int *index); + +static int +_string_list_length (string_list_t *list); + +static int +_string_list_equal (string_list_t *a, string_list_t *b); + +static argument_list_t * +_argument_list_create (void *ctx); + +static void +_argument_list_append (argument_list_t *list, token_list_t *argument); + +static int +_argument_list_length (argument_list_t *list); + +static token_list_t * +_argument_list_member_at (argument_list_t *list, int index); + +/* Note: This function ralloc_steal()s the str pointer. */ +static token_t * +_token_create_str (void *ctx, int type, char *str); + +static token_t * +_token_create_ival (void *ctx, int type, int ival); + +static token_list_t * +_token_list_create (void *ctx); + +/* Note: This function calls ralloc_steal on token. */ +static void +_token_list_append (token_list_t *list, token_t *token); + +static void +_token_list_append_list (token_list_t *list, token_list_t *tail); + +static int +_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b); + +static active_list_t * +_active_list_push (active_list_t *list, + const char *identifier, + token_node_t *marker); + +static active_list_t * +_active_list_pop (active_list_t *list); + +int +_active_list_contains (active_list_t *list, const char *identifier); + +static void +_glcpp_parser_expand_if (glcpp_parser_t *parser, int type, token_list_t *list); + +static void +_glcpp_parser_expand_token_list (glcpp_parser_t *parser, + token_list_t *list); + +static void +_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, + token_list_t *list); + +static void +_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc, + int condition); + +static void +_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, + const char *type, int condition); + +static void +_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc); + +#define yylex glcpp_parser_lex + +static int +glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser); + +static void +glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list); + +static void +add_builtin_define(glcpp_parser_t *parser, const char *name, int value); + + + +/* Line 189 of yacc.c */ +#line 216 "glcpp/glcpp-parse.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + COMMA_FINAL = 258, + DEFINED = 259, + ELIF_EXPANDED = 260, + HASH = 261, + HASH_DEFINE_FUNC = 262, + HASH_DEFINE_OBJ = 263, + HASH_ELIF = 264, + HASH_ELSE = 265, + HASH_ENDIF = 266, + HASH_IF = 267, + HASH_IFDEF = 268, + HASH_IFNDEF = 269, + HASH_UNDEF = 270, + HASH_VERSION = 271, + IDENTIFIER = 272, + IF_EXPANDED = 273, + INTEGER = 274, + INTEGER_STRING = 275, + NEWLINE = 276, + OTHER = 277, + PLACEHOLDER = 278, + SPACE = 279, + PASTE = 280, + OR = 281, + AND = 282, + NOT_EQUAL = 283, + EQUAL = 284, + GREATER_OR_EQUAL = 285, + LESS_OR_EQUAL = 286, + RIGHT_SHIFT = 287, + LEFT_SHIFT = 288, + UNARY = 289 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 304 "glcpp/glcpp-parse.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 2 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 606 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 57 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 17 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 101 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 162 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 289 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 47, 2, 2, 2, 43, 30, 2, + 45, 46, 41, 39, 49, 40, 54, 42, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, + 33, 56, 34, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 50, 2, 51, 29, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 52, 28, 53, 48, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 31, 32, 35, 36, 37, 38, 44 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 4, 7, 9, 11, 13, 16, 20, + 24, 29, 36, 44, 48, 52, 55, 60, 65, 69, + 72, 75, 78, 82, 85, 87, 89, 91, 95, 99, + 103, 107, 111, 115, 119, 123, 127, 131, 135, 139, + 143, 147, 151, 155, 159, 163, 166, 169, 172, 175, + 179, 181, 185, 187, 190, 193, 194, 196, 197, 199, + 202, 207, 209, 211, 214, 216, 219, 221, 223, 225, + 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, + 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, + 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, + 287, 289 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 58, 0, -1, -1, 58, 59, -1, 61, -1, 65, + -1, 60, -1, 6, 66, -1, 18, 63, 21, -1, + 5, 63, 21, -1, 8, 17, 67, 21, -1, 7, + 17, 45, 46, 67, 21, -1, 7, 17, 45, 64, + 46, 67, 21, -1, 15, 17, 21, -1, 12, 70, + 21, -1, 12, 21, -1, 13, 17, 68, 21, -1, + 14, 17, 68, 21, -1, 9, 70, 21, -1, 9, + 21, -1, 10, 21, -1, 11, 21, -1, 16, 62, + 21, -1, 6, 21, -1, 20, -1, 19, -1, 62, + -1, 63, 26, 63, -1, 63, 27, 63, -1, 63, + 28, 63, -1, 63, 29, 63, -1, 63, 30, 63, + -1, 63, 31, 63, -1, 63, 32, 63, -1, 63, + 35, 63, -1, 63, 36, 63, -1, 63, 34, 63, + -1, 63, 33, 63, -1, 63, 37, 63, -1, 63, + 38, 63, -1, 63, 40, 63, -1, 63, 39, 63, + -1, 63, 43, 63, -1, 63, 42, 63, -1, 63, + 41, 63, -1, 47, 63, -1, 48, 63, -1, 40, + 63, -1, 39, 63, -1, 45, 63, 46, -1, 17, + -1, 64, 49, 17, -1, 21, -1, 71, 21, -1, + 71, 21, -1, -1, 71, -1, -1, 71, -1, 4, + 17, -1, 4, 45, 17, 46, -1, 72, -1, 69, + -1, 70, 69, -1, 72, -1, 71, 72, -1, 17, + -1, 20, -1, 73, -1, 22, -1, 24, -1, 50, + -1, 51, -1, 45, -1, 46, -1, 52, -1, 53, + -1, 54, -1, 30, -1, 41, -1, 39, -1, 40, + -1, 48, -1, 47, -1, 42, -1, 43, -1, 38, + -1, 37, -1, 33, -1, 34, -1, 36, -1, 35, + -1, 32, -1, 31, -1, 29, -1, 28, -1, 27, + -1, 26, -1, 55, -1, 49, -1, 56, -1, 25, + -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 181, 181, 183, 187, 190, 195, 196, 200, 203, + 209, 212, 215, 218, 226, 245, 255, 260, 265, 284, + 299, 302, 305, 326, 330, 339, 344, 345, 348, 351, + 354, 357, 360, 363, 366, 369, 372, 375, 378, 381, + 384, 387, 390, 398, 406, 409, 412, 415, 418, 421, + 427, 432, 440, 441, 445, 451, 452, 455, 457, 464, + 468, 472, 477, 481, 488, 493, 500, 504, 508, 512, + 516, 523, 524, 525, 526, 527, 528, 529, 530, 531, + 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, + 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, + 552, 553 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "COMMA_FINAL", "DEFINED", + "ELIF_EXPANDED", "HASH", "HASH_DEFINE_FUNC", "HASH_DEFINE_OBJ", + "HASH_ELIF", "HASH_ELSE", "HASH_ENDIF", "HASH_IF", "HASH_IFDEF", + "HASH_IFNDEF", "HASH_UNDEF", "HASH_VERSION", "IDENTIFIER", "IF_EXPANDED", + "INTEGER", "INTEGER_STRING", "NEWLINE", "OTHER", "PLACEHOLDER", "SPACE", + "PASTE", "OR", "AND", "'|'", "'^'", "'&'", "NOT_EQUAL", "EQUAL", "'<'", + "'>'", "GREATER_OR_EQUAL", "LESS_OR_EQUAL", "RIGHT_SHIFT", "LEFT_SHIFT", + "'+'", "'-'", "'*'", "'/'", "'%'", "UNARY", "'('", "')'", "'!'", "'~'", + "','", "'['", "']'", "'{'", "'}'", "'.'", "';'", "'='", "$accept", + "input", "line", "expanded_line", "control_line", "integer_constant", + "expression", "identifier_list", "text_line", "non_directive", + "replacement_list", "junk", "conditional_token", "conditional_tokens", + "pp_tokens", "preprocessing_token", "operator", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 124, 94, + 38, 283, 284, 60, 62, 285, 286, 287, 288, 43, + 45, 42, 47, 37, 289, 40, 41, 33, 126, 44, + 91, 93, 123, 125, 46, 59, 61 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 57, 58, 58, 59, 59, 59, 59, 60, 60, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 62, 62, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 64, 64, 65, 65, 66, 67, 67, 68, 68, 69, + 69, 69, 70, 70, 71, 71, 72, 72, 72, 72, + 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 2, 1, 1, 1, 2, 3, 3, + 4, 6, 7, 3, 3, 2, 4, 4, 3, 2, + 2, 2, 3, 2, 1, 1, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, + 1, 3, 1, 2, 2, 0, 1, 0, 1, 2, + 4, 1, 1, 2, 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, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 66, 0, 67, 52, 69, + 70, 101, 97, 96, 95, 94, 78, 93, 92, 88, + 89, 91, 90, 87, 86, 80, 81, 79, 84, 85, + 73, 74, 83, 82, 99, 71, 72, 75, 76, 77, + 98, 100, 3, 6, 4, 5, 0, 64, 68, 25, + 24, 0, 0, 0, 0, 0, 26, 0, 23, 7, + 0, 0, 55, 0, 19, 62, 0, 61, 20, 21, + 15, 0, 57, 57, 0, 0, 0, 53, 65, 48, + 47, 0, 45, 46, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 56, 59, 0, 18, + 63, 14, 0, 58, 0, 13, 22, 8, 49, 27, + 28, 29, 30, 31, 32, 33, 37, 36, 34, 35, + 38, 39, 41, 40, 44, 43, 42, 50, 55, 0, + 10, 0, 16, 17, 0, 55, 0, 60, 11, 0, + 51, 12 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 1, 52, 53, 54, 66, 67, 149, 55, 69, + 115, 122, 75, 76, 116, 57, 58 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -147 +static const yytype_int16 yypact[] = +{ + -147, 112, -147, 28, -10, 55, 62, 152, -15, 59, + 192, 85, 86, 87, 51, -147, 28, -147, -147, -147, + -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, + -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, + -147, -147, -147, -147, -147, -147, -147, -147, -147, -147, + -147, -147, -147, -147, -147, -147, 312, -147, -147, -147, + -147, 28, 28, 28, 28, 28, -147, 428, -147, -147, + 352, 63, 392, 17, -147, -147, 232, -147, -147, -147, + -147, 272, 392, 392, 84, 89, 451, -147, -147, -147, + -147, 469, -147, -147, -147, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, -147, 60, 90, 392, -147, 96, -147, + -147, -147, 93, 392, 94, -147, -147, -147, -147, 489, + 505, 520, 534, 547, 558, 558, 18, 18, 18, 18, + 563, 563, 23, 23, -147, -147, -147, -147, 392, 32, + -147, 61, -147, -147, 110, 392, 118, -147, -147, 149, + -147, -147 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -147, -147, -147, -147, -147, 157, -11, -147, -147, -147, + -146, 92, -68, 200, 0, -7, -147 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 77, 56, 154, 77, 70, 86, 78, 15, 120, 159, + 17, 68, 19, 120, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 117, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 59, 60, 88, + 89, 90, 91, 92, 93, 106, 107, 108, 109, 110, + 111, 112, 118, 88, 110, 111, 112, 61, 62, 77, + 59, 60, 71, 63, 77, 64, 65, 147, 155, 72, + 79, 156, 123, 123, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 82, 83, 84, 125, 148, 157, 114, 88, + 126, 150, 2, 151, 152, 153, 88, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 158, 17, 18, 19, 160, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, + 161, 85, 17, 74, 19, 124, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, + 81, 0, 17, 80, 19, 0, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, + 0, 0, 17, 119, 19, 0, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 73, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, + 0, 0, 17, 121, 19, 0, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, + 0, 0, 17, 87, 19, 0, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, + 0, 0, 17, 113, 19, 0, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 15, + 0, 0, 17, 0, 19, 0, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 94, + 0, 0, 0, 0, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 127, 0, 0, 0, 0, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 0, 128, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 108, 109, 110, 111, 112 +}; + +static const yytype_int16 yycheck[] = +{ + 7, 1, 148, 10, 4, 16, 21, 17, 76, 155, + 20, 21, 22, 81, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 17, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 19, 20, 56, + 61, 62, 63, 64, 65, 37, 38, 39, 40, 41, + 42, 43, 45, 70, 41, 42, 43, 39, 40, 76, + 19, 20, 17, 45, 81, 47, 48, 17, 46, 17, + 21, 49, 82, 83, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 17, 17, 17, 21, 46, 46, 45, 116, + 21, 21, 0, 17, 21, 21, 123, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 21, 20, 21, 22, 17, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, + 21, 14, 20, 21, 22, 83, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, + 10, -1, 20, 21, 22, -1, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, + -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 4, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, + -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, + -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, + -1, -1, 20, 21, 22, -1, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 17, + -1, -1, 20, -1, 22, -1, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 21, + -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 21, -1, -1, -1, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, -1, -1, 46, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 39, 40, 41, 42, 43 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 58, 0, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 59, 60, 61, 65, 71, 72, 73, 19, + 20, 39, 40, 45, 47, 48, 62, 63, 21, 66, + 71, 17, 17, 4, 21, 69, 70, 72, 21, 21, + 21, 70, 17, 17, 17, 62, 63, 21, 72, 63, + 63, 63, 63, 63, 21, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 21, 45, 67, 71, 17, 45, 21, + 69, 21, 68, 71, 68, 21, 21, 21, 46, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 17, 46, 64, + 21, 17, 21, 21, 67, 46, 49, 46, 21, 67, + 17, 21 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (&yylloc, parser, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, &yylloc, parser) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, Location, parser); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + glcpp_parser_t *parser; +#endif +{ + if (!yyvaluep) + return; + YYUSE (yylocationp); + YYUSE (parser); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, parser) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + glcpp_parser_t *parser; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, glcpp_parser_t *parser) +#else +static void +yy_reduce_print (yyvsp, yylsp, yyrule, parser) + YYSTYPE *yyvsp; + YYLTYPE *yylsp; + int yyrule; + glcpp_parser_t *parser; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , &(yylsp[(yyi + 1) - (yynrhs)]) , parser); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, yylsp, Rule, parser); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, glcpp_parser_t *parser) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, yylocationp, parser) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + YYLTYPE *yylocationp; + glcpp_parser_t *parser; +#endif +{ + YYUSE (yyvaluep); + YYUSE (yylocationp); + YYUSE (parser); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (glcpp_parser_t *parser); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (glcpp_parser_t *parser) +#else +int +yyparse (parser) + glcpp_parser_t *parser; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Location data for the lookahead symbol. */ +YYLTYPE yylloc; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[3]; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + YYLTYPE yyloc; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + yylsp = yyls; + +#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL + /* Initialize the default location before parsing starts. */ + yylloc.first_line = yylloc.last_line = 1; + yylloc.first_column = yylloc.last_column = 1; +#endif + +/* User initialization code. */ + +/* Line 1251 of yacc.c */ +#line 148 "glcpp/glcpp-parse.y" +{ + yylloc.first_line = 1; + yylloc.first_column = 1; + yylloc.last_line = 1; + yylloc.last_column = 1; + yylloc.source = 0; +} + +/* Line 1251 of yacc.c */ +#line 1618 "glcpp/glcpp-parse.c" + yylsp[0] = yylloc; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + + yyls = yyls1; + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + *++yylsp = yylloc; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 4: + +/* Line 1464 of yacc.c */ +#line 187 "glcpp/glcpp-parse.y" + { + ralloc_strcat (&parser->output, "\n"); + ;} + break; + + case 5: + +/* Line 1464 of yacc.c */ +#line 190 "glcpp/glcpp-parse.y" + { + _glcpp_parser_print_expanded_token_list (parser, (yyvsp[(1) - (1)].token_list)); + ralloc_strcat (&parser->output, "\n"); + ralloc_free ((yyvsp[(1) - (1)].token_list)); + ;} + break; + + case 8: + +/* Line 1464 of yacc.c */ +#line 200 "glcpp/glcpp-parse.y" + { + _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (3)]), (yyvsp[(2) - (3)].ival)); + ;} + break; + + case 9: + +/* Line 1464 of yacc.c */ +#line 203 "glcpp/glcpp-parse.y" + { + _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (3)]), "elif", (yyvsp[(2) - (3)].ival)); + ;} + break; + + case 10: + +/* Line 1464 of yacc.c */ +#line 209 "glcpp/glcpp-parse.y" + { + _define_object_macro (parser, & (yylsp[(2) - (4)]), (yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].token_list)); + ;} + break; + + case 11: + +/* Line 1464 of yacc.c */ +#line 212 "glcpp/glcpp-parse.y" + { + _define_function_macro (parser, & (yylsp[(2) - (6)]), (yyvsp[(2) - (6)].str), NULL, (yyvsp[(5) - (6)].token_list)); + ;} + break; + + case 12: + +/* Line 1464 of yacc.c */ +#line 215 "glcpp/glcpp-parse.y" + { + _define_function_macro (parser, & (yylsp[(2) - (7)]), (yyvsp[(2) - (7)].str), (yyvsp[(4) - (7)].string_list), (yyvsp[(6) - (7)].token_list)); + ;} + break; + + case 13: + +/* Line 1464 of yacc.c */ +#line 218 "glcpp/glcpp-parse.y" + { + macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (3)].str)); + if (macro) { + hash_table_remove (parser->defines, (yyvsp[(2) - (3)].str)); + ralloc_free (macro); + } + ralloc_free ((yyvsp[(2) - (3)].str)); + ;} + break; + + case 14: + +/* Line 1464 of yacc.c */ +#line 226 "glcpp/glcpp-parse.y" + { + /* Be careful to only evaluate the 'if' expression if + * we are not skipping. When we are skipping, we + * simply push a new 0-valued 'if' onto the skip + * stack. + * + * This avoids generating diagnostics for invalid + * expressions that are being skipped. */ + if (parser->skip_stack == NULL || + parser->skip_stack->type == SKIP_NO_SKIP) + { + _glcpp_parser_expand_if (parser, IF_EXPANDED, (yyvsp[(2) - (3)].token_list)); + } + else + { + _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (3)]), 0); + parser->skip_stack->type = SKIP_TO_ENDIF; + } + ;} + break; + + case 15: + +/* Line 1464 of yacc.c */ +#line 245 "glcpp/glcpp-parse.y" + { + /* #if without an expression is only an error if we + * are not skipping */ + if (parser->skip_stack == NULL || + parser->skip_stack->type == SKIP_NO_SKIP) + { + glcpp_error(& (yylsp[(1) - (2)]), parser, "#if with no expression"); + } + _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (2)]), 0); + ;} + break; + + case 16: + +/* Line 1464 of yacc.c */ +#line 255 "glcpp/glcpp-parse.y" + { + macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (4)].str)); + ralloc_free ((yyvsp[(2) - (4)].str)); + _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (4)]), macro != NULL); + ;} + break; + + case 17: + +/* Line 1464 of yacc.c */ +#line 260 "glcpp/glcpp-parse.y" + { + macro_t *macro = hash_table_find (parser->defines, (yyvsp[(2) - (4)].str)); + ralloc_free ((yyvsp[(2) - (4)].str)); + _glcpp_parser_skip_stack_push_if (parser, & (yylsp[(1) - (4)]), macro == NULL); + ;} + break; + + case 18: + +/* Line 1464 of yacc.c */ +#line 265 "glcpp/glcpp-parse.y" + { + /* Be careful to only evaluate the 'elif' expression + * if we are not skipping. When we are skipping, we + * simply change to a 0-valued 'elif' on the skip + * stack. + * + * This avoids generating diagnostics for invalid + * expressions that are being skipped. */ + if (parser->skip_stack && + parser->skip_stack->type == SKIP_TO_ELSE) + { + _glcpp_parser_expand_if (parser, ELIF_EXPANDED, (yyvsp[(2) - (3)].token_list)); + } + else + { + _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (3)]), + "elif", 0); + } + ;} + break; + + case 19: + +/* Line 1464 of yacc.c */ +#line 284 "glcpp/glcpp-parse.y" + { + /* #elif without an expression is an error unless we + * are skipping. */ + if (parser->skip_stack && + parser->skip_stack->type == SKIP_TO_ELSE) + { + glcpp_error(& (yylsp[(1) - (2)]), parser, "#elif with no expression"); + } + else + { + _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (2)]), + "elif", 0); + glcpp_warning(& (yylsp[(1) - (2)]), parser, "ignoring illegal #elif without expression"); + } + ;} + break; + + case 20: + +/* Line 1464 of yacc.c */ +#line 299 "glcpp/glcpp-parse.y" + { + _glcpp_parser_skip_stack_change_if (parser, & (yylsp[(1) - (2)]), "else", 1); + ;} + break; + + case 21: + +/* Line 1464 of yacc.c */ +#line 302 "glcpp/glcpp-parse.y" + { + _glcpp_parser_skip_stack_pop (parser, & (yylsp[(1) - (2)])); + ;} + break; + + case 22: + +/* Line 1464 of yacc.c */ +#line 305 "glcpp/glcpp-parse.y" + { + macro_t *macro = hash_table_find (parser->defines, "__VERSION__"); + if (macro) { + hash_table_remove (parser->defines, "__VERSION__"); + ralloc_free (macro); + } + add_builtin_define (parser, "__VERSION__", (yyvsp[(2) - (3)].ival)); + + if ((yyvsp[(2) - (3)].ival) == 100) + add_builtin_define (parser, "GL_ES", 1); + + /* Currently, all ES2 implementations support highp in the + * fragment shader, so we always define this macro in ES2. + * If we ever get a driver that doesn't support highp, we'll + * need to add a flag to the gl_context and check that here. + */ + if ((yyvsp[(2) - (3)].ival) >= 130 || (yyvsp[(2) - (3)].ival) == 100) + add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1); + + ralloc_asprintf_append (&parser->output, "#version %" PRIiMAX, (yyvsp[(2) - (3)].ival)); + ;} + break; + + case 24: + +/* Line 1464 of yacc.c */ +#line 330 "glcpp/glcpp-parse.y" + { + if (strlen ((yyvsp[(1) - (1)].str)) >= 3 && strncmp ((yyvsp[(1) - (1)].str), "0x", 2) == 0) { + (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str) + 2, NULL, 16); + } else if ((yyvsp[(1) - (1)].str)[0] == '0') { + (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str), NULL, 8); + } else { + (yyval.ival) = strtoll ((yyvsp[(1) - (1)].str), NULL, 10); + } + ;} + break; + + case 25: + +/* Line 1464 of yacc.c */ +#line 339 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (1)].ival); + ;} + break; + + case 27: + +/* Line 1464 of yacc.c */ +#line 345 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) || (yyvsp[(3) - (3)].ival); + ;} + break; + + case 28: + +/* Line 1464 of yacc.c */ +#line 348 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) && (yyvsp[(3) - (3)].ival); + ;} + break; + + case 29: + +/* Line 1464 of yacc.c */ +#line 351 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); + ;} + break; + + case 30: + +/* Line 1464 of yacc.c */ +#line 354 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) ^ (yyvsp[(3) - (3)].ival); + ;} + break; + + case 31: + +/* Line 1464 of yacc.c */ +#line 357 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) & (yyvsp[(3) - (3)].ival); + ;} + break; + + case 32: + +/* Line 1464 of yacc.c */ +#line 360 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) != (yyvsp[(3) - (3)].ival); + ;} + break; + + case 33: + +/* Line 1464 of yacc.c */ +#line 363 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) == (yyvsp[(3) - (3)].ival); + ;} + break; + + case 34: + +/* Line 1464 of yacc.c */ +#line 366 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) >= (yyvsp[(3) - (3)].ival); + ;} + break; + + case 35: + +/* Line 1464 of yacc.c */ +#line 369 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) <= (yyvsp[(3) - (3)].ival); + ;} + break; + + case 36: + +/* Line 1464 of yacc.c */ +#line 372 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) > (yyvsp[(3) - (3)].ival); + ;} + break; + + case 37: + +/* Line 1464 of yacc.c */ +#line 375 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) < (yyvsp[(3) - (3)].ival); + ;} + break; + + case 38: + +/* Line 1464 of yacc.c */ +#line 378 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) >> (yyvsp[(3) - (3)].ival); + ;} + break; + + case 39: + +/* Line 1464 of yacc.c */ +#line 381 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) << (yyvsp[(3) - (3)].ival); + ;} + break; + + case 40: + +/* Line 1464 of yacc.c */ +#line 384 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) - (yyvsp[(3) - (3)].ival); + ;} + break; + + case 41: + +/* Line 1464 of yacc.c */ +#line 387 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) + (yyvsp[(3) - (3)].ival); + ;} + break; + + case 42: + +/* Line 1464 of yacc.c */ +#line 390 "glcpp/glcpp-parse.y" + { + if ((yyvsp[(3) - (3)].ival) == 0) { + yyerror (& (yylsp[(1) - (3)]), parser, + "zero modulus in preprocessor directive"); + } else { + (yyval.ival) = (yyvsp[(1) - (3)].ival) % (yyvsp[(3) - (3)].ival); + } + ;} + break; + + case 43: + +/* Line 1464 of yacc.c */ +#line 398 "glcpp/glcpp-parse.y" + { + if ((yyvsp[(3) - (3)].ival) == 0) { + yyerror (& (yylsp[(1) - (3)]), parser, + "division by 0 in preprocessor directive"); + } else { + (yyval.ival) = (yyvsp[(1) - (3)].ival) / (yyvsp[(3) - (3)].ival); + } + ;} + break; + + case 44: + +/* Line 1464 of yacc.c */ +#line 406 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(1) - (3)].ival) * (yyvsp[(3) - (3)].ival); + ;} + break; + + case 45: + +/* Line 1464 of yacc.c */ +#line 409 "glcpp/glcpp-parse.y" + { + (yyval.ival) = ! (yyvsp[(2) - (2)].ival); + ;} + break; + + case 46: + +/* Line 1464 of yacc.c */ +#line 412 "glcpp/glcpp-parse.y" + { + (yyval.ival) = ~ (yyvsp[(2) - (2)].ival); + ;} + break; + + case 47: + +/* Line 1464 of yacc.c */ +#line 415 "glcpp/glcpp-parse.y" + { + (yyval.ival) = - (yyvsp[(2) - (2)].ival); + ;} + break; + + case 48: + +/* Line 1464 of yacc.c */ +#line 418 "glcpp/glcpp-parse.y" + { + (yyval.ival) = + (yyvsp[(2) - (2)].ival); + ;} + break; + + case 49: + +/* Line 1464 of yacc.c */ +#line 421 "glcpp/glcpp-parse.y" + { + (yyval.ival) = (yyvsp[(2) - (3)].ival); + ;} + break; + + case 50: + +/* Line 1464 of yacc.c */ +#line 427 "glcpp/glcpp-parse.y" + { + (yyval.string_list) = _string_list_create (parser); + _string_list_append_item ((yyval.string_list), (yyvsp[(1) - (1)].str)); + ralloc_steal ((yyval.string_list), (yyvsp[(1) - (1)].str)); + ;} + break; + + case 51: + +/* Line 1464 of yacc.c */ +#line 432 "glcpp/glcpp-parse.y" + { + (yyval.string_list) = (yyvsp[(1) - (3)].string_list); + _string_list_append_item ((yyval.string_list), (yyvsp[(3) - (3)].str)); + ralloc_steal ((yyval.string_list), (yyvsp[(3) - (3)].str)); + ;} + break; + + case 52: + +/* Line 1464 of yacc.c */ +#line 440 "glcpp/glcpp-parse.y" + { (yyval.token_list) = NULL; ;} + break; + + case 54: + +/* Line 1464 of yacc.c */ +#line 445 "glcpp/glcpp-parse.y" + { + yyerror (& (yylsp[(1) - (2)]), parser, "Invalid tokens after #"); + ;} + break; + + case 55: + +/* Line 1464 of yacc.c */ +#line 451 "glcpp/glcpp-parse.y" + { (yyval.token_list) = NULL; ;} + break; + + case 58: + +/* Line 1464 of yacc.c */ +#line 457 "glcpp/glcpp-parse.y" + { + glcpp_warning(&(yylsp[(1) - (1)]), parser, "extra tokens at end of directive"); + ;} + break; + + case 59: + +/* Line 1464 of yacc.c */ +#line 464 "glcpp/glcpp-parse.y" + { + int v = hash_table_find (parser->defines, (yyvsp[(2) - (2)].str)) ? 1 : 0; + (yyval.token) = _token_create_ival (parser, INTEGER, v); + ;} + break; + + case 60: + +/* Line 1464 of yacc.c */ +#line 468 "glcpp/glcpp-parse.y" + { + int v = hash_table_find (parser->defines, (yyvsp[(3) - (4)].str)) ? 1 : 0; + (yyval.token) = _token_create_ival (parser, INTEGER, v); + ;} + break; + + case 62: + +/* Line 1464 of yacc.c */ +#line 477 "glcpp/glcpp-parse.y" + { + (yyval.token_list) = _token_list_create (parser); + _token_list_append ((yyval.token_list), (yyvsp[(1) - (1)].token)); + ;} + break; + + case 63: + +/* Line 1464 of yacc.c */ +#line 481 "glcpp/glcpp-parse.y" + { + (yyval.token_list) = (yyvsp[(1) - (2)].token_list); + _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token)); + ;} + break; + + case 64: + +/* Line 1464 of yacc.c */ +#line 488 "glcpp/glcpp-parse.y" + { + parser->space_tokens = 1; + (yyval.token_list) = _token_list_create (parser); + _token_list_append ((yyval.token_list), (yyvsp[(1) - (1)].token)); + ;} + break; + + case 65: + +/* Line 1464 of yacc.c */ +#line 493 "glcpp/glcpp-parse.y" + { + (yyval.token_list) = (yyvsp[(1) - (2)].token_list); + _token_list_append ((yyval.token_list), (yyvsp[(2) - (2)].token)); + ;} + break; + + case 66: + +/* Line 1464 of yacc.c */ +#line 500 "glcpp/glcpp-parse.y" + { + (yyval.token) = _token_create_str (parser, IDENTIFIER, (yyvsp[(1) - (1)].str)); + (yyval.token)->location = yylloc; + ;} + break; + + case 67: + +/* Line 1464 of yacc.c */ +#line 504 "glcpp/glcpp-parse.y" + { + (yyval.token) = _token_create_str (parser, INTEGER_STRING, (yyvsp[(1) - (1)].str)); + (yyval.token)->location = yylloc; + ;} + break; + + case 68: + +/* Line 1464 of yacc.c */ +#line 508 "glcpp/glcpp-parse.y" + { + (yyval.token) = _token_create_ival (parser, (yyvsp[(1) - (1)].ival), (yyvsp[(1) - (1)].ival)); + (yyval.token)->location = yylloc; + ;} + break; + + case 69: + +/* Line 1464 of yacc.c */ +#line 512 "glcpp/glcpp-parse.y" + { + (yyval.token) = _token_create_str (parser, OTHER, (yyvsp[(1) - (1)].str)); + (yyval.token)->location = yylloc; + ;} + break; + + case 70: + +/* Line 1464 of yacc.c */ +#line 516 "glcpp/glcpp-parse.y" + { + (yyval.token) = _token_create_ival (parser, SPACE, SPACE); + (yyval.token)->location = yylloc; + ;} + break; + + case 71: + +/* Line 1464 of yacc.c */ +#line 523 "glcpp/glcpp-parse.y" + { (yyval.ival) = '['; ;} + break; + + case 72: + +/* Line 1464 of yacc.c */ +#line 524 "glcpp/glcpp-parse.y" + { (yyval.ival) = ']'; ;} + break; + + case 73: + +/* Line 1464 of yacc.c */ +#line 525 "glcpp/glcpp-parse.y" + { (yyval.ival) = '('; ;} + break; + + case 74: + +/* Line 1464 of yacc.c */ +#line 526 "glcpp/glcpp-parse.y" + { (yyval.ival) = ')'; ;} + break; + + case 75: + +/* Line 1464 of yacc.c */ +#line 527 "glcpp/glcpp-parse.y" + { (yyval.ival) = '{'; ;} + break; + + case 76: + +/* Line 1464 of yacc.c */ +#line 528 "glcpp/glcpp-parse.y" + { (yyval.ival) = '}'; ;} + break; + + case 77: + +/* Line 1464 of yacc.c */ +#line 529 "glcpp/glcpp-parse.y" + { (yyval.ival) = '.'; ;} + break; + + case 78: + +/* Line 1464 of yacc.c */ +#line 530 "glcpp/glcpp-parse.y" + { (yyval.ival) = '&'; ;} + break; + + case 79: + +/* Line 1464 of yacc.c */ +#line 531 "glcpp/glcpp-parse.y" + { (yyval.ival) = '*'; ;} + break; + + case 80: + +/* Line 1464 of yacc.c */ +#line 532 "glcpp/glcpp-parse.y" + { (yyval.ival) = '+'; ;} + break; + + case 81: + +/* Line 1464 of yacc.c */ +#line 533 "glcpp/glcpp-parse.y" + { (yyval.ival) = '-'; ;} + break; + + case 82: + +/* Line 1464 of yacc.c */ +#line 534 "glcpp/glcpp-parse.y" + { (yyval.ival) = '~'; ;} + break; + + case 83: + +/* Line 1464 of yacc.c */ +#line 535 "glcpp/glcpp-parse.y" + { (yyval.ival) = '!'; ;} + break; + + case 84: + +/* Line 1464 of yacc.c */ +#line 536 "glcpp/glcpp-parse.y" + { (yyval.ival) = '/'; ;} + break; + + case 85: + +/* Line 1464 of yacc.c */ +#line 537 "glcpp/glcpp-parse.y" + { (yyval.ival) = '%'; ;} + break; + + case 86: + +/* Line 1464 of yacc.c */ +#line 538 "glcpp/glcpp-parse.y" + { (yyval.ival) = LEFT_SHIFT; ;} + break; + + case 87: + +/* Line 1464 of yacc.c */ +#line 539 "glcpp/glcpp-parse.y" + { (yyval.ival) = RIGHT_SHIFT; ;} + break; + + case 88: + +/* Line 1464 of yacc.c */ +#line 540 "glcpp/glcpp-parse.y" + { (yyval.ival) = '<'; ;} + break; + + case 89: + +/* Line 1464 of yacc.c */ +#line 541 "glcpp/glcpp-parse.y" + { (yyval.ival) = '>'; ;} + break; + + case 90: + +/* Line 1464 of yacc.c */ +#line 542 "glcpp/glcpp-parse.y" + { (yyval.ival) = LESS_OR_EQUAL; ;} + break; + + case 91: + +/* Line 1464 of yacc.c */ +#line 543 "glcpp/glcpp-parse.y" + { (yyval.ival) = GREATER_OR_EQUAL; ;} + break; + + case 92: + +/* Line 1464 of yacc.c */ +#line 544 "glcpp/glcpp-parse.y" + { (yyval.ival) = EQUAL; ;} + break; + + case 93: + +/* Line 1464 of yacc.c */ +#line 545 "glcpp/glcpp-parse.y" + { (yyval.ival) = NOT_EQUAL; ;} + break; + + case 94: + +/* Line 1464 of yacc.c */ +#line 546 "glcpp/glcpp-parse.y" + { (yyval.ival) = '^'; ;} + break; + + case 95: + +/* Line 1464 of yacc.c */ +#line 547 "glcpp/glcpp-parse.y" + { (yyval.ival) = '|'; ;} + break; + + case 96: + +/* Line 1464 of yacc.c */ +#line 548 "glcpp/glcpp-parse.y" + { (yyval.ival) = AND; ;} + break; + + case 97: + +/* Line 1464 of yacc.c */ +#line 549 "glcpp/glcpp-parse.y" + { (yyval.ival) = OR; ;} + break; + + case 98: + +/* Line 1464 of yacc.c */ +#line 550 "glcpp/glcpp-parse.y" + { (yyval.ival) = ';'; ;} + break; + + case 99: + +/* Line 1464 of yacc.c */ +#line 551 "glcpp/glcpp-parse.y" + { (yyval.ival) = ','; ;} + break; + + case 100: + +/* Line 1464 of yacc.c */ +#line 552 "glcpp/glcpp-parse.y" + { (yyval.ival) = '='; ;} + break; + + case 101: + +/* Line 1464 of yacc.c */ +#line 553 "glcpp/glcpp-parse.y" + { (yyval.ival) = PASTE; ;} + break; + + + +/* Line 1464 of yacc.c */ +#line 2662 "glcpp/glcpp-parse.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + *++yylsp = yyloc; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (&yylloc, parser, YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (&yylloc, parser, yymsg); + } + else + { + yyerror (&yylloc, parser, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + yyerror_range[1] = yylloc; + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, &yylloc, parser); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + yyerror_range[1] = yylsp[1-yylen]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + yyerror_range[1] = *yylsp; + yydestruct ("Error: popping", + yystos[yystate], yyvsp, yylsp, parser); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + yyerror_range[2] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the lookahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, yyerror_range, 2); + *++yylsp = yyloc; + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (&yylloc, parser, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc, parser); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, yylsp, parser); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1684 of yacc.c */ +#line 556 "glcpp/glcpp-parse.y" + + +string_list_t * +_string_list_create (void *ctx) +{ + string_list_t *list; + + list = ralloc (ctx, string_list_t); + list->head = NULL; + list->tail = NULL; + + return list; +} + +void +_string_list_append_item (string_list_t *list, const char *str) +{ + string_node_t *node; + + node = ralloc (list, string_node_t); + node->str = ralloc_strdup (node, str); + + node->next = NULL; + + if (list->head == NULL) { + list->head = node; + } else { + list->tail->next = node; + } + + list->tail = node; +} + +int +_string_list_contains (string_list_t *list, const char *member, int *index) +{ + string_node_t *node; + int i; + + if (list == NULL) + return 0; + + for (i = 0, node = list->head; node; i++, node = node->next) { + if (strcmp (node->str, member) == 0) { + if (index) + *index = i; + return 1; + } + } + + return 0; +} + +int +_string_list_length (string_list_t *list) +{ + int length = 0; + string_node_t *node; + + if (list == NULL) + return 0; + + for (node = list->head; node; node = node->next) + length++; + + return length; +} + +int +_string_list_equal (string_list_t *a, string_list_t *b) +{ + string_node_t *node_a, *node_b; + + if (a == NULL && b == NULL) + return 1; + + if (a == NULL || b == NULL) + return 0; + + for (node_a = a->head, node_b = b->head; + node_a && node_b; + node_a = node_a->next, node_b = node_b->next) + { + if (strcmp (node_a->str, node_b->str)) + return 0; + } + + /* Catch the case of lists being different lengths, (which + * would cause the loop above to terminate after the shorter + * list). */ + return node_a == node_b; +} + +argument_list_t * +_argument_list_create (void *ctx) +{ + argument_list_t *list; + + list = ralloc (ctx, argument_list_t); + list->head = NULL; + list->tail = NULL; + + return list; +} + +void +_argument_list_append (argument_list_t *list, token_list_t *argument) +{ + argument_node_t *node; + + node = ralloc (list, argument_node_t); + node->argument = argument; + + node->next = NULL; + + if (list->head == NULL) { + list->head = node; + } else { + list->tail->next = node; + } + + list->tail = node; +} + +int +_argument_list_length (argument_list_t *list) +{ + int length = 0; + argument_node_t *node; + + if (list == NULL) + return 0; + + for (node = list->head; node; node = node->next) + length++; + + return length; +} + +token_list_t * +_argument_list_member_at (argument_list_t *list, int index) +{ + argument_node_t *node; + int i; + + if (list == NULL) + return NULL; + + node = list->head; + for (i = 0; i < index; i++) { + node = node->next; + if (node == NULL) + break; + } + + if (node) + return node->argument; + + return NULL; +} + +/* Note: This function ralloc_steal()s the str pointer. */ +token_t * +_token_create_str (void *ctx, int type, char *str) +{ + token_t *token; + + token = ralloc (ctx, token_t); + token->type = type; + token->value.str = str; + + ralloc_steal (token, str); + + return token; +} + +token_t * +_token_create_ival (void *ctx, int type, int ival) +{ + token_t *token; + + token = ralloc (ctx, token_t); + token->type = type; + token->value.ival = ival; + + return token; +} + +token_list_t * +_token_list_create (void *ctx) +{ + token_list_t *list; + + list = ralloc (ctx, token_list_t); + list->head = NULL; + list->tail = NULL; + list->non_space_tail = NULL; + + return list; +} + +void +_token_list_append (token_list_t *list, token_t *token) +{ + token_node_t *node; + + node = ralloc (list, token_node_t); + node->token = token; + node->next = NULL; + + ralloc_steal (list, token); + + if (list->head == NULL) { + list->head = node; + } else { + list->tail->next = node; + } + + list->tail = node; + if (token->type != SPACE) + list->non_space_tail = node; +} + +void +_token_list_append_list (token_list_t *list, token_list_t *tail) +{ + if (tail == NULL || tail->head == NULL) + return; + + if (list->head == NULL) { + list->head = tail->head; + } else { + list->tail->next = tail->head; + } + + list->tail = tail->tail; + list->non_space_tail = tail->non_space_tail; +} + +static token_list_t * +_token_list_copy (void *ctx, token_list_t *other) +{ + token_list_t *copy; + token_node_t *node; + + if (other == NULL) + return NULL; + + copy = _token_list_create (ctx); + for (node = other->head; node; node = node->next) { + token_t *new_token = ralloc (copy, token_t); + *new_token = *node->token; + _token_list_append (copy, new_token); + } + + return copy; +} + +static void +_token_list_trim_trailing_space (token_list_t *list) +{ + token_node_t *tail, *next; + + if (list->non_space_tail) { + tail = list->non_space_tail->next; + list->non_space_tail->next = NULL; + list->tail = list->non_space_tail; + + while (tail) { + next = tail->next; + ralloc_free (tail); + tail = next; + } + } +} + +static int +_token_list_is_empty_ignoring_space (token_list_t *l) +{ + token_node_t *n; + + if (l == NULL) + return 1; + + n = l->head; + while (n != NULL && n->token->type == SPACE) + n = n->next; + + return n == NULL; +} + +int +_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b) +{ + token_node_t *node_a, *node_b; + + if (a == NULL || b == NULL) { + int a_empty = _token_list_is_empty_ignoring_space(a); + int b_empty = _token_list_is_empty_ignoring_space(b); + return a_empty == b_empty; + } + + node_a = a->head; + node_b = b->head; + + while (1) + { + if (node_a == NULL && node_b == NULL) + break; + + if (node_a == NULL || node_b == NULL) + return 0; + + if (node_a->token->type == SPACE) { + node_a = node_a->next; + continue; + } + + if (node_b->token->type == SPACE) { + node_b = node_b->next; + continue; + } + + if (node_a->token->type != node_b->token->type) + return 0; + + switch (node_a->token->type) { + case INTEGER: + if (node_a->token->value.ival != + node_b->token->value.ival) + { + return 0; + } + break; + case IDENTIFIER: + case INTEGER_STRING: + case OTHER: + if (strcmp (node_a->token->value.str, + node_b->token->value.str)) + { + return 0; + } + break; + } + + node_a = node_a->next; + node_b = node_b->next; + } + + return 1; +} + +static void +_token_print (char **out, token_t *token) +{ + if (token->type < 256) { + ralloc_asprintf_append (out, "%c", token->type); + return; + } + + switch (token->type) { + case INTEGER: + ralloc_asprintf_append (out, "%" PRIiMAX, token->value.ival); + break; + case IDENTIFIER: + case INTEGER_STRING: + case OTHER: + ralloc_strcat (out, token->value.str); + break; + case SPACE: + ralloc_strcat (out, " "); + break; + case LEFT_SHIFT: + ralloc_strcat (out, "<<"); + break; + case RIGHT_SHIFT: + ralloc_strcat (out, ">>"); + break; + case LESS_OR_EQUAL: + ralloc_strcat (out, "<="); + break; + case GREATER_OR_EQUAL: + ralloc_strcat (out, ">="); + break; + case EQUAL: + ralloc_strcat (out, "=="); + break; + case NOT_EQUAL: + ralloc_strcat (out, "!="); + break; + case AND: + ralloc_strcat (out, "&&"); + break; + case OR: + ralloc_strcat (out, "||"); + break; + case PASTE: + ralloc_strcat (out, "##"); + break; + case COMMA_FINAL: + ralloc_strcat (out, ","); + break; + case PLACEHOLDER: + /* Nothing to print. */ + break; + default: + assert(!"Error: Don't know how to print token."); + break; + } +} + +/* Return a new token (ralloc()ed off of 'token') formed by pasting + * 'token' and 'other'. Note that this function may return 'token' or + * 'other' directly rather than allocating anything new. + * + * Caution: Only very cursory error-checking is performed to see if + * the final result is a valid single token. */ +static token_t * +_token_paste (glcpp_parser_t *parser, token_t *token, token_t *other) +{ + token_t *combined = NULL; + + /* Pasting a placeholder onto anything makes no change. */ + if (other->type == PLACEHOLDER) + return token; + + /* When 'token' is a placeholder, just return 'other'. */ + if (token->type == PLACEHOLDER) + return other; + + /* A very few single-character punctuators can be combined + * with another to form a multi-character punctuator. */ + switch (token->type) { + case '<': + if (other->type == '<') + combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT); + else if (other->type == '=') + combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL); + break; + case '>': + if (other->type == '>') + combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT); + else if (other->type == '=') + combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL); + break; + case '=': + if (other->type == '=') + combined = _token_create_ival (token, EQUAL, EQUAL); + break; + case '!': + if (other->type == '=') + combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL); + break; + case '&': + if (other->type == '&') + combined = _token_create_ival (token, AND, AND); + break; + case '|': + if (other->type == '|') + combined = _token_create_ival (token, OR, OR); + break; + } + + if (combined != NULL) { + /* Inherit the location from the first token */ + combined->location = token->location; + return combined; + } + + /* Two string-valued tokens can usually just be mashed + * together. + * + * XXX: This isn't actually legitimate. Several things here + * should result in a diagnostic since the result cannot be a + * valid, single pre-processing token. For example, pasting + * "123" and "abc" is not legal, but we don't catch that + * here. */ + if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING) && + (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING)) + { + char *str; + + str = ralloc_asprintf (token, "%s%s", token->value.str, + other->value.str); + combined = _token_create_str (token, token->type, str); + combined->location = token->location; + return combined; + } + + glcpp_error (&token->location, parser, ""); + ralloc_strcat (&parser->info_log, "Pasting \""); + _token_print (&parser->info_log, token); + ralloc_strcat (&parser->info_log, "\" and \""); + _token_print (&parser->info_log, other); + ralloc_strcat (&parser->info_log, "\" does not give a valid preprocessing token.\n"); + + return token; +} + +static void +_token_list_print (glcpp_parser_t *parser, token_list_t *list) +{ + token_node_t *node; + + if (list == NULL) + return; + + for (node = list->head; node; node = node->next) + _token_print (&parser->output, node->token); +} + +void +yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error) +{ + glcpp_error(locp, parser, "%s", error); +} + +static void add_builtin_define(glcpp_parser_t *parser, + const char *name, int value) +{ + token_t *tok; + token_list_t *list; + + tok = _token_create_ival (parser, INTEGER, value); + + list = _token_list_create(parser); + _token_list_append(list, tok); + _define_object_macro(parser, NULL, name, list); +} + +glcpp_parser_t * +glcpp_parser_create (const struct gl_extensions *extensions, int api) +{ + glcpp_parser_t *parser; + int language_version; + + parser = ralloc (NULL, glcpp_parser_t); + + glcpp_lex_init_extra (parser, &parser->scanner); + parser->defines = hash_table_ctor (32, hash_table_string_hash, + hash_table_string_compare); + parser->active = NULL; + parser->lexing_if = 0; + parser->space_tokens = 1; + parser->newline_as_space = 0; + parser->in_control_line = 0; + parser->paren_count = 0; + + parser->skip_stack = NULL; + + parser->lex_from_list = NULL; + parser->lex_from_node = NULL; + + parser->output = ralloc_strdup(parser, ""); + parser->info_log = ralloc_strdup(parser, ""); + parser->error = 0; + + /* Add pre-defined macros. */ + add_builtin_define(parser, "GL_ARB_draw_buffers", 1); + add_builtin_define(parser, "GL_ARB_texture_rectangle", 1); + + if (api == API_OPENGLES2) + add_builtin_define(parser, "GL_ES", 1); + + if (extensions != NULL) { + if (extensions->EXT_texture_array) { + add_builtin_define(parser, "GL_EXT_texture_array", 1); + } + + if (extensions->ARB_fragment_coord_conventions) + add_builtin_define(parser, "GL_ARB_fragment_coord_conventions", + 1); + + if (extensions->ARB_explicit_attrib_location) + add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1); + if (extensions->AMD_conservative_depth) + add_builtin_define(parser, "GL_AMD_conservative_depth", 1); + } + + language_version = 110; + add_builtin_define(parser, "__VERSION__", language_version); + + return parser; +} + +int +glcpp_parser_parse (glcpp_parser_t *parser) +{ + return yyparse (parser); +} + +void +glcpp_parser_destroy (glcpp_parser_t *parser) +{ + glcpp_lex_destroy (parser->scanner); + hash_table_dtor (parser->defines); + ralloc_free (parser); +} + +typedef enum function_status +{ + FUNCTION_STATUS_SUCCESS, + FUNCTION_NOT_A_FUNCTION, + FUNCTION_UNBALANCED_PARENTHESES +} function_status_t; + +/* Find a set of function-like macro arguments by looking for a + * balanced set of parentheses. + * + * When called, 'node' should be the opening-parenthesis token, (or + * perhaps preceeding SPACE tokens). Upon successful return *last will + * be the last consumed node, (corresponding to the closing right + * parenthesis). + * + * Return values: + * + * FUNCTION_STATUS_SUCCESS: + * + * Successfully parsed a set of function arguments. + * + * FUNCTION_NOT_A_FUNCTION: + * + * Macro name not followed by a '('. This is not an error, but + * simply that the macro name should be treated as a non-macro. + * + * FUNCTION_UNBALANCED_PARENTHESES + * + * Macro name is not followed by a balanced set of parentheses. + */ +static function_status_t +_arguments_parse (argument_list_t *arguments, + token_node_t *node, + token_node_t **last) +{ + token_list_t *argument; + int paren_count; + + node = node->next; + + /* Ignore whitespace before first parenthesis. */ + while (node && node->token->type == SPACE) + node = node->next; + + if (node == NULL || node->token->type != '(') + return FUNCTION_NOT_A_FUNCTION; + + node = node->next; + + argument = _token_list_create (arguments); + _argument_list_append (arguments, argument); + + for (paren_count = 1; node; node = node->next) { + if (node->token->type == '(') + { + paren_count++; + } + else if (node->token->type == ')') + { + paren_count--; + if (paren_count == 0) + break; + } + + if (node->token->type == ',' && + paren_count == 1) + { + _token_list_trim_trailing_space (argument); + argument = _token_list_create (arguments); + _argument_list_append (arguments, argument); + } + else { + if (argument->head == NULL) { + /* Don't treat initial whitespace as + * part of the arguement. */ + if (node->token->type == SPACE) + continue; + } + _token_list_append (argument, node->token); + } + } + + if (paren_count) + return FUNCTION_UNBALANCED_PARENTHESES; + + *last = node; + + return FUNCTION_STATUS_SUCCESS; +} + +static token_list_t * +_token_list_create_with_one_space (void *ctx) +{ + token_list_t *list; + token_t *space; + + list = _token_list_create (ctx); + space = _token_create_ival (list, SPACE, SPACE); + _token_list_append (list, space); + + return list; +} + +static void +_glcpp_parser_expand_if (glcpp_parser_t *parser, int type, token_list_t *list) +{ + token_list_t *expanded; + token_t *token; + + expanded = _token_list_create (parser); + token = _token_create_ival (parser, type, type); + _token_list_append (expanded, token); + _glcpp_parser_expand_token_list (parser, list); + _token_list_append_list (expanded, list); + glcpp_parser_lex_from (parser, expanded); +} + +/* This is a helper function that's essentially part of the + * implementation of _glcpp_parser_expand_node. It shouldn't be called + * except for by that function. + * + * Returns NULL if node is a simple token with no expansion, (that is, + * although 'node' corresponds to an identifier defined as a + * function-like macro, it is not followed with a parenthesized + * argument list). + * + * Compute the complete expansion of node (which is a function-like + * macro) and subsequent nodes which are arguments. + * + * Returns the token list that results from the expansion and sets + * *last to the last node in the list that was consumed by the + * expansion. Specifically, *last will be set as follows: as the + * token of the closing right parenthesis. + */ +static token_list_t * +_glcpp_parser_expand_function (glcpp_parser_t *parser, + token_node_t *node, + token_node_t **last) + +{ + macro_t *macro; + const char *identifier; + argument_list_t *arguments; + function_status_t status; + token_list_t *substituted; + int parameter_index; + + identifier = node->token->value.str; + + macro = hash_table_find (parser->defines, identifier); + + assert (macro->is_function); + + arguments = _argument_list_create (parser); + status = _arguments_parse (arguments, node, last); + + switch (status) { + case FUNCTION_STATUS_SUCCESS: + break; + case FUNCTION_NOT_A_FUNCTION: + return NULL; + case FUNCTION_UNBALANCED_PARENTHESES: + glcpp_error (&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier); + return NULL; + } + + /* Replace a macro defined as empty with a SPACE token. */ + if (macro->replacements == NULL) { + ralloc_free (arguments); + return _token_list_create_with_one_space (parser); + } + + if (! ((_argument_list_length (arguments) == + _string_list_length (macro->parameters)) || + (_string_list_length (macro->parameters) == 0 && + _argument_list_length (arguments) == 1 && + arguments->head->argument->head == NULL))) + { + glcpp_error (&node->token->location, parser, + "Error: macro %s invoked with %d arguments (expected %d)\n", + identifier, + _argument_list_length (arguments), + _string_list_length (macro->parameters)); + return NULL; + } + + /* Perform argument substitution on the replacement list. */ + substituted = _token_list_create (arguments); + + for (node = macro->replacements->head; node; node = node->next) + { + if (node->token->type == IDENTIFIER && + _string_list_contains (macro->parameters, + node->token->value.str, + ¶meter_index)) + { + token_list_t *argument; + argument = _argument_list_member_at (arguments, + parameter_index); + /* Before substituting, we expand the argument + * tokens, or append a placeholder token for + * an empty argument. */ + if (argument->head) { + token_list_t *expanded_argument; + expanded_argument = _token_list_copy (parser, + argument); + _glcpp_parser_expand_token_list (parser, + expanded_argument); + _token_list_append_list (substituted, + expanded_argument); + } else { + token_t *new_token; + + new_token = _token_create_ival (substituted, + PLACEHOLDER, + PLACEHOLDER); + _token_list_append (substituted, new_token); + } + } else { + _token_list_append (substituted, node->token); + } + } + + /* After argument substitution, and before further expansion + * below, implement token pasting. */ + + _token_list_trim_trailing_space (substituted); + + node = substituted->head; + while (node) + { + token_node_t *next_non_space; + + /* Look ahead for a PASTE token, skipping space. */ + next_non_space = node->next; + while (next_non_space && next_non_space->token->type == SPACE) + next_non_space = next_non_space->next; + + if (next_non_space == NULL) + break; + + if (next_non_space->token->type != PASTE) { + node = next_non_space; + continue; + } + + /* Now find the next non-space token after the PASTE. */ + next_non_space = next_non_space->next; + while (next_non_space && next_non_space->token->type == SPACE) + next_non_space = next_non_space->next; + + if (next_non_space == NULL) { + yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n"); + return NULL; + } + + node->token = _token_paste (parser, node->token, next_non_space->token); + node->next = next_non_space->next; + if (next_non_space == substituted->tail) + substituted->tail = node; + + node = node->next; + } + + substituted->non_space_tail = substituted->tail; + + return substituted; +} + +/* Compute the complete expansion of node, (and subsequent nodes after + * 'node' in the case that 'node' is a function-like macro and + * subsequent nodes are arguments). + * + * Returns NULL if node is a simple token with no expansion. + * + * Otherwise, returns the token list that results from the expansion + * and sets *last to the last node in the list that was consumed by + * the expansion. Specifically, *last will be set as follows: + * + * As 'node' in the case of object-like macro expansion. + * + * As the token of the closing right parenthesis in the case of + * function-like macro expansion. + */ +static token_list_t * +_glcpp_parser_expand_node (glcpp_parser_t *parser, + token_node_t *node, + token_node_t **last) +{ + token_t *token = node->token; + const char *identifier; + macro_t *macro; + + /* We only expand identifiers */ + if (token->type != IDENTIFIER) { + /* We change any COMMA into a COMMA_FINAL to prevent + * it being mistaken for an argument separator + * later. */ + if (token->type == ',') { + token->type = COMMA_FINAL; + token->value.ival = COMMA_FINAL; + } + + return NULL; + } + + /* Look up this identifier in the hash table. */ + identifier = token->value.str; + macro = hash_table_find (parser->defines, identifier); + + /* Not a macro, so no expansion needed. */ + if (macro == NULL) + return NULL; + + /* Finally, don't expand this macro if we're already actively + * expanding it, (to avoid infinite recursion). */ + if (_active_list_contains (parser->active, identifier)) { + /* We change the token type here from IDENTIFIER to + * OTHER to prevent any future expansion of this + * unexpanded token. */ + char *str; + token_list_t *expansion; + token_t *final; + + str = ralloc_strdup (parser, token->value.str); + final = _token_create_str (parser, OTHER, str); + expansion = _token_list_create (parser); + _token_list_append (expansion, final); + *last = node; + return expansion; + } + + if (! macro->is_function) + { + *last = node; + + /* Replace a macro defined as empty with a SPACE token. */ + if (macro->replacements == NULL) + return _token_list_create_with_one_space (parser); + + return _token_list_copy (parser, macro->replacements); + } + + return _glcpp_parser_expand_function (parser, node, last); +} + +/* Push a new identifier onto the active list, returning the new list. + * + * Here, 'marker' is the token node that appears in the list after the + * expansion of 'identifier'. That is, when the list iterator begins + * examinging 'marker', then it is time to pop this node from the + * active stack. + */ +active_list_t * +_active_list_push (active_list_t *list, + const char *identifier, + token_node_t *marker) +{ + active_list_t *node; + + node = ralloc (list, active_list_t); + node->identifier = ralloc_strdup (node, identifier); + node->marker = marker; + node->next = list; + + return node; +} + +active_list_t * +_active_list_pop (active_list_t *list) +{ + active_list_t *node = list; + + if (node == NULL) + return NULL; + + node = list->next; + ralloc_free (list); + + return node; +} + +int +_active_list_contains (active_list_t *list, const char *identifier) +{ + active_list_t *node; + + if (list == NULL) + return 0; + + for (node = list; node; node = node->next) + if (strcmp (node->identifier, identifier) == 0) + return 1; + + return 0; +} + +/* Walk over the token list replacing nodes with their expansion. + * Whenever nodes are expanded the walking will walk over the new + * nodes, continuing to expand as necessary. The results are placed in + * 'list' itself; + */ +static void +_glcpp_parser_expand_token_list (glcpp_parser_t *parser, + token_list_t *list) +{ + token_node_t *node_prev; + token_node_t *node, *last = NULL; + token_list_t *expansion; + + if (list == NULL) + return; + + _token_list_trim_trailing_space (list); + + node_prev = NULL; + node = list->head; + + while (node) { + + while (parser->active && parser->active->marker == node) + parser->active = _active_list_pop (parser->active); + + /* Find the expansion for node, which will replace all + * nodes from node to last, inclusive. */ + expansion = _glcpp_parser_expand_node (parser, node, &last); + if (expansion) { + token_node_t *n; + + for (n = node; n != last->next; n = n->next) + while (parser->active && + parser->active->marker == n) + { + parser->active = _active_list_pop (parser->active); + } + + parser->active = _active_list_push (parser->active, + node->token->value.str, + last->next); + + /* Splice expansion into list, supporting a + * simple deletion if the expansion is + * empty. */ + if (expansion->head) { + if (node_prev) + node_prev->next = expansion->head; + else + list->head = expansion->head; + expansion->tail->next = last->next; + if (last == list->tail) + list->tail = expansion->tail; + } else { + if (node_prev) + node_prev->next = last->next; + else + list->head = last->next; + if (last == list->tail) + list->tail = NULL; + } + } else { + node_prev = node; + } + node = node_prev ? node_prev->next : list->head; + } + + while (parser->active) + parser->active = _active_list_pop (parser->active); + + list->non_space_tail = list->tail; +} + +void +_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, + token_list_t *list) +{ + if (list == NULL) + return; + + _glcpp_parser_expand_token_list (parser, list); + + _token_list_trim_trailing_space (list); + + _token_list_print (parser, list); +} + +static void +_check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc, + const char *identifier) +{ + /* According to the GLSL specification, macro names starting with "__" + * or "GL_" are reserved for future use. So, don't allow them. + */ + if (strncmp(identifier, "__", 2) == 0) { + glcpp_error (loc, parser, "Macro names starting with \"__\" are reserved.\n"); + } + if (strncmp(identifier, "GL_", 3) == 0) { + glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n"); + } +} + +static int +_macro_equal (macro_t *a, macro_t *b) +{ + if (a->is_function != b->is_function) + return 0; + + if (a->is_function) { + if (! _string_list_equal (a->parameters, b->parameters)) + return 0; + } + + return _token_list_equal_ignoring_space (a->replacements, + b->replacements); +} + +void +_define_object_macro (glcpp_parser_t *parser, + YYLTYPE *loc, + const char *identifier, + token_list_t *replacements) +{ + macro_t *macro, *previous; + + if (loc != NULL) + _check_for_reserved_macro_name(parser, loc, identifier); + + macro = ralloc (parser, macro_t); + + macro->is_function = 0; + macro->parameters = NULL; + macro->identifier = ralloc_strdup (macro, identifier); + macro->replacements = replacements; + ralloc_steal (macro, replacements); + + previous = hash_table_find (parser->defines, identifier); + if (previous) { + if (_macro_equal (macro, previous)) { + ralloc_free (macro); + return; + } + glcpp_error (loc, parser, "Redefinition of macro %s\n", + identifier); + } + + hash_table_insert (parser->defines, macro, identifier); +} + +void +_define_function_macro (glcpp_parser_t *parser, + YYLTYPE *loc, + const char *identifier, + string_list_t *parameters, + token_list_t *replacements) +{ + macro_t *macro, *previous; + + _check_for_reserved_macro_name(parser, loc, identifier); + + macro = ralloc (parser, macro_t); + ralloc_steal (macro, parameters); + ralloc_steal (macro, replacements); + + macro->is_function = 1; + macro->parameters = parameters; + macro->identifier = ralloc_strdup (macro, identifier); + macro->replacements = replacements; + previous = hash_table_find (parser->defines, identifier); + if (previous) { + if (_macro_equal (macro, previous)) { + ralloc_free (macro); + return; + } + glcpp_error (loc, parser, "Redefinition of macro %s\n", + identifier); + } + + hash_table_insert (parser->defines, macro, identifier); +} + +static int +glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) +{ + token_node_t *node; + int ret; + + if (parser->lex_from_list == NULL) { + ret = glcpp_lex (yylval, yylloc, parser->scanner); + + /* XXX: This ugly block of code exists for the sole + * purpose of converting a NEWLINE token into a SPACE + * token, but only in the case where we have seen a + * function-like macro name, but have not yet seen its + * closing parenthesis. + * + * There's perhaps a more compact way to do this with + * mid-rule actions in the grammar. + * + * I'm definitely not pleased with the complexity of + * this code here. + */ + if (parser->newline_as_space) + { + if (ret == '(') { + parser->paren_count++; + } else if (ret == ')') { + parser->paren_count--; + if (parser->paren_count == 0) + parser->newline_as_space = 0; + } else if (ret == NEWLINE) { + ret = SPACE; + } else if (ret != SPACE) { + if (parser->paren_count == 0) + parser->newline_as_space = 0; + } + } + else if (parser->in_control_line) + { + if (ret == NEWLINE) + parser->in_control_line = 0; + } + else if (ret == HASH_DEFINE_OBJ || ret == HASH_DEFINE_FUNC || + ret == HASH_UNDEF || ret == HASH_IF || + ret == HASH_IFDEF || ret == HASH_IFNDEF || + ret == HASH_ELIF || ret == HASH_ELSE || + ret == HASH_ENDIF || ret == HASH) + { + parser->in_control_line = 1; + } + else if (ret == IDENTIFIER) + { + macro_t *macro; + macro = hash_table_find (parser->defines, + yylval->str); + if (macro && macro->is_function) { + parser->newline_as_space = 1; + parser->paren_count = 0; + } + } + + return ret; + } + + node = parser->lex_from_node; + + if (node == NULL) { + ralloc_free (parser->lex_from_list); + parser->lex_from_list = NULL; + return NEWLINE; + } + + *yylval = node->token->value; + ret = node->token->type; + + parser->lex_from_node = node->next; + + return ret; +} + +static void +glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list) +{ + token_node_t *node; + + assert (parser->lex_from_list == NULL); + + /* Copy list, eliminating any space tokens. */ + parser->lex_from_list = _token_list_create (parser); + + for (node = list->head; node; node = node->next) { + if (node->token->type == SPACE) + continue; + _token_list_append (parser->lex_from_list, node->token); + } + + ralloc_free (list); + + parser->lex_from_node = parser->lex_from_list->head; + + /* It's possible the list consisted of nothing but whitespace. */ + if (parser->lex_from_node == NULL) { + ralloc_free (parser->lex_from_list); + parser->lex_from_list = NULL; + } +} + +static void +_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc, + int condition) +{ + skip_type_t current = SKIP_NO_SKIP; + skip_node_t *node; + + if (parser->skip_stack) + current = parser->skip_stack->type; + + node = ralloc (parser, skip_node_t); + node->loc = *loc; + + if (current == SKIP_NO_SKIP) { + if (condition) + node->type = SKIP_NO_SKIP; + else + node->type = SKIP_TO_ELSE; + } else { + node->type = SKIP_TO_ENDIF; + } + + node->next = parser->skip_stack; + parser->skip_stack = node; +} + +static void +_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, + const char *type, int condition) +{ + if (parser->skip_stack == NULL) { + glcpp_error (loc, parser, "%s without #if\n", type); + return; + } + + if (parser->skip_stack->type == SKIP_TO_ELSE) { + if (condition) + parser->skip_stack->type = SKIP_NO_SKIP; + } else { + parser->skip_stack->type = SKIP_TO_ENDIF; + } +} + +static void +_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc) +{ + skip_node_t *node; + + if (parser->skip_stack == NULL) { + glcpp_error (loc, parser, "#endif without #if\n"); + return; + } + + node = parser->skip_stack; + parser->skip_stack = node->next; + ralloc_free (node); +} + diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.h b/mesalib/src/glsl/glcpp/glcpp-parse.h index 50758930e..e51f0bcf0 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.h +++ b/mesalib/src/glsl/glcpp/glcpp-parse.h @@ -1,101 +1,100 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - COMMA_FINAL = 258, - DEFINED = 259, - ELIF_EXPANDED = 260, - HASH = 261, - HASH_DEFINE_FUNC = 262, - HASH_DEFINE_OBJ = 263, - HASH_ELIF = 264, - HASH_ELSE = 265, - HASH_ENDIF = 266, - HASH_IF = 267, - HASH_IFDEF = 268, - HASH_IFNDEF = 269, - HASH_UNDEF = 270, - HASH_VERSION = 271, - IDENTIFIER = 272, - IF_EXPANDED = 273, - INTEGER = 274, - INTEGER_STRING = 275, - NEWLINE = 276, - OTHER = 277, - PLACEHOLDER = 278, - SPACE = 279, - PASTE = 280, - OR = 281, - AND = 282, - NOT_EQUAL = 283, - EQUAL = 284, - GREATER_OR_EQUAL = 285, - LESS_OR_EQUAL = 286, - RIGHT_SHIFT = 287, - LEFT_SHIFT = 288, - UNARY = 289 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - +/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + COMMA_FINAL = 258, + DEFINED = 259, + ELIF_EXPANDED = 260, + HASH = 261, + HASH_DEFINE_FUNC = 262, + HASH_DEFINE_OBJ = 263, + HASH_ELIF = 264, + HASH_ELSE = 265, + HASH_ENDIF = 266, + HASH_IF = 267, + HASH_IFDEF = 268, + HASH_IFNDEF = 269, + HASH_UNDEF = 270, + HASH_VERSION = 271, + IDENTIFIER = 272, + IF_EXPANDED = 273, + INTEGER = 274, + INTEGER_STRING = 275, + NEWLINE = 276, + OTHER = 277, + PLACEHOLDER = 278, + SPACE = 279, + PASTE = 280, + OR = 281, + AND = 282, + NOT_EQUAL = 283, + EQUAL = 284, + GREATER_OR_EQUAL = 285, + LESS_OR_EQUAL = 286, + RIGHT_SHIFT = 287, + LEFT_SHIFT = 288, + UNARY = 289 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + + diff --git a/mesalib/src/glsl/glsl_lexer.cpp b/mesalib/src/glsl/glsl_lexer.cpp index 04927950f..ef9d0178f 100644 --- a/mesalib/src/glsl/glsl_lexer.cpp +++ b/mesalib/src/glsl/glsl_lexer.cpp @@ -1,3713 +1,3726 @@ -#line 2 "glsl_lexer.cpp" - -#line 4 "glsl_lexer.cpp" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE _mesa_glsl_restart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via _mesa_glsl_restart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void _mesa_glsl_restart (FILE *input_file ,yyscan_t yyscanner ); -void _mesa_glsl__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE _mesa_glsl__create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void _mesa_glsl__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void _mesa_glsl__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void _mesa_glsl_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void _mesa_glsl_pop_buffer_state (yyscan_t yyscanner ); - -static void _mesa_glsl_ensure_buffer_stack (yyscan_t yyscanner ); -static void _mesa_glsl__load_buffer_state (yyscan_t yyscanner ); -static void _mesa_glsl__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER _mesa_glsl__flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE _mesa_glsl__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE _mesa_glsl__scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE _mesa_glsl__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *_mesa_glsl_alloc (yy_size_t ,yyscan_t yyscanner ); -void *_mesa_glsl_realloc (void *,yy_size_t ,yyscan_t yyscanner ); -void _mesa_glsl_free (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer _mesa_glsl__create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - _mesa_glsl_ensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - _mesa_glsl_ensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define _mesa_glsl_wrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 210 -#define YY_END_OF_BUFFER 211 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[836] = - { 0, - 0, 0, 16, 16, 0, 0, 211, 209, 1, 21, - 209, 209, 209, 209, 209, 209, 209, 209, 120, 118, - 209, 209, 209, 208, 209, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 209, 1, 209, 210, 16, - 20, 210, 19, 17, 18, 14, 13, 1, 102, 111, - 103, 114, 108, 97, 110, 98, 117, 122, 109, 123, - 120, 0, 0, 125, 120, 0, 118, 118, 106, 99, - 101, 100, 107, 208, 115, 105, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 30, 208, - - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 34, 208, 208, 61, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 116, - 104, 1, 0, 0, 2, 0, 0, 0, 0, 16, - 15, 19, 18, 0, 122, 121, 0, 123, 0, 124, - 119, 112, 113, 208, 128, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 33, 208, 208, 208, - - 208, 208, 208, 208, 208, 208, 208, 26, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 62, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 0, 0, 0, 0, 15, 0, 122, 0, 121, 0, - 123, 124, 119, 208, 208, 24, 208, 208, 175, 168, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 32, - 131, 208, 208, 208, 208, 68, 208, 208, 136, 150, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - - 208, 208, 147, 171, 49, 50, 51, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 134, 126, 208, - 208, 27, 208, 208, 208, 208, 208, 208, 208, 46, - 47, 48, 95, 208, 208, 0, 0, 0, 0, 0, - 121, 208, 208, 28, 37, 38, 39, 208, 129, 208, - 23, 208, 208, 208, 208, 158, 159, 160, 208, 127, - 208, 151, 25, 161, 162, 163, 173, 155, 156, 157, - 208, 208, 208, 63, 153, 208, 208, 208, 40, 41, - 42, 208, 208, 208, 208, 208, 208, 208, 208, 208, - - 208, 208, 208, 208, 208, 208, 208, 148, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 130, 208, - 208, 170, 43, 44, 45, 208, 208, 31, 0, 0, - 0, 0, 178, 208, 208, 176, 208, 208, 208, 149, - 144, 181, 208, 208, 208, 208, 208, 208, 139, 208, - 208, 208, 96, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 208, 208, 208, 208, 154, 135, 208, 208, - 142, 36, 208, 208, 167, 69, 143, 94, 179, 137, - 208, 208, 208, 208, 208, 208, 208, 208, 0, 0, - 0, 0, 208, 208, 208, 138, 35, 208, 208, 208, - - 208, 208, 208, 182, 183, 184, 208, 208, 208, 208, - 208, 172, 208, 208, 208, 208, 208, 208, 208, 208, - 132, 208, 208, 208, 208, 208, 64, 208, 208, 65, - 208, 0, 0, 0, 0, 0, 208, 66, 29, 145, - 186, 187, 188, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 140, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 133, 190, 191, 192, 208, - 208, 152, 208, 141, 0, 0, 6, 0, 0, 0, - 12, 3, 22, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 185, 146, 67, 208, 208, 208, 208, 169, - - 208, 177, 174, 207, 71, 72, 73, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 0, 0, 0, - 0, 0, 0, 0, 208, 208, 208, 189, 208, 208, - 208, 208, 208, 82, 83, 84, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 193, - 88, 89, 90, 208, 4, 0, 5, 0, 0, 0, - 0, 0, 0, 208, 208, 208, 208, 208, 208, 208, - 204, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 74, 208, 208, 208, 208, 208, 208, 0, - 0, 0, 0, 208, 208, 205, 194, 208, 195, 208, - - 208, 208, 85, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 206, 208, 208, 91, 0, 0, - 0, 196, 197, 208, 200, 208, 201, 208, 208, 70, - 208, 208, 208, 164, 208, 165, 180, 208, 198, 199, - 208, 208, 0, 0, 0, 208, 208, 208, 208, 75, - 208, 76, 208, 208, 208, 208, 208, 0, 0, 0, - 0, 208, 208, 86, 87, 208, 77, 208, 208, 78, - 208, 92, 93, 0, 0, 0, 0, 208, 208, 208, - 208, 208, 208, 0, 0, 0, 0, 208, 208, 208, - 208, 208, 79, 0, 0, 0, 7, 0, 0, 202, - - 203, 208, 208, 208, 0, 0, 8, 0, 0, 208, - 208, 166, 0, 0, 0, 80, 81, 0, 0, 0, - 9, 0, 0, 10, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 11, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 1, 6, 1, 7, 8, 1, 9, - 10, 11, 12, 1, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 21, 21, 22, 22, 23, 1, 24, - 25, 26, 1, 1, 27, 28, 29, 30, 31, 32, - 33, 34, 34, 34, 34, 35, 34, 34, 34, 34, - 34, 36, 37, 38, 39, 34, 34, 40, 34, 34, - 1, 1, 1, 41, 42, 1, 43, 44, 45, 46, - - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 34, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 1, 68, 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, - 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, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[69] = - { 0, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 4, 4, 4, 4, - 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, - 1, 5, 4, 4, 4, 4, 3, 3, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 1 - } ; - -static yyconst flex_int16_t yy_base[845] = - { 0, - 0, 67, 73, 0, 1210, 1209, 1211, 1214, 68, 1214, - 1185, 1184, 134, 1183, 131, 132, 130, 1182, 146, 198, - 129, 1181, 144, 0, 130, 113, 124, 141, 150, 126, - 181, 1148, 159, 192, 118, 129, 146, 1142, 147, 174, - 206, 192, 203, 222, 1153, 203, 221, 231, 1214, 260, - 1214, 1187, 279, 1214, 0, 1214, 1214, 270, 1214, 1214, - 1214, 1214, 1214, 1214, 1214, 1214, 1214, 244, 1214, 255, - 139, 290, 307, 1214, 1214, 0, 0, 1214, 1176, 1214, - 1214, 1214, 1175, 0, 1214, 1214, 1138, 1143, 1136, 1139, - 1148, 1147, 1133, 1136, 1148, 144, 1142, 1129, 1126, 1140, - - 1126, 1123, 1123, 1129, 219, 193, 1123, 1134, 1119, 1125, - 1129, 1130, 0, 1121, 1132, 278, 1131, 1126, 1106, 224, - 1110, 1124, 1114, 232, 1107, 271, 1120, 1122, 1104, 1100, - 1108, 1105, 1094, 1103, 234, 1101, 1107, 1102, 1105, 1093, - 1096, 226, 145, 262, 1106, 1093, 1106, 263, 1099, 1214, - 1214, 338, 331, 343, 1214, 1084, 1097, 1088, 1099, 345, - 0, 334, 0, 345, 1214, 328, 391, 1214, 352, 398, - 338, 1214, 1214, 1094, 0, 1085, 1089, 1099, 1096, 332, - 1079, 1079, 1083, 320, 1094, 1091, 1091, 1089, 1086, 1077, - 1084, 1070, 1068, 1081, 1066, 1083, 0, 1080, 1067, 1075, - - 1072, 1076, 1077, 1070, 1067, 1055, 1054, 1068, 1071, 1058, - 1067, 1054, 1061, 1051, 364, 1057, 1060, 1050, 1058, 1046, - 1050, 1041, 1056, 1046, 1037, 1056, 1039, 1037, 1048, 1037, - 1032, 1030, 1044, 1029, 1031, 1028, 1040, 1039, 1042, 1023, - 338, 1032, 1027, 1025, 1035, 1013, 403, 1032, 1034, 1022, - 1014, 1018, 1030, 1013, 0, 415, 422, 439, 1214, 446, - 455, 1214, 1214, 1008, 1019, 0, 1016, 406, 0, 0, - 1009, 1007, 1009, 1004, 1013, 1001, 1019, 1007, 409, 0, - 0, 1001, 1012, 1011, 1011, 0, 995, 429, 0, 0, - 997, 460, 1005, 1006, 996, 990, 989, 990, 989, 989, - - 463, 984, 0, 0, 980, 979, 978, 980, 981, 986, - 980, 976, 990, 985, 984, 983, 974, 977, 977, 969, - 972, 967, 976, 981, 966, 979, 969, 0, 0, 976, - 972, 0, 963, 963, 969, 959, 967, 466, 964, 0, - 0, 0, 0, 953, 966, 965, 964, 961, 949, 472, - 479, 961, 963, 0, 0, 0, 0, 949, 0, 949, - 0, 948, 949, 943, 954, 0, 0, 0, 944, 0, - 940, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 951, 487, 950, 0, 0, 948, 944, 940, 0, 0, - 0, 932, 489, 494, 499, 937, 933, 939, 929, 927, - - 941, 925, 925, 939, 927, 939, 934, 0, 932, 929, - 933, 916, 918, 925, 931, 926, 925, 912, 0, 914, - 915, 0, 0, 0, 0, 912, 916, 0, 910, 963, - 909, 912, 0, 900, 910, 0, 898, 898, 912, 0, - 914, 0, 503, 926, 925, 924, 891, 890, 0, 908, - 907, 902, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 890, 904, 890, 887, 0, 0, 893, 892, - 0, 0, 890, 882, 0, 0, 0, 0, 0, 0, - 879, 891, 506, 883, 890, 889, 886, 880, 873, 524, - 889, 874, 869, 883, 881, 0, 0, 873, 896, 895, - - 894, 861, 860, 361, 365, 0, 873, 876, 874, 862, - 858, 0, 871, 868, 867, 856, 855, 854, 519, 863, - 0, 879, 878, 877, 844, 843, 0, 858, 844, 0, - 855, 850, 547, 553, 898, 843, 851, 0, 0, 0, - 870, 869, 0, 847, 850, 834, 842, 832, 840, 841, - 841, 840, 825, 559, 838, 0, 839, 827, 826, 822, - 850, 849, 848, 815, 814, 0, 848, 847, 0, 825, - 828, 0, 562, 0, 814, 580, 1214, 587, 0, 607, - 584, 1214, 0, 811, 810, 820, 820, 807, 822, 805, - 820, 815, 0, 0, 0, 831, 830, 829, 796, 0, - - 796, 0, 0, 0, 502, 524, 820, 807, 810, 794, - 793, 803, 803, 819, 818, 817, 784, 789, 615, 640, - 550, 806, 796, 784, 782, 781, 792, 0, 795, 791, - 793, 789, 775, 806, 805, 0, 787, 779, 770, 778, - 768, 779, 775, 777, 775, 775, 762, 761, 772, 0, - 791, 790, 0, 772, 1214, 555, 1214, 647, 0, 667, - 785, 770, 752, 769, 768, 751, 743, 751, 741, 749, - 0, 746, 745, 756, 739, 742, 757, 740, 753, 754, - 751, 748, 757, 750, 749, 732, 731, 730, 741, 582, - 754, 724, 734, 718, 717, 0, 745, 717, 743, 715, - - 719, 718, 0, 729, 732, 728, 730, 711, 725, 709, - 710, 718, 701, 700, 0, 706, 705, 0, 728, 713, - 706, 0, 0, 710, 0, 709, 0, 715, 714, 0, - 690, 698, 688, 716, 695, 0, 0, 708, 0, 0, - 707, 706, 746, 611, 696, 703, 702, 678, 677, 705, - 677, 703, 689, 674, 691, 670, 669, 190, 613, 557, - 667, 687, 686, 0, 0, 681, 0, 680, 686, 0, - 671, 0, 0, 671, 590, 343, 672, 645, 644, 654, - 635, 631, 612, 612, 604, 443, 635, 576, 575, 549, - 25, 87, 0, 183, 500, 552, 1214, 636, 591, 0, - - 0, 196, 258, 254, 272, 609, 1214, 614, 598, 279, - 284, 0, 336, 348, 671, 0, 0, 362, 672, 688, - 1214, 394, 689, 1214, 408, 670, 691, 649, 651, 474, - 476, 693, 694, 1214, 1214, 704, 707, 710, 530, 591, - 713, 717, 720, 722 - } ; - -static yyconst flex_int16_t yy_def[845] = - { 0, - 835, 1, 835, 3, 836, 836, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 837, 835, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 838, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 839, 835, 840, - 19, 835, 835, 835, 835, 841, 20, 835, 835, 835, - 835, 835, 835, 837, 835, 835, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 842, 835, 838, 835, 835, 840, 835, 835, 835, 835, - 841, 835, 835, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 835, 835, 835, 835, 842, 835, 835, 835, 835, 835, - 835, 835, 835, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 835, 835, 835, 835, 835, - 835, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 835, 835, - 835, 835, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 835, 835, - 835, 835, 837, 837, 837, 837, 837, 837, 837, 837, - - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 835, 835, 835, 835, 835, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 835, 835, 835, 835, 843, 835, - 835, 835, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 835, 835, 835, - 843, 835, 835, 835, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 835, 835, 835, 835, 844, 835, - 835, 835, 835, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 844, - 835, 835, 835, 837, 837, 837, 837, 837, 837, 837, - - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 835, 835, - 835, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 835, 835, 835, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 837, 837, 837, 835, 835, 835, - 835, 837, 837, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 835, 835, 835, 835, 837, 837, 837, - 837, 837, 837, 835, 835, 835, 835, 837, 837, 837, - 837, 837, 837, 835, 835, 835, 835, 835, 835, 837, - - 837, 837, 837, 837, 835, 835, 835, 835, 835, 837, - 837, 837, 835, 835, 835, 837, 837, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 0, 835, 835, 835, 835, 835, - 835, 835, 835, 835 - } ; - -static yyconst flex_int16_t yy_nxt[1283] = - { 0, - 8, 9, 10, 9, 11, 8, 12, 13, 8, 8, - 14, 15, 16, 17, 18, 19, 20, 20, 20, 20, - 20, 20, 8, 21, 22, 23, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 24, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 24, 24, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 24, 24, 24, 46, 47, 58, - 803, 58, 48, 49, 50, 51, 50, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 52, 49, 53, - 53, 53, 53, 53, 53, 54, 49, 49, 49, 55, - - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 49, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 49, 61, 64, 804, 66, 68, 68, 68, 68, 68, - 68, 68, 79, 80, 85, 65, 67, 87, 62, 70, - 119, 71, 71, 71, 71, 71, 71, 72, 82, 83, - 86, 121, 88, 89, 120, 122, 73, 74, 835, 101, - 90, 102, 91, 93, 75, 76, 92, 94, 123, 126, - 103, 758, 73, 74, 95, 241, 97, 96, 183, 184, - - 98, 110, 124, 835, 242, 127, 99, 75, 128, 111, - 76, 70, 100, 77, 77, 77, 77, 77, 77, 77, - 129, 112, 152, 104, 58, 805, 153, 150, 73, 74, - 130, 105, 154, 155, 106, 195, 78, 107, 138, 113, - 774, 139, 114, 108, 73, 74, 115, 116, 131, 196, - 140, 117, 810, 142, 118, 132, 133, 141, 143, 78, - 134, 160, 144, 160, 146, 145, 135, 136, 147, 137, - 151, 58, 193, 58, 164, 165, 231, 156, 148, 213, - 239, 240, 218, 194, 157, 167, 168, 214, 158, 219, - 164, 165, 232, 159, 162, 162, 162, 162, 162, 162, - - 162, 167, 168, 70, 243, 72, 72, 72, 72, 72, - 72, 72, 244, 248, 811, 221, 249, 812, 169, 169, - 73, 74, 170, 170, 170, 170, 170, 170, 170, 222, - 813, 205, 154, 155, 206, 207, 73, 74, 208, 152, - 209, 58, 816, 153, 154, 155, 160, 817, 160, 162, - 162, 162, 162, 162, 162, 162, 256, 256, 258, 259, - 257, 257, 257, 257, 257, 257, 257, 170, 170, 170, - 170, 170, 170, 170, 258, 259, 263, 156, 269, 274, - 275, 305, 306, 307, 157, 333, 818, 546, 158, 156, - 785, 548, 270, 159, 334, 819, 157, 547, 786, 263, - - 158, 549, 260, 260, 822, 159, 261, 261, 261, 261, - 261, 261, 261, 170, 170, 170, 170, 170, 170, 170, - 340, 341, 342, 355, 356, 357, 366, 367, 368, 262, - 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, - 257, 257, 257, 257, 796, 262, 374, 375, 376, 825, - 350, 350, 797, 165, 351, 351, 351, 351, 351, 351, - 351, 261, 261, 261, 261, 261, 261, 261, 826, 165, - 261, 261, 261, 261, 261, 261, 261, 378, 379, 380, - 389, 390, 391, 423, 424, 425, 168, 351, 351, 351, - 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, - - 351, 806, 168, 444, 445, 446, 454, 455, 456, 807, - 259, 457, 458, 459, 447, 448, 460, 461, 462, 499, - 500, 501, 522, 523, 524, 490, 259, 831, 639, 832, - 502, 503, 68, 525, 526, 561, 562, 563, 640, 533, - 534, 534, 534, 534, 534, 534, 564, 565, 576, 577, - 641, 576, 577, 796, 576, 577, 656, 657, 775, 642, - 643, 797, 578, 578, 578, 578, 578, 578, 580, 580, - 580, 580, 580, 580, 580, 596, 597, 598, 614, 615, - 616, 576, 577, 656, 657, 581, 579, 599, 576, 577, - 617, 775, 808, 166, 802, 619, 620, 620, 620, 620, - - 620, 620, 578, 578, 578, 578, 578, 578, 576, 577, - 806, 579, 759, 776, 759, 808, 656, 657, 807, 760, - 622, 760, 580, 580, 580, 580, 580, 580, 580, 623, - 658, 658, 658, 658, 658, 658, 798, 798, 801, 800, - 624, 656, 657, 799, 799, 814, 776, 809, 656, 657, - 829, 795, 829, 815, 659, 660, 660, 660, 660, 660, - 660, 660, 658, 658, 658, 658, 658, 658, 656, 657, - 809, 827, 820, 823, 794, 793, 792, 791, 828, 659, - 821, 824, 660, 660, 660, 660, 660, 660, 660, 820, - 823, 830, 827, 830, 833, 833, 790, 821, 824, 828, - - 789, 788, 834, 834, 56, 56, 56, 56, 56, 84, - 84, 84, 163, 163, 163, 171, 171, 255, 787, 255, - 255, 255, 621, 621, 690, 690, 784, 783, 782, 781, - 780, 779, 778, 777, 773, 772, 771, 770, 769, 768, - 767, 766, 765, 764, 763, 762, 761, 758, 757, 756, - 755, 754, 753, 752, 751, 750, 749, 748, 747, 746, - 745, 744, 743, 742, 741, 740, 739, 738, 737, 736, - 735, 734, 733, 732, 731, 730, 729, 728, 727, 726, - 725, 724, 723, 722, 721, 720, 719, 718, 717, 716, - 715, 714, 713, 712, 711, 710, 709, 708, 707, 706, - - 705, 704, 703, 702, 701, 700, 699, 698, 697, 696, - 695, 694, 693, 692, 691, 689, 688, 687, 686, 685, - 684, 683, 682, 681, 680, 679, 678, 677, 676, 675, - 674, 673, 672, 671, 670, 669, 668, 667, 666, 665, - 664, 663, 662, 661, 655, 654, 653, 652, 651, 650, - 649, 648, 647, 646, 645, 644, 638, 637, 636, 635, - 634, 633, 632, 631, 630, 629, 628, 627, 626, 625, - 618, 613, 612, 611, 610, 609, 608, 607, 606, 605, - 604, 603, 602, 601, 600, 595, 594, 593, 592, 591, - 590, 589, 588, 587, 586, 585, 584, 583, 582, 581, - - 575, 574, 573, 572, 571, 570, 569, 568, 567, 566, - 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, - 550, 545, 544, 543, 542, 541, 540, 539, 538, 537, - 536, 535, 532, 531, 530, 529, 528, 527, 521, 520, - 519, 518, 517, 516, 515, 514, 513, 512, 511, 510, - 509, 508, 507, 506, 505, 504, 498, 497, 496, 495, - 494, 493, 492, 491, 490, 489, 488, 487, 486, 485, - 484, 483, 482, 481, 480, 479, 478, 477, 476, 475, - 474, 473, 472, 471, 470, 469, 468, 467, 466, 465, - 464, 463, 453, 452, 451, 450, 449, 443, 442, 441, - - 440, 439, 438, 437, 436, 435, 434, 433, 432, 431, - 430, 429, 428, 427, 426, 422, 421, 420, 419, 418, - 417, 416, 415, 414, 413, 412, 411, 410, 409, 408, - 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, - 397, 396, 395, 394, 393, 392, 388, 387, 386, 385, - 384, 383, 382, 381, 377, 373, 372, 371, 370, 369, - 365, 364, 363, 362, 361, 360, 359, 358, 354, 353, - 352, 349, 348, 347, 346, 345, 344, 343, 339, 338, - 337, 336, 335, 332, 331, 330, 329, 328, 327, 326, - 325, 324, 323, 322, 321, 320, 319, 318, 317, 316, - - 315, 314, 313, 312, 311, 310, 309, 308, 304, 303, - 302, 301, 300, 299, 298, 297, 296, 295, 294, 293, - 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, - 282, 281, 280, 279, 278, 277, 276, 273, 272, 271, - 268, 267, 266, 265, 264, 254, 253, 252, 251, 250, - 247, 246, 245, 238, 237, 236, 235, 234, 233, 230, - 229, 228, 227, 226, 225, 224, 223, 220, 217, 216, - 215, 212, 211, 210, 204, 203, 202, 201, 200, 199, - 198, 197, 192, 191, 190, 189, 188, 187, 186, 185, - 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, - - 172, 161, 149, 125, 109, 81, 69, 63, 60, 59, - 835, 57, 57, 7, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835 - } ; - -static yyconst flex_int16_t yy_chk[1283] = - { 0, - 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, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 9, - 791, 9, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 13, 15, 792, 16, 17, 17, 17, 17, 17, - 17, 17, 21, 21, 25, 15, 16, 26, 13, 19, - 35, 19, 19, 19, 19, 19, 19, 19, 23, 23, - 25, 36, 26, 26, 35, 36, 19, 19, 71, 30, - 27, 30, 27, 28, 19, 19, 27, 28, 37, 39, - 30, 758, 19, 19, 28, 143, 29, 28, 96, 96, - - 29, 33, 37, 71, 143, 39, 29, 19, 39, 33, - 19, 20, 29, 20, 20, 20, 20, 20, 20, 20, - 40, 33, 47, 31, 47, 794, 47, 46, 20, 20, - 40, 31, 48, 48, 31, 106, 20, 31, 42, 34, - 758, 42, 34, 31, 20, 20, 34, 34, 41, 106, - 42, 34, 802, 43, 34, 41, 41, 42, 43, 20, - 41, 50, 43, 50, 44, 43, 41, 41, 44, 41, - 46, 58, 105, 58, 68, 68, 135, 48, 44, 120, - 142, 142, 124, 105, 48, 70, 70, 120, 48, 124, - 68, 68, 135, 48, 53, 53, 53, 53, 53, 53, - - 53, 70, 70, 72, 144, 72, 72, 72, 72, 72, - 72, 72, 144, 148, 803, 126, 148, 804, 73, 73, - 72, 72, 73, 73, 73, 73, 73, 73, 73, 126, - 805, 116, 153, 153, 116, 116, 72, 72, 116, 152, - 116, 152, 810, 152, 154, 154, 160, 811, 160, 162, - 162, 162, 162, 162, 162, 162, 164, 164, 166, 166, - 164, 164, 164, 164, 164, 164, 164, 169, 169, 169, - 169, 169, 169, 169, 166, 166, 171, 153, 180, 184, - 184, 215, 215, 215, 153, 241, 813, 504, 153, 154, - 776, 505, 180, 153, 241, 814, 154, 504, 776, 171, - - 154, 505, 167, 167, 818, 154, 167, 167, 167, 167, - 167, 167, 167, 170, 170, 170, 170, 170, 170, 170, - 247, 247, 247, 268, 268, 268, 279, 279, 279, 170, - 256, 256, 256, 256, 256, 256, 256, 257, 257, 257, - 257, 257, 257, 257, 786, 170, 288, 288, 288, 822, - 258, 258, 786, 257, 258, 258, 258, 258, 258, 258, - 258, 260, 260, 260, 260, 260, 260, 260, 825, 257, - 261, 261, 261, 261, 261, 261, 261, 292, 292, 292, - 301, 301, 301, 338, 338, 338, 261, 350, 350, 350, - 350, 350, 350, 350, 351, 351, 351, 351, 351, 351, - - 351, 795, 261, 382, 382, 382, 393, 393, 393, 795, - 351, 394, 394, 394, 382, 382, 395, 395, 395, 443, - 443, 443, 483, 483, 483, 490, 351, 830, 605, 831, - 443, 443, 839, 483, 483, 519, 519, 519, 605, 490, - 490, 490, 490, 490, 490, 490, 519, 519, 533, 533, - 606, 621, 621, 796, 534, 534, 656, 656, 760, 606, - 606, 796, 533, 533, 533, 533, 533, 533, 534, 534, - 534, 534, 534, 534, 534, 554, 554, 554, 573, 573, - 573, 576, 576, 690, 690, 581, 533, 554, 578, 578, - 573, 775, 799, 840, 790, 576, 576, 576, 576, 576, - - 576, 576, 578, 578, 578, 578, 578, 578, 580, 580, - 806, 533, 744, 760, 759, 808, 619, 619, 806, 744, - 581, 759, 580, 580, 580, 580, 580, 580, 580, 581, - 619, 619, 619, 619, 619, 619, 787, 798, 789, 788, - 581, 620, 620, 787, 798, 809, 775, 799, 658, 658, - 828, 785, 829, 809, 619, 620, 620, 620, 620, 620, - 620, 620, 658, 658, 658, 658, 658, 658, 660, 660, - 808, 826, 815, 819, 784, 783, 782, 781, 826, 619, - 815, 819, 660, 660, 660, 660, 660, 660, 660, 820, - 823, 828, 827, 829, 832, 833, 780, 820, 823, 827, - - 779, 778, 832, 833, 836, 836, 836, 836, 836, 837, - 837, 837, 838, 838, 838, 841, 841, 842, 777, 842, - 842, 842, 843, 843, 844, 844, 774, 771, 769, 768, - 766, 763, 762, 761, 757, 756, 755, 754, 753, 752, - 751, 750, 749, 748, 747, 746, 745, 743, 742, 741, - 738, 735, 734, 733, 732, 731, 729, 728, 726, 724, - 721, 720, 719, 717, 716, 714, 713, 712, 711, 710, - 709, 708, 707, 706, 705, 704, 702, 701, 700, 699, - 698, 697, 695, 694, 693, 692, 691, 689, 688, 687, - 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, - - 676, 675, 674, 673, 672, 670, 669, 668, 667, 666, - 665, 664, 663, 662, 661, 654, 652, 651, 649, 648, - 647, 646, 645, 644, 643, 642, 641, 640, 639, 638, - 637, 635, 634, 633, 632, 631, 630, 629, 627, 626, - 625, 624, 623, 622, 618, 617, 616, 615, 614, 613, - 612, 611, 610, 609, 608, 607, 601, 599, 598, 597, - 596, 592, 591, 590, 589, 588, 587, 586, 585, 584, - 575, 571, 570, 568, 567, 565, 564, 563, 562, 561, - 560, 559, 558, 557, 555, 553, 552, 551, 550, 549, - 548, 547, 546, 545, 544, 542, 541, 537, 536, 535, - - 532, 531, 529, 528, 526, 525, 524, 523, 522, 520, - 518, 517, 516, 515, 514, 513, 511, 510, 509, 508, - 507, 503, 502, 501, 500, 499, 498, 495, 494, 493, - 492, 491, 489, 488, 487, 486, 485, 484, 482, 481, - 474, 473, 470, 469, 466, 465, 464, 463, 452, 451, - 450, 448, 447, 446, 445, 444, 441, 439, 438, 437, - 435, 434, 432, 431, 430, 429, 427, 426, 421, 420, - 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, - 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, - 397, 396, 392, 388, 387, 386, 383, 381, 371, 369, - - 365, 364, 363, 362, 360, 358, 353, 352, 349, 348, - 347, 346, 345, 344, 339, 337, 336, 335, 334, 333, - 331, 330, 327, 326, 325, 324, 323, 322, 321, 320, - 319, 318, 317, 316, 315, 314, 313, 312, 311, 310, - 309, 308, 307, 306, 305, 302, 300, 299, 298, 297, - 296, 295, 294, 293, 291, 287, 285, 284, 283, 282, - 278, 277, 276, 275, 274, 273, 272, 271, 267, 265, - 264, 254, 253, 252, 251, 250, 249, 248, 246, 245, - 244, 243, 242, 240, 239, 238, 237, 236, 235, 234, - 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, - - 223, 222, 221, 220, 219, 218, 217, 216, 214, 213, - 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, - 202, 201, 200, 199, 198, 196, 195, 194, 193, 192, - 191, 190, 189, 188, 187, 186, 185, 183, 182, 181, - 179, 178, 177, 176, 174, 159, 158, 157, 156, 149, - 147, 146, 145, 141, 140, 139, 138, 137, 136, 134, - 133, 132, 131, 130, 129, 128, 127, 125, 123, 122, - 121, 119, 118, 117, 115, 114, 112, 111, 110, 109, - 108, 107, 104, 103, 102, 101, 100, 99, 98, 97, - 95, 94, 93, 92, 91, 90, 89, 88, 87, 83, - - 79, 52, 45, 38, 32, 22, 18, 14, 12, 11, - 7, 6, 5, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, - 835, 835 - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "glsl_lexer.lpp" -#line 2 "glsl_lexer.lpp" -/* - * Copyright © 2008, 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include -#include "strtod.h" -#include "ast.h" -#include "glsl_parser_extras.h" -#include "glsl_parser.h" - -#define YY_USER_ACTION \ - do { \ - yylloc->source = 0; \ - yylloc->first_column = yycolumn + 1; \ - yylloc->first_line = yylineno + 1; \ - yycolumn += yyleng; \ - } while(0); - -#define YY_USER_INIT yylineno = 0; yycolumn = 0; - -#define IS_UINT (yytext[yyleng - 1] == 'u' || yytext[yyleng - 1] == 'U') - -/* A macro for handling reserved words and keywords across language versions. - * - * Certain words start out as identifiers, become reserved words in - * later language revisions, and finally become language keywords. - * - * For example, consider the following lexer rule: - * samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER) - * - * This means that "samplerBuffer" will be treated as: - * - a keyword (SAMPLERBUFFER token) ...in GLSL >= 1.40 - * - a reserved word - error ...in GLSL >= 1.30 - * - an identifier ...in GLSL < 1.30 - */ -#define KEYWORD(reserved_version, allowed_version, token) \ - do { \ - if (yyextra->language_version >= allowed_version) { \ - return token; \ - } else if (yyextra->language_version >= reserved_version) { \ - _mesa_glsl_error(yylloc, yyextra, \ - "Illegal use of reserved word `%s'", yytext); \ - return ERROR_TOK; \ - } else { \ - yylval->identifier = strdup(yytext); \ - return IDENTIFIER; \ - } \ - } while (0) - -/* The ES macro can be used in KEYWORD checks: - * - * word KEYWORD(110 || ES, 400, TOKEN) - * ...means the word is reserved in GLSL ES 1.00, while - * - * word KEYWORD(110, 130 || ES, TOKEN) - * ...means the word is a legal keyword in GLSL ES 1.00. - */ -#define ES yyextra->es_shader - -#line 1071 "glsl_lexer.cpp" - -#define INITIAL 0 -#define PP 1 -#define PRAGMA 2 - -#define YY_EXTRA_TYPE struct _mesa_glsl_parse_state * - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - YYLTYPE * yylloc_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - - # define yylloc yyg->yylloc_r - -int _mesa_glsl_lex_init (yyscan_t* scanner); - -int _mesa_glsl_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int _mesa_glsl_lex_destroy (yyscan_t yyscanner ); - -int _mesa_glsl_get_debug (yyscan_t yyscanner ); - -void _mesa_glsl_set_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE _mesa_glsl_get_extra (yyscan_t yyscanner ); - -void _mesa_glsl_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *_mesa_glsl_get_in (yyscan_t yyscanner ); - -void _mesa_glsl_set_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *_mesa_glsl_get_out (yyscan_t yyscanner ); - -void _mesa_glsl_set_out (FILE * out_str ,yyscan_t yyscanner ); - -int _mesa_glsl_get_leng (yyscan_t yyscanner ); - -char *_mesa_glsl_get_text (yyscan_t yyscanner ); - -int _mesa_glsl_get_lineno (yyscan_t yyscanner ); - -void _mesa_glsl_set_lineno (int line_number ,yyscan_t yyscanner ); - -int _mesa_glsl_get_column (yyscan_t yyscanner ); - -void _mesa_glsl_set_column (int column_no ,yyscan_t yyscanner ); - -YYSTYPE * _mesa_glsl_get_lval (yyscan_t yyscanner ); - -void _mesa_glsl_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *_mesa_glsl_get_lloc (yyscan_t yyscanner ); - - void _mesa_glsl_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int _mesa_glsl_wrap (yyscan_t yyscanner ); -#else -extern int _mesa_glsl_wrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - unsigned n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int _mesa_glsl_lex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int _mesa_glsl_lex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - -#line 95 "glsl_lexer.lpp" - - -#line 1312 "glsl_lexer.cpp" - - yylval = yylval_param; - - yylloc = yylloc_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - _mesa_glsl_ensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - _mesa_glsl__load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; - yy_current_state += YY_AT_BOL(); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 836 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_current_state != 835 ); - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 97 "glsl_lexer.lpp" -; - YY_BREAK -/* Preprocessor tokens. */ -case 2: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 100 "glsl_lexer.lpp" -; - YY_BREAK -case 3: -YY_RULE_SETUP -#line 101 "glsl_lexer.lpp" -{ BEGIN PP; return VERSION; } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 102 "glsl_lexer.lpp" -{ BEGIN PP; return EXTENSION; } - YY_BREAK -case 5: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 103 "glsl_lexer.lpp" -{ - /* Eat characters until the first digit is - * encountered - */ - char *ptr = yytext; - while (!isdigit(*ptr)) - ptr++; - - /* Subtract one from the line number because - * yylineno is zero-based instead of - * one-based. - */ - yylineno = strtol(ptr, &ptr, 0) - 1; - yylloc->source = strtol(ptr, NULL, 0); - } - YY_BREAK -case 6: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 118 "glsl_lexer.lpp" -{ - /* Eat characters until the first digit is - * encountered - */ - char *ptr = yytext; - while (!isdigit(*ptr)) - ptr++; - - /* Subtract one from the line number because - * yylineno is zero-based instead of - * one-based. - */ - yylineno = strtol(ptr, &ptr, 0) - 1; - } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 132 "glsl_lexer.lpp" -{ - BEGIN PP; - return PRAGMA_DEBUG_ON; - } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 136 "glsl_lexer.lpp" -{ - BEGIN PP; - return PRAGMA_DEBUG_OFF; - } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 140 "glsl_lexer.lpp" -{ - BEGIN PP; - return PRAGMA_OPTIMIZE_ON; - } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 144 "glsl_lexer.lpp" -{ - BEGIN PP; - return PRAGMA_OPTIMIZE_OFF; - } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 148 "glsl_lexer.lpp" -{ - BEGIN PP; - return PRAGMA_INVARIANT_ALL; - } - YY_BREAK -case 12: -YY_RULE_SETUP -#line 152 "glsl_lexer.lpp" -{ BEGIN PRAGMA; } - YY_BREAK -case 13: -/* rule 13 can match eol */ -YY_RULE_SETUP -#line 154 "glsl_lexer.lpp" -{ BEGIN 0; yylineno++; yycolumn = 0; } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 155 "glsl_lexer.lpp" -{ } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 157 "glsl_lexer.lpp" -{ } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 158 "glsl_lexer.lpp" -{ } - YY_BREAK -case 17: -YY_RULE_SETUP -#line 159 "glsl_lexer.lpp" -return COLON; - YY_BREAK -case 18: -YY_RULE_SETUP -#line 160 "glsl_lexer.lpp" -{ - yylval->identifier = strdup(yytext); - return IDENTIFIER; - } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 164 "glsl_lexer.lpp" -{ - yylval->n = strtol(yytext, NULL, 10); - return INTCONSTANT; - } - YY_BREAK -case 20: -/* rule 20 can match eol */ -YY_RULE_SETUP -#line 168 "glsl_lexer.lpp" -{ BEGIN 0; yylineno++; yycolumn = 0; return EOL; } - YY_BREAK -case 21: -/* rule 21 can match eol */ -YY_RULE_SETUP -#line 170 "glsl_lexer.lpp" -{ yylineno++; yycolumn = 0; } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 172 "glsl_lexer.lpp" -return ATTRIBUTE; - YY_BREAK -case 23: -YY_RULE_SETUP -#line 173 "glsl_lexer.lpp" -return CONST_TOK; - YY_BREAK -case 24: -YY_RULE_SETUP -#line 174 "glsl_lexer.lpp" -return BOOL_TOK; - YY_BREAK -case 25: -YY_RULE_SETUP -#line 175 "glsl_lexer.lpp" -return FLOAT_TOK; - YY_BREAK -case 26: -YY_RULE_SETUP -#line 176 "glsl_lexer.lpp" -return INT_TOK; - YY_BREAK -case 27: -YY_RULE_SETUP -#line 177 "glsl_lexer.lpp" -KEYWORD(130, 130, UINT_TOK); - YY_BREAK -case 28: -YY_RULE_SETUP -#line 179 "glsl_lexer.lpp" -return BREAK; - YY_BREAK -case 29: -YY_RULE_SETUP -#line 180 "glsl_lexer.lpp" -return CONTINUE; - YY_BREAK -case 30: -YY_RULE_SETUP -#line 181 "glsl_lexer.lpp" -return DO; - YY_BREAK -case 31: -YY_RULE_SETUP -#line 182 "glsl_lexer.lpp" -return WHILE; - YY_BREAK -case 32: -YY_RULE_SETUP -#line 183 "glsl_lexer.lpp" -return ELSE; - YY_BREAK -case 33: -YY_RULE_SETUP -#line 184 "glsl_lexer.lpp" -return FOR; - YY_BREAK -case 34: -YY_RULE_SETUP -#line 185 "glsl_lexer.lpp" -return IF; - YY_BREAK -case 35: -YY_RULE_SETUP -#line 186 "glsl_lexer.lpp" -return DISCARD; - YY_BREAK -case 36: -YY_RULE_SETUP -#line 187 "glsl_lexer.lpp" -return RETURN; - YY_BREAK -case 37: -YY_RULE_SETUP -#line 189 "glsl_lexer.lpp" -return BVEC2; - YY_BREAK -case 38: -YY_RULE_SETUP -#line 190 "glsl_lexer.lpp" -return BVEC3; - YY_BREAK -case 39: -YY_RULE_SETUP -#line 191 "glsl_lexer.lpp" -return BVEC4; - YY_BREAK -case 40: -YY_RULE_SETUP -#line 192 "glsl_lexer.lpp" -return IVEC2; - YY_BREAK -case 41: -YY_RULE_SETUP -#line 193 "glsl_lexer.lpp" -return IVEC3; - YY_BREAK -case 42: -YY_RULE_SETUP -#line 194 "glsl_lexer.lpp" -return IVEC4; - YY_BREAK -case 43: -YY_RULE_SETUP -#line 195 "glsl_lexer.lpp" -KEYWORD(130, 130, UVEC2); - YY_BREAK -case 44: -YY_RULE_SETUP -#line 196 "glsl_lexer.lpp" -KEYWORD(130, 130, UVEC3); - YY_BREAK -case 45: -YY_RULE_SETUP -#line 197 "glsl_lexer.lpp" -KEYWORD(130, 130, UVEC4); - YY_BREAK -case 46: -YY_RULE_SETUP -#line 198 "glsl_lexer.lpp" -return VEC2; - YY_BREAK -case 47: -YY_RULE_SETUP -#line 199 "glsl_lexer.lpp" -return VEC3; - YY_BREAK -case 48: -YY_RULE_SETUP -#line 200 "glsl_lexer.lpp" -return VEC4; - YY_BREAK -case 49: -YY_RULE_SETUP -#line 201 "glsl_lexer.lpp" -return MAT2X2; - YY_BREAK -case 50: -YY_RULE_SETUP -#line 202 "glsl_lexer.lpp" -return MAT3X3; - YY_BREAK -case 51: -YY_RULE_SETUP -#line 203 "glsl_lexer.lpp" -return MAT4X4; - YY_BREAK -case 52: -YY_RULE_SETUP -#line 204 "glsl_lexer.lpp" -KEYWORD(120, 120, MAT2X2); - YY_BREAK -case 53: -YY_RULE_SETUP -#line 205 "glsl_lexer.lpp" -KEYWORD(120, 120, MAT2X3); - YY_BREAK -case 54: -YY_RULE_SETUP -#line 206 "glsl_lexer.lpp" -KEYWORD(120, 120, MAT2X4); - YY_BREAK -case 55: -YY_RULE_SETUP -#line 207 "glsl_lexer.lpp" -KEYWORD(120, 120, MAT3X2); - YY_BREAK -case 56: -YY_RULE_SETUP -#line 208 "glsl_lexer.lpp" -KEYWORD(120, 120, MAT3X3); - YY_BREAK -case 57: -YY_RULE_SETUP -#line 209 "glsl_lexer.lpp" -KEYWORD(120, 120, MAT3X4); - YY_BREAK -case 58: -YY_RULE_SETUP -#line 210 "glsl_lexer.lpp" -KEYWORD(120, 120, MAT4X2); - YY_BREAK -case 59: -YY_RULE_SETUP -#line 211 "glsl_lexer.lpp" -KEYWORD(120, 120, MAT4X3); - YY_BREAK -case 60: -YY_RULE_SETUP -#line 212 "glsl_lexer.lpp" -KEYWORD(120, 120, MAT4X4); - YY_BREAK -case 61: -YY_RULE_SETUP -#line 214 "glsl_lexer.lpp" -return IN_TOK; - YY_BREAK -case 62: -YY_RULE_SETUP -#line 215 "glsl_lexer.lpp" -return OUT_TOK; - YY_BREAK -case 63: -YY_RULE_SETUP -#line 216 "glsl_lexer.lpp" -return INOUT_TOK; - YY_BREAK -case 64: -YY_RULE_SETUP -#line 217 "glsl_lexer.lpp" -return UNIFORM; - YY_BREAK -case 65: -YY_RULE_SETUP -#line 218 "glsl_lexer.lpp" -return VARYING; - YY_BREAK -case 66: -YY_RULE_SETUP -#line 219 "glsl_lexer.lpp" -KEYWORD(120, 120, CENTROID); - YY_BREAK -case 67: -YY_RULE_SETUP -#line 220 "glsl_lexer.lpp" -KEYWORD(120 || ES, 120 || ES, INVARIANT); - YY_BREAK -case 68: -YY_RULE_SETUP -#line 221 "glsl_lexer.lpp" -KEYWORD(130 || ES, 130, FLAT); - YY_BREAK -case 69: -YY_RULE_SETUP -#line 222 "glsl_lexer.lpp" -KEYWORD(130, 130, SMOOTH); - YY_BREAK -case 70: -YY_RULE_SETUP -#line 223 "glsl_lexer.lpp" -KEYWORD(130, 130, NOPERSPECTIVE); - YY_BREAK -case 71: -YY_RULE_SETUP -#line 225 "glsl_lexer.lpp" -return SAMPLER1D; - YY_BREAK -case 72: -YY_RULE_SETUP -#line 226 "glsl_lexer.lpp" -return SAMPLER2D; - YY_BREAK -case 73: -YY_RULE_SETUP -#line 227 "glsl_lexer.lpp" -return SAMPLER3D; - YY_BREAK -case 74: -YY_RULE_SETUP -#line 228 "glsl_lexer.lpp" -return SAMPLERCUBE; - YY_BREAK -case 75: -YY_RULE_SETUP -#line 229 "glsl_lexer.lpp" -KEYWORD(130, 130, SAMPLER1DARRAY); - YY_BREAK -case 76: -YY_RULE_SETUP -#line 230 "glsl_lexer.lpp" -KEYWORD(130, 130, SAMPLER2DARRAY); - YY_BREAK -case 77: -YY_RULE_SETUP -#line 231 "glsl_lexer.lpp" -return SAMPLER1DSHADOW; - YY_BREAK -case 78: -YY_RULE_SETUP -#line 232 "glsl_lexer.lpp" -return SAMPLER2DSHADOW; - YY_BREAK -case 79: -YY_RULE_SETUP -#line 233 "glsl_lexer.lpp" -KEYWORD(130, 130, SAMPLERCUBESHADOW); - YY_BREAK -case 80: -YY_RULE_SETUP -#line 234 "glsl_lexer.lpp" -KEYWORD(130, 130, SAMPLER1DARRAYSHADOW); - YY_BREAK -case 81: -YY_RULE_SETUP -#line 235 "glsl_lexer.lpp" -KEYWORD(130, 130, SAMPLER2DARRAYSHADOW); - YY_BREAK -case 82: -YY_RULE_SETUP -#line 236 "glsl_lexer.lpp" -KEYWORD(130, 130, ISAMPLER1D); - YY_BREAK -case 83: -YY_RULE_SETUP -#line 237 "glsl_lexer.lpp" -KEYWORD(130, 130, ISAMPLER2D); - YY_BREAK -case 84: -YY_RULE_SETUP -#line 238 "glsl_lexer.lpp" -KEYWORD(130, 130, ISAMPLER3D); - YY_BREAK -case 85: -YY_RULE_SETUP -#line 239 "glsl_lexer.lpp" -KEYWORD(130, 130, ISAMPLERCUBE); - YY_BREAK -case 86: -YY_RULE_SETUP -#line 240 "glsl_lexer.lpp" -KEYWORD(130, 130, ISAMPLER1DARRAY); - YY_BREAK -case 87: -YY_RULE_SETUP -#line 241 "glsl_lexer.lpp" -KEYWORD(130, 130, ISAMPLER2DARRAY); - YY_BREAK -case 88: -YY_RULE_SETUP -#line 242 "glsl_lexer.lpp" -KEYWORD(130, 130, USAMPLER1D); - YY_BREAK -case 89: -YY_RULE_SETUP -#line 243 "glsl_lexer.lpp" -KEYWORD(130, 130, USAMPLER2D); - YY_BREAK -case 90: -YY_RULE_SETUP -#line 244 "glsl_lexer.lpp" -KEYWORD(130, 130, USAMPLER3D); - YY_BREAK -case 91: -YY_RULE_SETUP -#line 245 "glsl_lexer.lpp" -KEYWORD(130, 130, USAMPLERCUBE); - YY_BREAK -case 92: -YY_RULE_SETUP -#line 246 "glsl_lexer.lpp" -KEYWORD(130, 130, USAMPLER1DARRAY); - YY_BREAK -case 93: -YY_RULE_SETUP -#line 247 "glsl_lexer.lpp" -KEYWORD(130, 130, USAMPLER2DARRAY); - YY_BREAK -case 94: -YY_RULE_SETUP -#line 250 "glsl_lexer.lpp" -return STRUCT; - YY_BREAK -case 95: -YY_RULE_SETUP -#line 251 "glsl_lexer.lpp" -return VOID_TOK; - YY_BREAK -case 96: -YY_RULE_SETUP -#line 253 "glsl_lexer.lpp" -{ - if ((yyextra->language_version >= 140) - || yyextra->AMD_conservative_depth_enable - || yyextra->ARB_explicit_attrib_location_enable - || yyextra->ARB_fragment_coord_conventions_enable) { - return LAYOUT_TOK; - } else { - yylval->identifier = strdup(yytext); - return IDENTIFIER; - } - } - YY_BREAK -case 97: -YY_RULE_SETUP -#line 265 "glsl_lexer.lpp" -return INC_OP; - YY_BREAK -case 98: -YY_RULE_SETUP -#line 266 "glsl_lexer.lpp" -return DEC_OP; - YY_BREAK -case 99: -YY_RULE_SETUP -#line 267 "glsl_lexer.lpp" -return LE_OP; - YY_BREAK -case 100: -YY_RULE_SETUP -#line 268 "glsl_lexer.lpp" -return GE_OP; - YY_BREAK -case 101: -YY_RULE_SETUP -#line 269 "glsl_lexer.lpp" -return EQ_OP; - YY_BREAK -case 102: -YY_RULE_SETUP -#line 270 "glsl_lexer.lpp" -return NE_OP; - YY_BREAK -case 103: -YY_RULE_SETUP -#line 271 "glsl_lexer.lpp" -return AND_OP; - YY_BREAK -case 104: -YY_RULE_SETUP -#line 272 "glsl_lexer.lpp" -return OR_OP; - YY_BREAK -case 105: -YY_RULE_SETUP -#line 273 "glsl_lexer.lpp" -return XOR_OP; - YY_BREAK -case 106: -YY_RULE_SETUP -#line 274 "glsl_lexer.lpp" -return LEFT_OP; - YY_BREAK -case 107: -YY_RULE_SETUP -#line 275 "glsl_lexer.lpp" -return RIGHT_OP; - YY_BREAK -case 108: -YY_RULE_SETUP -#line 277 "glsl_lexer.lpp" -return MUL_ASSIGN; - YY_BREAK -case 109: -YY_RULE_SETUP -#line 278 "glsl_lexer.lpp" -return DIV_ASSIGN; - YY_BREAK -case 110: -YY_RULE_SETUP -#line 279 "glsl_lexer.lpp" -return ADD_ASSIGN; - YY_BREAK -case 111: -YY_RULE_SETUP -#line 280 "glsl_lexer.lpp" -return MOD_ASSIGN; - YY_BREAK -case 112: -YY_RULE_SETUP -#line 281 "glsl_lexer.lpp" -return LEFT_ASSIGN; - YY_BREAK -case 113: -YY_RULE_SETUP -#line 282 "glsl_lexer.lpp" -return RIGHT_ASSIGN; - YY_BREAK -case 114: -YY_RULE_SETUP -#line 283 "glsl_lexer.lpp" -return AND_ASSIGN; - YY_BREAK -case 115: -YY_RULE_SETUP -#line 284 "glsl_lexer.lpp" -return XOR_ASSIGN; - YY_BREAK -case 116: -YY_RULE_SETUP -#line 285 "glsl_lexer.lpp" -return OR_ASSIGN; - YY_BREAK -case 117: -YY_RULE_SETUP -#line 286 "glsl_lexer.lpp" -return SUB_ASSIGN; - YY_BREAK -case 118: -YY_RULE_SETUP -#line 288 "glsl_lexer.lpp" -{ - yylval->n = strtol(yytext, NULL, 10); - return IS_UINT ? UINTCONSTANT : INTCONSTANT; - } - YY_BREAK -case 119: -YY_RULE_SETUP -#line 292 "glsl_lexer.lpp" -{ - yylval->n = strtol(yytext + 2, NULL, 16); - return IS_UINT ? UINTCONSTANT : INTCONSTANT; - } - YY_BREAK -case 120: -YY_RULE_SETUP -#line 296 "glsl_lexer.lpp" -{ - yylval->n = strtol(yytext, NULL, 8); - return IS_UINT ? UINTCONSTANT : INTCONSTANT; - } - YY_BREAK -case 121: -YY_RULE_SETUP -#line 301 "glsl_lexer.lpp" -{ - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 122: -YY_RULE_SETUP -#line 305 "glsl_lexer.lpp" -{ - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 123: -YY_RULE_SETUP -#line 309 "glsl_lexer.lpp" -{ - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 124: -YY_RULE_SETUP -#line 313 "glsl_lexer.lpp" -{ - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 125: -YY_RULE_SETUP -#line 317 "glsl_lexer.lpp" -{ - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } - YY_BREAK -case 126: -YY_RULE_SETUP -#line 322 "glsl_lexer.lpp" -{ - yylval->n = 1; - return BOOLCONSTANT; - } - YY_BREAK -case 127: -YY_RULE_SETUP -#line 326 "glsl_lexer.lpp" -{ - yylval->n = 0; - return BOOLCONSTANT; - } - YY_BREAK -/* Reserved words in GLSL 1.10. */ -case 128: -YY_RULE_SETUP -#line 333 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, ASM); - YY_BREAK -case 129: -YY_RULE_SETUP -#line 334 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, CLASS); - YY_BREAK -case 130: -YY_RULE_SETUP -#line 335 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, UNION); - YY_BREAK -case 131: -YY_RULE_SETUP -#line 336 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, ENUM); - YY_BREAK -case 132: -YY_RULE_SETUP -#line 337 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, TYPEDEF); - YY_BREAK -case 133: -YY_RULE_SETUP -#line 338 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, TEMPLATE); - YY_BREAK -case 134: -YY_RULE_SETUP -#line 339 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, THIS); - YY_BREAK -case 135: -YY_RULE_SETUP -#line 340 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, PACKED_TOK); - YY_BREAK -case 136: -YY_RULE_SETUP -#line 341 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, GOTO); - YY_BREAK -case 137: -YY_RULE_SETUP -#line 342 "glsl_lexer.lpp" -KEYWORD(110 || ES, 130, SWITCH); - YY_BREAK -case 138: -YY_RULE_SETUP -#line 343 "glsl_lexer.lpp" -KEYWORD(110 || ES, 130, DEFAULT); - YY_BREAK -case 139: -YY_RULE_SETUP -#line 344 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, INLINE_TOK); - YY_BREAK -case 140: -YY_RULE_SETUP -#line 345 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, NOINLINE); - YY_BREAK -case 141: -YY_RULE_SETUP -#line 346 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, VOLATILE); - YY_BREAK -case 142: -YY_RULE_SETUP -#line 347 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, PUBLIC_TOK); - YY_BREAK -case 143: -YY_RULE_SETUP -#line 348 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, STATIC); - YY_BREAK -case 144: -YY_RULE_SETUP -#line 349 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, EXTERN); - YY_BREAK -case 145: -YY_RULE_SETUP -#line 350 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, EXTERNAL); - YY_BREAK -case 146: -YY_RULE_SETUP -#line 351 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, INTERFACE); - YY_BREAK -case 147: -YY_RULE_SETUP -#line 352 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, LONG_TOK); - YY_BREAK -case 148: -YY_RULE_SETUP -#line 353 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, SHORT_TOK); - YY_BREAK -case 149: -YY_RULE_SETUP -#line 354 "glsl_lexer.lpp" -KEYWORD(110 || ES, 400, DOUBLE_TOK); - YY_BREAK -case 150: -YY_RULE_SETUP -#line 355 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, HALF); - YY_BREAK -case 151: -YY_RULE_SETUP -#line 356 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, FIXED_TOK); - YY_BREAK -case 152: -YY_RULE_SETUP -#line 357 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, UNSIGNED); - YY_BREAK -case 153: -YY_RULE_SETUP -#line 358 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, INPUT_TOK); - YY_BREAK -case 154: -YY_RULE_SETUP -#line 359 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, OUTPUT); - YY_BREAK -case 155: -YY_RULE_SETUP -#line 360 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, HVEC2); - YY_BREAK -case 156: -YY_RULE_SETUP -#line 361 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, HVEC3); - YY_BREAK -case 157: -YY_RULE_SETUP -#line 362 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, HVEC4); - YY_BREAK -case 158: -YY_RULE_SETUP -#line 363 "glsl_lexer.lpp" -KEYWORD(110 || ES, 400, DVEC2); - YY_BREAK -case 159: -YY_RULE_SETUP -#line 364 "glsl_lexer.lpp" -KEYWORD(110 || ES, 400, DVEC3); - YY_BREAK -case 160: -YY_RULE_SETUP -#line 365 "glsl_lexer.lpp" -KEYWORD(110 || ES, 400, DVEC4); - YY_BREAK -case 161: -YY_RULE_SETUP -#line 366 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, FVEC2); - YY_BREAK -case 162: -YY_RULE_SETUP -#line 367 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, FVEC3); - YY_BREAK -case 163: -YY_RULE_SETUP -#line 368 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, FVEC4); - YY_BREAK -case 164: -YY_RULE_SETUP -#line 369 "glsl_lexer.lpp" -return SAMPLER2DRECT; - YY_BREAK -case 165: -YY_RULE_SETUP -#line 370 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, SAMPLER3DRECT); - YY_BREAK -case 166: -YY_RULE_SETUP -#line 371 "glsl_lexer.lpp" -return SAMPLER2DRECTSHADOW; - YY_BREAK -case 167: -YY_RULE_SETUP -#line 372 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, SIZEOF); - YY_BREAK -case 168: -YY_RULE_SETUP -#line 373 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, CAST); - YY_BREAK -case 169: -YY_RULE_SETUP -#line 374 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, NAMESPACE); - YY_BREAK -case 170: -YY_RULE_SETUP -#line 375 "glsl_lexer.lpp" -KEYWORD(110 || ES, 999, USING); - YY_BREAK -/* Additional reserved words in GLSL 1.20. */ -case 171: -YY_RULE_SETUP -#line 378 "glsl_lexer.lpp" -KEYWORD(120, 130 || ES, LOWP); - YY_BREAK -case 172: -YY_RULE_SETUP -#line 379 "glsl_lexer.lpp" -KEYWORD(120, 130 || ES, MEDIUMP); - YY_BREAK -case 173: -YY_RULE_SETUP -#line 380 "glsl_lexer.lpp" -KEYWORD(120, 130 || ES, HIGHP); - YY_BREAK -case 174: -YY_RULE_SETUP -#line 381 "glsl_lexer.lpp" -KEYWORD(120, 130 || ES, PRECISION); - YY_BREAK -/* Additional reserved words in GLSL 1.30. */ -case 175: -YY_RULE_SETUP -#line 384 "glsl_lexer.lpp" -KEYWORD(130, 130, CASE); - YY_BREAK -case 176: -YY_RULE_SETUP -#line 385 "glsl_lexer.lpp" -KEYWORD(130, 999, COMMON); - YY_BREAK -case 177: -YY_RULE_SETUP -#line 386 "glsl_lexer.lpp" -KEYWORD(130, 999, PARTITION); - YY_BREAK -case 178: -YY_RULE_SETUP -#line 387 "glsl_lexer.lpp" -KEYWORD(130, 999, ACTIVE); - YY_BREAK -case 179: -YY_RULE_SETUP -#line 388 "glsl_lexer.lpp" -KEYWORD(130 || ES, 999, SUPERP); - YY_BREAK -case 180: -YY_RULE_SETUP -#line 389 "glsl_lexer.lpp" -KEYWORD(130, 140, SAMPLERBUFFER); - YY_BREAK -case 181: -YY_RULE_SETUP -#line 390 "glsl_lexer.lpp" -KEYWORD(130, 999, FILTER); - YY_BREAK -case 182: -YY_RULE_SETUP -#line 391 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGE1D); - YY_BREAK -case 183: -YY_RULE_SETUP -#line 392 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGE2D); - YY_BREAK -case 184: -YY_RULE_SETUP -#line 393 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGE3D); - YY_BREAK -case 185: -YY_RULE_SETUP -#line 394 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGECUBE); - YY_BREAK -case 186: -YY_RULE_SETUP -#line 395 "glsl_lexer.lpp" -KEYWORD(130, 999, IIMAGE1D); - YY_BREAK -case 187: -YY_RULE_SETUP -#line 396 "glsl_lexer.lpp" -KEYWORD(130, 999, IIMAGE2D); - YY_BREAK -case 188: -YY_RULE_SETUP -#line 397 "glsl_lexer.lpp" -KEYWORD(130, 999, IIMAGE3D); - YY_BREAK -case 189: -YY_RULE_SETUP -#line 398 "glsl_lexer.lpp" -KEYWORD(130, 999, IIMAGECUBE); - YY_BREAK -case 190: -YY_RULE_SETUP -#line 399 "glsl_lexer.lpp" -KEYWORD(130, 999, UIMAGE1D); - YY_BREAK -case 191: -YY_RULE_SETUP -#line 400 "glsl_lexer.lpp" -KEYWORD(130, 999, UIMAGE2D); - YY_BREAK -case 192: -YY_RULE_SETUP -#line 401 "glsl_lexer.lpp" -KEYWORD(130, 999, UIMAGE3D); - YY_BREAK -case 193: -YY_RULE_SETUP -#line 402 "glsl_lexer.lpp" -KEYWORD(130, 999, UIMAGECUBE); - YY_BREAK -case 194: -YY_RULE_SETUP -#line 403 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGE1DARRAY); - YY_BREAK -case 195: -YY_RULE_SETUP -#line 404 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGE2DARRAY); - YY_BREAK -case 196: -YY_RULE_SETUP -#line 405 "glsl_lexer.lpp" -KEYWORD(130, 999, IIMAGE1DARRAY); - YY_BREAK -case 197: -YY_RULE_SETUP -#line 406 "glsl_lexer.lpp" -KEYWORD(130, 999, IIMAGE2DARRAY); - YY_BREAK -case 198: -YY_RULE_SETUP -#line 407 "glsl_lexer.lpp" -KEYWORD(130, 999, UIMAGE1DARRAY); - YY_BREAK -case 199: -YY_RULE_SETUP -#line 408 "glsl_lexer.lpp" -KEYWORD(130, 999, UIMAGE2DARRAY); - YY_BREAK -case 200: -YY_RULE_SETUP -#line 409 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGE1DSHADOW); - YY_BREAK -case 201: -YY_RULE_SETUP -#line 410 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGE2DSHADOW); - YY_BREAK -case 202: -YY_RULE_SETUP -#line 411 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGE1DARRAYSHADOW); - YY_BREAK -case 203: -YY_RULE_SETUP -#line 412 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGE2DARRAYSHADOW); - YY_BREAK -case 204: -YY_RULE_SETUP -#line 413 "glsl_lexer.lpp" -KEYWORD(130, 999, IMAGEBUFFER); - YY_BREAK -case 205: -YY_RULE_SETUP -#line 414 "glsl_lexer.lpp" -KEYWORD(130, 999, IIMAGEBUFFER); - YY_BREAK -case 206: -YY_RULE_SETUP -#line 415 "glsl_lexer.lpp" -KEYWORD(130, 999, UIMAGEBUFFER); - YY_BREAK -case 207: -YY_RULE_SETUP -#line 416 "glsl_lexer.lpp" -KEYWORD(130, 999, ROW_MAJOR); - YY_BREAK -case 208: -YY_RULE_SETUP -#line 418 "glsl_lexer.lpp" -{ - struct _mesa_glsl_parse_state *state = yyextra; - void *ctx = state; - yylval->identifier = ralloc_strdup(ctx, yytext); - return IDENTIFIER; - } - YY_BREAK -case 209: -YY_RULE_SETUP -#line 425 "glsl_lexer.lpp" -{ return yytext[0]; } - YY_BREAK -case 210: -YY_RULE_SETUP -#line 427 "glsl_lexer.lpp" -ECHO; - YY_BREAK -#line 2555 "glsl_lexer.cpp" -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(PP): -case YY_STATE_EOF(PRAGMA): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * _mesa_glsl_lex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( _mesa_glsl_wrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of _mesa_glsl_lex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - _mesa_glsl_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - 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; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - _mesa_glsl_restart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (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. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) _mesa_glsl_realloc((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; - 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; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 836 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 836 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 835); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - _mesa_glsl_restart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( _mesa_glsl_wrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void _mesa_glsl_restart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - _mesa_glsl_ensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - _mesa_glsl__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - _mesa_glsl__load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void _mesa_glsl__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * _mesa_glsl_pop_buffer_state(); - * _mesa_glsl_push_buffer_state(new_buffer); - */ - _mesa_glsl_ensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - _mesa_glsl__load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (_mesa_glsl_wrap()) processing, but the only time this flag - * is looked at is after _mesa_glsl_wrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void _mesa_glsl__load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE _mesa_glsl__create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) _mesa_glsl_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) _mesa_glsl_alloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__create_buffer()" ); - - b->yy_is_our_buffer = 1; - - _mesa_glsl__init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with _mesa_glsl__create_buffer() - * @param yyscanner The scanner object. - */ - void _mesa_glsl__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - _mesa_glsl_free((void *) b->yy_ch_buf ,yyscanner ); - - _mesa_glsl_free((void *) b ,yyscanner ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a _mesa_glsl_restart() or at EOF. - */ - static void _mesa_glsl__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - _mesa_glsl__flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then _mesa_glsl__init_buffer was _probably_ - * called from _mesa_glsl_restart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void _mesa_glsl__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - _mesa_glsl__load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void _mesa_glsl_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - _mesa_glsl_ensure_buffer_stack(yyscanner); - - /* This block is copied from _mesa_glsl__switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from _mesa_glsl__switch_to_buffer. */ - _mesa_glsl__load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void _mesa_glsl_pop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - _mesa_glsl__delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - _mesa_glsl__load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void _mesa_glsl_ensure_buffer_stack (yyscan_t yyscanner) -{ - int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_glsl_alloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl_ensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_glsl_realloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl_ensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE _mesa_glsl__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) _mesa_glsl_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__scan_buffer()" ); - - 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; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - _mesa_glsl__switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to _mesa_glsl_lex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * _mesa_glsl__scan_bytes() instead. - */ -YY_BUFFER_STATE _mesa_glsl__scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return _mesa_glsl__scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to _mesa_glsl_lex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE _mesa_glsl__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) _mesa_glsl_alloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = _mesa_glsl__scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in _mesa_glsl__scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE _mesa_glsl_get_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int _mesa_glsl_get_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int _mesa_glsl_get_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *_mesa_glsl_get_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *_mesa_glsl_get_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int _mesa_glsl_get_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *_mesa_glsl_get_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void _mesa_glsl_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void _mesa_glsl_set_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "_mesa_glsl_set_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void _mesa_glsl_set_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "_mesa_glsl_set_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see _mesa_glsl__switch_to_buffer - */ -void _mesa_glsl_set_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void _mesa_glsl_set_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int _mesa_glsl_get_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void _mesa_glsl_set_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * _mesa_glsl_get_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void _mesa_glsl_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -YYLTYPE *_mesa_glsl_get_lloc (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylloc; -} - -void _mesa_glsl_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylloc = yylloc_param; -} - -/* User-visible API */ - -/* _mesa_glsl_lex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int _mesa_glsl_lex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) _mesa_glsl_alloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* _mesa_glsl_lex_init_extra has the same functionality as _mesa_glsl_lex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to _mesa_glsl_alloc in - * the yyextra field. - */ - -int _mesa_glsl_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - _mesa_glsl_set_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) _mesa_glsl_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - _mesa_glsl_set_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from _mesa_glsl_lex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * _mesa_glsl_lex_init() - */ - return 0; -} - -/* _mesa_glsl_lex_destroy is for both reentrant and non-reentrant scanners. */ -int _mesa_glsl_lex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - _mesa_glsl__delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - _mesa_glsl_pop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - _mesa_glsl_free(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - _mesa_glsl_free(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * _mesa_glsl_lex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - _mesa_glsl_free ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *_mesa_glsl_alloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *_mesa_glsl_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void _mesa_glsl_free (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see _mesa_glsl_realloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 427 "glsl_lexer.lpp" - - - -void -_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string) -{ - _mesa_glsl_lex_init_extra(state,& state->scanner); - _mesa_glsl__scan_string(string,state->scanner); -} - -void -_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state) -{ - _mesa_glsl_lex_destroy(state->scanner); -} - +#line 2 "glsl_lexer.cpp" + +#line 4 "glsl_lexer.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE _mesa_glsl_restart(yyin ,yyscanner ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via _mesa_glsl_restart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void _mesa_glsl_restart (FILE *input_file ,yyscan_t yyscanner ); +void _mesa_glsl__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE _mesa_glsl__create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void _mesa_glsl__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void _mesa_glsl__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void _mesa_glsl_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void _mesa_glsl_pop_buffer_state (yyscan_t yyscanner ); + +static void _mesa_glsl_ensure_buffer_stack (yyscan_t yyscanner ); +static void _mesa_glsl__load_buffer_state (yyscan_t yyscanner ); +static void _mesa_glsl__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER _mesa_glsl__flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE _mesa_glsl__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE _mesa_glsl__scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE _mesa_glsl__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); + +void *_mesa_glsl_alloc (yy_size_t ,yyscan_t yyscanner ); +void *_mesa_glsl_realloc (void *,yy_size_t ,yyscan_t yyscanner ); +void _mesa_glsl_free (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer _mesa_glsl__create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + _mesa_glsl_ensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + _mesa_glsl_ensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define _mesa_glsl_wrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); +static int yy_get_next_buffer (yyscan_t yyscanner ); +static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yyg->yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 210 +#define YY_END_OF_BUFFER 211 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[836] = + { 0, + 0, 0, 16, 16, 0, 0, 211, 209, 1, 21, + 209, 209, 209, 209, 209, 209, 209, 209, 120, 118, + 209, 209, 209, 208, 209, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 209, 1, 209, 210, 16, + 20, 210, 19, 17, 18, 14, 13, 1, 102, 111, + 103, 114, 108, 97, 110, 98, 117, 122, 109, 123, + 120, 0, 0, 125, 120, 0, 118, 118, 106, 99, + 101, 100, 107, 208, 115, 105, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 30, 208, + + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 34, 208, 208, 61, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 116, + 104, 1, 0, 0, 2, 0, 0, 0, 0, 16, + 15, 19, 18, 0, 122, 121, 0, 123, 0, 124, + 119, 112, 113, 208, 128, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 33, 208, 208, 208, + + 208, 208, 208, 208, 208, 208, 208, 26, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 62, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 0, 0, 0, 0, 15, 0, 122, 0, 121, 0, + 123, 124, 119, 208, 208, 24, 208, 208, 175, 168, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 32, + 131, 208, 208, 208, 208, 68, 208, 208, 136, 150, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + + 208, 208, 147, 171, 49, 50, 51, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 134, 126, 208, + 208, 27, 208, 208, 208, 208, 208, 208, 208, 46, + 47, 48, 95, 208, 208, 0, 0, 0, 0, 0, + 121, 208, 208, 28, 37, 38, 39, 208, 129, 208, + 23, 208, 208, 208, 208, 158, 159, 160, 208, 127, + 208, 151, 25, 161, 162, 163, 173, 155, 156, 157, + 208, 208, 208, 63, 153, 208, 208, 208, 40, 41, + 42, 208, 208, 208, 208, 208, 208, 208, 208, 208, + + 208, 208, 208, 208, 208, 208, 208, 148, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 130, 208, + 208, 170, 43, 44, 45, 208, 208, 31, 0, 0, + 0, 0, 178, 208, 208, 176, 208, 208, 208, 149, + 144, 181, 208, 208, 208, 208, 208, 208, 139, 208, + 208, 208, 96, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 208, 208, 208, 208, 154, 135, 208, 208, + 142, 36, 208, 208, 167, 69, 143, 94, 179, 137, + 208, 208, 208, 208, 208, 208, 208, 208, 0, 0, + 0, 0, 208, 208, 208, 138, 35, 208, 208, 208, + + 208, 208, 208, 182, 183, 184, 208, 208, 208, 208, + 208, 172, 208, 208, 208, 208, 208, 208, 208, 208, + 132, 208, 208, 208, 208, 208, 64, 208, 208, 65, + 208, 0, 0, 0, 0, 0, 208, 66, 29, 145, + 186, 187, 188, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 140, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 133, 190, 191, 192, 208, + 208, 152, 208, 141, 0, 0, 6, 0, 0, 0, + 12, 3, 22, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 185, 146, 67, 208, 208, 208, 208, 169, + + 208, 177, 174, 207, 71, 72, 73, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 0, 0, 0, + 0, 0, 0, 0, 208, 208, 208, 189, 208, 208, + 208, 208, 208, 82, 83, 84, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 193, + 88, 89, 90, 208, 4, 0, 5, 0, 0, 0, + 0, 0, 0, 208, 208, 208, 208, 208, 208, 208, + 204, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 74, 208, 208, 208, 208, 208, 208, 0, + 0, 0, 0, 208, 208, 205, 194, 208, 195, 208, + + 208, 208, 85, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 206, 208, 208, 91, 0, 0, + 0, 196, 197, 208, 200, 208, 201, 208, 208, 70, + 208, 208, 208, 164, 208, 165, 180, 208, 198, 199, + 208, 208, 0, 0, 0, 208, 208, 208, 208, 75, + 208, 76, 208, 208, 208, 208, 208, 0, 0, 0, + 0, 208, 208, 86, 87, 208, 77, 208, 208, 78, + 208, 92, 93, 0, 0, 0, 0, 208, 208, 208, + 208, 208, 208, 0, 0, 0, 0, 208, 208, 208, + 208, 208, 79, 0, 0, 0, 7, 0, 0, 202, + + 203, 208, 208, 208, 0, 0, 8, 0, 0, 208, + 208, 166, 0, 0, 0, 80, 81, 0, 0, 0, + 9, 0, 0, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 11, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 1, 6, 1, 7, 8, 1, 9, + 10, 11, 12, 1, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 21, 21, 22, 22, 23, 1, 24, + 25, 26, 1, 1, 27, 28, 29, 30, 31, 32, + 33, 34, 34, 34, 34, 35, 34, 34, 34, 34, + 34, 36, 37, 38, 39, 34, 34, 40, 34, 34, + 1, 1, 1, 41, 42, 1, 43, 44, 45, 46, + + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 34, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 1, 68, 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, + 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, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[69] = + { 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, + 3, 3, 1, 1, 1, 1, 4, 4, 4, 4, + 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, + 1, 5, 4, 4, 4, 4, 3, 3, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 1 + } ; + +static yyconst flex_int16_t yy_base[845] = + { 0, + 0, 67, 73, 0, 1210, 1209, 1211, 1214, 68, 1214, + 1185, 1184, 134, 1183, 131, 132, 130, 1182, 146, 198, + 129, 1181, 144, 0, 130, 113, 124, 141, 150, 126, + 181, 1148, 159, 192, 118, 129, 146, 1142, 147, 174, + 206, 192, 203, 222, 1153, 203, 221, 231, 1214, 260, + 1214, 1187, 279, 1214, 0, 1214, 1214, 270, 1214, 1214, + 1214, 1214, 1214, 1214, 1214, 1214, 1214, 244, 1214, 255, + 139, 290, 307, 1214, 1214, 0, 0, 1214, 1176, 1214, + 1214, 1214, 1175, 0, 1214, 1214, 1138, 1143, 1136, 1139, + 1148, 1147, 1133, 1136, 1148, 144, 1142, 1129, 1126, 1140, + + 1126, 1123, 1123, 1129, 219, 193, 1123, 1134, 1119, 1125, + 1129, 1130, 0, 1121, 1132, 278, 1131, 1126, 1106, 224, + 1110, 1124, 1114, 232, 1107, 271, 1120, 1122, 1104, 1100, + 1108, 1105, 1094, 1103, 234, 1101, 1107, 1102, 1105, 1093, + 1096, 226, 145, 262, 1106, 1093, 1106, 263, 1099, 1214, + 1214, 338, 331, 343, 1214, 1084, 1097, 1088, 1099, 345, + 0, 334, 0, 345, 1214, 328, 391, 1214, 352, 398, + 338, 1214, 1214, 1094, 0, 1085, 1089, 1099, 1096, 332, + 1079, 1079, 1083, 320, 1094, 1091, 1091, 1089, 1086, 1077, + 1084, 1070, 1068, 1081, 1066, 1083, 0, 1080, 1067, 1075, + + 1072, 1076, 1077, 1070, 1067, 1055, 1054, 1068, 1071, 1058, + 1067, 1054, 1061, 1051, 364, 1057, 1060, 1050, 1058, 1046, + 1050, 1041, 1056, 1046, 1037, 1056, 1039, 1037, 1048, 1037, + 1032, 1030, 1044, 1029, 1031, 1028, 1040, 1039, 1042, 1023, + 338, 1032, 1027, 1025, 1035, 1013, 403, 1032, 1034, 1022, + 1014, 1018, 1030, 1013, 0, 415, 422, 439, 1214, 446, + 455, 1214, 1214, 1008, 1019, 0, 1016, 406, 0, 0, + 1009, 1007, 1009, 1004, 1013, 1001, 1019, 1007, 409, 0, + 0, 1001, 1012, 1011, 1011, 0, 995, 429, 0, 0, + 997, 460, 1005, 1006, 996, 990, 989, 990, 989, 989, + + 463, 984, 0, 0, 980, 979, 978, 980, 981, 986, + 980, 976, 990, 985, 984, 983, 974, 977, 977, 969, + 972, 967, 976, 981, 966, 979, 969, 0, 0, 976, + 972, 0, 963, 963, 969, 959, 967, 466, 964, 0, + 0, 0, 0, 953, 966, 965, 964, 961, 949, 472, + 479, 961, 963, 0, 0, 0, 0, 949, 0, 949, + 0, 948, 949, 943, 954, 0, 0, 0, 944, 0, + 940, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 951, 487, 950, 0, 0, 948, 944, 940, 0, 0, + 0, 932, 489, 494, 499, 937, 933, 939, 929, 927, + + 941, 925, 925, 939, 927, 939, 934, 0, 932, 929, + 933, 916, 918, 925, 931, 926, 925, 912, 0, 914, + 915, 0, 0, 0, 0, 912, 916, 0, 910, 963, + 909, 912, 0, 900, 910, 0, 898, 898, 912, 0, + 914, 0, 503, 926, 925, 924, 891, 890, 0, 908, + 907, 902, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 890, 904, 890, 887, 0, 0, 893, 892, + 0, 0, 890, 882, 0, 0, 0, 0, 0, 0, + 879, 891, 506, 883, 890, 889, 886, 880, 873, 524, + 889, 874, 869, 883, 881, 0, 0, 873, 896, 895, + + 894, 861, 860, 361, 365, 0, 873, 876, 874, 862, + 858, 0, 871, 868, 867, 856, 855, 854, 519, 863, + 0, 879, 878, 877, 844, 843, 0, 858, 844, 0, + 855, 850, 547, 553, 898, 843, 851, 0, 0, 0, + 870, 869, 0, 847, 850, 834, 842, 832, 840, 841, + 841, 840, 825, 559, 838, 0, 839, 827, 826, 822, + 850, 849, 848, 815, 814, 0, 848, 847, 0, 825, + 828, 0, 562, 0, 814, 580, 1214, 587, 0, 607, + 584, 1214, 0, 811, 810, 820, 820, 807, 822, 805, + 820, 815, 0, 0, 0, 831, 830, 829, 796, 0, + + 796, 0, 0, 0, 502, 524, 820, 807, 810, 794, + 793, 803, 803, 819, 818, 817, 784, 789, 615, 640, + 550, 806, 796, 784, 782, 781, 792, 0, 795, 791, + 793, 789, 775, 806, 805, 0, 787, 779, 770, 778, + 768, 779, 775, 777, 775, 775, 762, 761, 772, 0, + 791, 790, 0, 772, 1214, 555, 1214, 647, 0, 667, + 785, 770, 752, 769, 768, 751, 743, 751, 741, 749, + 0, 746, 745, 756, 739, 742, 757, 740, 753, 754, + 751, 748, 757, 750, 749, 732, 731, 730, 741, 582, + 754, 724, 734, 718, 717, 0, 745, 717, 743, 715, + + 719, 718, 0, 729, 732, 728, 730, 711, 725, 709, + 710, 718, 701, 700, 0, 706, 705, 0, 728, 713, + 706, 0, 0, 710, 0, 709, 0, 715, 714, 0, + 690, 698, 688, 716, 695, 0, 0, 708, 0, 0, + 707, 706, 746, 611, 696, 703, 702, 678, 677, 705, + 677, 703, 689, 674, 691, 670, 669, 190, 613, 557, + 667, 687, 686, 0, 0, 681, 0, 680, 686, 0, + 671, 0, 0, 671, 590, 343, 672, 645, 644, 654, + 635, 631, 612, 612, 604, 443, 635, 576, 575, 549, + 25, 87, 0, 183, 500, 552, 1214, 636, 591, 0, + + 0, 196, 258, 254, 272, 609, 1214, 614, 598, 279, + 284, 0, 336, 348, 671, 0, 0, 362, 672, 688, + 1214, 394, 689, 1214, 408, 670, 691, 649, 651, 474, + 476, 693, 694, 1214, 1214, 704, 707, 710, 530, 591, + 713, 717, 720, 722 + } ; + +static yyconst flex_int16_t yy_def[845] = + { 0, + 835, 1, 835, 3, 836, 836, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 837, 835, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 838, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 839, 835, 840, + 19, 835, 835, 835, 835, 841, 20, 835, 835, 835, + 835, 835, 835, 837, 835, 835, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 842, 835, 838, 835, 835, 840, 835, 835, 835, 835, + 841, 835, 835, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 835, 835, 835, 835, 842, 835, 835, 835, 835, 835, + 835, 835, 835, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 835, 835, 835, 835, 835, + 835, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 835, 835, + 835, 835, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 835, 835, + 835, 835, 837, 837, 837, 837, 837, 837, 837, 837, + + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 835, 835, 835, 835, 835, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 835, 835, 835, 835, 843, 835, + 835, 835, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 835, 835, 835, + 843, 835, 835, 835, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 835, 835, 835, 835, 844, 835, + 835, 835, 835, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 844, + 835, 835, 835, 837, 837, 837, 837, 837, 837, 837, + + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 835, 835, + 835, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 835, 835, 835, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 835, 835, 835, + 835, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 835, 835, 835, 835, 837, 837, 837, + 837, 837, 837, 835, 835, 835, 835, 837, 837, 837, + 837, 837, 837, 835, 835, 835, 835, 835, 835, 837, + + 837, 837, 837, 837, 835, 835, 835, 835, 835, 837, + 837, 837, 835, 835, 835, 837, 837, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 0, 835, 835, 835, 835, 835, + 835, 835, 835, 835 + } ; + +static yyconst flex_int16_t yy_nxt[1283] = + { 0, + 8, 9, 10, 9, 11, 8, 12, 13, 8, 8, + 14, 15, 16, 17, 18, 19, 20, 20, 20, 20, + 20, 20, 8, 21, 22, 23, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 24, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 24, 24, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 24, 24, 24, 46, 47, 58, + 803, 58, 48, 49, 50, 51, 50, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 52, 49, 53, + 53, 53, 53, 53, 53, 54, 49, 49, 49, 55, + + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 49, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 49, 61, 64, 804, 66, 68, 68, 68, 68, 68, + 68, 68, 79, 80, 85, 65, 67, 87, 62, 70, + 119, 71, 71, 71, 71, 71, 71, 72, 82, 83, + 86, 121, 88, 89, 120, 122, 73, 74, 835, 101, + 90, 102, 91, 93, 75, 76, 92, 94, 123, 126, + 103, 758, 73, 74, 95, 241, 97, 96, 183, 184, + + 98, 110, 124, 835, 242, 127, 99, 75, 128, 111, + 76, 70, 100, 77, 77, 77, 77, 77, 77, 77, + 129, 112, 152, 104, 58, 805, 153, 150, 73, 74, + 130, 105, 154, 155, 106, 195, 78, 107, 138, 113, + 774, 139, 114, 108, 73, 74, 115, 116, 131, 196, + 140, 117, 810, 142, 118, 132, 133, 141, 143, 78, + 134, 160, 144, 160, 146, 145, 135, 136, 147, 137, + 151, 58, 193, 58, 164, 165, 231, 156, 148, 213, + 239, 240, 218, 194, 157, 167, 168, 214, 158, 219, + 164, 165, 232, 159, 162, 162, 162, 162, 162, 162, + + 162, 167, 168, 70, 243, 72, 72, 72, 72, 72, + 72, 72, 244, 248, 811, 221, 249, 812, 169, 169, + 73, 74, 170, 170, 170, 170, 170, 170, 170, 222, + 813, 205, 154, 155, 206, 207, 73, 74, 208, 152, + 209, 58, 816, 153, 154, 155, 160, 817, 160, 162, + 162, 162, 162, 162, 162, 162, 256, 256, 258, 259, + 257, 257, 257, 257, 257, 257, 257, 170, 170, 170, + 170, 170, 170, 170, 258, 259, 263, 156, 269, 274, + 275, 305, 306, 307, 157, 333, 818, 546, 158, 156, + 785, 548, 270, 159, 334, 819, 157, 547, 786, 263, + + 158, 549, 260, 260, 822, 159, 261, 261, 261, 261, + 261, 261, 261, 170, 170, 170, 170, 170, 170, 170, + 340, 341, 342, 355, 356, 357, 366, 367, 368, 262, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 796, 262, 374, 375, 376, 825, + 350, 350, 797, 165, 351, 351, 351, 351, 351, 351, + 351, 261, 261, 261, 261, 261, 261, 261, 826, 165, + 261, 261, 261, 261, 261, 261, 261, 378, 379, 380, + 389, 390, 391, 423, 424, 425, 168, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, + + 351, 806, 168, 444, 445, 446, 454, 455, 456, 807, + 259, 457, 458, 459, 447, 448, 460, 461, 462, 499, + 500, 501, 522, 523, 524, 490, 259, 831, 639, 832, + 502, 503, 68, 525, 526, 561, 562, 563, 640, 533, + 534, 534, 534, 534, 534, 534, 564, 565, 576, 577, + 641, 576, 577, 796, 576, 577, 656, 657, 775, 642, + 643, 797, 578, 578, 578, 578, 578, 578, 580, 580, + 580, 580, 580, 580, 580, 596, 597, 598, 614, 615, + 616, 576, 577, 656, 657, 581, 579, 599, 576, 577, + 617, 775, 808, 166, 802, 619, 620, 620, 620, 620, + + 620, 620, 578, 578, 578, 578, 578, 578, 576, 577, + 806, 579, 759, 776, 759, 808, 656, 657, 807, 760, + 622, 760, 580, 580, 580, 580, 580, 580, 580, 623, + 658, 658, 658, 658, 658, 658, 798, 798, 801, 800, + 624, 656, 657, 799, 799, 814, 776, 809, 656, 657, + 829, 795, 829, 815, 659, 660, 660, 660, 660, 660, + 660, 660, 658, 658, 658, 658, 658, 658, 656, 657, + 809, 827, 820, 823, 794, 793, 792, 791, 828, 659, + 821, 824, 660, 660, 660, 660, 660, 660, 660, 820, + 823, 830, 827, 830, 833, 833, 790, 821, 824, 828, + + 789, 788, 834, 834, 56, 56, 56, 56, 56, 84, + 84, 84, 163, 163, 163, 171, 171, 255, 787, 255, + 255, 255, 621, 621, 690, 690, 784, 783, 782, 781, + 780, 779, 778, 777, 773, 772, 771, 770, 769, 768, + 767, 766, 765, 764, 763, 762, 761, 758, 757, 756, + 755, 754, 753, 752, 751, 750, 749, 748, 747, 746, + 745, 744, 743, 742, 741, 740, 739, 738, 737, 736, + 735, 734, 733, 732, 731, 730, 729, 728, 727, 726, + 725, 724, 723, 722, 721, 720, 719, 718, 717, 716, + 715, 714, 713, 712, 711, 710, 709, 708, 707, 706, + + 705, 704, 703, 702, 701, 700, 699, 698, 697, 696, + 695, 694, 693, 692, 691, 689, 688, 687, 686, 685, + 684, 683, 682, 681, 680, 679, 678, 677, 676, 675, + 674, 673, 672, 671, 670, 669, 668, 667, 666, 665, + 664, 663, 662, 661, 655, 654, 653, 652, 651, 650, + 649, 648, 647, 646, 645, 644, 638, 637, 636, 635, + 634, 633, 632, 631, 630, 629, 628, 627, 626, 625, + 618, 613, 612, 611, 610, 609, 608, 607, 606, 605, + 604, 603, 602, 601, 600, 595, 594, 593, 592, 591, + 590, 589, 588, 587, 586, 585, 584, 583, 582, 581, + + 575, 574, 573, 572, 571, 570, 569, 568, 567, 566, + 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, + 550, 545, 544, 543, 542, 541, 540, 539, 538, 537, + 536, 535, 532, 531, 530, 529, 528, 527, 521, 520, + 519, 518, 517, 516, 515, 514, 513, 512, 511, 510, + 509, 508, 507, 506, 505, 504, 498, 497, 496, 495, + 494, 493, 492, 491, 490, 489, 488, 487, 486, 485, + 484, 483, 482, 481, 480, 479, 478, 477, 476, 475, + 474, 473, 472, 471, 470, 469, 468, 467, 466, 465, + 464, 463, 453, 452, 451, 450, 449, 443, 442, 441, + + 440, 439, 438, 437, 436, 435, 434, 433, 432, 431, + 430, 429, 428, 427, 426, 422, 421, 420, 419, 418, + 417, 416, 415, 414, 413, 412, 411, 410, 409, 408, + 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, + 397, 396, 395, 394, 393, 392, 388, 387, 386, 385, + 384, 383, 382, 381, 377, 373, 372, 371, 370, 369, + 365, 364, 363, 362, 361, 360, 359, 358, 354, 353, + 352, 349, 348, 347, 346, 345, 344, 343, 339, 338, + 337, 336, 335, 332, 331, 330, 329, 328, 327, 326, + 325, 324, 323, 322, 321, 320, 319, 318, 317, 316, + + 315, 314, 313, 312, 311, 310, 309, 308, 304, 303, + 302, 301, 300, 299, 298, 297, 296, 295, 294, 293, + 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, + 282, 281, 280, 279, 278, 277, 276, 273, 272, 271, + 268, 267, 266, 265, 264, 254, 253, 252, 251, 250, + 247, 246, 245, 238, 237, 236, 235, 234, 233, 230, + 229, 228, 227, 226, 225, 224, 223, 220, 217, 216, + 215, 212, 211, 210, 204, 203, 202, 201, 200, 199, + 198, 197, 192, 191, 190, 189, 188, 187, 186, 185, + 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, + + 172, 161, 149, 125, 109, 81, 69, 63, 60, 59, + 835, 57, 57, 7, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835 + } ; + +static yyconst flex_int16_t yy_chk[1283] = + { 0, + 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, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 9, + 791, 9, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 13, 15, 792, 16, 17, 17, 17, 17, 17, + 17, 17, 21, 21, 25, 15, 16, 26, 13, 19, + 35, 19, 19, 19, 19, 19, 19, 19, 23, 23, + 25, 36, 26, 26, 35, 36, 19, 19, 71, 30, + 27, 30, 27, 28, 19, 19, 27, 28, 37, 39, + 30, 758, 19, 19, 28, 143, 29, 28, 96, 96, + + 29, 33, 37, 71, 143, 39, 29, 19, 39, 33, + 19, 20, 29, 20, 20, 20, 20, 20, 20, 20, + 40, 33, 47, 31, 47, 794, 47, 46, 20, 20, + 40, 31, 48, 48, 31, 106, 20, 31, 42, 34, + 758, 42, 34, 31, 20, 20, 34, 34, 41, 106, + 42, 34, 802, 43, 34, 41, 41, 42, 43, 20, + 41, 50, 43, 50, 44, 43, 41, 41, 44, 41, + 46, 58, 105, 58, 68, 68, 135, 48, 44, 120, + 142, 142, 124, 105, 48, 70, 70, 120, 48, 124, + 68, 68, 135, 48, 53, 53, 53, 53, 53, 53, + + 53, 70, 70, 72, 144, 72, 72, 72, 72, 72, + 72, 72, 144, 148, 803, 126, 148, 804, 73, 73, + 72, 72, 73, 73, 73, 73, 73, 73, 73, 126, + 805, 116, 153, 153, 116, 116, 72, 72, 116, 152, + 116, 152, 810, 152, 154, 154, 160, 811, 160, 162, + 162, 162, 162, 162, 162, 162, 164, 164, 166, 166, + 164, 164, 164, 164, 164, 164, 164, 169, 169, 169, + 169, 169, 169, 169, 166, 166, 171, 153, 180, 184, + 184, 215, 215, 215, 153, 241, 813, 504, 153, 154, + 776, 505, 180, 153, 241, 814, 154, 504, 776, 171, + + 154, 505, 167, 167, 818, 154, 167, 167, 167, 167, + 167, 167, 167, 170, 170, 170, 170, 170, 170, 170, + 247, 247, 247, 268, 268, 268, 279, 279, 279, 170, + 256, 256, 256, 256, 256, 256, 256, 257, 257, 257, + 257, 257, 257, 257, 786, 170, 288, 288, 288, 822, + 258, 258, 786, 257, 258, 258, 258, 258, 258, 258, + 258, 260, 260, 260, 260, 260, 260, 260, 825, 257, + 261, 261, 261, 261, 261, 261, 261, 292, 292, 292, + 301, 301, 301, 338, 338, 338, 261, 350, 350, 350, + 350, 350, 350, 350, 351, 351, 351, 351, 351, 351, + + 351, 795, 261, 382, 382, 382, 393, 393, 393, 795, + 351, 394, 394, 394, 382, 382, 395, 395, 395, 443, + 443, 443, 483, 483, 483, 490, 351, 830, 605, 831, + 443, 443, 839, 483, 483, 519, 519, 519, 605, 490, + 490, 490, 490, 490, 490, 490, 519, 519, 533, 533, + 606, 621, 621, 796, 534, 534, 656, 656, 760, 606, + 606, 796, 533, 533, 533, 533, 533, 533, 534, 534, + 534, 534, 534, 534, 534, 554, 554, 554, 573, 573, + 573, 576, 576, 690, 690, 581, 533, 554, 578, 578, + 573, 775, 799, 840, 790, 576, 576, 576, 576, 576, + + 576, 576, 578, 578, 578, 578, 578, 578, 580, 580, + 806, 533, 744, 760, 759, 808, 619, 619, 806, 744, + 581, 759, 580, 580, 580, 580, 580, 580, 580, 581, + 619, 619, 619, 619, 619, 619, 787, 798, 789, 788, + 581, 620, 620, 787, 798, 809, 775, 799, 658, 658, + 828, 785, 829, 809, 619, 620, 620, 620, 620, 620, + 620, 620, 658, 658, 658, 658, 658, 658, 660, 660, + 808, 826, 815, 819, 784, 783, 782, 781, 826, 619, + 815, 819, 660, 660, 660, 660, 660, 660, 660, 820, + 823, 828, 827, 829, 832, 833, 780, 820, 823, 827, + + 779, 778, 832, 833, 836, 836, 836, 836, 836, 837, + 837, 837, 838, 838, 838, 841, 841, 842, 777, 842, + 842, 842, 843, 843, 844, 844, 774, 771, 769, 768, + 766, 763, 762, 761, 757, 756, 755, 754, 753, 752, + 751, 750, 749, 748, 747, 746, 745, 743, 742, 741, + 738, 735, 734, 733, 732, 731, 729, 728, 726, 724, + 721, 720, 719, 717, 716, 714, 713, 712, 711, 710, + 709, 708, 707, 706, 705, 704, 702, 701, 700, 699, + 698, 697, 695, 694, 693, 692, 691, 689, 688, 687, + 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, + + 676, 675, 674, 673, 672, 670, 669, 668, 667, 666, + 665, 664, 663, 662, 661, 654, 652, 651, 649, 648, + 647, 646, 645, 644, 643, 642, 641, 640, 639, 638, + 637, 635, 634, 633, 632, 631, 630, 629, 627, 626, + 625, 624, 623, 622, 618, 617, 616, 615, 614, 613, + 612, 611, 610, 609, 608, 607, 601, 599, 598, 597, + 596, 592, 591, 590, 589, 588, 587, 586, 585, 584, + 575, 571, 570, 568, 567, 565, 564, 563, 562, 561, + 560, 559, 558, 557, 555, 553, 552, 551, 550, 549, + 548, 547, 546, 545, 544, 542, 541, 537, 536, 535, + + 532, 531, 529, 528, 526, 525, 524, 523, 522, 520, + 518, 517, 516, 515, 514, 513, 511, 510, 509, 508, + 507, 503, 502, 501, 500, 499, 498, 495, 494, 493, + 492, 491, 489, 488, 487, 486, 485, 484, 482, 481, + 474, 473, 470, 469, 466, 465, 464, 463, 452, 451, + 450, 448, 447, 446, 445, 444, 441, 439, 438, 437, + 435, 434, 432, 431, 430, 429, 427, 426, 421, 420, + 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, + 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, + 397, 396, 392, 388, 387, 386, 383, 381, 371, 369, + + 365, 364, 363, 362, 360, 358, 353, 352, 349, 348, + 347, 346, 345, 344, 339, 337, 336, 335, 334, 333, + 331, 330, 327, 326, 325, 324, 323, 322, 321, 320, + 319, 318, 317, 316, 315, 314, 313, 312, 311, 310, + 309, 308, 307, 306, 305, 302, 300, 299, 298, 297, + 296, 295, 294, 293, 291, 287, 285, 284, 283, 282, + 278, 277, 276, 275, 274, 273, 272, 271, 267, 265, + 264, 254, 253, 252, 251, 250, 249, 248, 246, 245, + 244, 243, 242, 240, 239, 238, 237, 236, 235, 234, + 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, + + 223, 222, 221, 220, 219, 218, 217, 216, 214, 213, + 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, + 202, 201, 200, 199, 198, 196, 195, 194, 193, 192, + 191, 190, 189, 188, 187, 186, 185, 183, 182, 181, + 179, 178, 177, 176, 174, 159, 158, 157, 156, 149, + 147, 146, 145, 141, 140, 139, 138, 137, 136, 134, + 133, 132, 131, 130, 129, 128, 127, 125, 123, 122, + 121, 119, 118, 117, 115, 114, 112, 111, 110, 109, + 108, 107, 104, 103, 102, 101, 100, 99, 98, 97, + 95, 94, 93, 92, 91, 90, 89, 88, 87, 83, + + 79, 52, 45, 38, 32, 22, 18, 14, 12, 11, + 7, 6, 5, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, 835 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "glsl_lexer.lpp" +#line 2 "glsl_lexer.lpp" +/* + * Copyright © 2008, 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include +#include "strtod.h" +#include "ast.h" +#include "glsl_parser_extras.h" +#include "glsl_parser.h" + +static int classify_identifier(struct _mesa_glsl_parse_state *, const char *); + +#define YY_USER_ACTION \ + do { \ + yylloc->source = 0; \ + yylloc->first_column = yycolumn + 1; \ + yylloc->first_line = yylineno + 1; \ + yycolumn += yyleng; \ + } while(0); + +#define YY_USER_INIT yylineno = 0; yycolumn = 0; + +#define IS_UINT (yytext[yyleng - 1] == 'u' || yytext[yyleng - 1] == 'U') + +/* A macro for handling reserved words and keywords across language versions. + * + * Certain words start out as identifiers, become reserved words in + * later language revisions, and finally become language keywords. + * + * For example, consider the following lexer rule: + * samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER) + * + * This means that "samplerBuffer" will be treated as: + * - a keyword (SAMPLERBUFFER token) ...in GLSL >= 1.40 + * - a reserved word - error ...in GLSL >= 1.30 + * - an identifier ...in GLSL < 1.30 + */ +#define KEYWORD(reserved_version, allowed_version, token) \ + do { \ + if (yyextra->language_version >= allowed_version) { \ + return token; \ + } else if (yyextra->language_version >= reserved_version) { \ + _mesa_glsl_error(yylloc, yyextra, \ + "Illegal use of reserved word `%s'", yytext); \ + return ERROR_TOK; \ + } else { \ + yylval->identifier = strdup(yytext); \ + return classify_identifier(yyextra, yytext); \ + } \ + } while (0) + +/* The ES macro can be used in KEYWORD checks: + * + * word KEYWORD(110 || ES, 400, TOKEN) + * ...means the word is reserved in GLSL ES 1.00, while + * + * word KEYWORD(110, 130 || ES, TOKEN) + * ...means the word is a legal keyword in GLSL ES 1.00. + */ +#define ES yyextra->es_shader + +#line 1073 "glsl_lexer.cpp" + +#define INITIAL 0 +#define PP 1 +#define PRAGMA 2 + +#define YY_EXTRA_TYPE struct _mesa_glsl_parse_state * + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + int yy_n_chars; + int yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + YYSTYPE * yylval_r; + + YYLTYPE * yylloc_r; + + }; /* end struct yyguts_t */ + +static int yy_init_globals (yyscan_t yyscanner ); + + /* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ + # define yylval yyg->yylval_r + + # define yylloc yyg->yylloc_r + +int _mesa_glsl_lex_init (yyscan_t* scanner); + +int _mesa_glsl_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int _mesa_glsl_lex_destroy (yyscan_t yyscanner ); + +int _mesa_glsl_get_debug (yyscan_t yyscanner ); + +void _mesa_glsl_set_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE _mesa_glsl_get_extra (yyscan_t yyscanner ); + +void _mesa_glsl_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *_mesa_glsl_get_in (yyscan_t yyscanner ); + +void _mesa_glsl_set_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *_mesa_glsl_get_out (yyscan_t yyscanner ); + +void _mesa_glsl_set_out (FILE * out_str ,yyscan_t yyscanner ); + +int _mesa_glsl_get_leng (yyscan_t yyscanner ); + +char *_mesa_glsl_get_text (yyscan_t yyscanner ); + +int _mesa_glsl_get_lineno (yyscan_t yyscanner ); + +void _mesa_glsl_set_lineno (int line_number ,yyscan_t yyscanner ); + +int _mesa_glsl_get_column (yyscan_t yyscanner ); + +void _mesa_glsl_set_column (int column_no ,yyscan_t yyscanner ); + +YYSTYPE * _mesa_glsl_get_lval (yyscan_t yyscanner ); + +void _mesa_glsl_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + + YYLTYPE *_mesa_glsl_get_lloc (yyscan_t yyscanner ); + + void _mesa_glsl_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int _mesa_glsl_wrap (yyscan_t yyscanner ); +#else +extern int _mesa_glsl_wrap (yyscan_t yyscanner ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner ); +#else +static int input (yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + unsigned n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int _mesa_glsl_lex \ + (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); + +#define YY_DECL int _mesa_glsl_lex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + if ( yyleng > 0 ) \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ + (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + +#line 97 "glsl_lexer.lpp" + + +#line 1314 "glsl_lexer.cpp" + + yylval = yylval_param; + + yylloc = yylloc_param; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + _mesa_glsl_ensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + _mesa_glsl__load_buffer_state(yyscanner ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yyg->yy_start; + yy_current_state += YY_AT_BOL(); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 836 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 835 ); + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 99 "glsl_lexer.lpp" +; + YY_BREAK +/* Preprocessor tokens. */ +case 2: +*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ +yyg->yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 102 "glsl_lexer.lpp" +; + YY_BREAK +case 3: +YY_RULE_SETUP +#line 103 "glsl_lexer.lpp" +{ BEGIN PP; return VERSION; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 104 "glsl_lexer.lpp" +{ BEGIN PP; return EXTENSION; } + YY_BREAK +case 5: +*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ +yyg->yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 105 "glsl_lexer.lpp" +{ + /* Eat characters until the first digit is + * encountered + */ + char *ptr = yytext; + while (!isdigit(*ptr)) + ptr++; + + /* Subtract one from the line number because + * yylineno is zero-based instead of + * one-based. + */ + yylineno = strtol(ptr, &ptr, 0) - 1; + yylloc->source = strtol(ptr, NULL, 0); + } + YY_BREAK +case 6: +*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ +yyg->yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 120 "glsl_lexer.lpp" +{ + /* Eat characters until the first digit is + * encountered + */ + char *ptr = yytext; + while (!isdigit(*ptr)) + ptr++; + + /* Subtract one from the line number because + * yylineno is zero-based instead of + * one-based. + */ + yylineno = strtol(ptr, &ptr, 0) - 1; + } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 134 "glsl_lexer.lpp" +{ + BEGIN PP; + return PRAGMA_DEBUG_ON; + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 138 "glsl_lexer.lpp" +{ + BEGIN PP; + return PRAGMA_DEBUG_OFF; + } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 142 "glsl_lexer.lpp" +{ + BEGIN PP; + return PRAGMA_OPTIMIZE_ON; + } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 146 "glsl_lexer.lpp" +{ + BEGIN PP; + return PRAGMA_OPTIMIZE_OFF; + } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 150 "glsl_lexer.lpp" +{ + BEGIN PP; + return PRAGMA_INVARIANT_ALL; + } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 154 "glsl_lexer.lpp" +{ BEGIN PRAGMA; } + YY_BREAK +case 13: +/* rule 13 can match eol */ +YY_RULE_SETUP +#line 156 "glsl_lexer.lpp" +{ BEGIN 0; yylineno++; yycolumn = 0; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 157 "glsl_lexer.lpp" +{ } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 159 "glsl_lexer.lpp" +{ } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 160 "glsl_lexer.lpp" +{ } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 161 "glsl_lexer.lpp" +return COLON; + YY_BREAK +case 18: +YY_RULE_SETUP +#line 162 "glsl_lexer.lpp" +{ + yylval->identifier = strdup(yytext); + return IDENTIFIER; + } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 166 "glsl_lexer.lpp" +{ + yylval->n = strtol(yytext, NULL, 10); + return INTCONSTANT; + } + YY_BREAK +case 20: +/* rule 20 can match eol */ +YY_RULE_SETUP +#line 170 "glsl_lexer.lpp" +{ BEGIN 0; yylineno++; yycolumn = 0; return EOL; } + YY_BREAK +case 21: +/* rule 21 can match eol */ +YY_RULE_SETUP +#line 172 "glsl_lexer.lpp" +{ yylineno++; yycolumn = 0; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 174 "glsl_lexer.lpp" +return ATTRIBUTE; + YY_BREAK +case 23: +YY_RULE_SETUP +#line 175 "glsl_lexer.lpp" +return CONST_TOK; + YY_BREAK +case 24: +YY_RULE_SETUP +#line 176 "glsl_lexer.lpp" +return BOOL_TOK; + YY_BREAK +case 25: +YY_RULE_SETUP +#line 177 "glsl_lexer.lpp" +return FLOAT_TOK; + YY_BREAK +case 26: +YY_RULE_SETUP +#line 178 "glsl_lexer.lpp" +return INT_TOK; + YY_BREAK +case 27: +YY_RULE_SETUP +#line 179 "glsl_lexer.lpp" +KEYWORD(130, 130, UINT_TOK); + YY_BREAK +case 28: +YY_RULE_SETUP +#line 181 "glsl_lexer.lpp" +return BREAK; + YY_BREAK +case 29: +YY_RULE_SETUP +#line 182 "glsl_lexer.lpp" +return CONTINUE; + YY_BREAK +case 30: +YY_RULE_SETUP +#line 183 "glsl_lexer.lpp" +return DO; + YY_BREAK +case 31: +YY_RULE_SETUP +#line 184 "glsl_lexer.lpp" +return WHILE; + YY_BREAK +case 32: +YY_RULE_SETUP +#line 185 "glsl_lexer.lpp" +return ELSE; + YY_BREAK +case 33: +YY_RULE_SETUP +#line 186 "glsl_lexer.lpp" +return FOR; + YY_BREAK +case 34: +YY_RULE_SETUP +#line 187 "glsl_lexer.lpp" +return IF; + YY_BREAK +case 35: +YY_RULE_SETUP +#line 188 "glsl_lexer.lpp" +return DISCARD; + YY_BREAK +case 36: +YY_RULE_SETUP +#line 189 "glsl_lexer.lpp" +return RETURN; + YY_BREAK +case 37: +YY_RULE_SETUP +#line 191 "glsl_lexer.lpp" +return BVEC2; + YY_BREAK +case 38: +YY_RULE_SETUP +#line 192 "glsl_lexer.lpp" +return BVEC3; + YY_BREAK +case 39: +YY_RULE_SETUP +#line 193 "glsl_lexer.lpp" +return BVEC4; + YY_BREAK +case 40: +YY_RULE_SETUP +#line 194 "glsl_lexer.lpp" +return IVEC2; + YY_BREAK +case 41: +YY_RULE_SETUP +#line 195 "glsl_lexer.lpp" +return IVEC3; + YY_BREAK +case 42: +YY_RULE_SETUP +#line 196 "glsl_lexer.lpp" +return IVEC4; + YY_BREAK +case 43: +YY_RULE_SETUP +#line 197 "glsl_lexer.lpp" +KEYWORD(130, 130, UVEC2); + YY_BREAK +case 44: +YY_RULE_SETUP +#line 198 "glsl_lexer.lpp" +KEYWORD(130, 130, UVEC3); + YY_BREAK +case 45: +YY_RULE_SETUP +#line 199 "glsl_lexer.lpp" +KEYWORD(130, 130, UVEC4); + YY_BREAK +case 46: +YY_RULE_SETUP +#line 200 "glsl_lexer.lpp" +return VEC2; + YY_BREAK +case 47: +YY_RULE_SETUP +#line 201 "glsl_lexer.lpp" +return VEC3; + YY_BREAK +case 48: +YY_RULE_SETUP +#line 202 "glsl_lexer.lpp" +return VEC4; + YY_BREAK +case 49: +YY_RULE_SETUP +#line 203 "glsl_lexer.lpp" +return MAT2X2; + YY_BREAK +case 50: +YY_RULE_SETUP +#line 204 "glsl_lexer.lpp" +return MAT3X3; + YY_BREAK +case 51: +YY_RULE_SETUP +#line 205 "glsl_lexer.lpp" +return MAT4X4; + YY_BREAK +case 52: +YY_RULE_SETUP +#line 206 "glsl_lexer.lpp" +KEYWORD(120, 120, MAT2X2); + YY_BREAK +case 53: +YY_RULE_SETUP +#line 207 "glsl_lexer.lpp" +KEYWORD(120, 120, MAT2X3); + YY_BREAK +case 54: +YY_RULE_SETUP +#line 208 "glsl_lexer.lpp" +KEYWORD(120, 120, MAT2X4); + YY_BREAK +case 55: +YY_RULE_SETUP +#line 209 "glsl_lexer.lpp" +KEYWORD(120, 120, MAT3X2); + YY_BREAK +case 56: +YY_RULE_SETUP +#line 210 "glsl_lexer.lpp" +KEYWORD(120, 120, MAT3X3); + YY_BREAK +case 57: +YY_RULE_SETUP +#line 211 "glsl_lexer.lpp" +KEYWORD(120, 120, MAT3X4); + YY_BREAK +case 58: +YY_RULE_SETUP +#line 212 "glsl_lexer.lpp" +KEYWORD(120, 120, MAT4X2); + YY_BREAK +case 59: +YY_RULE_SETUP +#line 213 "glsl_lexer.lpp" +KEYWORD(120, 120, MAT4X3); + YY_BREAK +case 60: +YY_RULE_SETUP +#line 214 "glsl_lexer.lpp" +KEYWORD(120, 120, MAT4X4); + YY_BREAK +case 61: +YY_RULE_SETUP +#line 216 "glsl_lexer.lpp" +return IN_TOK; + YY_BREAK +case 62: +YY_RULE_SETUP +#line 217 "glsl_lexer.lpp" +return OUT_TOK; + YY_BREAK +case 63: +YY_RULE_SETUP +#line 218 "glsl_lexer.lpp" +return INOUT_TOK; + YY_BREAK +case 64: +YY_RULE_SETUP +#line 219 "glsl_lexer.lpp" +return UNIFORM; + YY_BREAK +case 65: +YY_RULE_SETUP +#line 220 "glsl_lexer.lpp" +return VARYING; + YY_BREAK +case 66: +YY_RULE_SETUP +#line 221 "glsl_lexer.lpp" +KEYWORD(120, 120, CENTROID); + YY_BREAK +case 67: +YY_RULE_SETUP +#line 222 "glsl_lexer.lpp" +KEYWORD(120 || ES, 120 || ES, INVARIANT); + YY_BREAK +case 68: +YY_RULE_SETUP +#line 223 "glsl_lexer.lpp" +KEYWORD(130 || ES, 130, FLAT); + YY_BREAK +case 69: +YY_RULE_SETUP +#line 224 "glsl_lexer.lpp" +KEYWORD(130, 130, SMOOTH); + YY_BREAK +case 70: +YY_RULE_SETUP +#line 225 "glsl_lexer.lpp" +KEYWORD(130, 130, NOPERSPECTIVE); + YY_BREAK +case 71: +YY_RULE_SETUP +#line 227 "glsl_lexer.lpp" +return SAMPLER1D; + YY_BREAK +case 72: +YY_RULE_SETUP +#line 228 "glsl_lexer.lpp" +return SAMPLER2D; + YY_BREAK +case 73: +YY_RULE_SETUP +#line 229 "glsl_lexer.lpp" +return SAMPLER3D; + YY_BREAK +case 74: +YY_RULE_SETUP +#line 230 "glsl_lexer.lpp" +return SAMPLERCUBE; + YY_BREAK +case 75: +YY_RULE_SETUP +#line 231 "glsl_lexer.lpp" +KEYWORD(130, 130, SAMPLER1DARRAY); + YY_BREAK +case 76: +YY_RULE_SETUP +#line 232 "glsl_lexer.lpp" +KEYWORD(130, 130, SAMPLER2DARRAY); + YY_BREAK +case 77: +YY_RULE_SETUP +#line 233 "glsl_lexer.lpp" +return SAMPLER1DSHADOW; + YY_BREAK +case 78: +YY_RULE_SETUP +#line 234 "glsl_lexer.lpp" +return SAMPLER2DSHADOW; + YY_BREAK +case 79: +YY_RULE_SETUP +#line 235 "glsl_lexer.lpp" +KEYWORD(130, 130, SAMPLERCUBESHADOW); + YY_BREAK +case 80: +YY_RULE_SETUP +#line 236 "glsl_lexer.lpp" +KEYWORD(130, 130, SAMPLER1DARRAYSHADOW); + YY_BREAK +case 81: +YY_RULE_SETUP +#line 237 "glsl_lexer.lpp" +KEYWORD(130, 130, SAMPLER2DARRAYSHADOW); + YY_BREAK +case 82: +YY_RULE_SETUP +#line 238 "glsl_lexer.lpp" +KEYWORD(130, 130, ISAMPLER1D); + YY_BREAK +case 83: +YY_RULE_SETUP +#line 239 "glsl_lexer.lpp" +KEYWORD(130, 130, ISAMPLER2D); + YY_BREAK +case 84: +YY_RULE_SETUP +#line 240 "glsl_lexer.lpp" +KEYWORD(130, 130, ISAMPLER3D); + YY_BREAK +case 85: +YY_RULE_SETUP +#line 241 "glsl_lexer.lpp" +KEYWORD(130, 130, ISAMPLERCUBE); + YY_BREAK +case 86: +YY_RULE_SETUP +#line 242 "glsl_lexer.lpp" +KEYWORD(130, 130, ISAMPLER1DARRAY); + YY_BREAK +case 87: +YY_RULE_SETUP +#line 243 "glsl_lexer.lpp" +KEYWORD(130, 130, ISAMPLER2DARRAY); + YY_BREAK +case 88: +YY_RULE_SETUP +#line 244 "glsl_lexer.lpp" +KEYWORD(130, 130, USAMPLER1D); + YY_BREAK +case 89: +YY_RULE_SETUP +#line 245 "glsl_lexer.lpp" +KEYWORD(130, 130, USAMPLER2D); + YY_BREAK +case 90: +YY_RULE_SETUP +#line 246 "glsl_lexer.lpp" +KEYWORD(130, 130, USAMPLER3D); + YY_BREAK +case 91: +YY_RULE_SETUP +#line 247 "glsl_lexer.lpp" +KEYWORD(130, 130, USAMPLERCUBE); + YY_BREAK +case 92: +YY_RULE_SETUP +#line 248 "glsl_lexer.lpp" +KEYWORD(130, 130, USAMPLER1DARRAY); + YY_BREAK +case 93: +YY_RULE_SETUP +#line 249 "glsl_lexer.lpp" +KEYWORD(130, 130, USAMPLER2DARRAY); + YY_BREAK +case 94: +YY_RULE_SETUP +#line 252 "glsl_lexer.lpp" +return STRUCT; + YY_BREAK +case 95: +YY_RULE_SETUP +#line 253 "glsl_lexer.lpp" +return VOID_TOK; + YY_BREAK +case 96: +YY_RULE_SETUP +#line 255 "glsl_lexer.lpp" +{ + if ((yyextra->language_version >= 140) + || yyextra->AMD_conservative_depth_enable + || yyextra->ARB_explicit_attrib_location_enable + || yyextra->ARB_fragment_coord_conventions_enable) { + return LAYOUT_TOK; + } else { + yylval->identifier = strdup(yytext); + return IDENTIFIER; + } + } + YY_BREAK +case 97: +YY_RULE_SETUP +#line 267 "glsl_lexer.lpp" +return INC_OP; + YY_BREAK +case 98: +YY_RULE_SETUP +#line 268 "glsl_lexer.lpp" +return DEC_OP; + YY_BREAK +case 99: +YY_RULE_SETUP +#line 269 "glsl_lexer.lpp" +return LE_OP; + YY_BREAK +case 100: +YY_RULE_SETUP +#line 270 "glsl_lexer.lpp" +return GE_OP; + YY_BREAK +case 101: +YY_RULE_SETUP +#line 271 "glsl_lexer.lpp" +return EQ_OP; + YY_BREAK +case 102: +YY_RULE_SETUP +#line 272 "glsl_lexer.lpp" +return NE_OP; + YY_BREAK +case 103: +YY_RULE_SETUP +#line 273 "glsl_lexer.lpp" +return AND_OP; + YY_BREAK +case 104: +YY_RULE_SETUP +#line 274 "glsl_lexer.lpp" +return OR_OP; + YY_BREAK +case 105: +YY_RULE_SETUP +#line 275 "glsl_lexer.lpp" +return XOR_OP; + YY_BREAK +case 106: +YY_RULE_SETUP +#line 276 "glsl_lexer.lpp" +return LEFT_OP; + YY_BREAK +case 107: +YY_RULE_SETUP +#line 277 "glsl_lexer.lpp" +return RIGHT_OP; + YY_BREAK +case 108: +YY_RULE_SETUP +#line 279 "glsl_lexer.lpp" +return MUL_ASSIGN; + YY_BREAK +case 109: +YY_RULE_SETUP +#line 280 "glsl_lexer.lpp" +return DIV_ASSIGN; + YY_BREAK +case 110: +YY_RULE_SETUP +#line 281 "glsl_lexer.lpp" +return ADD_ASSIGN; + YY_BREAK +case 111: +YY_RULE_SETUP +#line 282 "glsl_lexer.lpp" +return MOD_ASSIGN; + YY_BREAK +case 112: +YY_RULE_SETUP +#line 283 "glsl_lexer.lpp" +return LEFT_ASSIGN; + YY_BREAK +case 113: +YY_RULE_SETUP +#line 284 "glsl_lexer.lpp" +return RIGHT_ASSIGN; + YY_BREAK +case 114: +YY_RULE_SETUP +#line 285 "glsl_lexer.lpp" +return AND_ASSIGN; + YY_BREAK +case 115: +YY_RULE_SETUP +#line 286 "glsl_lexer.lpp" +return XOR_ASSIGN; + YY_BREAK +case 116: +YY_RULE_SETUP +#line 287 "glsl_lexer.lpp" +return OR_ASSIGN; + YY_BREAK +case 117: +YY_RULE_SETUP +#line 288 "glsl_lexer.lpp" +return SUB_ASSIGN; + YY_BREAK +case 118: +YY_RULE_SETUP +#line 290 "glsl_lexer.lpp" +{ + yylval->n = strtol(yytext, NULL, 10); + return IS_UINT ? UINTCONSTANT : INTCONSTANT; + } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 294 "glsl_lexer.lpp" +{ + yylval->n = strtol(yytext + 2, NULL, 16); + return IS_UINT ? UINTCONSTANT : INTCONSTANT; + } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 298 "glsl_lexer.lpp" +{ + yylval->n = strtol(yytext, NULL, 8); + return IS_UINT ? UINTCONSTANT : INTCONSTANT; + } + YY_BREAK +case 121: +YY_RULE_SETUP +#line 303 "glsl_lexer.lpp" +{ + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 307 "glsl_lexer.lpp" +{ + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } + YY_BREAK +case 123: +YY_RULE_SETUP +#line 311 "glsl_lexer.lpp" +{ + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 315 "glsl_lexer.lpp" +{ + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } + YY_BREAK +case 125: +YY_RULE_SETUP +#line 319 "glsl_lexer.lpp" +{ + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 324 "glsl_lexer.lpp" +{ + yylval->n = 1; + return BOOLCONSTANT; + } + YY_BREAK +case 127: +YY_RULE_SETUP +#line 328 "glsl_lexer.lpp" +{ + yylval->n = 0; + return BOOLCONSTANT; + } + YY_BREAK +/* Reserved words in GLSL 1.10. */ +case 128: +YY_RULE_SETUP +#line 335 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, ASM); + YY_BREAK +case 129: +YY_RULE_SETUP +#line 336 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, CLASS); + YY_BREAK +case 130: +YY_RULE_SETUP +#line 337 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, UNION); + YY_BREAK +case 131: +YY_RULE_SETUP +#line 338 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, ENUM); + YY_BREAK +case 132: +YY_RULE_SETUP +#line 339 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, TYPEDEF); + YY_BREAK +case 133: +YY_RULE_SETUP +#line 340 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, TEMPLATE); + YY_BREAK +case 134: +YY_RULE_SETUP +#line 341 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, THIS); + YY_BREAK +case 135: +YY_RULE_SETUP +#line 342 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, PACKED_TOK); + YY_BREAK +case 136: +YY_RULE_SETUP +#line 343 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, GOTO); + YY_BREAK +case 137: +YY_RULE_SETUP +#line 344 "glsl_lexer.lpp" +KEYWORD(110 || ES, 130, SWITCH); + YY_BREAK +case 138: +YY_RULE_SETUP +#line 345 "glsl_lexer.lpp" +KEYWORD(110 || ES, 130, DEFAULT); + YY_BREAK +case 139: +YY_RULE_SETUP +#line 346 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, INLINE_TOK); + YY_BREAK +case 140: +YY_RULE_SETUP +#line 347 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, NOINLINE); + YY_BREAK +case 141: +YY_RULE_SETUP +#line 348 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, VOLATILE); + YY_BREAK +case 142: +YY_RULE_SETUP +#line 349 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, PUBLIC_TOK); + YY_BREAK +case 143: +YY_RULE_SETUP +#line 350 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, STATIC); + YY_BREAK +case 144: +YY_RULE_SETUP +#line 351 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, EXTERN); + YY_BREAK +case 145: +YY_RULE_SETUP +#line 352 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, EXTERNAL); + YY_BREAK +case 146: +YY_RULE_SETUP +#line 353 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, INTERFACE); + YY_BREAK +case 147: +YY_RULE_SETUP +#line 354 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, LONG_TOK); + YY_BREAK +case 148: +YY_RULE_SETUP +#line 355 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, SHORT_TOK); + YY_BREAK +case 149: +YY_RULE_SETUP +#line 356 "glsl_lexer.lpp" +KEYWORD(110 || ES, 400, DOUBLE_TOK); + YY_BREAK +case 150: +YY_RULE_SETUP +#line 357 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, HALF); + YY_BREAK +case 151: +YY_RULE_SETUP +#line 358 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, FIXED_TOK); + YY_BREAK +case 152: +YY_RULE_SETUP +#line 359 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, UNSIGNED); + YY_BREAK +case 153: +YY_RULE_SETUP +#line 360 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, INPUT_TOK); + YY_BREAK +case 154: +YY_RULE_SETUP +#line 361 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, OUTPUT); + YY_BREAK +case 155: +YY_RULE_SETUP +#line 362 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, HVEC2); + YY_BREAK +case 156: +YY_RULE_SETUP +#line 363 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, HVEC3); + YY_BREAK +case 157: +YY_RULE_SETUP +#line 364 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, HVEC4); + YY_BREAK +case 158: +YY_RULE_SETUP +#line 365 "glsl_lexer.lpp" +KEYWORD(110 || ES, 400, DVEC2); + YY_BREAK +case 159: +YY_RULE_SETUP +#line 366 "glsl_lexer.lpp" +KEYWORD(110 || ES, 400, DVEC3); + YY_BREAK +case 160: +YY_RULE_SETUP +#line 367 "glsl_lexer.lpp" +KEYWORD(110 || ES, 400, DVEC4); + YY_BREAK +case 161: +YY_RULE_SETUP +#line 368 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, FVEC2); + YY_BREAK +case 162: +YY_RULE_SETUP +#line 369 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, FVEC3); + YY_BREAK +case 163: +YY_RULE_SETUP +#line 370 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, FVEC4); + YY_BREAK +case 164: +YY_RULE_SETUP +#line 371 "glsl_lexer.lpp" +return SAMPLER2DRECT; + YY_BREAK +case 165: +YY_RULE_SETUP +#line 372 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, SAMPLER3DRECT); + YY_BREAK +case 166: +YY_RULE_SETUP +#line 373 "glsl_lexer.lpp" +return SAMPLER2DRECTSHADOW; + YY_BREAK +case 167: +YY_RULE_SETUP +#line 374 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, SIZEOF); + YY_BREAK +case 168: +YY_RULE_SETUP +#line 375 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, CAST); + YY_BREAK +case 169: +YY_RULE_SETUP +#line 376 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, NAMESPACE); + YY_BREAK +case 170: +YY_RULE_SETUP +#line 377 "glsl_lexer.lpp" +KEYWORD(110 || ES, 999, USING); + YY_BREAK +/* Additional reserved words in GLSL 1.20. */ +case 171: +YY_RULE_SETUP +#line 380 "glsl_lexer.lpp" +KEYWORD(120, 130 || ES, LOWP); + YY_BREAK +case 172: +YY_RULE_SETUP +#line 381 "glsl_lexer.lpp" +KEYWORD(120, 130 || ES, MEDIUMP); + YY_BREAK +case 173: +YY_RULE_SETUP +#line 382 "glsl_lexer.lpp" +KEYWORD(120, 130 || ES, HIGHP); + YY_BREAK +case 174: +YY_RULE_SETUP +#line 383 "glsl_lexer.lpp" +KEYWORD(120, 130 || ES, PRECISION); + YY_BREAK +/* Additional reserved words in GLSL 1.30. */ +case 175: +YY_RULE_SETUP +#line 386 "glsl_lexer.lpp" +KEYWORD(130, 130, CASE); + YY_BREAK +case 176: +YY_RULE_SETUP +#line 387 "glsl_lexer.lpp" +KEYWORD(130, 999, COMMON); + YY_BREAK +case 177: +YY_RULE_SETUP +#line 388 "glsl_lexer.lpp" +KEYWORD(130, 999, PARTITION); + YY_BREAK +case 178: +YY_RULE_SETUP +#line 389 "glsl_lexer.lpp" +KEYWORD(130, 999, ACTIVE); + YY_BREAK +case 179: +YY_RULE_SETUP +#line 390 "glsl_lexer.lpp" +KEYWORD(130 || ES, 999, SUPERP); + YY_BREAK +case 180: +YY_RULE_SETUP +#line 391 "glsl_lexer.lpp" +KEYWORD(130, 140, SAMPLERBUFFER); + YY_BREAK +case 181: +YY_RULE_SETUP +#line 392 "glsl_lexer.lpp" +KEYWORD(130, 999, FILTER); + YY_BREAK +case 182: +YY_RULE_SETUP +#line 393 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGE1D); + YY_BREAK +case 183: +YY_RULE_SETUP +#line 394 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGE2D); + YY_BREAK +case 184: +YY_RULE_SETUP +#line 395 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGE3D); + YY_BREAK +case 185: +YY_RULE_SETUP +#line 396 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGECUBE); + YY_BREAK +case 186: +YY_RULE_SETUP +#line 397 "glsl_lexer.lpp" +KEYWORD(130, 999, IIMAGE1D); + YY_BREAK +case 187: +YY_RULE_SETUP +#line 398 "glsl_lexer.lpp" +KEYWORD(130, 999, IIMAGE2D); + YY_BREAK +case 188: +YY_RULE_SETUP +#line 399 "glsl_lexer.lpp" +KEYWORD(130, 999, IIMAGE3D); + YY_BREAK +case 189: +YY_RULE_SETUP +#line 400 "glsl_lexer.lpp" +KEYWORD(130, 999, IIMAGECUBE); + YY_BREAK +case 190: +YY_RULE_SETUP +#line 401 "glsl_lexer.lpp" +KEYWORD(130, 999, UIMAGE1D); + YY_BREAK +case 191: +YY_RULE_SETUP +#line 402 "glsl_lexer.lpp" +KEYWORD(130, 999, UIMAGE2D); + YY_BREAK +case 192: +YY_RULE_SETUP +#line 403 "glsl_lexer.lpp" +KEYWORD(130, 999, UIMAGE3D); + YY_BREAK +case 193: +YY_RULE_SETUP +#line 404 "glsl_lexer.lpp" +KEYWORD(130, 999, UIMAGECUBE); + YY_BREAK +case 194: +YY_RULE_SETUP +#line 405 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGE1DARRAY); + YY_BREAK +case 195: +YY_RULE_SETUP +#line 406 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGE2DARRAY); + YY_BREAK +case 196: +YY_RULE_SETUP +#line 407 "glsl_lexer.lpp" +KEYWORD(130, 999, IIMAGE1DARRAY); + YY_BREAK +case 197: +YY_RULE_SETUP +#line 408 "glsl_lexer.lpp" +KEYWORD(130, 999, IIMAGE2DARRAY); + YY_BREAK +case 198: +YY_RULE_SETUP +#line 409 "glsl_lexer.lpp" +KEYWORD(130, 999, UIMAGE1DARRAY); + YY_BREAK +case 199: +YY_RULE_SETUP +#line 410 "glsl_lexer.lpp" +KEYWORD(130, 999, UIMAGE2DARRAY); + YY_BREAK +case 200: +YY_RULE_SETUP +#line 411 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGE1DSHADOW); + YY_BREAK +case 201: +YY_RULE_SETUP +#line 412 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGE2DSHADOW); + YY_BREAK +case 202: +YY_RULE_SETUP +#line 413 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGE1DARRAYSHADOW); + YY_BREAK +case 203: +YY_RULE_SETUP +#line 414 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGE2DARRAYSHADOW); + YY_BREAK +case 204: +YY_RULE_SETUP +#line 415 "glsl_lexer.lpp" +KEYWORD(130, 999, IMAGEBUFFER); + YY_BREAK +case 205: +YY_RULE_SETUP +#line 416 "glsl_lexer.lpp" +KEYWORD(130, 999, IIMAGEBUFFER); + YY_BREAK +case 206: +YY_RULE_SETUP +#line 417 "glsl_lexer.lpp" +KEYWORD(130, 999, UIMAGEBUFFER); + YY_BREAK +case 207: +YY_RULE_SETUP +#line 418 "glsl_lexer.lpp" +KEYWORD(130, 999, ROW_MAJOR); + YY_BREAK +case 208: +YY_RULE_SETUP +#line 420 "glsl_lexer.lpp" +{ + struct _mesa_glsl_parse_state *state = yyextra; + void *ctx = state; + yylval->identifier = ralloc_strdup(ctx, yytext); + return classify_identifier(state, yytext); + } + YY_BREAK +case 209: +YY_RULE_SETUP +#line 427 "glsl_lexer.lpp" +{ return yytext[0]; } + YY_BREAK +case 210: +YY_RULE_SETUP +#line 429 "glsl_lexer.lpp" +ECHO; + YY_BREAK +#line 2557 "glsl_lexer.cpp" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(PP): +case YY_STATE_EOF(PRAGMA): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * _mesa_glsl_lex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( _mesa_glsl_wrap(yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of _mesa_glsl_lex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = yyg->yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + _mesa_glsl_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + 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; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + _mesa_glsl_restart(yyin ,yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (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. */ + yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) _mesa_glsl_realloc((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; + 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; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yyg->yy_start; + yy_current_state += YY_AT_BOL(); + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 836 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +{ + register int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + register char *yy_cp = yyg->yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 836 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 835); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (yyscan_t yyscanner) +#else + static int input (yyscan_t yyscanner) +#endif + +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + _mesa_glsl_restart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( _mesa_glsl_wrap(yyscanner ) ) + return EOF; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ + void _mesa_glsl_restart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + _mesa_glsl_ensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + _mesa_glsl__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + _mesa_glsl__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + _mesa_glsl__load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ + void _mesa_glsl__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * _mesa_glsl_pop_buffer_state(); + * _mesa_glsl_push_buffer_state(new_buffer); + */ + _mesa_glsl_ensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + _mesa_glsl__load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (_mesa_glsl_wrap()) processing, but the only time this flag + * is looked at is after _mesa_glsl_wrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void _mesa_glsl__load_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ + YY_BUFFER_STATE _mesa_glsl__create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) _mesa_glsl_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) _mesa_glsl_alloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__create_buffer()" ); + + b->yy_is_our_buffer = 1; + + _mesa_glsl__init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with _mesa_glsl__create_buffer() + * @param yyscanner The scanner object. + */ + void _mesa_glsl__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + _mesa_glsl_free((void *) b->yy_ch_buf ,yyscanner ); + + _mesa_glsl_free((void *) b ,yyscanner ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a _mesa_glsl_restart() or at EOF. + */ + static void _mesa_glsl__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + _mesa_glsl__flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then _mesa_glsl__init_buffer was _probably_ + * called from _mesa_glsl_restart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ + void _mesa_glsl__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + _mesa_glsl__load_buffer_state(yyscanner ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void _mesa_glsl_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + _mesa_glsl_ensure_buffer_stack(yyscanner); + + /* This block is copied from _mesa_glsl__switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from _mesa_glsl__switch_to_buffer. */ + _mesa_glsl__load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void _mesa_glsl_pop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + _mesa_glsl__delete_buffer(YY_CURRENT_BUFFER ,yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + _mesa_glsl__load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void _mesa_glsl_ensure_buffer_stack (yyscan_t yyscanner) +{ + int num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_glsl_alloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl_ensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)_mesa_glsl_realloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl_ensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE _mesa_glsl__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) _mesa_glsl_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__scan_buffer()" ); + + 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; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + _mesa_glsl__switch_to_buffer(b ,yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to _mesa_glsl_lex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * _mesa_glsl__scan_bytes() instead. + */ +YY_BUFFER_STATE _mesa_glsl__scan_string (yyconst char * yystr , yyscan_t yyscanner) +{ + + return _mesa_glsl__scan_bytes(yystr,strlen(yystr) ,yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to _mesa_glsl_lex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE _mesa_glsl__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) _mesa_glsl_alloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in _mesa_glsl__scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = _mesa_glsl__scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in _mesa_glsl__scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yyg->yy_hold_char; \ + yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ + yyg->yy_hold_char = *yyg->yy_c_buf_p; \ + *yyg->yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE _mesa_glsl_get_extra (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int _mesa_glsl_get_lineno (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int _mesa_glsl_get_column (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *_mesa_glsl_get_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *_mesa_glsl_get_out (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +int _mesa_glsl_get_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *_mesa_glsl_get_text (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void _mesa_glsl_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/** Set the current line number. + * @param line_number + * @param yyscanner The scanner object. + */ +void _mesa_glsl_set_lineno (int line_number , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "_mesa_glsl_set_lineno called with no buffer" , yyscanner); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void _mesa_glsl_set_column (int column_no , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "_mesa_glsl_set_column called with no buffer" , yyscanner); + + yycolumn = column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * @param yyscanner The scanner object. + * @see _mesa_glsl__switch_to_buffer + */ +void _mesa_glsl_set_in (FILE * in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void _mesa_glsl_set_out (FILE * out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int _mesa_glsl_get_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void _mesa_glsl_set_debug (int bdebug , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; +} + +/* Accessor methods for yylval and yylloc */ + +YYSTYPE * _mesa_glsl_get_lval (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylval; +} + +void _mesa_glsl_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylval = yylval_param; +} + +YYLTYPE *_mesa_glsl_get_lloc (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylloc; +} + +void _mesa_glsl_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylloc = yylloc_param; +} + +/* User-visible API */ + +/* _mesa_glsl_lex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ + +int _mesa_glsl_lex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) _mesa_glsl_alloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* _mesa_glsl_lex_init_extra has the same functionality as _mesa_glsl_lex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to _mesa_glsl_alloc in + * the yyextra field. + */ + +int _mesa_glsl_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + _mesa_glsl_set_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) _mesa_glsl_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + _mesa_glsl_set_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +static int yy_init_globals (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from _mesa_glsl_lex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * _mesa_glsl_lex_init() + */ + return 0; +} + +/* _mesa_glsl_lex_destroy is for both reentrant and non-reentrant scanners. */ +int _mesa_glsl_lex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + _mesa_glsl__delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + _mesa_glsl_pop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + _mesa_glsl_free(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + _mesa_glsl_free(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * _mesa_glsl_lex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + _mesa_glsl_free ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *_mesa_glsl_alloc (yy_size_t size , yyscan_t yyscanner) +{ + return (void *) malloc( size ); +} + +void *_mesa_glsl_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void _mesa_glsl_free (void * ptr , yyscan_t yyscanner) +{ + free( (char *) ptr ); /* see _mesa_glsl_realloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 429 "glsl_lexer.lpp" + + + +int +classify_identifier(struct _mesa_glsl_parse_state *state, const char *name) +{ + if (state->symbols->get_variable(name) || state->symbols->get_function(name)) + return IDENTIFIER; + else if (state->symbols->get_type(name)) + return TYPE_IDENTIFIER; + else + return NEW_IDENTIFIER; +} + +void +_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string) +{ + _mesa_glsl_lex_init_extra(state,& state->scanner); + _mesa_glsl__scan_string(string,state->scanner); +} + +void +_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state) +{ + _mesa_glsl_lex_destroy(state->scanner); +} + diff --git a/mesalib/src/glsl/glsl_lexer.lpp b/mesalib/src/glsl/glsl_lexer.lpp index d3d53ffb6..e6f45f413 100644 --- a/mesalib/src/glsl/glsl_lexer.lpp +++ b/mesalib/src/glsl/glsl_lexer.lpp @@ -1,440 +1,453 @@ -%{ -/* - * Copyright © 2008, 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include -#include "strtod.h" -#include "ast.h" -#include "glsl_parser_extras.h" -#include "glsl_parser.h" - -#define YY_USER_ACTION \ - do { \ - yylloc->source = 0; \ - yylloc->first_column = yycolumn + 1; \ - yylloc->first_line = yylineno + 1; \ - yycolumn += yyleng; \ - } while(0); - -#define YY_USER_INIT yylineno = 0; yycolumn = 0; - -#define IS_UINT (yytext[yyleng - 1] == 'u' || yytext[yyleng - 1] == 'U') - -/* A macro for handling reserved words and keywords across language versions. - * - * Certain words start out as identifiers, become reserved words in - * later language revisions, and finally become language keywords. - * - * For example, consider the following lexer rule: - * samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER) - * - * This means that "samplerBuffer" will be treated as: - * - a keyword (SAMPLERBUFFER token) ...in GLSL >= 1.40 - * - a reserved word - error ...in GLSL >= 1.30 - * - an identifier ...in GLSL < 1.30 - */ -#define KEYWORD(reserved_version, allowed_version, token) \ - do { \ - if (yyextra->language_version >= allowed_version) { \ - return token; \ - } else if (yyextra->language_version >= reserved_version) { \ - _mesa_glsl_error(yylloc, yyextra, \ - "Illegal use of reserved word `%s'", yytext); \ - return ERROR_TOK; \ - } else { \ - yylval->identifier = strdup(yytext); \ - return IDENTIFIER; \ - } \ - } while (0) - -/* The ES macro can be used in KEYWORD checks: - * - * word KEYWORD(110 || ES, 400, TOKEN) - * ...means the word is reserved in GLSL ES 1.00, while - * - * word KEYWORD(110, 130 || ES, TOKEN) - * ...means the word is a legal keyword in GLSL ES 1.00. - */ -#define ES yyextra->es_shader -%} - -%option bison-bridge bison-locations reentrant noyywrap -%option nounput noyy_top_state -%option never-interactive -%option prefix="_mesa_glsl_" -%option extra-type="struct _mesa_glsl_parse_state *" - -%x PP PRAGMA - -DEC_INT [1-9][0-9]* -HEX_INT 0[xX][0-9a-fA-F]+ -OCT_INT 0[0-7]* -INT ({DEC_INT}|{HEX_INT}|{OCT_INT}) -SPC [ \t]* -SPCP [ \t]+ -HASH ^{SPC}#{SPC} -%% - -[ \r\t]+ ; - - /* Preprocessor tokens. */ -^[ \t]*#[ \t]*$ ; -^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; } -^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; } -{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ { - /* Eat characters until the first digit is - * encountered - */ - char *ptr = yytext; - while (!isdigit(*ptr)) - ptr++; - - /* Subtract one from the line number because - * yylineno is zero-based instead of - * one-based. - */ - yylineno = strtol(ptr, &ptr, 0) - 1; - yylloc->source = strtol(ptr, NULL, 0); - } -{HASH}line{SPCP}{INT}{SPC}$ { - /* Eat characters until the first digit is - * encountered - */ - char *ptr = yytext; - while (!isdigit(*ptr)) - ptr++; - - /* Subtract one from the line number because - * yylineno is zero-based instead of - * one-based. - */ - yylineno = strtol(ptr, &ptr, 0) - 1; - } -^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) { - BEGIN PP; - return PRAGMA_DEBUG_ON; - } -^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}off{SPC}\) { - BEGIN PP; - return PRAGMA_DEBUG_OFF; - } -^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}on{SPC}\) { - BEGIN PP; - return PRAGMA_OPTIMIZE_ON; - } -^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}off{SPC}\) { - BEGIN PP; - return PRAGMA_OPTIMIZE_OFF; - } -^{SPC}#{SPC}pragma{SPCP}STDGL{SPCP}invariant{SPC}\({SPC}all{SPC}\) { - BEGIN PP; - return PRAGMA_INVARIANT_ALL; - } -^{SPC}#{SPC}pragma{SPCP} { BEGIN PRAGMA; } - -\n { BEGIN 0; yylineno++; yycolumn = 0; } -. { } - -\/\/[^\n]* { } -[ \t\r]* { } -: return COLON; -[_a-zA-Z][_a-zA-Z0-9]* { - yylval->identifier = strdup(yytext); - return IDENTIFIER; - } -[1-9][0-9]* { - yylval->n = strtol(yytext, NULL, 10); - return INTCONSTANT; - } -\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; } - -\n { yylineno++; yycolumn = 0; } - -attribute return ATTRIBUTE; -const return CONST_TOK; -bool return BOOL_TOK; -float return FLOAT_TOK; -int return INT_TOK; -uint KEYWORD(130, 130, UINT_TOK); - -break return BREAK; -continue return CONTINUE; -do return DO; -while return WHILE; -else return ELSE; -for return FOR; -if return IF; -discard return DISCARD; -return return RETURN; - -bvec2 return BVEC2; -bvec3 return BVEC3; -bvec4 return BVEC4; -ivec2 return IVEC2; -ivec3 return IVEC3; -ivec4 return IVEC4; -uvec2 KEYWORD(130, 130, UVEC2); -uvec3 KEYWORD(130, 130, UVEC3); -uvec4 KEYWORD(130, 130, UVEC4); -vec2 return VEC2; -vec3 return VEC3; -vec4 return VEC4; -mat2 return MAT2X2; -mat3 return MAT3X3; -mat4 return MAT4X4; -mat2x2 KEYWORD(120, 120, MAT2X2); -mat2x3 KEYWORD(120, 120, MAT2X3); -mat2x4 KEYWORD(120, 120, MAT2X4); -mat3x2 KEYWORD(120, 120, MAT3X2); -mat3x3 KEYWORD(120, 120, MAT3X3); -mat3x4 KEYWORD(120, 120, MAT3X4); -mat4x2 KEYWORD(120, 120, MAT4X2); -mat4x3 KEYWORD(120, 120, MAT4X3); -mat4x4 KEYWORD(120, 120, MAT4X4); - -in return IN_TOK; -out return OUT_TOK; -inout return INOUT_TOK; -uniform return UNIFORM; -varying return VARYING; -centroid KEYWORD(120, 120, CENTROID); -invariant KEYWORD(120 || ES, 120 || ES, INVARIANT); -flat KEYWORD(130 || ES, 130, FLAT); -smooth KEYWORD(130, 130, SMOOTH); -noperspective KEYWORD(130, 130, NOPERSPECTIVE); - -sampler1D return SAMPLER1D; -sampler2D return SAMPLER2D; -sampler3D return SAMPLER3D; -samplerCube return SAMPLERCUBE; -sampler1DArray KEYWORD(130, 130, SAMPLER1DARRAY); -sampler2DArray KEYWORD(130, 130, SAMPLER2DARRAY); -sampler1DShadow return SAMPLER1DSHADOW; -sampler2DShadow return SAMPLER2DSHADOW; -samplerCubeShadow KEYWORD(130, 130, SAMPLERCUBESHADOW); -sampler1DArrayShadow KEYWORD(130, 130, SAMPLER1DARRAYSHADOW); -sampler2DArrayShadow KEYWORD(130, 130, SAMPLER2DARRAYSHADOW); -isampler1D KEYWORD(130, 130, ISAMPLER1D); -isampler2D KEYWORD(130, 130, ISAMPLER2D); -isampler3D KEYWORD(130, 130, ISAMPLER3D); -isamplerCube KEYWORD(130, 130, ISAMPLERCUBE); -isampler1DArray KEYWORD(130, 130, ISAMPLER1DARRAY); -isampler2DArray KEYWORD(130, 130, ISAMPLER2DARRAY); -usampler1D KEYWORD(130, 130, USAMPLER1D); -usampler2D KEYWORD(130, 130, USAMPLER2D); -usampler3D KEYWORD(130, 130, USAMPLER3D); -usamplerCube KEYWORD(130, 130, USAMPLERCUBE); -usampler1DArray KEYWORD(130, 130, USAMPLER1DARRAY); -usampler2DArray KEYWORD(130, 130, USAMPLER2DARRAY); - - -struct return STRUCT; -void return VOID_TOK; - -layout { - if ((yyextra->language_version >= 140) - || yyextra->AMD_conservative_depth_enable - || yyextra->ARB_explicit_attrib_location_enable - || yyextra->ARB_fragment_coord_conventions_enable) { - return LAYOUT_TOK; - } else { - yylval->identifier = strdup(yytext); - return IDENTIFIER; - } - } - -\+\+ return INC_OP; --- return DEC_OP; -\<= return LE_OP; ->= return GE_OP; -== return EQ_OP; -!= return NE_OP; -&& return AND_OP; -\|\| return OR_OP; -"^^" return XOR_OP; -"<<" return LEFT_OP; -">>" return RIGHT_OP; - -\*= return MUL_ASSIGN; -\/= return DIV_ASSIGN; -\+= return ADD_ASSIGN; -\%= return MOD_ASSIGN; -\<\<= return LEFT_ASSIGN; ->>= return RIGHT_ASSIGN; -&= return AND_ASSIGN; -"^=" return XOR_ASSIGN; -\|= return OR_ASSIGN; --= return SUB_ASSIGN; - -[1-9][0-9]*[uU]? { - yylval->n = strtol(yytext, NULL, 10); - return IS_UINT ? UINTCONSTANT : INTCONSTANT; - } -0[xX][0-9a-fA-F]+[uU]? { - yylval->n = strtol(yytext + 2, NULL, 16); - return IS_UINT ? UINTCONSTANT : INTCONSTANT; - } -0[0-7]*[uU]? { - yylval->n = strtol(yytext, NULL, 8); - return IS_UINT ? UINTCONSTANT : INTCONSTANT; - } - -[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? { - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } -\.[0-9]+([eE][+-]?[0-9]+)?[fF]? { - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } -[0-9]+\.([eE][+-]?[0-9]+)?[fF]? { - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } -[0-9]+[eE][+-]?[0-9]+[fF]? { - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } -[0-9]+[fF] { - yylval->real = glsl_strtod(yytext, NULL); - return FLOATCONSTANT; - } - -true { - yylval->n = 1; - return BOOLCONSTANT; - } -false { - yylval->n = 0; - return BOOLCONSTANT; - } - - - /* Reserved words in GLSL 1.10. */ -asm KEYWORD(110 || ES, 999, ASM); -class KEYWORD(110 || ES, 999, CLASS); -union KEYWORD(110 || ES, 999, UNION); -enum KEYWORD(110 || ES, 999, ENUM); -typedef KEYWORD(110 || ES, 999, TYPEDEF); -template KEYWORD(110 || ES, 999, TEMPLATE); -this KEYWORD(110 || ES, 999, THIS); -packed KEYWORD(110 || ES, 999, PACKED_TOK); -goto KEYWORD(110 || ES, 999, GOTO); -switch KEYWORD(110 || ES, 130, SWITCH); -default KEYWORD(110 || ES, 130, DEFAULT); -inline KEYWORD(110 || ES, 999, INLINE_TOK); -noinline KEYWORD(110 || ES, 999, NOINLINE); -volatile KEYWORD(110 || ES, 999, VOLATILE); -public KEYWORD(110 || ES, 999, PUBLIC_TOK); -static KEYWORD(110 || ES, 999, STATIC); -extern KEYWORD(110 || ES, 999, EXTERN); -external KEYWORD(110 || ES, 999, EXTERNAL); -interface KEYWORD(110 || ES, 999, INTERFACE); -long KEYWORD(110 || ES, 999, LONG_TOK); -short KEYWORD(110 || ES, 999, SHORT_TOK); -double KEYWORD(110 || ES, 400, DOUBLE_TOK); -half KEYWORD(110 || ES, 999, HALF); -fixed KEYWORD(110 || ES, 999, FIXED_TOK); -unsigned KEYWORD(110 || ES, 999, UNSIGNED); -input KEYWORD(110 || ES, 999, INPUT_TOK); -output KEYWORD(110 || ES, 999, OUTPUT); -hvec2 KEYWORD(110 || ES, 999, HVEC2); -hvec3 KEYWORD(110 || ES, 999, HVEC3); -hvec4 KEYWORD(110 || ES, 999, HVEC4); -dvec2 KEYWORD(110 || ES, 400, DVEC2); -dvec3 KEYWORD(110 || ES, 400, DVEC3); -dvec4 KEYWORD(110 || ES, 400, DVEC4); -fvec2 KEYWORD(110 || ES, 999, FVEC2); -fvec3 KEYWORD(110 || ES, 999, FVEC3); -fvec4 KEYWORD(110 || ES, 999, FVEC4); -sampler2DRect return SAMPLER2DRECT; -sampler3DRect KEYWORD(110 || ES, 999, SAMPLER3DRECT); -sampler2DRectShadow return SAMPLER2DRECTSHADOW; -sizeof KEYWORD(110 || ES, 999, SIZEOF); -cast KEYWORD(110 || ES, 999, CAST); -namespace KEYWORD(110 || ES, 999, NAMESPACE); -using KEYWORD(110 || ES, 999, USING); - - /* Additional reserved words in GLSL 1.20. */ -lowp KEYWORD(120, 130 || ES, LOWP); -mediump KEYWORD(120, 130 || ES, MEDIUMP); -highp KEYWORD(120, 130 || ES, HIGHP); -precision KEYWORD(120, 130 || ES, PRECISION); - - /* Additional reserved words in GLSL 1.30. */ -case KEYWORD(130, 130, CASE); -common KEYWORD(130, 999, COMMON); -partition KEYWORD(130, 999, PARTITION); -active KEYWORD(130, 999, ACTIVE); -superp KEYWORD(130 || ES, 999, SUPERP); -samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER); -filter KEYWORD(130, 999, FILTER); -image1D KEYWORD(130, 999, IMAGE1D); -image2D KEYWORD(130, 999, IMAGE2D); -image3D KEYWORD(130, 999, IMAGE3D); -imageCube KEYWORD(130, 999, IMAGECUBE); -iimage1D KEYWORD(130, 999, IIMAGE1D); -iimage2D KEYWORD(130, 999, IIMAGE2D); -iimage3D KEYWORD(130, 999, IIMAGE3D); -iimageCube KEYWORD(130, 999, IIMAGECUBE); -uimage1D KEYWORD(130, 999, UIMAGE1D); -uimage2D KEYWORD(130, 999, UIMAGE2D); -uimage3D KEYWORD(130, 999, UIMAGE3D); -uimageCube KEYWORD(130, 999, UIMAGECUBE); -image1DArray KEYWORD(130, 999, IMAGE1DARRAY); -image2DArray KEYWORD(130, 999, IMAGE2DARRAY); -iimage1DArray KEYWORD(130, 999, IIMAGE1DARRAY); -iimage2DArray KEYWORD(130, 999, IIMAGE2DARRAY); -uimage1DArray KEYWORD(130, 999, UIMAGE1DARRAY); -uimage2DArray KEYWORD(130, 999, UIMAGE2DARRAY); -image1DShadow KEYWORD(130, 999, IMAGE1DSHADOW); -image2DShadow KEYWORD(130, 999, IMAGE2DSHADOW); -image1DArrayShadow KEYWORD(130, 999, IMAGE1DARRAYSHADOW); -image2DArrayShadow KEYWORD(130, 999, IMAGE2DARRAYSHADOW); -imageBuffer KEYWORD(130, 999, IMAGEBUFFER); -iimageBuffer KEYWORD(130, 999, IIMAGEBUFFER); -uimageBuffer KEYWORD(130, 999, UIMAGEBUFFER); -row_major KEYWORD(130, 999, ROW_MAJOR); - -[_a-zA-Z][_a-zA-Z0-9]* { - struct _mesa_glsl_parse_state *state = yyextra; - void *ctx = state; - yylval->identifier = ralloc_strdup(ctx, yytext); - return IDENTIFIER; - } - -. { return yytext[0]; } - -%% - -void -_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string) -{ - yylex_init_extra(state, & state->scanner); - yy_scan_string(string, state->scanner); -} - -void -_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state) -{ - yylex_destroy(state->scanner); -} +%{ +/* + * Copyright © 2008, 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include +#include "strtod.h" +#include "ast.h" +#include "glsl_parser_extras.h" +#include "glsl_parser.h" + +static int classify_identifier(struct _mesa_glsl_parse_state *, const char *); + +#define YY_USER_ACTION \ + do { \ + yylloc->source = 0; \ + yylloc->first_column = yycolumn + 1; \ + yylloc->first_line = yylineno + 1; \ + yycolumn += yyleng; \ + } while(0); + +#define YY_USER_INIT yylineno = 0; yycolumn = 0; + +#define IS_UINT (yytext[yyleng - 1] == 'u' || yytext[yyleng - 1] == 'U') + +/* A macro for handling reserved words and keywords across language versions. + * + * Certain words start out as identifiers, become reserved words in + * later language revisions, and finally become language keywords. + * + * For example, consider the following lexer rule: + * samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER) + * + * This means that "samplerBuffer" will be treated as: + * - a keyword (SAMPLERBUFFER token) ...in GLSL >= 1.40 + * - a reserved word - error ...in GLSL >= 1.30 + * - an identifier ...in GLSL < 1.30 + */ +#define KEYWORD(reserved_version, allowed_version, token) \ + do { \ + if (yyextra->language_version >= allowed_version) { \ + return token; \ + } else if (yyextra->language_version >= reserved_version) { \ + _mesa_glsl_error(yylloc, yyextra, \ + "Illegal use of reserved word `%s'", yytext); \ + return ERROR_TOK; \ + } else { \ + yylval->identifier = strdup(yytext); \ + return classify_identifier(yyextra, yytext); \ + } \ + } while (0) + +/* The ES macro can be used in KEYWORD checks: + * + * word KEYWORD(110 || ES, 400, TOKEN) + * ...means the word is reserved in GLSL ES 1.00, while + * + * word KEYWORD(110, 130 || ES, TOKEN) + * ...means the word is a legal keyword in GLSL ES 1.00. + */ +#define ES yyextra->es_shader +%} + +%option bison-bridge bison-locations reentrant noyywrap +%option nounput noyy_top_state +%option never-interactive +%option prefix="_mesa_glsl_" +%option extra-type="struct _mesa_glsl_parse_state *" + +%x PP PRAGMA + +DEC_INT [1-9][0-9]* +HEX_INT 0[xX][0-9a-fA-F]+ +OCT_INT 0[0-7]* +INT ({DEC_INT}|{HEX_INT}|{OCT_INT}) +SPC [ \t]* +SPCP [ \t]+ +HASH ^{SPC}#{SPC} +%% + +[ \r\t]+ ; + + /* Preprocessor tokens. */ +^[ \t]*#[ \t]*$ ; +^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; } +^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; } +{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ { + /* Eat characters until the first digit is + * encountered + */ + char *ptr = yytext; + while (!isdigit(*ptr)) + ptr++; + + /* Subtract one from the line number because + * yylineno is zero-based instead of + * one-based. + */ + yylineno = strtol(ptr, &ptr, 0) - 1; + yylloc->source = strtol(ptr, NULL, 0); + } +{HASH}line{SPCP}{INT}{SPC}$ { + /* Eat characters until the first digit is + * encountered + */ + char *ptr = yytext; + while (!isdigit(*ptr)) + ptr++; + + /* Subtract one from the line number because + * yylineno is zero-based instead of + * one-based. + */ + yylineno = strtol(ptr, &ptr, 0) - 1; + } +^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) { + BEGIN PP; + return PRAGMA_DEBUG_ON; + } +^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}off{SPC}\) { + BEGIN PP; + return PRAGMA_DEBUG_OFF; + } +^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}on{SPC}\) { + BEGIN PP; + return PRAGMA_OPTIMIZE_ON; + } +^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}off{SPC}\) { + BEGIN PP; + return PRAGMA_OPTIMIZE_OFF; + } +^{SPC}#{SPC}pragma{SPCP}STDGL{SPCP}invariant{SPC}\({SPC}all{SPC}\) { + BEGIN PP; + return PRAGMA_INVARIANT_ALL; + } +^{SPC}#{SPC}pragma{SPCP} { BEGIN PRAGMA; } + +\n { BEGIN 0; yylineno++; yycolumn = 0; } +. { } + +\/\/[^\n]* { } +[ \t\r]* { } +: return COLON; +[_a-zA-Z][_a-zA-Z0-9]* { + yylval->identifier = strdup(yytext); + return IDENTIFIER; + } +[1-9][0-9]* { + yylval->n = strtol(yytext, NULL, 10); + return INTCONSTANT; + } +\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; } + +\n { yylineno++; yycolumn = 0; } + +attribute return ATTRIBUTE; +const return CONST_TOK; +bool return BOOL_TOK; +float return FLOAT_TOK; +int return INT_TOK; +uint KEYWORD(130, 130, UINT_TOK); + +break return BREAK; +continue return CONTINUE; +do return DO; +while return WHILE; +else return ELSE; +for return FOR; +if return IF; +discard return DISCARD; +return return RETURN; + +bvec2 return BVEC2; +bvec3 return BVEC3; +bvec4 return BVEC4; +ivec2 return IVEC2; +ivec3 return IVEC3; +ivec4 return IVEC4; +uvec2 KEYWORD(130, 130, UVEC2); +uvec3 KEYWORD(130, 130, UVEC3); +uvec4 KEYWORD(130, 130, UVEC4); +vec2 return VEC2; +vec3 return VEC3; +vec4 return VEC4; +mat2 return MAT2X2; +mat3 return MAT3X3; +mat4 return MAT4X4; +mat2x2 KEYWORD(120, 120, MAT2X2); +mat2x3 KEYWORD(120, 120, MAT2X3); +mat2x4 KEYWORD(120, 120, MAT2X4); +mat3x2 KEYWORD(120, 120, MAT3X2); +mat3x3 KEYWORD(120, 120, MAT3X3); +mat3x4 KEYWORD(120, 120, MAT3X4); +mat4x2 KEYWORD(120, 120, MAT4X2); +mat4x3 KEYWORD(120, 120, MAT4X3); +mat4x4 KEYWORD(120, 120, MAT4X4); + +in return IN_TOK; +out return OUT_TOK; +inout return INOUT_TOK; +uniform return UNIFORM; +varying return VARYING; +centroid KEYWORD(120, 120, CENTROID); +invariant KEYWORD(120 || ES, 120 || ES, INVARIANT); +flat KEYWORD(130 || ES, 130, FLAT); +smooth KEYWORD(130, 130, SMOOTH); +noperspective KEYWORD(130, 130, NOPERSPECTIVE); + +sampler1D return SAMPLER1D; +sampler2D return SAMPLER2D; +sampler3D return SAMPLER3D; +samplerCube return SAMPLERCUBE; +sampler1DArray KEYWORD(130, 130, SAMPLER1DARRAY); +sampler2DArray KEYWORD(130, 130, SAMPLER2DARRAY); +sampler1DShadow return SAMPLER1DSHADOW; +sampler2DShadow return SAMPLER2DSHADOW; +samplerCubeShadow KEYWORD(130, 130, SAMPLERCUBESHADOW); +sampler1DArrayShadow KEYWORD(130, 130, SAMPLER1DARRAYSHADOW); +sampler2DArrayShadow KEYWORD(130, 130, SAMPLER2DARRAYSHADOW); +isampler1D KEYWORD(130, 130, ISAMPLER1D); +isampler2D KEYWORD(130, 130, ISAMPLER2D); +isampler3D KEYWORD(130, 130, ISAMPLER3D); +isamplerCube KEYWORD(130, 130, ISAMPLERCUBE); +isampler1DArray KEYWORD(130, 130, ISAMPLER1DARRAY); +isampler2DArray KEYWORD(130, 130, ISAMPLER2DARRAY); +usampler1D KEYWORD(130, 130, USAMPLER1D); +usampler2D KEYWORD(130, 130, USAMPLER2D); +usampler3D KEYWORD(130, 130, USAMPLER3D); +usamplerCube KEYWORD(130, 130, USAMPLERCUBE); +usampler1DArray KEYWORD(130, 130, USAMPLER1DARRAY); +usampler2DArray KEYWORD(130, 130, USAMPLER2DARRAY); + + +struct return STRUCT; +void return VOID_TOK; + +layout { + if ((yyextra->language_version >= 140) + || yyextra->AMD_conservative_depth_enable + || yyextra->ARB_explicit_attrib_location_enable + || yyextra->ARB_fragment_coord_conventions_enable) { + return LAYOUT_TOK; + } else { + yylval->identifier = strdup(yytext); + return IDENTIFIER; + } + } + +\+\+ return INC_OP; +-- return DEC_OP; +\<= return LE_OP; +>= return GE_OP; +== return EQ_OP; +!= return NE_OP; +&& return AND_OP; +\|\| return OR_OP; +"^^" return XOR_OP; +"<<" return LEFT_OP; +">>" return RIGHT_OP; + +\*= return MUL_ASSIGN; +\/= return DIV_ASSIGN; +\+= return ADD_ASSIGN; +\%= return MOD_ASSIGN; +\<\<= return LEFT_ASSIGN; +>>= return RIGHT_ASSIGN; +&= return AND_ASSIGN; +"^=" return XOR_ASSIGN; +\|= return OR_ASSIGN; +-= return SUB_ASSIGN; + +[1-9][0-9]*[uU]? { + yylval->n = strtol(yytext, NULL, 10); + return IS_UINT ? UINTCONSTANT : INTCONSTANT; + } +0[xX][0-9a-fA-F]+[uU]? { + yylval->n = strtol(yytext + 2, NULL, 16); + return IS_UINT ? UINTCONSTANT : INTCONSTANT; + } +0[0-7]*[uU]? { + yylval->n = strtol(yytext, NULL, 8); + return IS_UINT ? UINTCONSTANT : INTCONSTANT; + } + +[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? { + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } +\.[0-9]+([eE][+-]?[0-9]+)?[fF]? { + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } +[0-9]+\.([eE][+-]?[0-9]+)?[fF]? { + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } +[0-9]+[eE][+-]?[0-9]+[fF]? { + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } +[0-9]+[fF] { + yylval->real = glsl_strtod(yytext, NULL); + return FLOATCONSTANT; + } + +true { + yylval->n = 1; + return BOOLCONSTANT; + } +false { + yylval->n = 0; + return BOOLCONSTANT; + } + + + /* Reserved words in GLSL 1.10. */ +asm KEYWORD(110 || ES, 999, ASM); +class KEYWORD(110 || ES, 999, CLASS); +union KEYWORD(110 || ES, 999, UNION); +enum KEYWORD(110 || ES, 999, ENUM); +typedef KEYWORD(110 || ES, 999, TYPEDEF); +template KEYWORD(110 || ES, 999, TEMPLATE); +this KEYWORD(110 || ES, 999, THIS); +packed KEYWORD(110 || ES, 999, PACKED_TOK); +goto KEYWORD(110 || ES, 999, GOTO); +switch KEYWORD(110 || ES, 130, SWITCH); +default KEYWORD(110 || ES, 130, DEFAULT); +inline KEYWORD(110 || ES, 999, INLINE_TOK); +noinline KEYWORD(110 || ES, 999, NOINLINE); +volatile KEYWORD(110 || ES, 999, VOLATILE); +public KEYWORD(110 || ES, 999, PUBLIC_TOK); +static KEYWORD(110 || ES, 999, STATIC); +extern KEYWORD(110 || ES, 999, EXTERN); +external KEYWORD(110 || ES, 999, EXTERNAL); +interface KEYWORD(110 || ES, 999, INTERFACE); +long KEYWORD(110 || ES, 999, LONG_TOK); +short KEYWORD(110 || ES, 999, SHORT_TOK); +double KEYWORD(110 || ES, 400, DOUBLE_TOK); +half KEYWORD(110 || ES, 999, HALF); +fixed KEYWORD(110 || ES, 999, FIXED_TOK); +unsigned KEYWORD(110 || ES, 999, UNSIGNED); +input KEYWORD(110 || ES, 999, INPUT_TOK); +output KEYWORD(110 || ES, 999, OUTPUT); +hvec2 KEYWORD(110 || ES, 999, HVEC2); +hvec3 KEYWORD(110 || ES, 999, HVEC3); +hvec4 KEYWORD(110 || ES, 999, HVEC4); +dvec2 KEYWORD(110 || ES, 400, DVEC2); +dvec3 KEYWORD(110 || ES, 400, DVEC3); +dvec4 KEYWORD(110 || ES, 400, DVEC4); +fvec2 KEYWORD(110 || ES, 999, FVEC2); +fvec3 KEYWORD(110 || ES, 999, FVEC3); +fvec4 KEYWORD(110 || ES, 999, FVEC4); +sampler2DRect return SAMPLER2DRECT; +sampler3DRect KEYWORD(110 || ES, 999, SAMPLER3DRECT); +sampler2DRectShadow return SAMPLER2DRECTSHADOW; +sizeof KEYWORD(110 || ES, 999, SIZEOF); +cast KEYWORD(110 || ES, 999, CAST); +namespace KEYWORD(110 || ES, 999, NAMESPACE); +using KEYWORD(110 || ES, 999, USING); + + /* Additional reserved words in GLSL 1.20. */ +lowp KEYWORD(120, 130 || ES, LOWP); +mediump KEYWORD(120, 130 || ES, MEDIUMP); +highp KEYWORD(120, 130 || ES, HIGHP); +precision KEYWORD(120, 130 || ES, PRECISION); + + /* Additional reserved words in GLSL 1.30. */ +case KEYWORD(130, 130, CASE); +common KEYWORD(130, 999, COMMON); +partition KEYWORD(130, 999, PARTITION); +active KEYWORD(130, 999, ACTIVE); +superp KEYWORD(130 || ES, 999, SUPERP); +samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER); +filter KEYWORD(130, 999, FILTER); +image1D KEYWORD(130, 999, IMAGE1D); +image2D KEYWORD(130, 999, IMAGE2D); +image3D KEYWORD(130, 999, IMAGE3D); +imageCube KEYWORD(130, 999, IMAGECUBE); +iimage1D KEYWORD(130, 999, IIMAGE1D); +iimage2D KEYWORD(130, 999, IIMAGE2D); +iimage3D KEYWORD(130, 999, IIMAGE3D); +iimageCube KEYWORD(130, 999, IIMAGECUBE); +uimage1D KEYWORD(130, 999, UIMAGE1D); +uimage2D KEYWORD(130, 999, UIMAGE2D); +uimage3D KEYWORD(130, 999, UIMAGE3D); +uimageCube KEYWORD(130, 999, UIMAGECUBE); +image1DArray KEYWORD(130, 999, IMAGE1DARRAY); +image2DArray KEYWORD(130, 999, IMAGE2DARRAY); +iimage1DArray KEYWORD(130, 999, IIMAGE1DARRAY); +iimage2DArray KEYWORD(130, 999, IIMAGE2DARRAY); +uimage1DArray KEYWORD(130, 999, UIMAGE1DARRAY); +uimage2DArray KEYWORD(130, 999, UIMAGE2DARRAY); +image1DShadow KEYWORD(130, 999, IMAGE1DSHADOW); +image2DShadow KEYWORD(130, 999, IMAGE2DSHADOW); +image1DArrayShadow KEYWORD(130, 999, IMAGE1DARRAYSHADOW); +image2DArrayShadow KEYWORD(130, 999, IMAGE2DARRAYSHADOW); +imageBuffer KEYWORD(130, 999, IMAGEBUFFER); +iimageBuffer KEYWORD(130, 999, IIMAGEBUFFER); +uimageBuffer KEYWORD(130, 999, UIMAGEBUFFER); +row_major KEYWORD(130, 999, ROW_MAJOR); + +[_a-zA-Z][_a-zA-Z0-9]* { + struct _mesa_glsl_parse_state *state = yyextra; + void *ctx = state; + yylval->identifier = ralloc_strdup(ctx, yytext); + return classify_identifier(state, yytext); + } + +. { return yytext[0]; } + +%% + +int +classify_identifier(struct _mesa_glsl_parse_state *state, const char *name) +{ + if (state->symbols->get_variable(name) || state->symbols->get_function(name)) + return IDENTIFIER; + else if (state->symbols->get_type(name)) + return TYPE_IDENTIFIER; + else + return NEW_IDENTIFIER; +} + +void +_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string) +{ + yylex_init_extra(state, & state->scanner); + yy_scan_string(string, state->scanner); +} + +void +_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state) +{ + yylex_destroy(state->scanner); +} diff --git a/mesalib/src/glsl/glsl_parser.cpp b/mesalib/src/glsl/glsl_parser.cpp index 69435997a..1d445d400 100644 --- a/mesalib/src/glsl/glsl_parser.cpp +++ b/mesalib/src/glsl/glsl_parser.cpp @@ -1,5370 +1,5456 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2009, 2010 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.4.3" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* Using locations. */ -#define YYLSP_NEEDED 1 - -/* Substitute the variable and function names. */ -#define yyparse _mesa_glsl_parse -#define yylex _mesa_glsl_lex -#define yyerror _mesa_glsl_error -#define yylval _mesa_glsl_lval -#define yychar _mesa_glsl_char -#define yydebug _mesa_glsl_debug -#define yynerrs _mesa_glsl_nerrs -#define yylloc _mesa_glsl_lloc - -/* Copy the first part of user declarations. */ - -/* Line 189 of yacc.c */ -#line 1 "glsl_parser.ypp" - -/* - * Copyright © 2008, 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include -#include -#include -#include - -#include "ast.h" -#include "glsl_parser_extras.h" -#include "glsl_types.h" - -#define YYLEX_PARAM state->scanner - - - -/* Line 189 of yacc.c */ -#line 117 "glsl_parser.cpp" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - ATTRIBUTE = 258, - CONST_TOK = 259, - BOOL_TOK = 260, - FLOAT_TOK = 261, - INT_TOK = 262, - UINT_TOK = 263, - BREAK = 264, - CONTINUE = 265, - DO = 266, - ELSE = 267, - FOR = 268, - IF = 269, - DISCARD = 270, - RETURN = 271, - SWITCH = 272, - CASE = 273, - DEFAULT = 274, - BVEC2 = 275, - BVEC3 = 276, - BVEC4 = 277, - IVEC2 = 278, - IVEC3 = 279, - IVEC4 = 280, - UVEC2 = 281, - UVEC3 = 282, - UVEC4 = 283, - VEC2 = 284, - VEC3 = 285, - VEC4 = 286, - CENTROID = 287, - IN_TOK = 288, - OUT_TOK = 289, - INOUT_TOK = 290, - UNIFORM = 291, - VARYING = 292, - NOPERSPECTIVE = 293, - FLAT = 294, - SMOOTH = 295, - MAT2X2 = 296, - MAT2X3 = 297, - MAT2X4 = 298, - MAT3X2 = 299, - MAT3X3 = 300, - MAT3X4 = 301, - MAT4X2 = 302, - MAT4X3 = 303, - MAT4X4 = 304, - SAMPLER1D = 305, - SAMPLER2D = 306, - SAMPLER3D = 307, - SAMPLERCUBE = 308, - SAMPLER1DSHADOW = 309, - SAMPLER2DSHADOW = 310, - SAMPLERCUBESHADOW = 311, - SAMPLER1DARRAY = 312, - SAMPLER2DARRAY = 313, - SAMPLER1DARRAYSHADOW = 314, - SAMPLER2DARRAYSHADOW = 315, - ISAMPLER1D = 316, - ISAMPLER2D = 317, - ISAMPLER3D = 318, - ISAMPLERCUBE = 319, - ISAMPLER1DARRAY = 320, - ISAMPLER2DARRAY = 321, - USAMPLER1D = 322, - USAMPLER2D = 323, - USAMPLER3D = 324, - USAMPLERCUBE = 325, - USAMPLER1DARRAY = 326, - USAMPLER2DARRAY = 327, - STRUCT = 328, - VOID_TOK = 329, - WHILE = 330, - IDENTIFIER = 331, - FLOATCONSTANT = 332, - INTCONSTANT = 333, - UINTCONSTANT = 334, - BOOLCONSTANT = 335, - FIELD_SELECTION = 336, - LEFT_OP = 337, - RIGHT_OP = 338, - INC_OP = 339, - DEC_OP = 340, - LE_OP = 341, - GE_OP = 342, - EQ_OP = 343, - NE_OP = 344, - AND_OP = 345, - OR_OP = 346, - XOR_OP = 347, - MUL_ASSIGN = 348, - DIV_ASSIGN = 349, - ADD_ASSIGN = 350, - MOD_ASSIGN = 351, - LEFT_ASSIGN = 352, - RIGHT_ASSIGN = 353, - AND_ASSIGN = 354, - XOR_ASSIGN = 355, - OR_ASSIGN = 356, - SUB_ASSIGN = 357, - INVARIANT = 358, - LOWP = 359, - MEDIUMP = 360, - HIGHP = 361, - SUPERP = 362, - PRECISION = 363, - VERSION = 364, - EXTENSION = 365, - LINE = 366, - COLON = 367, - EOL = 368, - INTERFACE = 369, - OUTPUT = 370, - PRAGMA_DEBUG_ON = 371, - PRAGMA_DEBUG_OFF = 372, - PRAGMA_OPTIMIZE_ON = 373, - PRAGMA_OPTIMIZE_OFF = 374, - PRAGMA_INVARIANT_ALL = 375, - LAYOUT_TOK = 376, - ASM = 377, - CLASS = 378, - UNION = 379, - ENUM = 380, - TYPEDEF = 381, - TEMPLATE = 382, - THIS = 383, - PACKED_TOK = 384, - GOTO = 385, - INLINE_TOK = 386, - NOINLINE = 387, - VOLATILE = 388, - PUBLIC_TOK = 389, - STATIC = 390, - EXTERN = 391, - EXTERNAL = 392, - LONG_TOK = 393, - SHORT_TOK = 394, - DOUBLE_TOK = 395, - HALF = 396, - FIXED_TOK = 397, - UNSIGNED = 398, - INPUT_TOK = 399, - OUPTUT = 400, - HVEC2 = 401, - HVEC3 = 402, - HVEC4 = 403, - DVEC2 = 404, - DVEC3 = 405, - DVEC4 = 406, - FVEC2 = 407, - FVEC3 = 408, - FVEC4 = 409, - SAMPLER2DRECT = 410, - SAMPLER3DRECT = 411, - SAMPLER2DRECTSHADOW = 412, - SIZEOF = 413, - CAST = 414, - NAMESPACE = 415, - USING = 416, - ERROR_TOK = 417, - COMMON = 418, - PARTITION = 419, - ACTIVE = 420, - SAMPLERBUFFER = 421, - FILTER = 422, - IMAGE1D = 423, - IMAGE2D = 424, - IMAGE3D = 425, - IMAGECUBE = 426, - IMAGE1DARRAY = 427, - IMAGE2DARRAY = 428, - IIMAGE1D = 429, - IIMAGE2D = 430, - IIMAGE3D = 431, - IIMAGECUBE = 432, - IIMAGE1DARRAY = 433, - IIMAGE2DARRAY = 434, - UIMAGE1D = 435, - UIMAGE2D = 436, - UIMAGE3D = 437, - UIMAGECUBE = 438, - UIMAGE1DARRAY = 439, - UIMAGE2DARRAY = 440, - IMAGE1DSHADOW = 441, - IMAGE2DSHADOW = 442, - IMAGEBUFFER = 443, - IIMAGEBUFFER = 444, - UIMAGEBUFFER = 445, - IMAGE1DARRAYSHADOW = 446, - IMAGE2DARRAYSHADOW = 447, - ROW_MAJOR = 448 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 214 of yacc.c */ -#line 52 "glsl_parser.ypp" - - int n; - float real; - char *identifier; - - struct ast_type_qualifier type_qualifier; - - ast_node *node; - ast_type_specifier *type_specifier; - ast_fully_specified_type *fully_specified_type; - ast_function *function; - ast_parameter_declarator *parameter_declarator; - ast_function_definition *function_definition; - ast_compound_statement *compound_statement; - ast_expression *expression; - ast_declarator_list *declarator_list; - ast_struct_specifier *struct_specifier; - ast_declaration *declaration; - - struct { - ast_node *cond; - ast_expression *rest; - } for_rest_statement; - - struct { - ast_node *then_statement; - ast_node *else_statement; - } selection_rest_statement; - - - -/* Line 214 of yacc.c */ -#line 378 "glsl_parser.cpp" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -/* Copy the second part of user declarations. */ - - -/* Line 264 of yacc.c */ -#line 403 "glsl_parser.cpp" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 5 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 3738 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 218 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 87 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 279 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 415 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 448 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 202, 2, 2, 2, 206, 209, 2, - 194, 195, 204, 200, 199, 201, 198, 205, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 213, 215, - 207, 214, 208, 212, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 196, 2, 197, 210, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 216, 211, 217, 203, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 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, 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, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 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, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 4, 9, 10, 14, 17, 20, 23, - 26, 29, 30, 33, 39, 41, 44, 46, 48, 50, - 52, 54, 56, 60, 62, 67, 69, 73, 76, 79, - 81, 83, 85, 89, 92, 95, 98, 100, 103, 107, - 110, 112, 114, 116, 118, 121, 124, 127, 129, 131, - 133, 135, 137, 141, 145, 149, 151, 155, 159, 161, - 165, 169, 171, 175, 179, 183, 187, 189, 193, 197, - 199, 203, 205, 209, 211, 215, 217, 221, 223, 227, - 229, 233, 235, 241, 243, 247, 249, 251, 253, 255, - 257, 259, 261, 263, 265, 267, 269, 271, 275, 277, - 280, 283, 288, 291, 293, 295, 298, 302, 306, 309, - 315, 319, 322, 326, 329, 330, 332, 334, 336, 338, - 340, 344, 350, 357, 365, 374, 380, 382, 385, 390, - 396, 403, 411, 416, 419, 421, 424, 429, 431, 435, - 437, 441, 443, 445, 447, 449, 451, 453, 456, 458, - 461, 464, 468, 470, 472, 474, 476, 479, 481, 483, - 486, 489, 491, 493, 496, 498, 502, 507, 509, 511, - 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, - 533, 535, 537, 539, 541, 543, 545, 547, 549, 551, - 553, 555, 557, 559, 561, 563, 565, 567, 569, 571, - 573, 575, 577, 579, 581, 583, 585, 587, 589, 591, - 593, 595, 597, 599, 601, 603, 605, 607, 609, 611, - 613, 615, 617, 619, 621, 627, 632, 634, 637, 641, - 643, 647, 649, 654, 656, 658, 660, 662, 664, 666, - 668, 670, 672, 674, 676, 679, 683, 685, 687, 690, - 694, 696, 699, 701, 704, 710, 714, 716, 718, 723, - 729, 733, 736, 742, 750, 757, 759, 761, 763, 764, - 767, 771, 774, 777, 780, 784, 787, 789, 791, 793 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int16 yyrhs[] = -{ - 219, 0, -1, -1, 221, 223, 220, 225, -1, -1, - 109, 78, 113, -1, 116, 113, -1, 117, 113, -1, - 118, 113, -1, 119, 113, -1, 120, 113, -1, -1, - 223, 224, -1, 110, 76, 112, 76, 113, -1, 303, - -1, 225, 303, -1, 76, -1, 226, -1, 78, -1, - 79, -1, 77, -1, 80, -1, 194, 253, 195, -1, - 227, -1, 228, 196, 229, 197, -1, 230, -1, 228, - 198, 76, -1, 228, 84, -1, 228, 85, -1, 253, - -1, 231, -1, 232, -1, 228, 198, 232, -1, 234, - 195, -1, 233, 195, -1, 235, 74, -1, 235, -1, - 235, 251, -1, 234, 199, 251, -1, 236, 194, -1, - 274, -1, 76, -1, 81, -1, 228, -1, 84, 237, - -1, 85, 237, -1, 238, 237, -1, 200, -1, 201, - -1, 202, -1, 203, -1, 237, -1, 239, 204, 237, - -1, 239, 205, 237, -1, 239, 206, 237, -1, 239, - -1, 240, 200, 239, -1, 240, 201, 239, -1, 240, - -1, 241, 82, 240, -1, 241, 83, 240, -1, 241, - -1, 242, 207, 241, -1, 242, 208, 241, -1, 242, - 86, 241, -1, 242, 87, 241, -1, 242, -1, 243, - 88, 242, -1, 243, 89, 242, -1, 243, -1, 244, - 209, 243, -1, 244, -1, 245, 210, 244, -1, 245, - -1, 246, 211, 245, -1, 246, -1, 247, 90, 246, - -1, 247, -1, 248, 92, 247, -1, 248, -1, 249, - 91, 248, -1, 249, -1, 249, 212, 253, 213, 251, - -1, 250, -1, 237, 252, 251, -1, 214, -1, 93, - -1, 94, -1, 96, -1, 95, -1, 102, -1, 97, - -1, 98, -1, 99, -1, 100, -1, 101, -1, 251, - -1, 253, 199, 251, -1, 250, -1, 256, 215, -1, - 264, 215, -1, 108, 278, 275, 215, -1, 257, 195, - -1, 259, -1, 258, -1, 259, 261, -1, 258, 199, - 261, -1, 266, 76, 194, -1, 274, 76, -1, 274, - 76, 196, 254, 197, -1, 271, 262, 260, -1, 262, - 260, -1, 271, 262, 263, -1, 262, 263, -1, -1, - 33, -1, 34, -1, 35, -1, 274, -1, 265, -1, - 264, 199, 76, -1, 264, 199, 76, 196, 197, -1, - 264, 199, 76, 196, 254, 197, -1, 264, 199, 76, - 196, 197, 214, 284, -1, 264, 199, 76, 196, 254, - 197, 214, 284, -1, 264, 199, 76, 214, 284, -1, - 266, -1, 266, 76, -1, 266, 76, 196, 197, -1, - 266, 76, 196, 254, 197, -1, 266, 76, 196, 197, - 214, 284, -1, 266, 76, 196, 254, 197, 214, 284, - -1, 266, 76, 214, 284, -1, 103, 76, -1, 274, - -1, 272, 274, -1, 121, 194, 268, 195, -1, 269, - -1, 268, 199, 269, -1, 76, -1, 76, 214, 78, - -1, 40, -1, 39, -1, 38, -1, 4, -1, 273, - -1, 267, -1, 267, 273, -1, 270, -1, 270, 273, - -1, 103, 273, -1, 103, 270, 273, -1, 103, -1, - 4, -1, 3, -1, 37, -1, 32, 37, -1, 33, - -1, 34, -1, 32, 33, -1, 32, 34, -1, 36, - -1, 275, -1, 278, 275, -1, 276, -1, 276, 196, - 197, -1, 276, 196, 254, 197, -1, 277, -1, 279, - -1, 76, -1, 74, -1, 6, -1, 7, -1, 8, - -1, 5, -1, 29, -1, 30, -1, 31, -1, 20, - -1, 21, -1, 22, -1, 23, -1, 24, -1, 25, - -1, 26, -1, 27, -1, 28, -1, 41, -1, 42, - -1, 43, -1, 44, -1, 45, -1, 46, -1, 47, - -1, 48, -1, 49, -1, 50, -1, 51, -1, 155, - -1, 52, -1, 53, -1, 54, -1, 55, -1, 157, - -1, 56, -1, 57, -1, 58, -1, 59, -1, 60, - -1, 61, -1, 62, -1, 63, -1, 64, -1, 65, - -1, 66, -1, 67, -1, 68, -1, 69, -1, 70, - -1, 71, -1, 72, -1, 106, -1, 105, -1, 104, - -1, 73, 76, 216, 280, 217, -1, 73, 216, 280, - 217, -1, 281, -1, 280, 281, -1, 274, 282, 215, - -1, 283, -1, 282, 199, 283, -1, 76, -1, 76, - 196, 254, 197, -1, 251, -1, 255, -1, 288, -1, - 287, -1, 285, -1, 292, -1, 293, -1, 296, -1, - 297, -1, 298, -1, 302, -1, 216, 217, -1, 216, - 291, 217, -1, 290, -1, 287, -1, 216, 217, -1, - 216, 291, 217, -1, 286, -1, 291, 286, -1, 215, - -1, 253, 215, -1, 14, 194, 253, 195, 294, -1, - 286, 12, 286, -1, 286, -1, 253, -1, 266, 76, - 214, 284, -1, 17, 194, 253, 195, 288, -1, 18, - 253, 213, -1, 19, 213, -1, 75, 194, 295, 195, - 289, -1, 11, 286, 75, 194, 253, 195, 215, -1, - 13, 194, 299, 301, 195, 289, -1, 292, -1, 285, - -1, 295, -1, -1, 300, 215, -1, 300, 215, 253, - -1, 10, 215, -1, 9, 215, -1, 16, 215, -1, - 16, 253, 215, -1, 15, 215, -1, 304, -1, 255, - -1, 222, -1, 256, 290, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 213, 213, 212, 219, 221, 261, 262, 263, 264, - 265, 277, 279, 283, 292, 300, 311, 315, 322, 329, - 336, 343, 350, 357, 358, 364, 368, 375, 381, 390, - 394, 398, 399, 408, 409, 413, 414, 418, 424, 436, - 440, 446, 453, 464, 465, 471, 477, 487, 488, 489, - 490, 494, 495, 501, 507, 516, 517, 523, 532, 533, - 539, 548, 549, 555, 561, 567, 576, 577, 583, 592, - 593, 602, 603, 612, 613, 622, 623, 632, 633, 642, - 643, 652, 653, 662, 663, 672, 673, 674, 675, 676, - 677, 678, 679, 680, 681, 682, 686, 690, 706, 710, - 714, 718, 727, 731, 732, 736, 741, 749, 760, 770, - 785, 792, 797, 808, 821, 824, 829, 834, 843, 847, - 848, 857, 866, 875, 884, 893, 906, 917, 926, 935, - 944, 953, 962, 971, 985, 992, 1003, 1010, 1011, 1030, - 1082, 1123, 1128, 1133, 1141, 1149, 1150, 1151, 1156, 1157, - 1162, 1167, 1173, 1181, 1186, 1191, 1196, 1202, 1207, 1212, - 1217, 1222, 1230, 1234, 1242, 1243, 1249, 1258, 1264, 1270, - 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, - 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, - 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, - 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, - 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, - 1329, 1333, 1343, 1353, 1366, 1372, 1381, 1386, 1394, 1409, - 1414, 1422, 1428, 1437, 1441, 1447, 1448, 1452, 1453, 1454, - 1455, 1456, 1457, 1458, 1462, 1468, 1477, 1478, 1482, 1488, - 1497, 1507, 1519, 1525, 1534, 1543, 1548, 1556, 1560, 1574, - 1578, 1579, 1583, 1590, 1597, 1607, 1608, 1612, 1614, 1620, - 1625, 1634, 1640, 1646, 1652, 1658, 1667, 1668, 1669, 1673 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "ATTRIBUTE", "CONST_TOK", "BOOL_TOK", - "FLOAT_TOK", "INT_TOK", "UINT_TOK", "BREAK", "CONTINUE", "DO", "ELSE", - "FOR", "IF", "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "BVEC2", - "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", "UVEC2", "UVEC3", "UVEC4", - "VEC2", "VEC3", "VEC4", "CENTROID", "IN_TOK", "OUT_TOK", "INOUT_TOK", - "UNIFORM", "VARYING", "NOPERSPECTIVE", "FLAT", "SMOOTH", "MAT2X2", - "MAT2X3", "MAT2X4", "MAT3X2", "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3", - "MAT4X4", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", - "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", - "SAMPLER1DARRAY", "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW", - "SAMPLER2DARRAYSHADOW", "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D", - "ISAMPLERCUBE", "ISAMPLER1DARRAY", "ISAMPLER2DARRAY", "USAMPLER1D", - "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", "USAMPLER1DARRAY", - "USAMPLER2DARRAY", "STRUCT", "VOID_TOK", "WHILE", "IDENTIFIER", - "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", "INVARIANT", - "LOWP", "MEDIUMP", "HIGHP", "SUPERP", "PRECISION", "VERSION", - "EXTENSION", "LINE", "COLON", "EOL", "INTERFACE", "OUTPUT", - "PRAGMA_DEBUG_ON", "PRAGMA_DEBUG_OFF", "PRAGMA_OPTIMIZE_ON", - "PRAGMA_OPTIMIZE_OFF", "PRAGMA_INVARIANT_ALL", "LAYOUT_TOK", "ASM", - "CLASS", "UNION", "ENUM", "TYPEDEF", "TEMPLATE", "THIS", "PACKED_TOK", - "GOTO", "INLINE_TOK", "NOINLINE", "VOLATILE", "PUBLIC_TOK", "STATIC", - "EXTERN", "EXTERNAL", "LONG_TOK", "SHORT_TOK", "DOUBLE_TOK", "HALF", - "FIXED_TOK", "UNSIGNED", "INPUT_TOK", "OUPTUT", "HVEC2", "HVEC3", - "HVEC4", "DVEC2", "DVEC3", "DVEC4", "FVEC2", "FVEC3", "FVEC4", - "SAMPLER2DRECT", "SAMPLER3DRECT", "SAMPLER2DRECTSHADOW", "SIZEOF", - "CAST", "NAMESPACE", "USING", "ERROR_TOK", "COMMON", "PARTITION", - "ACTIVE", "SAMPLERBUFFER", "FILTER", "IMAGE1D", "IMAGE2D", "IMAGE3D", - "IMAGECUBE", "IMAGE1DARRAY", "IMAGE2DARRAY", "IIMAGE1D", "IIMAGE2D", - "IIMAGE3D", "IIMAGECUBE", "IIMAGE1DARRAY", "IIMAGE2DARRAY", "UIMAGE1D", - "UIMAGE2D", "UIMAGE3D", "UIMAGECUBE", "UIMAGE1DARRAY", "UIMAGE2DARRAY", - "IMAGE1DSHADOW", "IMAGE2DSHADOW", "IMAGEBUFFER", "IIMAGEBUFFER", - "UIMAGEBUFFER", "IMAGE1DARRAYSHADOW", "IMAGE2DARRAYSHADOW", "ROW_MAJOR", - "'('", "')'", "'['", "']'", "'.'", "','", "'+'", "'-'", "'!'", "'~'", - "'*'", "'/'", "'%'", "'<'", "'>'", "'&'", "'^'", "'|'", "'?'", "':'", - "'='", "';'", "'{'", "'}'", "$accept", "translation_unit", "$@1", - "version_statement", "pragma_statement", "extension_statement_list", - "extension_statement", "external_declaration_list", - "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", - "multiplicative_expression", "additive_expression", "shift_expression", - "relational_expression", "equality_expression", "and_expression", - "exclusive_or_expression", "inclusive_or_expression", - "logical_and_expression", "logical_xor_expression", - "logical_or_expression", "conditional_expression", - "assignment_expression", "assignment_operator", "expression", - "constant_expression", "declaration", "function_prototype", - "function_declarator", "function_header_with_parameters", - "function_header", "parameter_declarator", "parameter_declaration", - "parameter_qualifier", "parameter_type_specifier", - "init_declarator_list", "single_declaration", "fully_specified_type", - "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id", - "interpolation_qualifier", "parameter_type_qualifier", "type_qualifier", - "storage_qualifier", "type_specifier", "type_specifier_no_prec", - "type_specifier_nonarray", "basic_type_specifier_nonarray", - "precision_qualifier", "struct_specifier", "struct_declaration_list", - "struct_declaration", "struct_declarator_list", "struct_declarator", - "initializer", "declaration_statement", "statement", "simple_statement", - "compound_statement", "statement_no_new_scope", - "compound_statement_no_new_scope", "statement_list", - "expression_statement", "selection_statement", - "selection_rest_statement", "condition", "switch_statement", - "case_label", "iteration_statement", "for_init_statement", - "conditionopt", "for_rest_statement", "jump_statement", - "external_declaration", "function_definition", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 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, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 40, 41, 91, 93, 46, 44, - 43, 45, 33, 126, 42, 47, 37, 60, 62, 38, - 94, 124, 63, 58, 61, 59, 123, 125 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint16 yyr1[] = -{ - 0, 218, 220, 219, 221, 221, 222, 222, 222, 222, - 222, 223, 223, 224, 225, 225, 226, 227, 227, 227, - 227, 227, 227, 228, 228, 228, 228, 228, 228, 229, - 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, - 236, 236, 236, 237, 237, 237, 237, 238, 238, 238, - 238, 239, 239, 239, 239, 240, 240, 240, 241, 241, - 241, 242, 242, 242, 242, 242, 243, 243, 243, 244, - 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, - 249, 250, 250, 251, 251, 252, 252, 252, 252, 252, - 252, 252, 252, 252, 252, 252, 253, 253, 254, 255, - 255, 255, 256, 257, 257, 258, 258, 259, 260, 260, - 261, 261, 261, 261, 262, 262, 262, 262, 263, 264, - 264, 264, 264, 264, 264, 264, 265, 265, 265, 265, - 265, 265, 265, 265, 266, 266, 267, 268, 268, 269, - 269, 270, 270, 270, 271, 272, 272, 272, 272, 272, - 272, 272, 272, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 274, 274, 275, 275, 275, 276, 276, 276, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 278, 278, 278, 279, 279, 280, 280, 281, 282, - 282, 283, 283, 284, 285, 286, 286, 287, 287, 287, - 287, 287, 287, 287, 288, 288, 289, 289, 290, 290, - 291, 291, 292, 292, 293, 294, 294, 295, 295, 296, - 297, 297, 298, 298, 298, 299, 299, 300, 300, 301, - 301, 302, 302, 302, 302, 302, 303, 303, 303, 304 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 0, 4, 0, 3, 2, 2, 2, 2, - 2, 0, 2, 5, 1, 2, 1, 1, 1, 1, - 1, 1, 3, 1, 4, 1, 3, 2, 2, 1, - 1, 1, 3, 2, 2, 2, 1, 2, 3, 2, - 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, - 1, 1, 3, 3, 3, 1, 3, 3, 1, 3, - 3, 1, 3, 3, 3, 3, 1, 3, 3, 1, - 3, 1, 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, 4, 2, 1, 1, 2, 3, 3, 2, 5, - 3, 2, 3, 2, 0, 1, 1, 1, 1, 1, - 3, 5, 6, 7, 8, 5, 1, 2, 4, 5, - 6, 7, 4, 2, 1, 2, 4, 1, 3, 1, - 3, 1, 1, 1, 1, 1, 1, 2, 1, 2, - 2, 3, 1, 1, 1, 1, 2, 1, 1, 2, - 2, 1, 1, 2, 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, 1, 5, 4, 1, 2, 3, 1, - 3, 1, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 3, 1, 1, 2, 3, - 1, 2, 1, 2, 5, 3, 1, 1, 4, 5, - 3, 2, 5, 7, 6, 1, 1, 1, 0, 2, - 3, 2, 2, 2, 3, 2, 1, 1, 1, 2 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint16 yydefact[] = -{ - 4, 0, 0, 11, 0, 1, 2, 5, 0, 0, - 12, 0, 154, 153, 174, 171, 172, 173, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 175, 176, 177, - 0, 157, 158, 161, 155, 143, 142, 141, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 199, - 200, 201, 202, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 0, 170, 169, 152, 223, 222, 221, 0, 0, 0, - 0, 0, 0, 0, 198, 203, 278, 3, 277, 0, - 0, 104, 114, 0, 119, 126, 146, 148, 0, 145, - 134, 162, 164, 167, 0, 168, 14, 276, 0, 159, - 160, 156, 0, 0, 133, 0, 150, 0, 6, 7, - 8, 9, 10, 0, 15, 99, 0, 279, 102, 114, - 144, 115, 116, 117, 105, 0, 114, 0, 100, 127, - 147, 149, 135, 0, 163, 0, 0, 0, 0, 226, - 151, 0, 139, 0, 137, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 16, 20, 18, 19, - 21, 42, 0, 0, 0, 47, 48, 49, 50, 252, - 0, 248, 17, 23, 43, 25, 30, 31, 0, 0, - 36, 0, 51, 0, 55, 58, 61, 66, 69, 71, - 73, 75, 77, 79, 81, 83, 96, 0, 234, 0, - 134, 237, 250, 236, 235, 0, 238, 239, 240, 241, - 242, 243, 106, 111, 113, 118, 0, 120, 107, 0, - 0, 165, 51, 98, 0, 40, 13, 0, 231, 0, - 229, 225, 227, 101, 0, 136, 0, 272, 271, 0, - 0, 0, 275, 273, 0, 0, 0, 261, 0, 44, - 45, 0, 244, 0, 27, 28, 0, 0, 34, 33, - 0, 170, 37, 39, 86, 87, 89, 88, 91, 92, - 93, 94, 95, 90, 85, 0, 46, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 253, 249, - 251, 108, 110, 112, 0, 0, 128, 0, 233, 132, - 166, 224, 0, 0, 228, 140, 138, 0, 266, 265, - 268, 0, 274, 0, 260, 152, 257, 0, 0, 22, - 245, 0, 29, 26, 32, 38, 84, 52, 53, 54, - 56, 57, 59, 60, 64, 65, 62, 63, 67, 68, - 70, 72, 74, 76, 78, 80, 0, 97, 0, 121, - 0, 125, 0, 129, 0, 230, 0, 267, 0, 0, - 0, 0, 0, 0, 24, 0, 0, 0, 122, 130, - 0, 232, 0, 269, 0, 256, 254, 259, 0, 247, - 262, 246, 82, 109, 123, 0, 131, 0, 270, 264, - 0, 258, 124, 263, 255 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 2, 9, 3, 86, 6, 10, 87, 182, 183, - 184, 341, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 285, 207, 234, 208, 209, 90, - 91, 92, 223, 134, 135, 224, 93, 94, 95, 96, - 153, 154, 97, 136, 98, 99, 235, 101, 102, 103, - 104, 105, 148, 149, 239, 240, 319, 211, 212, 213, - 214, 400, 401, 215, 216, 217, 396, 338, 218, 219, - 220, 330, 378, 379, 221, 106, 107 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -321 -static const yytype_int16 yypact[] = -{ - -86, -57, 45, -321, -56, -321, -50, -321, -10, 3320, - -321, -26, -321, -321, -321, -321, -321, -321, -321, -321, - -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, - 79, -321, -321, -321, -321, -321, -321, -321, -321, -321, - -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, - -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, - -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, - -70, -321, -321, 43, -321, -321, -321, 18, -22, -12, - -5, 2, 25, -101, -321, -321, -321, 3320, -321, -43, - -55, -54, 6, -148, -321, 52, 211, 211, 3509, -321, - -321, -321, -47, -321, 3581, -321, -321, -321, 110, -321, - -321, -321, -14, 3509, -321, 211, -321, 3581, -321, -321, - -321, -321, -321, 131, -321, -321, 389, -321, -321, 15, - -321, -321, -321, -321, -321, 3509, 109, 136, -321, -152, - -321, -321, -321, 2400, -321, 105, 3509, 143, 1781, -321, - -321, 7, 9, -107, -321, 10, 12, 1249, 27, 36, - 17, 2015, 40, 2952, 22, 42, -65, -321, -321, -321, - -321, -321, 2952, 2952, 2952, -321, -321, -321, -321, -321, - 604, -321, -321, -321, -20, -321, -321, -321, 47, -92, - 3136, 46, -67, 2952, -24, -16, 111, -73, 108, 37, - 41, 39, 162, 161, -82, -321, -321, -147, -321, 44, - 61, -321, -321, -321, -321, 819, -321, -321, -321, -321, - -321, -321, -321, -321, -321, 181, 3509, -160, -321, 2584, - 2952, -321, -321, -321, 63, -321, -321, 1898, 62, -146, - -321, -321, -321, -321, 183, -321, 131, -321, -321, 187, - 1664, 2952, -321, -321, -144, 2952, -140, -321, 2216, -321, - -321, -81, -321, 1034, -321, -321, 2952, 3437, -321, -321, - 2952, 70, -321, -321, -321, -321, -321, -321, -321, -321, - -321, -321, -321, -321, -321, 2952, -321, 2952, 2952, 2952, - 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, - 2952, 2952, 2952, 2952, 2952, 2952, 2952, 2952, -321, -321, - -321, 74, -321, -321, 2768, 2952, 64, 69, -321, -321, - -321, -321, 2952, 143, -321, -321, -321, 82, -321, -321, - 2216, -74, -321, -68, -321, 235, 78, 203, 85, -321, - -321, 84, 78, 88, -321, -321, -321, -321, -321, -321, - -24, -24, -16, -16, 111, 111, 111, 111, -73, -73, - 108, 37, 41, 39, 162, 161, -129, -321, 2952, 71, - 86, -321, 2952, 72, 87, -321, 2952, -321, 73, 92, - 1249, 75, 76, 1463, -321, 2952, 95, 2952, 80, -321, - 2952, -321, -63, 2952, 1463, 277, -321, -321, 2952, -321, - -321, -321, -321, -321, -321, 2952, -321, 81, 78, -321, - 1249, -321, -321, -321, -321 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, - -321, -321, -321, -321, 26, -321, -321, -321, -321, -135, - -321, -91, -88, -106, -90, -3, -6, -4, -2, -1, - 0, -321, -139, -174, -321, -156, -217, 11, 13, -321, - -321, -321, 83, 170, 164, 89, -321, -321, -243, -321, - -321, 56, -71, -321, -321, -72, -9, -32, -321, -321, - 227, -321, 160, -131, -321, -15, -195, 57, -154, -320, - -69, -84, 222, 133, 66, -321, -321, -13, -321, -321, - -321, -321, -321, -321, -321, 231, -321 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -170 -static const yytype_int16 yytable[] = -{ - 100, 116, 115, 249, 233, 254, 112, 256, 232, 305, - 130, -169, 317, 294, 295, 337, 272, 242, 261, 130, - 88, 4, 89, 1, 140, 141, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 314, 259, 260, 131, - 132, 133, 228, 150, 229, 5, 12, 13, 131, 132, - 133, 137, 307, 323, 315, 307, 318, 7, 286, 307, - 8, 310, 230, 399, 264, 265, 11, 138, 308, 324, - 307, 332, 144, 334, 399, 30, 31, 32, 100, 33, - 34, 35, 36, 37, 385, 151, 108, 337, 245, 142, - 233, 118, 246, 123, 232, 331, 345, 370, 88, 333, - 89, 119, 336, 269, 147, 374, 242, 270, 120, 310, - 342, 346, 109, 110, 339, 121, 111, 210, 307, 114, - 371, 380, 74, 75, 76, 307, 225, 381, 139, -41, - 306, 307, 407, 367, 296, 297, 307, 147, 122, 147, - 128, 318, 131, 132, 133, 129, 113, 284, 210, 143, - 366, 386, 347, 348, 349, 232, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, - 232, 210, 125, 126, 336, 233, 266, 389, 267, 232, - 287, 288, 289, 233, 290, 291, 145, 232, 354, 355, - 356, 357, 404, 292, 293, 406, 298, 299, 318, 350, - 351, -103, 146, 411, 352, 353, 210, 152, 358, 359, - 412, 402, 227, 318, 12, 13, 318, 225, 236, 238, - 392, 250, 243, 244, 318, 247, 395, 248, 147, 233, - 251, 318, 252, 232, 255, 257, 258, 408, 12, 13, - 273, 210, 268, 30, 31, 32, 300, 33, 34, 210, - 302, 301, 303, 304, 210, -40, 414, 311, 322, 125, - 320, 325, 327, 116, 115, -35, 373, 30, 31, 32, - 368, 33, 34, 35, 36, 37, 376, 307, 372, 382, - 383, 384, -41, 388, 391, 387, 390, 394, 393, 410, - 398, 180, 403, 344, 405, 361, 413, 360, 362, 222, - 226, 363, 326, 364, 117, 365, 237, 328, 375, 312, - 409, 127, 397, 263, 0, 313, 329, 377, 124, 0, - 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 210, 0, 0, 210, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, - 0, 0, 12, 13, 14, 15, 16, 17, 155, 156, - 157, 210, 158, 159, 160, 161, 162, 163, 164, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 0, 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, 165, 166, 167, 168, 169, 170, - 171, 0, 0, 172, 173, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 73, 74, 75, 76, 0, 77, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 84, 0, 85, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 174, 0, 0, 0, 0, 0, 175, - 176, 177, 178, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 179, 180, 181, 12, 13, 14, - 15, 16, 17, 155, 156, 157, 0, 158, 159, 160, - 161, 162, 163, 164, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, - 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, 165, - 166, 167, 168, 169, 170, 171, 0, 0, 172, 173, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 73, 74, 75, - 76, 0, 77, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, - 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 174, 0, - 0, 0, 0, 0, 175, 176, 177, 178, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, - 180, 262, 12, 13, 14, 15, 16, 17, 155, 156, - 157, 0, 158, 159, 160, 161, 162, 163, 164, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 0, 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, 165, 166, 167, 168, 169, 170, - 171, 0, 0, 172, 173, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 73, 74, 75, 76, 0, 77, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 84, 0, 85, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 174, 0, 0, 0, 0, 0, 175, - 176, 177, 178, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 179, 180, 309, 12, 13, 14, - 15, 16, 17, 155, 156, 157, 0, 158, 159, 160, - 161, 162, 163, 164, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, - 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, 165, - 166, 167, 168, 169, 170, 171, 0, 0, 172, 173, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 73, 74, 75, - 76, 0, 77, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, - 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 174, 0, - 0, 0, 0, 0, 175, 176, 177, 178, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, - 180, 340, 12, 13, 14, 15, 16, 17, 155, 156, - 157, 0, 158, 159, 160, 161, 162, 163, 164, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 0, 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, 165, 166, 167, 168, 169, 170, - 171, 0, 0, 172, 173, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 73, 74, 75, 76, 0, 77, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 84, 0, 85, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 174, 0, 0, 0, 0, 0, 175, - 176, 177, 178, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 179, 180, 12, 13, 14, 15, - 16, 17, 155, 156, 157, 0, 158, 159, 160, 161, - 162, 163, 164, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 0, 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, 165, 166, - 167, 168, 169, 170, 171, 0, 0, 172, 173, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 73, 74, 75, 76, - 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, - 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 174, 0, 0, - 0, 0, 0, 175, 176, 177, 178, 12, 13, 14, - 15, 16, 17, 0, 0, 0, 0, 0, 179, 126, - 0, 0, 0, 0, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, - 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, 0, - 166, 167, 168, 169, 170, 171, 0, 0, 172, 173, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 73, 74, 75, - 76, 0, 77, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 83, 14, 15, 16, 17, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 0, 0, 0, 0, 0, 0, 84, - 0, 85, 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, 0, 72, 174, 0, - 0, 0, 0, 0, 175, 176, 177, 178, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, - 0, 0, 0, 0, 0, 74, 75, 76, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 0, 0, 0, 0, 0, 0, 84, 0, 85, 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, 0, 72, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, - 0, 0, 74, 75, 76, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, - 0, 0, 0, 84, 0, 85, 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, - 0, 166, 167, 168, 169, 170, 171, 0, 0, 172, - 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 321, 0, 0, 0, 74, - 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 84, 0, 85, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, - 0, 0, 0, 0, 0, 175, 176, 177, 178, 12, - 13, 14, 15, 16, 17, 0, 0, 0, 0, 0, - 253, 0, 0, 0, 0, 0, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 0, 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, 0, 166, 167, 168, 169, 170, 171, 0, 0, - 172, 173, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, - 74, 75, 76, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 84, 0, 85, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 14, 15, 16, 17, 0, - 174, 0, 0, 0, 0, 0, 175, 176, 177, 178, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 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, 0, 166, 167, 168, 169, - 170, 171, 0, 0, 172, 173, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 74, 75, 76, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 84, 0, 85, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, - 15, 16, 17, 0, 174, 0, 0, 231, 0, 0, - 175, 176, 177, 178, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 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, 0, - 166, 167, 168, 169, 170, 171, 0, 0, 172, 173, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, - 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, - 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 14, 15, 16, 17, 0, 174, 0, - 0, 316, 0, 0, 175, 176, 177, 178, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 166, 167, 168, 169, 170, 171, - 0, 0, 172, 173, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 74, 75, 76, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 84, 0, 85, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 14, 15, 16, - 17, 0, 174, 0, 0, 369, 0, 0, 175, 176, - 177, 178, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 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, 0, 166, 167, - 168, 169, 170, 171, 0, 0, 172, 173, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 74, 75, 76, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 84, 0, 85, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 14, 15, 16, 17, 0, 174, 0, 0, 0, - 0, 0, 175, 176, 177, 178, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 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, - 271, 0, 166, 167, 168, 169, 170, 171, 0, 0, - 172, 173, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 74, 75, 76, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 84, 0, 85, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 12, 13, 14, 15, 16, 17, 0, - 174, 0, 0, 0, 0, 0, 175, 176, 177, 178, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 0, 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, 0, 72, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 73, 74, 75, 76, 0, 77, 0, - 0, 0, 0, 0, 0, 0, 78, 79, 80, 81, - 82, 83, 14, 15, 16, 17, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, - 0, 0, 0, 0, 0, 84, 0, 85, 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, 0, 343, 14, 15, 16, 17, 171, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 74, 75, 76, 0, 0, 0, 0, 0, 0, - 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, 0, 72, 14, 15, 16, 17, - 0, 0, 84, 0, 85, 0, 0, 0, 0, 0, - 0, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 74, 75, 76, 0, 0, 0, 0, - 0, 0, 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, 0, 72, 0, 0, - 0, 0, 0, 0, 84, 0, 85, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 84, 0, 85 -}; - -static const yytype_int16 yycheck[] = -{ - 9, 73, 73, 157, 143, 161, 76, 163, 143, 91, - 4, 76, 229, 86, 87, 258, 190, 148, 174, 4, - 9, 78, 9, 109, 96, 97, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 196, 172, 173, 33, - 34, 35, 194, 115, 196, 0, 3, 4, 33, 34, - 35, 199, 199, 199, 214, 199, 230, 113, 193, 199, - 110, 215, 214, 383, 84, 85, 76, 215, 215, 215, - 199, 215, 104, 213, 394, 32, 33, 34, 87, 36, - 37, 38, 39, 40, 213, 117, 112, 330, 195, 98, - 229, 113, 199, 194, 229, 251, 270, 314, 87, 255, - 87, 113, 258, 195, 113, 322, 237, 199, 113, 263, - 266, 285, 33, 34, 195, 113, 37, 126, 199, 76, - 315, 195, 104, 105, 106, 199, 135, 195, 76, 194, - 212, 199, 195, 307, 207, 208, 199, 146, 113, 148, - 195, 315, 33, 34, 35, 199, 216, 214, 157, 196, - 306, 368, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 180, 215, 216, 330, 314, 196, 372, 198, 314, - 204, 205, 206, 322, 200, 201, 76, 322, 294, 295, - 296, 297, 387, 82, 83, 390, 88, 89, 372, 290, - 291, 195, 216, 398, 292, 293, 215, 76, 298, 299, - 405, 385, 76, 387, 3, 4, 390, 226, 113, 76, - 376, 194, 215, 214, 398, 215, 380, 215, 237, 368, - 194, 405, 215, 368, 194, 213, 194, 393, 3, 4, - 194, 250, 195, 32, 33, 34, 209, 36, 37, 258, - 211, 210, 90, 92, 263, 194, 410, 76, 196, 215, - 197, 78, 75, 335, 335, 195, 197, 32, 33, 34, - 196, 36, 37, 38, 39, 40, 194, 199, 214, 76, - 195, 197, 194, 197, 197, 214, 214, 195, 215, 12, - 214, 216, 197, 267, 214, 301, 215, 300, 302, 129, - 136, 303, 246, 304, 77, 305, 146, 250, 323, 226, - 394, 89, 381, 180, -1, 226, 250, 330, 87, -1, - -1, 330, -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, 380, -1, -1, 383, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 394, -1, -1, -1, -1, - -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 410, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, -1, 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, 76, 77, 78, 79, 80, - 81, -1, -1, 84, 85, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, -1, 108, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 121, -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, 155, -1, 157, -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, 194, -1, -1, -1, -1, -1, 200, - 201, 202, 203, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 215, 216, 217, 3, 4, 5, - 6, 7, 8, 9, 10, 11, -1, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, -1, - 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, - 76, 77, 78, 79, 80, 81, -1, -1, 84, 85, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 103, 104, 105, - 106, -1, 108, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 121, -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, 155, - -1, 157, -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, 194, -1, - -1, -1, -1, -1, 200, 201, 202, 203, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, - 216, 217, 3, 4, 5, 6, 7, 8, 9, 10, - 11, -1, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, -1, 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, 76, 77, 78, 79, 80, - 81, -1, -1, 84, 85, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, -1, 108, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 121, -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, 155, -1, 157, -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, 194, -1, -1, -1, -1, -1, 200, - 201, 202, 203, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 215, 216, 217, 3, 4, 5, - 6, 7, 8, 9, 10, 11, -1, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, -1, - 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, - 76, 77, 78, 79, 80, 81, -1, -1, 84, 85, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 103, 104, 105, - 106, -1, 108, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 121, -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, 155, - -1, 157, -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, 194, -1, - -1, -1, -1, -1, 200, 201, 202, 203, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, - 216, 217, 3, 4, 5, 6, 7, 8, 9, 10, - 11, -1, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, -1, 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, 76, 77, 78, 79, 80, - 81, -1, -1, 84, 85, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, -1, 108, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 121, -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, 155, -1, 157, -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, 194, -1, -1, -1, -1, -1, 200, - 201, 202, 203, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 215, 216, 3, 4, 5, 6, - 7, 8, 9, 10, 11, -1, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, -1, 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, 76, - 77, 78, 79, 80, 81, -1, -1, 84, 85, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - -1, 108, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 121, -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, 155, -1, - 157, -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, 194, -1, -1, - -1, -1, -1, 200, 201, 202, 203, 3, 4, 5, - 6, 7, 8, -1, -1, -1, -1, -1, 215, 216, - -1, -1, -1, -1, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, -1, - 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, -1, - 76, 77, 78, 79, 80, 81, -1, -1, 84, 85, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 103, 104, 105, - 106, -1, 108, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 121, 5, 6, 7, 8, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, -1, -1, -1, -1, -1, -1, 155, - -1, 157, 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, -1, 76, 194, -1, - -1, -1, -1, -1, 200, 201, 202, 203, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, - -1, -1, -1, -1, -1, 104, 105, 106, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 5, 6, 7, 8, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - -1, -1, -1, -1, -1, -1, 155, -1, 157, 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, -1, 76, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 217, -1, - -1, -1, 104, 105, 106, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, - -1, -1, -1, 155, -1, 157, 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, - -1, 76, 77, 78, 79, 80, 81, -1, -1, 84, - 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 217, -1, -1, -1, 104, - 105, 106, -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, - 155, -1, 157, -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, 194, - -1, -1, -1, -1, -1, 200, 201, 202, 203, 3, - 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, - 215, -1, -1, -1, -1, -1, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, -1, 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, -1, 76, 77, 78, 79, 80, 81, -1, -1, - 84, 85, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 103, - 104, 105, 106, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 121, -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, 155, -1, 157, -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, 5, 6, 7, 8, -1, - 194, -1, -1, -1, -1, -1, 200, 201, 202, 203, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 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, -1, 76, 77, 78, 79, - 80, 81, -1, -1, 84, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 104, 105, 106, -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, 155, -1, 157, -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, 5, - 6, 7, 8, -1, 194, -1, -1, 197, -1, -1, - 200, 201, 202, 203, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 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, -1, - 76, 77, 78, 79, 80, 81, -1, -1, 84, 85, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 104, 105, - 106, -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, 155, - -1, 157, -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, 5, 6, 7, 8, -1, 194, -1, - -1, 197, -1, -1, 200, 201, 202, 203, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 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, -1, 76, 77, 78, 79, 80, 81, - -1, -1, 84, 85, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 104, 105, 106, -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, 155, -1, 157, -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, 5, 6, 7, - 8, -1, 194, -1, -1, 197, -1, -1, 200, 201, - 202, 203, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 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, -1, 76, 77, - 78, 79, 80, 81, -1, -1, 84, 85, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 104, 105, 106, -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, 155, -1, 157, - -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, 5, 6, 7, 8, -1, 194, -1, -1, -1, - -1, -1, 200, 201, 202, 203, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 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, -1, 76, 77, 78, 79, 80, 81, -1, -1, - 84, 85, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 104, 105, 106, -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, 155, -1, 157, -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, 3, 4, 5, 6, 7, 8, -1, - 194, -1, -1, -1, -1, -1, 200, 201, 202, 203, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, -1, 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, -1, 76, -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, 103, 104, 105, 106, -1, 108, -1, - -1, -1, -1, -1, -1, -1, 116, 117, 118, 119, - 120, 121, 5, 6, 7, 8, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, - -1, -1, -1, -1, -1, 155, -1, 157, 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, -1, 76, 5, 6, 7, 8, 81, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 104, 105, 106, -1, -1, -1, -1, -1, -1, - 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, -1, 76, 5, 6, 7, 8, - -1, -1, 155, -1, 157, -1, -1, -1, -1, -1, - -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 104, 105, 106, -1, -1, -1, -1, - -1, -1, 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, -1, 76, -1, -1, - -1, -1, -1, -1, 155, -1, 157, -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, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 155, -1, 157 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint16 yystos[] = -{ - 0, 109, 219, 221, 78, 0, 223, 113, 110, 220, - 224, 76, 3, 4, 5, 6, 7, 8, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 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, 76, 103, 104, 105, 106, 108, 116, 117, - 118, 119, 120, 121, 155, 157, 222, 225, 255, 256, - 257, 258, 259, 264, 265, 266, 267, 270, 272, 273, - 274, 275, 276, 277, 278, 279, 303, 304, 112, 33, - 34, 37, 76, 216, 76, 270, 273, 278, 113, 113, - 113, 113, 113, 194, 303, 215, 216, 290, 195, 199, - 4, 33, 34, 35, 261, 262, 271, 199, 215, 76, - 273, 273, 274, 196, 275, 76, 216, 274, 280, 281, - 273, 275, 76, 268, 269, 9, 10, 11, 13, 14, - 15, 16, 17, 18, 19, 75, 76, 77, 78, 79, - 80, 81, 84, 85, 194, 200, 201, 202, 203, 215, - 216, 217, 226, 227, 228, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 253, 255, 256, - 274, 285, 286, 287, 288, 291, 292, 293, 296, 297, - 298, 302, 261, 260, 263, 274, 262, 76, 194, 196, - 214, 197, 237, 250, 254, 274, 113, 280, 76, 282, - 283, 217, 281, 215, 214, 195, 199, 215, 215, 286, - 194, 194, 215, 215, 253, 194, 253, 213, 194, 237, - 237, 253, 217, 291, 84, 85, 196, 198, 195, 195, - 199, 74, 251, 194, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 214, 252, 237, 204, 205, 206, - 200, 201, 82, 83, 86, 87, 207, 208, 88, 89, - 209, 210, 211, 90, 92, 91, 212, 199, 215, 217, - 286, 76, 260, 263, 196, 214, 197, 254, 251, 284, - 197, 217, 196, 199, 215, 78, 269, 75, 285, 292, - 299, 253, 215, 253, 213, 103, 253, 266, 295, 195, - 217, 229, 253, 76, 232, 251, 251, 237, 237, 237, - 239, 239, 240, 240, 241, 241, 241, 241, 242, 242, - 243, 244, 245, 246, 247, 248, 253, 251, 196, 197, - 254, 284, 214, 197, 254, 283, 194, 295, 300, 301, - 195, 195, 76, 195, 197, 213, 254, 214, 197, 284, - 214, 197, 253, 215, 195, 286, 294, 288, 214, 287, - 289, 290, 251, 197, 284, 214, 284, 195, 253, 289, - 12, 284, 284, 215, 286 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc, scanner) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, state); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - struct _mesa_glsl_parse_state *state; -#endif -{ - if (!yyvaluep) - return; - YYUSE (yylocationp); - YYUSE (state); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - struct _mesa_glsl_parse_state *state; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct _mesa_glsl_parse_state *state) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, state) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - struct _mesa_glsl_parse_state *state; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , state); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, state); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct _mesa_glsl_parse_state *state) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, state) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - struct _mesa_glsl_parse_state *state; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (state); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (struct _mesa_glsl_parse_state *state); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (struct _mesa_glsl_parse_state *state) -#else -int -yyparse (state) - struct _mesa_glsl_parse_state *state; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc; - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - yylsp = yyls; - -#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 1; -#endif - -/* User initialization code. */ - -/* Line 1251 of yacc.c */ -#line 41 "glsl_parser.ypp" -{ - yylloc.first_line = 1; - yylloc.first_column = 1; - yylloc.last_line = 1; - yylloc.last_column = 1; - yylloc.source = 0; -} - -/* Line 1251 of yacc.c */ -#line 2640 "glsl_parser.cpp" - yylsp[0] = yylloc; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: - -/* Line 1464 of yacc.c */ -#line 213 "glsl_parser.ypp" - { - _mesa_glsl_initialize_types(state); - ;} - break; - - case 5: - -/* Line 1464 of yacc.c */ -#line 222 "glsl_parser.ypp" - { - bool supported = false; - - switch ((yyvsp[(2) - (3)].n)) { - case 100: - state->es_shader = true; - supported = state->Const.GLSL_100ES; - break; - case 110: - supported = state->Const.GLSL_110; - break; - case 120: - supported = state->Const.GLSL_120; - break; - case 130: - supported = state->Const.GLSL_130; - break; - default: - supported = false; - break; - } - - state->language_version = (yyvsp[(2) - (3)].n); - state->version_string = - ralloc_asprintf(state, "GLSL%s %d.%02d", - state->es_shader ? " ES" : "", - state->language_version / 100, - state->language_version % 100); - - if (!supported) { - _mesa_glsl_error(& (yylsp[(2) - (3)]), state, "%s is not supported. " - "Supported versions are: %s\n", - state->version_string, - state->supported_version_string); - } - ;} - break; - - case 10: - -/* Line 1464 of yacc.c */ -#line 266 "glsl_parser.ypp" - { - if (state->language_version < 120) { - _mesa_glsl_warning(& (yylsp[(1) - (2)]), state, - "pragma `invariant(all)' not supported in %s", - state->version_string); - } else { - state->all_invariant = true; - } - ;} - break; - - case 13: - -/* Line 1464 of yacc.c */ -#line 284 "glsl_parser.ypp" - { - if (!_mesa_glsl_process_extension((yyvsp[(2) - (5)].identifier), & (yylsp[(2) - (5)]), (yyvsp[(4) - (5)].identifier), & (yylsp[(4) - (5)]), state)) { - YYERROR; - } - ;} - break; - - case 14: - -/* Line 1464 of yacc.c */ -#line 293 "glsl_parser.ypp" - { - /* FINISHME: The NULL test is required because pragmas are set to - * FINISHME: NULL. (See production rule for external_declaration.) - */ - if ((yyvsp[(1) - (1)].node) != NULL) - state->translation_unit.push_tail(& (yyvsp[(1) - (1)].node)->link); - ;} - break; - - case 15: - -/* Line 1464 of yacc.c */ -#line 301 "glsl_parser.ypp" - { - /* FINISHME: The NULL test is required because pragmas are set to - * FINISHME: NULL. (See production rule for external_declaration.) - */ - if ((yyvsp[(2) - (2)].node) != NULL) - state->translation_unit.push_tail(& (yyvsp[(2) - (2)].node)->link); - ;} - break; - - case 17: - -/* Line 1464 of yacc.c */ -#line 316 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.identifier = (yyvsp[(1) - (1)].identifier); - ;} - break; - - case 18: - -/* Line 1464 of yacc.c */ -#line 323 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.int_constant = (yyvsp[(1) - (1)].n); - ;} - break; - - case 19: - -/* Line 1464 of yacc.c */ -#line 330 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.uint_constant = (yyvsp[(1) - (1)].n); - ;} - break; - - case 20: - -/* Line 1464 of yacc.c */ -#line 337 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.float_constant = (yyvsp[(1) - (1)].real); - ;} - break; - - case 21: - -/* Line 1464 of yacc.c */ -#line 344 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.bool_constant = (yyvsp[(1) - (1)].n); - ;} - break; - - case 22: - -/* Line 1464 of yacc.c */ -#line 351 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(2) - (3)].expression); - ;} - break; - - case 24: - -/* Line 1464 of yacc.c */ -#line 359 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_array_index, (yyvsp[(1) - (4)].expression), (yyvsp[(3) - (4)].expression), NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 25: - -/* Line 1464 of yacc.c */ -#line 365 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(1) - (1)].expression); - ;} - break; - - case 26: - -/* Line 1464 of yacc.c */ -#line 369 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->primary_expression.identifier = (yyvsp[(3) - (3)].identifier); - ;} - break; - - case 27: - -/* Line 1464 of yacc.c */ -#line 376 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_post_inc, (yyvsp[(1) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 28: - -/* Line 1464 of yacc.c */ -#line 382 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_post_dec, (yyvsp[(1) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 32: - -/* Line 1464 of yacc.c */ -#line 400 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 37: - -/* Line 1464 of yacc.c */ -#line 419 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(1) - (2)].expression); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->expressions.push_tail(& (yyvsp[(2) - (2)].expression)->link); - ;} - break; - - case 38: - -/* Line 1464 of yacc.c */ -#line 425 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(1) - (3)].expression); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link); - ;} - break; - - case 40: - -/* Line 1464 of yacc.c */ -#line 441 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_function_expression((yyvsp[(1) - (1)].type_specifier)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 41: - -/* Line 1464 of yacc.c */ -#line 447 "glsl_parser.ypp" - { - void *ctx = state; - ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); - (yyval.expression) = new(ctx) ast_function_expression(callee); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 42: - -/* Line 1464 of yacc.c */ -#line 454 "glsl_parser.ypp" - { - void *ctx = state; - ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); - (yyval.expression) = new(ctx) ast_function_expression(callee); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 44: - -/* Line 1464 of yacc.c */ -#line 466 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_pre_inc, (yyvsp[(2) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 45: - -/* Line 1464 of yacc.c */ -#line 472 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_pre_dec, (yyvsp[(2) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 46: - -/* Line 1464 of yacc.c */ -#line 478 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression((yyvsp[(1) - (2)].n), (yyvsp[(2) - (2)].expression), NULL, NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 47: - -/* Line 1464 of yacc.c */ -#line 487 "glsl_parser.ypp" - { (yyval.n) = ast_plus; ;} - break; - - case 48: - -/* Line 1464 of yacc.c */ -#line 488 "glsl_parser.ypp" - { (yyval.n) = ast_neg; ;} - break; - - case 49: - -/* Line 1464 of yacc.c */ -#line 489 "glsl_parser.ypp" - { (yyval.n) = ast_logic_not; ;} - break; - - case 50: - -/* Line 1464 of yacc.c */ -#line 490 "glsl_parser.ypp" - { (yyval.n) = ast_bit_not; ;} - break; - - case 52: - -/* Line 1464 of yacc.c */ -#line 496 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_mul, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 53: - -/* Line 1464 of yacc.c */ -#line 502 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_div, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 54: - -/* Line 1464 of yacc.c */ -#line 508 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_mod, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 56: - -/* Line 1464 of yacc.c */ -#line 518 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_add, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 57: - -/* Line 1464 of yacc.c */ -#line 524 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_sub, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 59: - -/* Line 1464 of yacc.c */ -#line 534 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_lshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 60: - -/* Line 1464 of yacc.c */ -#line 540 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_rshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 62: - -/* Line 1464 of yacc.c */ -#line 550 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_less, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 63: - -/* Line 1464 of yacc.c */ -#line 556 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_greater, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 64: - -/* Line 1464 of yacc.c */ -#line 562 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_lequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 65: - -/* Line 1464 of yacc.c */ -#line 568 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_gequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 67: - -/* Line 1464 of yacc.c */ -#line 578 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_equal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 68: - -/* Line 1464 of yacc.c */ -#line 584 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_nequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 70: - -/* Line 1464 of yacc.c */ -#line 594 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 72: - -/* Line 1464 of yacc.c */ -#line 604 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 74: - -/* Line 1464 of yacc.c */ -#line 614 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 76: - -/* Line 1464 of yacc.c */ -#line 624 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 78: - -/* Line 1464 of yacc.c */ -#line 634 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 80: - -/* Line 1464 of yacc.c */ -#line 644 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 82: - -/* Line 1464 of yacc.c */ -#line 654 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression(ast_conditional, (yyvsp[(1) - (5)].expression), (yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].expression)); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 84: - -/* Line 1464 of yacc.c */ -#line 664 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.expression) = new(ctx) ast_expression((yyvsp[(2) - (3)].n), (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); - (yyval.expression)->set_location(yylloc); - ;} - break; - - case 85: - -/* Line 1464 of yacc.c */ -#line 672 "glsl_parser.ypp" - { (yyval.n) = ast_assign; ;} - break; - - case 86: - -/* Line 1464 of yacc.c */ -#line 673 "glsl_parser.ypp" - { (yyval.n) = ast_mul_assign; ;} - break; - - case 87: - -/* Line 1464 of yacc.c */ -#line 674 "glsl_parser.ypp" - { (yyval.n) = ast_div_assign; ;} - break; - - case 88: - -/* Line 1464 of yacc.c */ -#line 675 "glsl_parser.ypp" - { (yyval.n) = ast_mod_assign; ;} - break; - - case 89: - -/* Line 1464 of yacc.c */ -#line 676 "glsl_parser.ypp" - { (yyval.n) = ast_add_assign; ;} - break; - - case 90: - -/* Line 1464 of yacc.c */ -#line 677 "glsl_parser.ypp" - { (yyval.n) = ast_sub_assign; ;} - break; - - case 91: - -/* Line 1464 of yacc.c */ -#line 678 "glsl_parser.ypp" - { (yyval.n) = ast_ls_assign; ;} - break; - - case 92: - -/* Line 1464 of yacc.c */ -#line 679 "glsl_parser.ypp" - { (yyval.n) = ast_rs_assign; ;} - break; - - case 93: - -/* Line 1464 of yacc.c */ -#line 680 "glsl_parser.ypp" - { (yyval.n) = ast_and_assign; ;} - break; - - case 94: - -/* Line 1464 of yacc.c */ -#line 681 "glsl_parser.ypp" - { (yyval.n) = ast_xor_assign; ;} - break; - - case 95: - -/* Line 1464 of yacc.c */ -#line 682 "glsl_parser.ypp" - { (yyval.n) = ast_or_assign; ;} - break; - - case 96: - -/* Line 1464 of yacc.c */ -#line 687 "glsl_parser.ypp" - { - (yyval.expression) = (yyvsp[(1) - (1)].expression); - ;} - break; - - case 97: - -/* Line 1464 of yacc.c */ -#line 691 "glsl_parser.ypp" - { - void *ctx = state; - if ((yyvsp[(1) - (3)].expression)->oper != ast_sequence) { - (yyval.expression) = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); - (yyval.expression)->set_location(yylloc); - (yyval.expression)->expressions.push_tail(& (yyvsp[(1) - (3)].expression)->link); - } else { - (yyval.expression) = (yyvsp[(1) - (3)].expression); - } - - (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link); - ;} - break; - - case 99: - -/* Line 1464 of yacc.c */ -#line 711 "glsl_parser.ypp" - { - (yyval.node) = (yyvsp[(1) - (2)].function); - ;} - break; - - case 100: - -/* Line 1464 of yacc.c */ -#line 715 "glsl_parser.ypp" - { - (yyval.node) = (yyvsp[(1) - (2)].declarator_list); - ;} - break; - - case 101: - -/* Line 1464 of yacc.c */ -#line 719 "glsl_parser.ypp" - { - (yyvsp[(3) - (4)].type_specifier)->precision = (yyvsp[(2) - (4)].n); - (yyvsp[(3) - (4)].type_specifier)->is_precision_statement = true; - (yyval.node) = (yyvsp[(3) - (4)].type_specifier); - ;} - break; - - case 105: - -/* Line 1464 of yacc.c */ -#line 737 "glsl_parser.ypp" - { - (yyval.function) = (yyvsp[(1) - (2)].function); - (yyval.function)->parameters.push_tail(& (yyvsp[(2) - (2)].parameter_declarator)->link); - ;} - break; - - case 106: - -/* Line 1464 of yacc.c */ -#line 742 "glsl_parser.ypp" - { - (yyval.function) = (yyvsp[(1) - (3)].function); - (yyval.function)->parameters.push_tail(& (yyvsp[(3) - (3)].parameter_declarator)->link); - ;} - break; - - case 107: - -/* Line 1464 of yacc.c */ -#line 750 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.function) = new(ctx) ast_function(); - (yyval.function)->set_location(yylloc); - (yyval.function)->return_type = (yyvsp[(1) - (3)].fully_specified_type); - (yyval.function)->identifier = (yyvsp[(2) - (3)].identifier); - ;} - break; - - case 108: - -/* Line 1464 of yacc.c */ -#line 761 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); - (yyval.parameter_declarator)->set_location(yylloc); - (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); - (yyval.parameter_declarator)->type->set_location(yylloc); - (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (2)].type_specifier); - (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (2)].identifier); - ;} - break; - - case 109: - -/* Line 1464 of yacc.c */ -#line 771 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); - (yyval.parameter_declarator)->set_location(yylloc); - (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); - (yyval.parameter_declarator)->type->set_location(yylloc); - (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (5)].type_specifier); - (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (5)].identifier); - (yyval.parameter_declarator)->is_array = true; - (yyval.parameter_declarator)->array_size = (yyvsp[(4) - (5)].expression); - ;} - break; - - case 110: - -/* Line 1464 of yacc.c */ -#line 786 "glsl_parser.ypp" - { - (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i; - - (yyval.parameter_declarator) = (yyvsp[(3) - (3)].parameter_declarator); - (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier); - ;} - break; - - case 111: - -/* Line 1464 of yacc.c */ -#line 793 "glsl_parser.ypp" - { - (yyval.parameter_declarator) = (yyvsp[(2) - (2)].parameter_declarator); - (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier); - ;} - break; - - case 112: - -/* Line 1464 of yacc.c */ -#line 798 "glsl_parser.ypp" - { - void *ctx = state; - (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i; - - (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); - (yyval.parameter_declarator)->set_location(yylloc); - (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); - (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier); - (yyval.parameter_declarator)->type->specifier = (yyvsp[(3) - (3)].type_specifier); - ;} - break; - - case 113: - -/* Line 1464 of yacc.c */ -#line 809 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); - (yyval.parameter_declarator)->set_location(yylloc); - (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); - (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier); - (yyval.parameter_declarator)->type->specifier = (yyvsp[(2) - (2)].type_specifier); - ;} - break; - - case 114: - -/* Line 1464 of yacc.c */ -#line 821 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - ;} - break; - - case 115: - -/* Line 1464 of yacc.c */ -#line 825 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.in = 1; - ;} - break; - - case 116: - -/* Line 1464 of yacc.c */ -#line 830 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.out = 1; - ;} - break; - - case 117: - -/* Line 1464 of yacc.c */ -#line 835 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.in = 1; - (yyval.type_qualifier).flags.q.out = 1; - ;} - break; - - case 120: - -/* Line 1464 of yacc.c */ -#line 849 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (3)].identifier), false, NULL, NULL); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (3)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 121: - -/* Line 1464 of yacc.c */ -#line 858 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), true, NULL, NULL); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 122: - -/* Line 1464 of yacc.c */ -#line 867 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (6)].identifier), true, (yyvsp[(5) - (6)].expression), NULL); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (6)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 123: - -/* Line 1464 of yacc.c */ -#line 876 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (7)].identifier), true, NULL, (yyvsp[(7) - (7)].expression)); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (7)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 124: - -/* Line 1464 of yacc.c */ -#line 885 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (8)].identifier), true, (yyvsp[(5) - (8)].expression), (yyvsp[(8) - (8)].expression)); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (8)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 125: - -/* Line 1464 of yacc.c */ -#line 894 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), false, NULL, (yyvsp[(5) - (5)].expression)); - decl->set_location(yylloc); - - (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 126: - -/* Line 1464 of yacc.c */ -#line 907 "glsl_parser.ypp" - { - void *ctx = state; - if ((yyvsp[(1) - (1)].fully_specified_type)->specifier->type_specifier != ast_struct) { - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "empty declaration list\n"); - YYERROR; - } else { - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (1)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - } - ;} - break; - - case 127: - -/* Line 1464 of yacc.c */ -#line 918 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (2)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 128: - -/* Line 1464 of yacc.c */ -#line 927 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), true, NULL, NULL); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 129: - -/* Line 1464 of yacc.c */ -#line 936 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (5)].identifier), true, (yyvsp[(4) - (5)].expression), NULL); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (5)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 130: - -/* Line 1464 of yacc.c */ -#line 945 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (6)].identifier), true, NULL, (yyvsp[(6) - (6)].expression)); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (6)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 131: - -/* Line 1464 of yacc.c */ -#line 954 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (7)].identifier), true, (yyvsp[(4) - (7)].expression), (yyvsp[(7) - (7)].expression)); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (7)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 132: - -/* Line 1464 of yacc.c */ -#line 963 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); - - (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 133: - -/* Line 1464 of yacc.c */ -#line 972 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); - - (yyval.declarator_list) = new(ctx) ast_declarator_list(NULL); - (yyval.declarator_list)->set_location(yylloc); - (yyval.declarator_list)->invariant = true; - - (yyval.declarator_list)->declarations.push_tail(&decl->link); - ;} - break; - - case 134: - -/* Line 1464 of yacc.c */ -#line 986 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); - (yyval.fully_specified_type)->set_location(yylloc); - (yyval.fully_specified_type)->specifier = (yyvsp[(1) - (1)].type_specifier); - ;} - break; - - case 135: - -/* Line 1464 of yacc.c */ -#line 993 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); - (yyval.fully_specified_type)->set_location(yylloc); - (yyval.fully_specified_type)->qualifier = (yyvsp[(1) - (2)].type_qualifier); - (yyval.fully_specified_type)->specifier = (yyvsp[(2) - (2)].type_specifier); - ;} - break; - - case 136: - -/* Line 1464 of yacc.c */ -#line 1004 "glsl_parser.ypp" - { - (yyval.type_qualifier) = (yyvsp[(3) - (4)].type_qualifier); - ;} - break; - - case 138: - -/* Line 1464 of yacc.c */ -#line 1012 "glsl_parser.ypp" - { - if (((yyvsp[(1) - (3)].type_qualifier).flags.i & (yyvsp[(3) - (3)].type_qualifier).flags.i) != 0) { - _mesa_glsl_error(& (yylsp[(3) - (3)]), state, - "duplicate layout qualifiers used\n"); - YYERROR; - } - - (yyval.type_qualifier).flags.i = (yyvsp[(1) - (3)].type_qualifier).flags.i | (yyvsp[(3) - (3)].type_qualifier).flags.i; - - if ((yyvsp[(1) - (3)].type_qualifier).flags.q.explicit_location) - (yyval.type_qualifier).location = (yyvsp[(1) - (3)].type_qualifier).location; - - if ((yyvsp[(3) - (3)].type_qualifier).flags.q.explicit_location) - (yyval.type_qualifier).location = (yyvsp[(3) - (3)].type_qualifier).location; - ;} - break; - - case 139: - -/* Line 1464 of yacc.c */ -#line 1031 "glsl_parser.ypp" - { - bool got_one = false; - - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - - /* Layout qualifiers for ARB_fragment_coord_conventions. */ - if (!got_one && state->ARB_fragment_coord_conventions_enable) { - if (strcmp((yyvsp[(1) - (1)].identifier), "origin_upper_left") == 0) { - got_one = true; - (yyval.type_qualifier).flags.q.origin_upper_left = 1; - } else if (strcmp((yyvsp[(1) - (1)].identifier), "pixel_center_integer") == 0) { - got_one = true; - (yyval.type_qualifier).flags.q.pixel_center_integer = 1; - } - - if (got_one && state->ARB_fragment_coord_conventions_warn) { - _mesa_glsl_warning(& (yylsp[(1) - (1)]), state, - "GL_ARB_fragment_coord_conventions layout " - "identifier `%s' used\n", (yyvsp[(1) - (1)].identifier)); - } - } - - /* Layout qualifiers for AMD_conservative_depth. */ - if (!got_one && state->AMD_conservative_depth_enable) { - if (strcmp((yyvsp[(1) - (1)].identifier), "depth_any") == 0) { - got_one = true; - (yyval.type_qualifier).flags.q.depth_any = 1; - } else if (strcmp((yyvsp[(1) - (1)].identifier), "depth_greater") == 0) { - got_one = true; - (yyval.type_qualifier).flags.q.depth_greater = 1; - } else if (strcmp((yyvsp[(1) - (1)].identifier), "depth_less") == 0) { - got_one = true; - (yyval.type_qualifier).flags.q.depth_less = 1; - } else if (strcmp((yyvsp[(1) - (1)].identifier), "depth_unchanged") == 0) { - got_one = true; - (yyval.type_qualifier).flags.q.depth_unchanged = 1; - } - - if (got_one && state->AMD_conservative_depth_warn) { - _mesa_glsl_warning(& (yylsp[(1) - (1)]), state, - "GL_AMD_conservative_depth " - "layout qualifier `%s' is used\n", (yyvsp[(1) - (1)].identifier)); - } - } - - if (!got_one) { - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "unrecognized layout identifier " - "`%s'\n", (yyvsp[(1) - (1)].identifier)); - YYERROR; - } - ;} - break; - - case 140: - -/* Line 1464 of yacc.c */ -#line 1083 "glsl_parser.ypp" - { - bool got_one = false; - - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - - if (state->ARB_explicit_attrib_location_enable) { - /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and - * FINISHME: GLSL 1.30 (or later) are supported. - */ - if (strcmp("location", (yyvsp[(1) - (3)].identifier)) == 0) { - got_one = true; - - (yyval.type_qualifier).flags.q.explicit_location = 1; - - if ((yyvsp[(3) - (3)].n) >= 0) { - (yyval.type_qualifier).location = (yyvsp[(3) - (3)].n); - } else { - _mesa_glsl_error(& (yylsp[(3) - (3)]), state, - "invalid location %d specified\n", (yyvsp[(3) - (3)].n)); - YYERROR; - } - } - } - - /* If the identifier didn't match any known layout identifiers, - * emit an error. - */ - if (!got_one) { - _mesa_glsl_error(& (yylsp[(1) - (3)]), state, "unrecognized layout identifier " - "`%s'\n", (yyvsp[(1) - (3)].identifier)); - YYERROR; - } else if (state->ARB_explicit_attrib_location_warn) { - _mesa_glsl_warning(& (yylsp[(1) - (3)]), state, - "GL_ARB_explicit_attrib_location layout " - "identifier `%s' used\n", (yyvsp[(1) - (3)].identifier)); - } - ;} - break; - - case 141: - -/* Line 1464 of yacc.c */ -#line 1124 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.smooth = 1; - ;} - break; - - case 142: - -/* Line 1464 of yacc.c */ -#line 1129 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.flat = 1; - ;} - break; - - case 143: - -/* Line 1464 of yacc.c */ -#line 1134 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.noperspective = 1; - ;} - break; - - case 144: - -/* Line 1464 of yacc.c */ -#line 1142 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.constant = 1; - ;} - break; - - case 147: - -/* Line 1464 of yacc.c */ -#line 1152 "glsl_parser.ypp" - { - (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier); - (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i; - ;} - break; - - case 149: - -/* Line 1464 of yacc.c */ -#line 1158 "glsl_parser.ypp" - { - (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier); - (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i; - ;} - break; - - case 150: - -/* Line 1464 of yacc.c */ -#line 1163 "glsl_parser.ypp" - { - (yyval.type_qualifier) = (yyvsp[(2) - (2)].type_qualifier); - (yyval.type_qualifier).flags.q.invariant = 1; - ;} - break; - - case 151: - -/* Line 1464 of yacc.c */ -#line 1168 "glsl_parser.ypp" - { - (yyval.type_qualifier) = (yyvsp[(2) - (3)].type_qualifier); - (yyval.type_qualifier).flags.i |= (yyvsp[(3) - (3)].type_qualifier).flags.i; - (yyval.type_qualifier).flags.q.invariant = 1; - ;} - break; - - case 152: - -/* Line 1464 of yacc.c */ -#line 1174 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.invariant = 1; - ;} - break; - - case 153: - -/* Line 1464 of yacc.c */ -#line 1182 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.constant = 1; - ;} - break; - - case 154: - -/* Line 1464 of yacc.c */ -#line 1187 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.attribute = 1; - ;} - break; - - case 155: - -/* Line 1464 of yacc.c */ -#line 1192 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.varying = 1; - ;} - break; - - case 156: - -/* Line 1464 of yacc.c */ -#line 1197 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.centroid = 1; - (yyval.type_qualifier).flags.q.varying = 1; - ;} - break; - - case 157: - -/* Line 1464 of yacc.c */ -#line 1203 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.in = 1; - ;} - break; - - case 158: - -/* Line 1464 of yacc.c */ -#line 1208 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.out = 1; - ;} - break; - - case 159: - -/* Line 1464 of yacc.c */ -#line 1213 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.in = 1; - ;} - break; - - case 160: - -/* Line 1464 of yacc.c */ -#line 1218 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.out = 1; - ;} - break; - - case 161: - -/* Line 1464 of yacc.c */ -#line 1223 "glsl_parser.ypp" - { - memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); - (yyval.type_qualifier).flags.q.uniform = 1; - ;} - break; - - case 162: - -/* Line 1464 of yacc.c */ -#line 1231 "glsl_parser.ypp" - { - (yyval.type_specifier) = (yyvsp[(1) - (1)].type_specifier); - ;} - break; - - case 163: - -/* Line 1464 of yacc.c */ -#line 1235 "glsl_parser.ypp" - { - (yyval.type_specifier) = (yyvsp[(2) - (2)].type_specifier); - (yyval.type_specifier)->precision = (yyvsp[(1) - (2)].n); - ;} - break; - - case 165: - -/* Line 1464 of yacc.c */ -#line 1244 "glsl_parser.ypp" - { - (yyval.type_specifier) = (yyvsp[(1) - (3)].type_specifier); - (yyval.type_specifier)->is_array = true; - (yyval.type_specifier)->array_size = NULL; - ;} - break; - - case 166: - -/* Line 1464 of yacc.c */ -#line 1250 "glsl_parser.ypp" - { - (yyval.type_specifier) = (yyvsp[(1) - (4)].type_specifier); - (yyval.type_specifier)->is_array = true; - (yyval.type_specifier)->array_size = (yyvsp[(3) - (4)].expression); - ;} - break; - - case 167: - -/* Line 1464 of yacc.c */ -#line 1259 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].n)); - (yyval.type_specifier)->set_location(yylloc); - ;} - break; - - case 168: - -/* Line 1464 of yacc.c */ -#line 1265 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].struct_specifier)); - (yyval.type_specifier)->set_location(yylloc); - ;} - break; - - case 169: - -/* Line 1464 of yacc.c */ -#line 1271 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].identifier)); - (yyval.type_specifier)->set_location(yylloc); - ;} - break; - - case 170: - -/* Line 1464 of yacc.c */ -#line 1279 "glsl_parser.ypp" - { (yyval.n) = ast_void; ;} - break; - - case 171: - -/* Line 1464 of yacc.c */ -#line 1280 "glsl_parser.ypp" - { (yyval.n) = ast_float; ;} - break; - - case 172: - -/* Line 1464 of yacc.c */ -#line 1281 "glsl_parser.ypp" - { (yyval.n) = ast_int; ;} - break; - - case 173: - -/* Line 1464 of yacc.c */ -#line 1282 "glsl_parser.ypp" - { (yyval.n) = ast_uint; ;} - break; - - case 174: - -/* Line 1464 of yacc.c */ -#line 1283 "glsl_parser.ypp" - { (yyval.n) = ast_bool; ;} - break; - - case 175: - -/* Line 1464 of yacc.c */ -#line 1284 "glsl_parser.ypp" - { (yyval.n) = ast_vec2; ;} - break; - - case 176: - -/* Line 1464 of yacc.c */ -#line 1285 "glsl_parser.ypp" - { (yyval.n) = ast_vec3; ;} - break; - - case 177: - -/* Line 1464 of yacc.c */ -#line 1286 "glsl_parser.ypp" - { (yyval.n) = ast_vec4; ;} - break; - - case 178: - -/* Line 1464 of yacc.c */ -#line 1287 "glsl_parser.ypp" - { (yyval.n) = ast_bvec2; ;} - break; - - case 179: - -/* Line 1464 of yacc.c */ -#line 1288 "glsl_parser.ypp" - { (yyval.n) = ast_bvec3; ;} - break; - - case 180: - -/* Line 1464 of yacc.c */ -#line 1289 "glsl_parser.ypp" - { (yyval.n) = ast_bvec4; ;} - break; - - case 181: - -/* Line 1464 of yacc.c */ -#line 1290 "glsl_parser.ypp" - { (yyval.n) = ast_ivec2; ;} - break; - - case 182: - -/* Line 1464 of yacc.c */ -#line 1291 "glsl_parser.ypp" - { (yyval.n) = ast_ivec3; ;} - break; - - case 183: - -/* Line 1464 of yacc.c */ -#line 1292 "glsl_parser.ypp" - { (yyval.n) = ast_ivec4; ;} - break; - - case 184: - -/* Line 1464 of yacc.c */ -#line 1293 "glsl_parser.ypp" - { (yyval.n) = ast_uvec2; ;} - break; - - case 185: - -/* Line 1464 of yacc.c */ -#line 1294 "glsl_parser.ypp" - { (yyval.n) = ast_uvec3; ;} - break; - - case 186: - -/* Line 1464 of yacc.c */ -#line 1295 "glsl_parser.ypp" - { (yyval.n) = ast_uvec4; ;} - break; - - case 187: - -/* Line 1464 of yacc.c */ -#line 1296 "glsl_parser.ypp" - { (yyval.n) = ast_mat2; ;} - break; - - case 188: - -/* Line 1464 of yacc.c */ -#line 1297 "glsl_parser.ypp" - { (yyval.n) = ast_mat2x3; ;} - break; - - case 189: - -/* Line 1464 of yacc.c */ -#line 1298 "glsl_parser.ypp" - { (yyval.n) = ast_mat2x4; ;} - break; - - case 190: - -/* Line 1464 of yacc.c */ -#line 1299 "glsl_parser.ypp" - { (yyval.n) = ast_mat3x2; ;} - break; - - case 191: - -/* Line 1464 of yacc.c */ -#line 1300 "glsl_parser.ypp" - { (yyval.n) = ast_mat3; ;} - break; - - case 192: - -/* Line 1464 of yacc.c */ -#line 1301 "glsl_parser.ypp" - { (yyval.n) = ast_mat3x4; ;} - break; - - case 193: - -/* Line 1464 of yacc.c */ -#line 1302 "glsl_parser.ypp" - { (yyval.n) = ast_mat4x2; ;} - break; - - case 194: - -/* Line 1464 of yacc.c */ -#line 1303 "glsl_parser.ypp" - { (yyval.n) = ast_mat4x3; ;} - break; - - case 195: - -/* Line 1464 of yacc.c */ -#line 1304 "glsl_parser.ypp" - { (yyval.n) = ast_mat4; ;} - break; - - case 196: - -/* Line 1464 of yacc.c */ -#line 1305 "glsl_parser.ypp" - { (yyval.n) = ast_sampler1d; ;} - break; - - case 197: - -/* Line 1464 of yacc.c */ -#line 1306 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2d; ;} - break; - - case 198: - -/* Line 1464 of yacc.c */ -#line 1307 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2drect; ;} - break; - - case 199: - -/* Line 1464 of yacc.c */ -#line 1308 "glsl_parser.ypp" - { (yyval.n) = ast_sampler3d; ;} - break; - - case 200: - -/* Line 1464 of yacc.c */ -#line 1309 "glsl_parser.ypp" - { (yyval.n) = ast_samplercube; ;} - break; - - case 201: - -/* Line 1464 of yacc.c */ -#line 1310 "glsl_parser.ypp" - { (yyval.n) = ast_sampler1dshadow; ;} - break; - - case 202: - -/* Line 1464 of yacc.c */ -#line 1311 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2dshadow; ;} - break; - - case 203: - -/* Line 1464 of yacc.c */ -#line 1312 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2drectshadow; ;} - break; - - case 204: - -/* Line 1464 of yacc.c */ -#line 1313 "glsl_parser.ypp" - { (yyval.n) = ast_samplercubeshadow; ;} - break; - - case 205: - -/* Line 1464 of yacc.c */ -#line 1314 "glsl_parser.ypp" - { (yyval.n) = ast_sampler1darray; ;} - break; - - case 206: - -/* Line 1464 of yacc.c */ -#line 1315 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2darray; ;} - break; - - case 207: - -/* Line 1464 of yacc.c */ -#line 1316 "glsl_parser.ypp" - { (yyval.n) = ast_sampler1darrayshadow; ;} - break; - - case 208: - -/* Line 1464 of yacc.c */ -#line 1317 "glsl_parser.ypp" - { (yyval.n) = ast_sampler2darrayshadow; ;} - break; - - case 209: - -/* Line 1464 of yacc.c */ -#line 1318 "glsl_parser.ypp" - { (yyval.n) = ast_isampler1d; ;} - break; - - case 210: - -/* Line 1464 of yacc.c */ -#line 1319 "glsl_parser.ypp" - { (yyval.n) = ast_isampler2d; ;} - break; - - case 211: - -/* Line 1464 of yacc.c */ -#line 1320 "glsl_parser.ypp" - { (yyval.n) = ast_isampler3d; ;} - break; - - case 212: - -/* Line 1464 of yacc.c */ -#line 1321 "glsl_parser.ypp" - { (yyval.n) = ast_isamplercube; ;} - break; - - case 213: - -/* Line 1464 of yacc.c */ -#line 1322 "glsl_parser.ypp" - { (yyval.n) = ast_isampler1darray; ;} - break; - - case 214: - -/* Line 1464 of yacc.c */ -#line 1323 "glsl_parser.ypp" - { (yyval.n) = ast_isampler2darray; ;} - break; - - case 215: - -/* Line 1464 of yacc.c */ -#line 1324 "glsl_parser.ypp" - { (yyval.n) = ast_usampler1d; ;} - break; - - case 216: - -/* Line 1464 of yacc.c */ -#line 1325 "glsl_parser.ypp" - { (yyval.n) = ast_usampler2d; ;} - break; - - case 217: - -/* Line 1464 of yacc.c */ -#line 1326 "glsl_parser.ypp" - { (yyval.n) = ast_usampler3d; ;} - break; - - case 218: - -/* Line 1464 of yacc.c */ -#line 1327 "glsl_parser.ypp" - { (yyval.n) = ast_usamplercube; ;} - break; - - case 219: - -/* Line 1464 of yacc.c */ -#line 1328 "glsl_parser.ypp" - { (yyval.n) = ast_usampler1darray; ;} - break; - - case 220: - -/* Line 1464 of yacc.c */ -#line 1329 "glsl_parser.ypp" - { (yyval.n) = ast_usampler2darray; ;} - break; - - case 221: - -/* Line 1464 of yacc.c */ -#line 1333 "glsl_parser.ypp" - { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, - "precision qualifier forbidden " - "in %s (1.30 or later " - "required)\n", - state->version_string); - - (yyval.n) = ast_precision_high; - ;} - break; - - case 222: - -/* Line 1464 of yacc.c */ -#line 1343 "glsl_parser.ypp" - { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, - "precision qualifier forbidden " - "in %s (1.30 or later " - "required)\n", - state->version_string); - - (yyval.n) = ast_precision_medium; - ;} - break; - - case 223: - -/* Line 1464 of yacc.c */ -#line 1353 "glsl_parser.ypp" - { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, - "precision qualifier forbidden " - "in %s (1.30 or later " - "required)\n", - state->version_string); - - (yyval.n) = ast_precision_low; - ;} - break; - - case 224: - -/* Line 1464 of yacc.c */ -#line 1367 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.struct_specifier) = new(ctx) ast_struct_specifier((yyvsp[(2) - (5)].identifier), (yyvsp[(4) - (5)].node)); - (yyval.struct_specifier)->set_location(yylloc); - ;} - break; - - case 225: - -/* Line 1464 of yacc.c */ -#line 1373 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.struct_specifier) = new(ctx) ast_struct_specifier(NULL, (yyvsp[(3) - (4)].node)); - (yyval.struct_specifier)->set_location(yylloc); - ;} - break; - - case 226: - -/* Line 1464 of yacc.c */ -#line 1382 "glsl_parser.ypp" - { - (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].declarator_list); - (yyvsp[(1) - (1)].declarator_list)->link.self_link(); - ;} - break; - - case 227: - -/* Line 1464 of yacc.c */ -#line 1387 "glsl_parser.ypp" - { - (yyval.node) = (ast_node *) (yyvsp[(1) - (2)].node); - (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].declarator_list)->link); - ;} - break; - - case 228: - -/* Line 1464 of yacc.c */ -#line 1395 "glsl_parser.ypp" - { - void *ctx = state; - ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); - type->set_location(yylloc); - - type->specifier = (yyvsp[(1) - (3)].type_specifier); - (yyval.declarator_list) = new(ctx) ast_declarator_list(type); - (yyval.declarator_list)->set_location(yylloc); - - (yyval.declarator_list)->declarations.push_degenerate_list_at_head(& (yyvsp[(2) - (3)].declaration)->link); - ;} - break; - - case 229: - -/* Line 1464 of yacc.c */ -#line 1410 "glsl_parser.ypp" - { - (yyval.declaration) = (yyvsp[(1) - (1)].declaration); - (yyvsp[(1) - (1)].declaration)->link.self_link(); - ;} - break; - - case 230: - -/* Line 1464 of yacc.c */ -#line 1415 "glsl_parser.ypp" - { - (yyval.declaration) = (yyvsp[(1) - (3)].declaration); - (yyval.declaration)->link.insert_before(& (yyvsp[(3) - (3)].declaration)->link); - ;} - break; - - case 231: - -/* Line 1464 of yacc.c */ -#line 1423 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (1)].identifier), false, NULL, NULL); - (yyval.declaration)->set_location(yylloc); - ;} - break; - - case 232: - -/* Line 1464 of yacc.c */ -#line 1429 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (4)].identifier), true, (yyvsp[(3) - (4)].expression), NULL); - (yyval.declaration)->set_location(yylloc); - ;} - break; - - case 235: - -/* Line 1464 of yacc.c */ -#line 1447 "glsl_parser.ypp" - { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} - break; - - case 240: - -/* Line 1464 of yacc.c */ -#line 1455 "glsl_parser.ypp" - { (yyval.node) = NULL; ;} - break; - - case 241: - -/* Line 1464 of yacc.c */ -#line 1456 "glsl_parser.ypp" - { (yyval.node) = NULL; ;} - break; - - case 244: - -/* Line 1464 of yacc.c */ -#line 1463 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.compound_statement) = new(ctx) ast_compound_statement(true, NULL); - (yyval.compound_statement)->set_location(yylloc); - ;} - break; - - case 245: - -/* Line 1464 of yacc.c */ -#line 1469 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.compound_statement) = new(ctx) ast_compound_statement(true, (yyvsp[(2) - (3)].node)); - (yyval.compound_statement)->set_location(yylloc); - ;} - break; - - case 246: - -/* Line 1464 of yacc.c */ -#line 1477 "glsl_parser.ypp" - { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} - break; - - case 248: - -/* Line 1464 of yacc.c */ -#line 1483 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.compound_statement) = new(ctx) ast_compound_statement(false, NULL); - (yyval.compound_statement)->set_location(yylloc); - ;} - break; - - case 249: - -/* Line 1464 of yacc.c */ -#line 1489 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.compound_statement) = new(ctx) ast_compound_statement(false, (yyvsp[(2) - (3)].node)); - (yyval.compound_statement)->set_location(yylloc); - ;} - break; - - case 250: - -/* Line 1464 of yacc.c */ -#line 1498 "glsl_parser.ypp" - { - if ((yyvsp[(1) - (1)].node) == NULL) { - _mesa_glsl_error(& (yylsp[(1) - (1)]), state, " statement\n"); - assert((yyvsp[(1) - (1)].node) != NULL); - } - - (yyval.node) = (yyvsp[(1) - (1)].node); - (yyval.node)->link.self_link(); - ;} - break; - - case 251: - -/* Line 1464 of yacc.c */ -#line 1508 "glsl_parser.ypp" - { - if ((yyvsp[(2) - (2)].node) == NULL) { - _mesa_glsl_error(& (yylsp[(2) - (2)]), state, " statement\n"); - assert((yyvsp[(2) - (2)].node) != NULL); - } - (yyval.node) = (yyvsp[(1) - (2)].node); - (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].node)->link); - ;} - break; - - case 252: - -/* Line 1464 of yacc.c */ -#line 1520 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_expression_statement(NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 253: - -/* Line 1464 of yacc.c */ -#line 1526 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_expression_statement((yyvsp[(1) - (2)].expression)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 254: - -/* Line 1464 of yacc.c */ -#line 1535 "glsl_parser.ypp" - { - (yyval.node) = new(state) ast_selection_statement((yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].selection_rest_statement).then_statement, - (yyvsp[(5) - (5)].selection_rest_statement).else_statement); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 255: - -/* Line 1464 of yacc.c */ -#line 1544 "glsl_parser.ypp" - { - (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (3)].node); - (yyval.selection_rest_statement).else_statement = (yyvsp[(3) - (3)].node); - ;} - break; - - case 256: - -/* Line 1464 of yacc.c */ -#line 1549 "glsl_parser.ypp" - { - (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (1)].node); - (yyval.selection_rest_statement).else_statement = NULL; - ;} - break; - - case 257: - -/* Line 1464 of yacc.c */ -#line 1557 "glsl_parser.ypp" - { - (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].expression); - ;} - break; - - case 258: - -/* Line 1464 of yacc.c */ -#line 1561 "glsl_parser.ypp" - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); - ast_declarator_list *declarator = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); - decl->set_location(yylloc); - declarator->set_location(yylloc); - - declarator->declarations.push_tail(&decl->link); - (yyval.node) = declarator; - ;} - break; - - case 262: - -/* Line 1464 of yacc.c */ -#line 1584 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, - NULL, (yyvsp[(3) - (5)].node), NULL, (yyvsp[(5) - (5)].node)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 263: - -/* Line 1464 of yacc.c */ -#line 1591 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, - NULL, (yyvsp[(5) - (7)].expression), NULL, (yyvsp[(2) - (7)].node)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 264: - -/* Line 1464 of yacc.c */ -#line 1598 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, - (yyvsp[(3) - (6)].node), (yyvsp[(4) - (6)].for_rest_statement).cond, (yyvsp[(4) - (6)].for_rest_statement).rest, (yyvsp[(6) - (6)].node)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 268: - -/* Line 1464 of yacc.c */ -#line 1614 "glsl_parser.ypp" - { - (yyval.node) = NULL; - ;} - break; - - case 269: - -/* Line 1464 of yacc.c */ -#line 1621 "glsl_parser.ypp" - { - (yyval.for_rest_statement).cond = (yyvsp[(1) - (2)].node); - (yyval.for_rest_statement).rest = NULL; - ;} - break; - - case 270: - -/* Line 1464 of yacc.c */ -#line 1626 "glsl_parser.ypp" - { - (yyval.for_rest_statement).cond = (yyvsp[(1) - (3)].node); - (yyval.for_rest_statement).rest = (yyvsp[(3) - (3)].expression); - ;} - break; - - case 271: - -/* Line 1464 of yacc.c */ -#line 1635 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 272: - -/* Line 1464 of yacc.c */ -#line 1641 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 273: - -/* Line 1464 of yacc.c */ -#line 1647 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 274: - -/* Line 1464 of yacc.c */ -#line 1653 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, (yyvsp[(2) - (3)].expression)); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 275: - -/* Line 1464 of yacc.c */ -#line 1659 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); - (yyval.node)->set_location(yylloc); - ;} - break; - - case 276: - -/* Line 1464 of yacc.c */ -#line 1667 "glsl_parser.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].function_definition); ;} - break; - - case 277: - -/* Line 1464 of yacc.c */ -#line 1668 "glsl_parser.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); ;} - break; - - case 278: - -/* Line 1464 of yacc.c */ -#line 1669 "glsl_parser.ypp" - { (yyval.node) = NULL; ;} - break; - - case 279: - -/* Line 1464 of yacc.c */ -#line 1674 "glsl_parser.ypp" - { - void *ctx = state; - (yyval.function_definition) = new(ctx) ast_function_definition(); - (yyval.function_definition)->set_location(yylloc); - (yyval.function_definition)->prototype = (yyvsp[(1) - (2)].function); - (yyval.function_definition)->body = (yyvsp[(2) - (2)].compound_statement); - ;} - break; - - - -/* Line 1464 of yacc.c */ -#line 5154 "glsl_parser.cpp" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (&yylloc, state, YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (&yylloc, state, yymsg); - } - else - { - yyerror (&yylloc, state, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, state); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, state); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, yyerror_range, 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, state, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, state); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, state); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - +/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 1 + +/* Substitute the variable and function names. */ +#define yyparse _mesa_glsl_parse +#define yylex _mesa_glsl_lex +#define yyerror _mesa_glsl_error +#define yylval _mesa_glsl_lval +#define yychar _mesa_glsl_char +#define yydebug _mesa_glsl_debug +#define yynerrs _mesa_glsl_nerrs +#define yylloc _mesa_glsl_lloc + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 1 "glsl_parser.ypp" + +/* + * Copyright © 2008, 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include +#include +#include +#include + +#include "ast.h" +#include "glsl_parser_extras.h" +#include "glsl_types.h" + +#define YYLEX_PARAM state->scanner + + + +/* Line 189 of yacc.c */ +#line 117 "glsl_parser.cpp" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ATTRIBUTE = 258, + CONST_TOK = 259, + BOOL_TOK = 260, + FLOAT_TOK = 261, + INT_TOK = 262, + UINT_TOK = 263, + BREAK = 264, + CONTINUE = 265, + DO = 266, + ELSE = 267, + FOR = 268, + IF = 269, + DISCARD = 270, + RETURN = 271, + SWITCH = 272, + CASE = 273, + DEFAULT = 274, + BVEC2 = 275, + BVEC3 = 276, + BVEC4 = 277, + IVEC2 = 278, + IVEC3 = 279, + IVEC4 = 280, + UVEC2 = 281, + UVEC3 = 282, + UVEC4 = 283, + VEC2 = 284, + VEC3 = 285, + VEC4 = 286, + CENTROID = 287, + IN_TOK = 288, + OUT_TOK = 289, + INOUT_TOK = 290, + UNIFORM = 291, + VARYING = 292, + NOPERSPECTIVE = 293, + FLAT = 294, + SMOOTH = 295, + MAT2X2 = 296, + MAT2X3 = 297, + MAT2X4 = 298, + MAT3X2 = 299, + MAT3X3 = 300, + MAT3X4 = 301, + MAT4X2 = 302, + MAT4X3 = 303, + MAT4X4 = 304, + SAMPLER1D = 305, + SAMPLER2D = 306, + SAMPLER3D = 307, + SAMPLERCUBE = 308, + SAMPLER1DSHADOW = 309, + SAMPLER2DSHADOW = 310, + SAMPLERCUBESHADOW = 311, + SAMPLER1DARRAY = 312, + SAMPLER2DARRAY = 313, + SAMPLER1DARRAYSHADOW = 314, + SAMPLER2DARRAYSHADOW = 315, + ISAMPLER1D = 316, + ISAMPLER2D = 317, + ISAMPLER3D = 318, + ISAMPLERCUBE = 319, + ISAMPLER1DARRAY = 320, + ISAMPLER2DARRAY = 321, + USAMPLER1D = 322, + USAMPLER2D = 323, + USAMPLER3D = 324, + USAMPLERCUBE = 325, + USAMPLER1DARRAY = 326, + USAMPLER2DARRAY = 327, + STRUCT = 328, + VOID_TOK = 329, + WHILE = 330, + IDENTIFIER = 331, + TYPE_IDENTIFIER = 332, + NEW_IDENTIFIER = 333, + FLOATCONSTANT = 334, + INTCONSTANT = 335, + UINTCONSTANT = 336, + BOOLCONSTANT = 337, + FIELD_SELECTION = 338, + LEFT_OP = 339, + RIGHT_OP = 340, + INC_OP = 341, + DEC_OP = 342, + LE_OP = 343, + GE_OP = 344, + EQ_OP = 345, + NE_OP = 346, + AND_OP = 347, + OR_OP = 348, + XOR_OP = 349, + MUL_ASSIGN = 350, + DIV_ASSIGN = 351, + ADD_ASSIGN = 352, + MOD_ASSIGN = 353, + LEFT_ASSIGN = 354, + RIGHT_ASSIGN = 355, + AND_ASSIGN = 356, + XOR_ASSIGN = 357, + OR_ASSIGN = 358, + SUB_ASSIGN = 359, + INVARIANT = 360, + LOWP = 361, + MEDIUMP = 362, + HIGHP = 363, + SUPERP = 364, + PRECISION = 365, + VERSION = 366, + EXTENSION = 367, + LINE = 368, + COLON = 369, + EOL = 370, + INTERFACE = 371, + OUTPUT = 372, + PRAGMA_DEBUG_ON = 373, + PRAGMA_DEBUG_OFF = 374, + PRAGMA_OPTIMIZE_ON = 375, + PRAGMA_OPTIMIZE_OFF = 376, + PRAGMA_INVARIANT_ALL = 377, + LAYOUT_TOK = 378, + ASM = 379, + CLASS = 380, + UNION = 381, + ENUM = 382, + TYPEDEF = 383, + TEMPLATE = 384, + THIS = 385, + PACKED_TOK = 386, + GOTO = 387, + INLINE_TOK = 388, + NOINLINE = 389, + VOLATILE = 390, + PUBLIC_TOK = 391, + STATIC = 392, + EXTERN = 393, + EXTERNAL = 394, + LONG_TOK = 395, + SHORT_TOK = 396, + DOUBLE_TOK = 397, + HALF = 398, + FIXED_TOK = 399, + UNSIGNED = 400, + INPUT_TOK = 401, + OUPTUT = 402, + HVEC2 = 403, + HVEC3 = 404, + HVEC4 = 405, + DVEC2 = 406, + DVEC3 = 407, + DVEC4 = 408, + FVEC2 = 409, + FVEC3 = 410, + FVEC4 = 411, + SAMPLER2DRECT = 412, + SAMPLER3DRECT = 413, + SAMPLER2DRECTSHADOW = 414, + SIZEOF = 415, + CAST = 416, + NAMESPACE = 417, + USING = 418, + ERROR_TOK = 419, + COMMON = 420, + PARTITION = 421, + ACTIVE = 422, + SAMPLERBUFFER = 423, + FILTER = 424, + IMAGE1D = 425, + IMAGE2D = 426, + IMAGE3D = 427, + IMAGECUBE = 428, + IMAGE1DARRAY = 429, + IMAGE2DARRAY = 430, + IIMAGE1D = 431, + IIMAGE2D = 432, + IIMAGE3D = 433, + IIMAGECUBE = 434, + IIMAGE1DARRAY = 435, + IIMAGE2DARRAY = 436, + UIMAGE1D = 437, + UIMAGE2D = 438, + UIMAGE3D = 439, + UIMAGECUBE = 440, + UIMAGE1DARRAY = 441, + UIMAGE2DARRAY = 442, + IMAGE1DSHADOW = 443, + IMAGE2DSHADOW = 444, + IMAGEBUFFER = 445, + IIMAGEBUFFER = 446, + UIMAGEBUFFER = 447, + IMAGE1DARRAYSHADOW = 448, + IMAGE2DARRAYSHADOW = 449, + ROW_MAJOR = 450 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 214 of yacc.c */ +#line 52 "glsl_parser.ypp" + + int n; + float real; + char *identifier; + + struct ast_type_qualifier type_qualifier; + + ast_node *node; + ast_type_specifier *type_specifier; + ast_fully_specified_type *fully_specified_type; + ast_function *function; + ast_parameter_declarator *parameter_declarator; + ast_function_definition *function_definition; + ast_compound_statement *compound_statement; + ast_expression *expression; + ast_declarator_list *declarator_list; + ast_struct_specifier *struct_specifier; + ast_declaration *declaration; + + struct { + ast_node *cond; + ast_expression *rest; + } for_rest_statement; + + struct { + ast_node *then_statement; + ast_node *else_statement; + } selection_rest_statement; + + + +/* Line 214 of yacc.c */ +#line 380 "glsl_parser.cpp" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 405 "glsl_parser.cpp" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 5 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 3692 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 220 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 93 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 291 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 434 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 450 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 204, 2, 2, 2, 208, 211, 2, + 196, 197, 206, 202, 201, 203, 200, 207, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 215, 217, + 209, 216, 210, 214, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 198, 2, 199, 212, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 218, 213, 219, 205, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 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, 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, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 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, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 4, 9, 10, 14, 17, 20, 23, + 26, 29, 30, 33, 35, 37, 39, 45, 47, 50, + 52, 54, 56, 58, 60, 62, 64, 68, 70, 75, + 77, 81, 84, 87, 89, 91, 93, 97, 100, 103, + 106, 108, 111, 115, 118, 120, 122, 124, 127, 130, + 133, 135, 138, 142, 145, 147, 150, 153, 156, 158, + 160, 162, 164, 166, 170, 174, 178, 180, 184, 188, + 190, 194, 198, 200, 204, 208, 212, 216, 218, 222, + 226, 228, 232, 234, 238, 240, 244, 246, 250, 252, + 256, 258, 262, 264, 270, 272, 276, 278, 280, 282, + 284, 286, 288, 290, 292, 294, 296, 298, 300, 304, + 306, 309, 312, 317, 320, 322, 324, 327, 331, 335, + 338, 344, 348, 351, 355, 358, 359, 361, 363, 365, + 367, 369, 373, 379, 386, 394, 403, 409, 411, 414, + 419, 425, 432, 440, 445, 448, 450, 453, 458, 460, + 464, 466, 470, 472, 474, 476, 478, 480, 482, 485, + 487, 490, 493, 497, 499, 501, 503, 505, 508, 510, + 512, 515, 518, 520, 522, 525, 527, 531, 536, 538, + 540, 542, 544, 546, 548, 550, 552, 554, 556, 558, + 560, 562, 564, 566, 568, 570, 572, 574, 576, 578, + 580, 582, 584, 586, 588, 590, 592, 594, 596, 598, + 600, 602, 604, 606, 608, 610, 612, 614, 616, 618, + 620, 622, 624, 626, 628, 630, 632, 634, 636, 638, + 640, 642, 644, 646, 648, 650, 656, 661, 663, 666, + 670, 672, 676, 678, 683, 685, 687, 689, 691, 693, + 695, 697, 699, 701, 703, 705, 708, 709, 714, 716, + 718, 721, 725, 727, 730, 732, 735, 741, 745, 747, + 749, 754, 760, 764, 767, 773, 781, 788, 790, 792, + 794, 795, 798, 802, 805, 808, 811, 815, 818, 820, + 822, 824 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int16 yyrhs[] = +{ + 221, 0, -1, -1, 223, 225, 222, 228, -1, -1, + 111, 80, 115, -1, 118, 115, -1, 119, 115, -1, + 120, 115, -1, 121, 115, -1, 122, 115, -1, -1, + 225, 227, -1, 76, -1, 77, -1, 78, -1, 112, + 226, 114, 226, 115, -1, 311, -1, 228, 311, -1, + 76, -1, 78, -1, 229, -1, 80, -1, 81, -1, + 79, -1, 82, -1, 196, 260, 197, -1, 230, -1, + 231, 198, 232, 199, -1, 233, -1, 231, 200, 226, + -1, 231, 86, -1, 231, 87, -1, 260, -1, 234, + -1, 235, -1, 231, 200, 240, -1, 237, 197, -1, + 236, 197, -1, 238, 74, -1, 238, -1, 238, 258, + -1, 237, 201, 258, -1, 239, 196, -1, 281, -1, + 229, -1, 83, -1, 242, 197, -1, 241, 197, -1, + 243, 74, -1, 243, -1, 243, 258, -1, 242, 201, + 258, -1, 229, 196, -1, 231, -1, 86, 244, -1, + 87, 244, -1, 245, 244, -1, 202, -1, 203, -1, + 204, -1, 205, -1, 244, -1, 246, 206, 244, -1, + 246, 207, 244, -1, 246, 208, 244, -1, 246, -1, + 247, 202, 246, -1, 247, 203, 246, -1, 247, -1, + 248, 84, 247, -1, 248, 85, 247, -1, 248, -1, + 249, 209, 248, -1, 249, 210, 248, -1, 249, 88, + 248, -1, 249, 89, 248, -1, 249, -1, 250, 90, + 249, -1, 250, 91, 249, -1, 250, -1, 251, 211, + 250, -1, 251, -1, 252, 212, 251, -1, 252, -1, + 253, 213, 252, -1, 253, -1, 254, 92, 253, -1, + 254, -1, 255, 94, 254, -1, 255, -1, 256, 93, + 255, -1, 256, -1, 256, 214, 260, 215, 258, -1, + 257, -1, 244, 259, 258, -1, 216, -1, 95, -1, + 96, -1, 98, -1, 97, -1, 104, -1, 99, -1, + 100, -1, 101, -1, 102, -1, 103, -1, 258, -1, + 260, 201, 258, -1, 257, -1, 263, 217, -1, 271, + 217, -1, 110, 285, 282, 217, -1, 264, 197, -1, + 266, -1, 265, -1, 266, 268, -1, 265, 201, 268, + -1, 273, 229, 196, -1, 281, 226, -1, 281, 226, + 198, 261, 199, -1, 278, 269, 267, -1, 269, 267, + -1, 278, 269, 270, -1, 269, 270, -1, -1, 33, + -1, 34, -1, 35, -1, 281, -1, 272, -1, 271, + 201, 226, -1, 271, 201, 226, 198, 199, -1, 271, + 201, 226, 198, 261, 199, -1, 271, 201, 226, 198, + 199, 216, 291, -1, 271, 201, 226, 198, 261, 199, + 216, 291, -1, 271, 201, 226, 216, 291, -1, 273, + -1, 273, 226, -1, 273, 226, 198, 199, -1, 273, + 226, 198, 261, 199, -1, 273, 226, 198, 199, 216, + 291, -1, 273, 226, 198, 261, 199, 216, 291, -1, + 273, 226, 216, 291, -1, 105, 229, -1, 281, -1, + 279, 281, -1, 123, 196, 275, 197, -1, 276, -1, + 275, 201, 276, -1, 226, -1, 226, 216, 80, -1, + 40, -1, 39, -1, 38, -1, 4, -1, 280, -1, + 274, -1, 274, 280, -1, 277, -1, 277, 280, -1, + 105, 280, -1, 105, 277, 280, -1, 105, -1, 4, + -1, 3, -1, 37, -1, 32, 37, -1, 33, -1, + 34, -1, 32, 33, -1, 32, 34, -1, 36, -1, + 282, -1, 285, 282, -1, 283, -1, 283, 198, 199, + -1, 283, 198, 261, 199, -1, 284, -1, 286, -1, + 77, -1, 74, -1, 6, -1, 7, -1, 8, -1, + 5, -1, 29, -1, 30, -1, 31, -1, 20, -1, + 21, -1, 22, -1, 23, -1, 24, -1, 25, -1, + 26, -1, 27, -1, 28, -1, 41, -1, 42, -1, + 43, -1, 44, -1, 45, -1, 46, -1, 47, -1, + 48, -1, 49, -1, 50, -1, 51, -1, 157, -1, + 52, -1, 53, -1, 54, -1, 55, -1, 159, -1, + 56, -1, 57, -1, 58, -1, 59, -1, 60, -1, + 61, -1, 62, -1, 63, -1, 64, -1, 65, -1, + 66, -1, 67, -1, 68, -1, 69, -1, 70, -1, + 71, -1, 72, -1, 108, -1, 107, -1, 106, -1, + 73, 226, 218, 287, 219, -1, 73, 218, 287, 219, + -1, 288, -1, 287, 288, -1, 281, 289, 217, -1, + 290, -1, 289, 201, 290, -1, 226, -1, 226, 198, + 261, 199, -1, 258, -1, 262, -1, 295, -1, 294, + -1, 292, -1, 300, -1, 301, -1, 304, -1, 305, + -1, 306, -1, 310, -1, 218, 219, -1, -1, 218, + 296, 299, 219, -1, 298, -1, 294, -1, 218, 219, + -1, 218, 299, 219, -1, 293, -1, 299, 293, -1, + 217, -1, 260, 217, -1, 14, 196, 260, 197, 302, + -1, 293, 12, 293, -1, 293, -1, 260, -1, 273, + 226, 216, 291, -1, 17, 196, 260, 197, 295, -1, + 18, 260, 215, -1, 19, 215, -1, 75, 196, 303, + 197, 297, -1, 11, 293, 75, 196, 260, 197, 217, + -1, 13, 196, 307, 309, 197, 297, -1, 300, -1, + 292, -1, 303, -1, -1, 308, 217, -1, 308, 217, + 260, -1, 10, 217, -1, 9, 217, -1, 16, 217, + -1, 16, 260, 217, -1, 15, 217, -1, 312, -1, + 262, -1, 224, -1, 263, 298, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 218, 218, 217, 229, 231, 271, 272, 273, 274, + 275, 287, 289, 293, 294, 295, 299, 308, 316, 327, + 328, 332, 339, 346, 353, 360, 367, 374, 375, 381, + 385, 392, 398, 407, 411, 415, 416, 425, 426, 430, + 431, 435, 441, 453, 457, 463, 470, 480, 481, 485, + 486, 490, 496, 508, 519, 520, 526, 532, 542, 543, + 544, 545, 549, 550, 556, 562, 571, 572, 578, 587, + 588, 594, 603, 604, 610, 616, 622, 631, 632, 638, + 647, 648, 657, 658, 667, 668, 677, 678, 687, 688, + 697, 698, 707, 708, 717, 718, 727, 728, 729, 730, + 731, 732, 733, 734, 735, 736, 737, 741, 745, 761, + 765, 770, 774, 783, 787, 788, 792, 797, 805, 819, + 829, 844, 851, 856, 867, 880, 883, 888, 893, 902, + 906, 907, 917, 927, 937, 947, 957, 971, 982, 991, + 1000, 1009, 1018, 1027, 1036, 1050, 1057, 1068, 1075, 1076, + 1095, 1147, 1188, 1193, 1198, 1206, 1214, 1215, 1216, 1221, + 1222, 1227, 1232, 1238, 1246, 1251, 1256, 1261, 1267, 1272, + 1277, 1282, 1287, 1295, 1299, 1307, 1308, 1314, 1323, 1329, + 1335, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, + 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, + 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, + 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, + 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, + 1393, 1394, 1398, 1408, 1418, 1431, 1438, 1447, 1452, 1460, + 1475, 1480, 1488, 1495, 1504, 1508, 1514, 1515, 1519, 1520, + 1521, 1522, 1523, 1524, 1525, 1529, 1536, 1535, 1549, 1550, + 1554, 1560, 1569, 1579, 1591, 1597, 1606, 1615, 1620, 1628, + 1632, 1646, 1650, 1651, 1655, 1662, 1669, 1679, 1680, 1684, + 1686, 1692, 1697, 1706, 1712, 1718, 1724, 1730, 1739, 1740, + 1741, 1745 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "ATTRIBUTE", "CONST_TOK", "BOOL_TOK", + "FLOAT_TOK", "INT_TOK", "UINT_TOK", "BREAK", "CONTINUE", "DO", "ELSE", + "FOR", "IF", "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "BVEC2", + "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", "UVEC2", "UVEC3", "UVEC4", + "VEC2", "VEC3", "VEC4", "CENTROID", "IN_TOK", "OUT_TOK", "INOUT_TOK", + "UNIFORM", "VARYING", "NOPERSPECTIVE", "FLAT", "SMOOTH", "MAT2X2", + "MAT2X3", "MAT2X4", "MAT3X2", "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3", + "MAT4X4", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", + "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", + "SAMPLER1DARRAY", "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW", + "SAMPLER2DARRAYSHADOW", "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D", + "ISAMPLERCUBE", "ISAMPLER1DARRAY", "ISAMPLER2DARRAY", "USAMPLER1D", + "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", "USAMPLER1DARRAY", + "USAMPLER2DARRAY", "STRUCT", "VOID_TOK", "WHILE", "IDENTIFIER", + "TYPE_IDENTIFIER", "NEW_IDENTIFIER", "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", "INVARIANT", "LOWP", "MEDIUMP", "HIGHP", + "SUPERP", "PRECISION", "VERSION", "EXTENSION", "LINE", "COLON", "EOL", + "INTERFACE", "OUTPUT", "PRAGMA_DEBUG_ON", "PRAGMA_DEBUG_OFF", + "PRAGMA_OPTIMIZE_ON", "PRAGMA_OPTIMIZE_OFF", "PRAGMA_INVARIANT_ALL", + "LAYOUT_TOK", "ASM", "CLASS", "UNION", "ENUM", "TYPEDEF", "TEMPLATE", + "THIS", "PACKED_TOK", "GOTO", "INLINE_TOK", "NOINLINE", "VOLATILE", + "PUBLIC_TOK", "STATIC", "EXTERN", "EXTERNAL", "LONG_TOK", "SHORT_TOK", + "DOUBLE_TOK", "HALF", "FIXED_TOK", "UNSIGNED", "INPUT_TOK", "OUPTUT", + "HVEC2", "HVEC3", "HVEC4", "DVEC2", "DVEC3", "DVEC4", "FVEC2", "FVEC3", + "FVEC4", "SAMPLER2DRECT", "SAMPLER3DRECT", "SAMPLER2DRECTSHADOW", + "SIZEOF", "CAST", "NAMESPACE", "USING", "ERROR_TOK", "COMMON", + "PARTITION", "ACTIVE", "SAMPLERBUFFER", "FILTER", "IMAGE1D", "IMAGE2D", + "IMAGE3D", "IMAGECUBE", "IMAGE1DARRAY", "IMAGE2DARRAY", "IIMAGE1D", + "IIMAGE2D", "IIMAGE3D", "IIMAGECUBE", "IIMAGE1DARRAY", "IIMAGE2DARRAY", + "UIMAGE1D", "UIMAGE2D", "UIMAGE3D", "UIMAGECUBE", "UIMAGE1DARRAY", + "UIMAGE2DARRAY", "IMAGE1DSHADOW", "IMAGE2DSHADOW", "IMAGEBUFFER", + "IIMAGEBUFFER", "UIMAGEBUFFER", "IMAGE1DARRAYSHADOW", + "IMAGE2DARRAYSHADOW", "ROW_MAJOR", "'('", "')'", "'['", "']'", "'.'", + "','", "'+'", "'-'", "'!'", "'~'", "'*'", "'/'", "'%'", "'<'", "'>'", + "'&'", "'^'", "'|'", "'?'", "':'", "'='", "';'", "'{'", "'}'", "$accept", + "translation_unit", "$@1", "version_statement", "pragma_statement", + "extension_statement_list", "any_identifier", "extension_statement", + "external_declaration_list", "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", "method_call_generic", + "method_call_header_no_parameters", "method_call_header_with_parameters", + "method_call_header", "unary_expression", "unary_operator", + "multiplicative_expression", "additive_expression", "shift_expression", + "relational_expression", "equality_expression", "and_expression", + "exclusive_or_expression", "inclusive_or_expression", + "logical_and_expression", "logical_xor_expression", + "logical_or_expression", "conditional_expression", + "assignment_expression", "assignment_operator", "expression", + "constant_expression", "declaration", "function_prototype", + "function_declarator", "function_header_with_parameters", + "function_header", "parameter_declarator", "parameter_declaration", + "parameter_qualifier", "parameter_type_specifier", + "init_declarator_list", "single_declaration", "fully_specified_type", + "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id", + "interpolation_qualifier", "parameter_type_qualifier", "type_qualifier", + "storage_qualifier", "type_specifier", "type_specifier_no_prec", + "type_specifier_nonarray", "basic_type_specifier_nonarray", + "precision_qualifier", "struct_specifier", "struct_declaration_list", + "struct_declaration", "struct_declarator_list", "struct_declarator", + "initializer", "declaration_statement", "statement", "simple_statement", + "compound_statement", "$@2", "statement_no_new_scope", + "compound_statement_no_new_scope", "statement_list", + "expression_statement", "selection_statement", + "selection_rest_statement", "condition", "switch_statement", + "case_label", "iteration_statement", "for_init_statement", + "conditionopt", "for_rest_statement", "jump_statement", + "external_declaration", "function_definition", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 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, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 40, 41, 91, 93, + 46, 44, 43, 45, 33, 126, 42, 47, 37, 60, + 62, 38, 94, 124, 63, 58, 61, 59, 123, 125 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 220, 222, 221, 223, 223, 224, 224, 224, 224, + 224, 225, 225, 226, 226, 226, 227, 228, 228, 229, + 229, 230, 230, 230, 230, 230, 230, 231, 231, 231, + 231, 231, 231, 232, 233, 234, 234, 235, 235, 236, + 236, 237, 237, 238, 239, 239, 239, 240, 240, 241, + 241, 242, 242, 243, 244, 244, 244, 244, 245, 245, + 245, 245, 246, 246, 246, 246, 247, 247, 247, 248, + 248, 248, 249, 249, 249, 249, 249, 250, 250, 250, + 251, 251, 252, 252, 253, 253, 254, 254, 255, 255, + 256, 256, 257, 257, 258, 258, 259, 259, 259, 259, + 259, 259, 259, 259, 259, 259, 259, 260, 260, 261, + 262, 262, 262, 263, 264, 264, 265, 265, 266, 267, + 267, 268, 268, 268, 268, 269, 269, 269, 269, 270, + 271, 271, 271, 271, 271, 271, 271, 272, 272, 272, + 272, 272, 272, 272, 272, 273, 273, 274, 275, 275, + 276, 276, 277, 277, 277, 278, 279, 279, 279, 279, + 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 281, 281, 282, 282, 282, 283, 283, + 283, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 285, 285, 285, 286, 286, 287, 287, 288, + 289, 289, 290, 290, 291, 292, 293, 293, 294, 294, + 294, 294, 294, 294, 294, 295, 296, 295, 297, 297, + 298, 298, 299, 299, 300, 300, 301, 302, 302, 303, + 303, 304, 305, 305, 306, 306, 306, 307, 307, 308, + 308, 309, 309, 310, 310, 310, 310, 310, 311, 311, + 311, 312 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 4, 0, 3, 2, 2, 2, 2, + 2, 0, 2, 1, 1, 1, 5, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 3, 1, 4, 1, + 3, 2, 2, 1, 1, 1, 3, 2, 2, 2, + 1, 2, 3, 2, 1, 1, 1, 2, 2, 2, + 1, 2, 3, 2, 1, 2, 2, 2, 1, 1, + 1, 1, 1, 3, 3, 3, 1, 3, 3, 1, + 3, 3, 1, 3, 3, 3, 3, 1, 3, 3, + 1, 3, 1, 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, 4, 2, 1, 1, 2, 3, 3, 2, + 5, 3, 2, 3, 2, 0, 1, 1, 1, 1, + 1, 3, 5, 6, 7, 8, 5, 1, 2, 4, + 5, 6, 7, 4, 2, 1, 2, 4, 1, 3, + 1, 3, 1, 1, 1, 1, 1, 1, 2, 1, + 2, 2, 3, 1, 1, 1, 1, 2, 1, 1, + 2, 2, 1, 1, 2, 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, 1, 5, 4, 1, 2, 3, + 1, 3, 1, 4, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 0, 4, 1, 1, + 2, 3, 1, 2, 1, 2, 5, 3, 1, 1, + 4, 5, 3, 2, 5, 7, 6, 1, 1, 1, + 0, 2, 3, 2, 2, 2, 3, 2, 1, 1, + 1, 2 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 4, 0, 0, 11, 0, 1, 2, 5, 0, 0, + 12, 13, 14, 15, 0, 165, 164, 185, 182, 183, + 184, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 186, 187, 188, 0, 168, 169, 172, 166, 154, 153, + 152, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 210, 211, 212, 213, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 0, 181, 180, 163, 234, 233, 232, + 0, 0, 0, 0, 0, 0, 0, 209, 214, 290, + 3, 289, 0, 0, 115, 125, 0, 130, 137, 157, + 159, 0, 156, 145, 173, 175, 178, 0, 179, 17, + 288, 0, 170, 171, 167, 0, 0, 19, 20, 144, + 0, 161, 0, 6, 7, 8, 9, 10, 0, 18, + 110, 0, 291, 113, 125, 155, 126, 127, 128, 116, + 0, 125, 0, 111, 13, 15, 138, 0, 158, 160, + 146, 0, 174, 0, 0, 0, 237, 0, 162, 0, + 150, 0, 148, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 22, 23, 25, 46, 0, + 0, 0, 58, 59, 60, 61, 264, 256, 260, 21, + 27, 54, 29, 34, 35, 0, 0, 40, 0, 62, + 0, 66, 69, 72, 77, 80, 82, 84, 86, 88, + 90, 92, 94, 107, 0, 245, 0, 145, 248, 262, + 247, 246, 0, 249, 250, 251, 252, 253, 254, 117, + 122, 124, 129, 0, 131, 0, 0, 118, 176, 62, + 109, 0, 44, 16, 242, 0, 240, 236, 238, 0, + 112, 0, 147, 0, 284, 283, 0, 0, 0, 287, + 285, 0, 0, 0, 273, 0, 55, 56, 0, 255, + 0, 31, 32, 0, 0, 38, 37, 0, 181, 41, + 43, 97, 98, 100, 99, 102, 103, 104, 105, 106, + 101, 96, 0, 57, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 265, 261, 263, 119, 121, + 123, 0, 0, 139, 0, 244, 143, 177, 0, 0, + 239, 235, 151, 149, 0, 278, 277, 280, 0, 286, + 0, 272, 163, 269, 0, 0, 26, 0, 0, 33, + 30, 0, 36, 0, 0, 50, 42, 95, 63, 64, + 65, 67, 68, 70, 71, 75, 76, 73, 74, 78, + 79, 81, 83, 85, 87, 89, 91, 0, 108, 0, + 132, 0, 136, 0, 140, 0, 241, 0, 279, 0, + 0, 0, 0, 0, 0, 257, 28, 53, 48, 47, + 0, 181, 51, 0, 0, 0, 133, 141, 0, 243, + 0, 281, 0, 268, 266, 271, 0, 259, 274, 258, + 52, 93, 120, 134, 0, 142, 0, 282, 276, 0, + 270, 135, 275, 267 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 2, 9, 3, 89, 6, 160, 10, 90, 189, + 190, 191, 348, 192, 193, 194, 195, 196, 197, 198, + 352, 353, 354, 355, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 292, + 214, 241, 215, 216, 93, 94, 95, 230, 139, 140, + 231, 96, 97, 98, 99, 161, 162, 100, 141, 101, + 102, 242, 104, 105, 106, 107, 108, 155, 156, 245, + 246, 326, 218, 219, 220, 221, 270, 418, 419, 222, + 223, 224, 414, 345, 225, 226, 227, 337, 389, 390, + 228, 109, 110 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -366 +static const yytype_int16 yypact[] = +{ + -57, -43, 62, -366, -50, -366, -30, -366, 67, 3341, + -366, -366, -366, -366, -6, -366, -366, -366, -366, -366, + -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, + -366, -366, -366, 8, -366, -366, -366, -366, -366, -366, + -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, + -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, + -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, + -366, -366, -366, -65, -366, -366, 226, -366, -366, -366, + 51, -31, -28, 6, 13, 15, -44, -366, -366, -366, + 3341, -366, -183, -47, -29, 18, -169, -366, 140, 24, + 24, 3460, -366, -366, -366, -24, -366, 3533, -366, -366, + -366, 67, -366, -366, -366, 3460, -48, -366, -366, -366, + 24, -366, 3533, -366, -366, -366, -366, -366, 67, -366, + -366, 408, -366, -366, 55, -366, -366, -366, -366, -366, + 3460, 200, 67, -366, -20, -18, -178, 23, -366, -366, + -366, 2225, -366, 72, 67, 1598, -366, 3460, -366, 4, + 10, -84, -366, 11, 14, 1059, 40, 42, 29, 1836, + 43, 2783, 34, 54, -366, -366, -366, -366, -366, 2783, + 2783, 2783, -366, -366, -366, -366, -366, 32, -366, 56, + -366, -71, -366, -366, -366, 57, -81, 2969, 61, -27, + 2783, 35, -88, -41, -70, 33, 60, 41, 59, 181, + 180, -89, -366, -366, -168, -366, 58, 80, -366, -366, + -366, -366, 625, -366, -366, -366, -366, -366, -366, -366, + -366, -366, 67, 3460, -177, 2411, 2783, -366, -366, -366, + -366, 78, -366, -366, 81, -137, -366, -366, -366, 1717, + -366, 201, -366, 67, -366, -366, 205, 1478, 2783, -366, + -366, -134, 2783, -115, -366, 2039, -366, -366, -60, -366, + 1059, -366, -366, 2783, 140, -366, -366, 2783, 85, -366, + -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, + -366, -366, 2783, -366, 2783, 2783, 2783, 2783, 2783, 2783, + 2783, 2783, 2783, 2783, 2783, 2783, 2783, 2783, 2783, 2783, + 2783, 2783, 2783, 2783, 2783, -366, -366, -366, 86, -366, + -366, 2597, 2783, 69, 87, -366, -366, -366, 2783, 67, + -366, -366, -366, -366, 91, -366, -366, 2039, -59, -366, + -46, -366, 129, 88, 67, 93, -366, 842, 89, 88, + -366, 95, -366, 96, -37, 3155, -366, -366, -366, -366, + -366, 35, 35, -88, -88, -41, -41, -41, -41, -70, + -70, 33, 60, 41, 59, 181, 180, -96, -366, 2783, + 76, 97, -366, 2783, 79, 98, -366, 2783, -366, 77, + 101, 1059, 83, 90, 1275, -366, -366, -366, -366, -366, + 2783, 102, -366, 2783, 108, 2783, 94, -366, 2783, -366, + -26, 2783, 1275, 297, -366, -366, 2783, -366, -366, -366, + -366, -366, -366, -366, 2783, -366, 100, 88, -366, 1059, + -366, -366, -366, -366 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -366, -366, -366, -366, -366, -366, -7, -366, -366, -62, + -366, -366, -366, -366, -366, -366, -366, -366, -366, -366, + -366, -366, -366, -366, -101, -366, -113, -109, -121, -61, + 5, 3, 9, 16, 2, 7, -366, -142, -100, -366, + -164, -225, 21, 22, -366, -366, -366, 82, 186, 173, + 92, -366, -366, -242, -366, -366, 68, -73, -366, -366, + -74, -9, -67, -366, -366, 243, -366, 170, -147, -366, + 0, -298, 73, -159, -365, -58, -366, -80, 239, 63, + 84, -366, -366, -2, -366, -366, -366, -366, -366, -366, + -366, 246, -366 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -115 +static const yytype_int16 yytable[] = +{ + 103, 14, 121, 120, 312, 261, 256, 263, 248, 240, + 324, 11, 12, 13, 119, 271, 272, 268, 301, 302, + 235, 321, 135, 344, 382, 148, 149, 15, 16, 417, + 91, 92, 142, 314, 130, 131, 147, 4, 236, 322, + 152, 112, 113, 299, 300, 114, 158, 417, 143, 315, + 239, 136, 137, 138, 1, 159, 33, 34, 35, 135, + 36, 37, 5, 317, 329, 7, 116, 314, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 266, 267, + 330, 103, 8, 339, 123, 407, 314, 124, 136, 137, + 138, 146, 150, 240, 338, 344, 381, 279, 340, 293, + 341, 343, 248, 385, 153, 314, 154, 423, 111, 349, + 425, 91, 92, 252, 297, 298, 276, 253, 430, 403, + 277, 125, 217, 305, 306, 313, 431, 273, 126, 274, + 127, 232, 15, 16, 239, 234, 325, 346, 391, 303, + 304, 314, 314, 11, 12, 13, 154, 244, 154, 377, + 133, 392, 128, 115, 404, 314, 217, 77, 78, 79, + 399, 33, 34, 35, 400, 36, 37, 38, 39, 40, + 157, 426, 134, 343, 151, 314, -19, 356, -20, 240, + 365, 366, 367, 368, 361, 362, 240, 243, 317, 291, + 363, 364, 357, 358, 359, 360, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 351, 217, 378, -114, 144, 12, 145, 237, + 239, 250, 325, 410, 232, 318, 251, 239, 254, 15, + 16, 255, 413, 136, 137, 138, 257, 240, 258, 262, + 154, 294, 295, 296, 369, 370, 259, 427, 217, 264, + 265, 269, -45, 308, 275, 402, 217, 280, 33, 34, + 35, 217, 36, 37, 38, 39, 40, 350, 121, 120, + 433, 307, 309, 310, 311, 130, -44, 327, 239, 328, + 334, 332, -39, 325, 379, 383, 384, 387, 396, 314, + 394, 397, 405, 398, 411, 408, 406, 409, 412, -49, + 420, 187, 117, 421, 118, 325, 416, 422, 325, 429, + 424, 372, 371, 375, 233, 319, 325, 432, 373, 376, + 229, 333, 244, 122, 325, 320, 374, 249, 217, 386, + 335, 132, 428, 347, 415, 388, 129, 393, 217, 0, + 0, 336, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 217, 0, 0, 217, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, + 0, 15, 16, 17, 18, 19, 20, 163, 164, 165, + 217, 166, 167, 168, 169, 170, 171, 172, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 0, 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, 173, 117, 75, 118, 174, 175, 176, + 177, 178, 0, 0, 179, 180, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 76, 77, 78, 79, 0, 80, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 87, 0, 88, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 181, 0, 0, 0, 0, 0, + 182, 183, 184, 185, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 186, 187, 188, 15, 16, + 17, 18, 19, 20, 163, 164, 165, 0, 166, 167, + 168, 169, 170, 171, 172, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 0, 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, + 173, 117, 75, 118, 174, 175, 176, 177, 178, 0, + 0, 179, 180, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 76, 77, 78, 79, 0, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 0, 88, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 181, 0, 0, 0, 0, 0, 182, 183, 184, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 186, 187, 316, 15, 16, 17, 18, 19, + 20, 163, 164, 165, 0, 166, 167, 168, 169, 170, + 171, 172, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 0, 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, 173, 117, 75, + 118, 174, 175, 176, 177, 178, 0, 0, 179, 180, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 76, 77, 78, + 79, 0, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, + 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 181, 0, + 0, 0, 0, 0, 182, 183, 184, 185, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, + 187, 395, 15, 16, 17, 18, 19, 20, 163, 164, + 165, 0, 166, 167, 168, 169, 170, 171, 172, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 0, 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, 173, 117, 75, 118, 174, 175, + 176, 177, 178, 0, 0, 179, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 76, 77, 78, 79, 0, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 87, 0, 88, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 181, 0, 0, 0, 0, + 0, 182, 183, 184, 185, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 186, 187, 15, 16, + 17, 18, 19, 20, 163, 164, 165, 0, 166, 167, + 168, 169, 170, 171, 172, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 0, 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, + 173, 117, 75, 118, 174, 175, 176, 177, 178, 0, + 0, 179, 180, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 76, 77, 78, 79, 0, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 0, 88, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 181, 0, 0, 0, 0, 0, 182, 183, 184, + 185, 15, 16, 17, 18, 19, 20, 0, 0, 0, + 0, 0, 186, 131, 0, 0, 0, 0, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 0, 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, 0, 117, 75, 118, 174, 175, 176, + 177, 178, 0, 0, 179, 180, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 76, 77, 78, 79, 0, 80, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 17, 18, 19, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 0, 0, 0, 0, 0, 87, 0, 88, 0, 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, 0, 181, 75, 0, 0, 0, 0, + 182, 183, 184, 185, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 78, 79, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 18, 19, 20, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, + 0, 0, 0, 0, 0, 87, 0, 88, 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, 0, 0, 75, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, + 0, 0, 0, 77, 78, 79, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, 19, 20, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, + 0, 0, 0, 0, 87, 0, 88, 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, 0, 117, 75, 118, 174, 175, 176, 177, 178, + 0, 0, 179, 180, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, + 0, 0, 77, 78, 79, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 87, 0, 88, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 181, 0, 0, 0, 0, 0, 182, 183, + 184, 185, 15, 16, 17, 18, 19, 20, 0, 0, + 0, 0, 0, 260, 0, 0, 0, 0, 0, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 0, 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, 0, 117, 75, 118, 174, 175, + 176, 177, 178, 0, 0, 179, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 342, 77, 78, 79, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 87, 0, 88, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 18, 19, 20, 0, 181, 0, 0, 0, 0, + 0, 182, 183, 184, 185, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, + 0, 117, 75, 118, 174, 175, 176, 177, 178, 0, + 0, 179, 180, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 78, 79, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 0, 88, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, + 0, 181, 0, 0, 238, 0, 0, 182, 183, 184, + 185, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 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, 0, 117, 75, 118, + 174, 175, 176, 177, 178, 0, 0, 179, 180, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 77, 78, 79, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, + 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 18, 19, 20, 0, 181, 0, 0, + 323, 0, 0, 182, 183, 184, 185, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 117, 75, 118, 174, 175, 176, 177, + 178, 0, 0, 179, 180, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 77, 78, 79, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 87, 0, 88, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, + 19, 20, 0, 181, 0, 0, 380, 0, 0, 182, + 183, 184, 185, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 0, 117, + 75, 118, 174, 175, 176, 177, 178, 0, 0, 179, + 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, + 78, 79, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 87, 0, 88, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 18, 19, 20, 0, 181, + 0, 0, 0, 0, 0, 182, 183, 184, 185, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 278, 0, 117, 75, 118, 174, 175, + 176, 177, 178, 0, 0, 179, 180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 77, 78, 79, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 87, 0, 88, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 18, 19, 20, 0, 181, 0, 0, 0, 0, + 0, 182, 183, 184, 185, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 401, + 0, 117, 75, 118, 174, 175, 176, 177, 178, 0, + 0, 179, 180, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 78, 79, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 87, 0, 88, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 16, 17, 18, 19, 20, + 0, 181, 0, 0, 0, 0, 0, 182, 183, 184, + 185, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 0, 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, 0, 0, 75, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 76, 77, 78, 79, + 0, 80, 0, 0, 0, 0, 0, 0, 0, 81, + 82, 83, 84, 85, 86, 17, 18, 19, 20, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 0, 0, 0, 0, 0, 0, 87, 0, + 88, 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, 0, 0, 75, 17, 18, + 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 0, 77, 78, 79, 0, + 0, 0, 0, 0, 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, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 87, 0, 88, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 87, 0, 88 +}; + +static const yytype_int16 yycheck[] = +{ + 9, 8, 76, 76, 93, 169, 165, 171, 155, 151, + 235, 76, 77, 78, 76, 86, 87, 181, 88, 89, + 198, 198, 4, 265, 322, 99, 100, 3, 4, 394, + 9, 9, 201, 201, 217, 218, 98, 80, 216, 216, + 107, 33, 34, 84, 85, 37, 120, 412, 217, 217, + 151, 33, 34, 35, 111, 122, 32, 33, 34, 4, + 36, 37, 0, 222, 201, 115, 73, 201, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 179, 180, + 217, 90, 112, 217, 115, 383, 201, 115, 33, 34, + 35, 98, 101, 235, 258, 337, 321, 197, 262, 200, + 215, 265, 249, 328, 111, 201, 115, 405, 114, 273, + 408, 90, 90, 197, 202, 203, 197, 201, 416, 215, + 201, 115, 131, 90, 91, 214, 424, 198, 115, 200, + 115, 140, 3, 4, 235, 142, 236, 197, 197, 209, + 210, 201, 201, 76, 77, 78, 155, 154, 157, 313, + 197, 197, 196, 218, 379, 201, 165, 106, 107, 108, + 197, 32, 33, 34, 201, 36, 37, 38, 39, 40, + 218, 197, 201, 337, 198, 201, 196, 277, 196, 321, + 301, 302, 303, 304, 297, 298, 328, 115, 347, 216, + 299, 300, 292, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 274, 222, 314, 197, 76, 77, 78, 196, + 321, 217, 322, 387, 233, 232, 216, 328, 217, 3, + 4, 217, 391, 33, 34, 35, 196, 379, 196, 196, + 249, 206, 207, 208, 305, 306, 217, 411, 257, 215, + 196, 219, 196, 212, 197, 355, 265, 196, 32, 33, + 34, 270, 36, 37, 38, 39, 40, 274, 342, 342, + 429, 211, 213, 92, 94, 217, 196, 199, 379, 198, + 75, 80, 197, 383, 198, 216, 199, 196, 199, 201, + 197, 196, 216, 197, 217, 216, 199, 199, 197, 197, + 400, 218, 76, 403, 78, 405, 216, 199, 408, 12, + 216, 308, 307, 311, 141, 233, 416, 217, 309, 312, + 134, 253, 329, 80, 424, 233, 310, 157, 337, 329, + 257, 92, 412, 270, 392, 337, 90, 344, 347, -1, + -1, 257, -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, 391, -1, -1, 394, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 412, -1, -1, -1, -1, -1, -1, + -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 429, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, -1, 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, 76, 77, 78, 79, 80, 81, + 82, 83, -1, -1, 86, 87, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, -1, 110, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 123, -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, 157, -1, 159, -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, 196, -1, -1, -1, -1, -1, + 202, 203, 204, 205, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 217, 218, 219, 3, 4, + 5, 6, 7, 8, 9, 10, 11, -1, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + -1, 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, 76, 77, 78, 79, 80, 81, 82, 83, -1, + -1, 86, 87, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 105, 106, 107, 108, -1, 110, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 123, -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, 157, -1, 159, -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, 196, -1, -1, -1, -1, -1, 202, 203, 204, + 205, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 217, 218, 219, 3, 4, 5, 6, 7, + 8, 9, 10, 11, -1, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, -1, 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, 76, 77, + 78, 79, 80, 81, 82, 83, -1, -1, 86, 87, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, + 108, -1, 110, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 123, -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, 157, + -1, 159, -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, 196, -1, + -1, -1, -1, -1, 202, 203, 204, 205, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 217, + 218, 219, 3, 4, 5, 6, 7, 8, 9, 10, + 11, -1, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, -1, 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, 76, 77, 78, 79, 80, + 81, 82, 83, -1, -1, 86, 87, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 105, 106, 107, 108, -1, 110, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 123, -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, 157, -1, 159, -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, 196, -1, -1, -1, -1, + -1, 202, 203, 204, 205, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 217, 218, 3, 4, + 5, 6, 7, 8, 9, 10, 11, -1, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + -1, 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, 76, 77, 78, 79, 80, 81, 82, 83, -1, + -1, 86, 87, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 105, 106, 107, 108, -1, 110, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 123, -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, 157, -1, 159, -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, 196, -1, -1, -1, -1, -1, 202, 203, 204, + 205, 3, 4, 5, 6, 7, 8, -1, -1, -1, + -1, -1, 217, 218, -1, -1, -1, -1, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, -1, 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, -1, 76, 77, 78, 79, 80, 81, + 82, 83, -1, -1, 86, 87, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 105, 106, 107, 108, -1, 110, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 123, -1, 5, 6, 7, 8, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + -1, -1, -1, -1, -1, 157, -1, 159, -1, 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, -1, 196, 77, -1, -1, -1, -1, + 202, 203, 204, 205, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 217, -1, -1, -1, -1, + -1, -1, -1, -1, 106, 107, 108, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 5, 6, 7, 8, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, + -1, -1, -1, -1, -1, 157, -1, 159, 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, -1, -1, 77, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 219, -1, -1, + -1, -1, -1, 106, 107, 108, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5, 6, 7, 8, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, + -1, -1, -1, -1, 157, -1, 159, 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, -1, 76, 77, 78, 79, 80, 81, 82, 83, + -1, -1, 86, 87, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 219, -1, -1, -1, + -1, -1, 106, 107, 108, -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, 157, -1, 159, -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, 196, -1, -1, -1, -1, -1, 202, 203, + 204, 205, 3, 4, 5, 6, 7, 8, -1, -1, + -1, -1, -1, 217, -1, -1, -1, -1, -1, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, -1, 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, -1, 76, 77, 78, 79, 80, + 81, 82, 83, -1, -1, 86, 87, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 105, 106, 107, 108, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 123, -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, 157, -1, 159, -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, + 5, 6, 7, 8, -1, 196, -1, -1, -1, -1, + -1, 202, 203, 204, 205, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 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, + -1, 76, 77, 78, 79, 80, 81, 82, 83, -1, + -1, 86, 87, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 106, 107, 108, -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, 157, -1, 159, -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, 5, 6, 7, 8, + -1, 196, -1, -1, 199, -1, -1, 202, 203, 204, + 205, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 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, -1, 76, 77, 78, + 79, 80, 81, 82, 83, -1, -1, 86, 87, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 106, 107, 108, + -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, 157, -1, + 159, -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, 5, 6, 7, 8, -1, 196, -1, -1, + 199, -1, -1, 202, 203, 204, 205, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 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, -1, 76, 77, 78, 79, 80, 81, 82, + 83, -1, -1, 86, 87, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 106, 107, 108, -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, 157, -1, 159, -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, 5, 6, + 7, 8, -1, 196, -1, -1, 199, -1, -1, 202, + 203, 204, 205, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 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, -1, 76, + 77, 78, 79, 80, 81, 82, 83, -1, -1, 86, + 87, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 106, + 107, 108, -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, + 157, -1, 159, -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, 5, 6, 7, 8, -1, 196, + -1, -1, -1, -1, -1, 202, 203, 204, 205, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 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, -1, 76, 77, 78, 79, 80, + 81, 82, 83, -1, -1, 86, 87, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 106, 107, 108, -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, 157, -1, 159, -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, + 5, 6, 7, 8, -1, 196, -1, -1, -1, -1, + -1, 202, 203, 204, 205, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 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, + -1, 76, 77, 78, 79, 80, 81, 82, 83, -1, + -1, 86, 87, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 106, 107, 108, -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, 157, -1, 159, -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, 3, 4, 5, 6, 7, 8, + -1, 196, -1, -1, -1, -1, -1, 202, 203, 204, + 205, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, -1, 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, -1, -1, 77, -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, 105, 106, 107, 108, + -1, 110, -1, -1, -1, -1, -1, -1, -1, 118, + 119, 120, 121, 122, 123, 5, 6, 7, 8, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, -1, -1, -1, -1, -1, -1, 157, -1, + 159, 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, -1, -1, 77, 5, 6, + 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, -1, 106, 107, 108, -1, + -1, -1, -1, -1, 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, -1, -1, + 77, -1, -1, -1, -1, -1, -1, 157, -1, 159, + -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, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 157, -1, 159 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint16 yystos[] = +{ + 0, 111, 221, 223, 80, 0, 225, 115, 112, 222, + 227, 76, 77, 78, 226, 3, 4, 5, 6, 7, + 8, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 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, 77, 105, 106, 107, 108, + 110, 118, 119, 120, 121, 122, 123, 157, 159, 224, + 228, 262, 263, 264, 265, 266, 271, 272, 273, 274, + 277, 279, 280, 281, 282, 283, 284, 285, 286, 311, + 312, 114, 33, 34, 37, 218, 226, 76, 78, 229, + 277, 280, 285, 115, 115, 115, 115, 115, 196, 311, + 217, 218, 298, 197, 201, 4, 33, 34, 35, 268, + 269, 278, 201, 217, 76, 78, 226, 229, 280, 280, + 281, 198, 282, 226, 281, 287, 288, 218, 280, 282, + 226, 275, 276, 9, 10, 11, 13, 14, 15, 16, + 17, 18, 19, 75, 79, 80, 81, 82, 83, 86, + 87, 196, 202, 203, 204, 205, 217, 218, 219, 229, + 230, 231, 233, 234, 235, 236, 237, 238, 239, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 260, 262, 263, 281, 292, 293, + 294, 295, 299, 300, 301, 304, 305, 306, 310, 268, + 267, 270, 281, 269, 226, 198, 216, 196, 199, 244, + 257, 261, 281, 115, 226, 289, 290, 219, 288, 287, + 217, 216, 197, 201, 217, 217, 293, 196, 196, 217, + 217, 260, 196, 260, 215, 196, 244, 244, 260, 219, + 296, 86, 87, 198, 200, 197, 197, 201, 74, 258, + 196, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 216, 259, 244, 206, 207, 208, 202, 203, 84, + 85, 88, 89, 209, 210, 90, 91, 211, 212, 213, + 92, 94, 93, 214, 201, 217, 219, 293, 226, 267, + 270, 198, 216, 199, 261, 258, 291, 199, 198, 201, + 217, 219, 80, 276, 75, 292, 300, 307, 260, 217, + 260, 215, 105, 260, 273, 303, 197, 299, 232, 260, + 226, 229, 240, 241, 242, 243, 258, 258, 244, 244, + 244, 246, 246, 247, 247, 248, 248, 248, 248, 249, + 249, 250, 251, 252, 253, 254, 255, 260, 258, 198, + 199, 261, 291, 216, 199, 261, 290, 196, 303, 308, + 309, 197, 197, 226, 197, 219, 199, 196, 197, 197, + 201, 74, 258, 215, 261, 216, 199, 291, 216, 199, + 260, 217, 197, 293, 302, 295, 216, 294, 297, 298, + 258, 258, 199, 291, 216, 291, 197, 260, 297, 12, + 291, 291, 217, 293 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, &yylloc, scanner) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, Location, state); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + struct _mesa_glsl_parse_state *state; +#endif +{ + if (!yyvaluep) + return; + YYUSE (yylocationp); + YYUSE (state); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct _mesa_glsl_parse_state *state) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + struct _mesa_glsl_parse_state *state; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct _mesa_glsl_parse_state *state) +#else +static void +yy_reduce_print (yyvsp, yylsp, yyrule, state) + YYSTYPE *yyvsp; + YYLTYPE *yylsp; + int yyrule; + struct _mesa_glsl_parse_state *state; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , &(yylsp[(yyi + 1) - (yynrhs)]) , state); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, yylsp, Rule, state); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct _mesa_glsl_parse_state *state) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, yylocationp, state) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + YYLTYPE *yylocationp; + struct _mesa_glsl_parse_state *state; +#endif +{ + YYUSE (yyvaluep); + YYUSE (yylocationp); + YYUSE (state); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (struct _mesa_glsl_parse_state *state); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (struct _mesa_glsl_parse_state *state) +#else +int +yyparse (state) + struct _mesa_glsl_parse_state *state; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Location data for the lookahead symbol. */ +YYLTYPE yylloc; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[3]; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + YYLTYPE yyloc; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + yylsp = yyls; + +#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL + /* Initialize the default location before parsing starts. */ + yylloc.first_line = yylloc.last_line = 1; + yylloc.first_column = yylloc.last_column = 1; +#endif + +/* User initialization code. */ + +/* Line 1251 of yacc.c */ +#line 41 "glsl_parser.ypp" +{ + yylloc.first_line = 1; + yylloc.first_column = 1; + yylloc.last_line = 1; + yylloc.last_column = 1; + yylloc.source = 0; +} + +/* Line 1251 of yacc.c */ +#line 2657 "glsl_parser.cpp" + yylsp[0] = yylloc; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + + yyls = yyls1; + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + *++yylsp = yylloc; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: + +/* Line 1464 of yacc.c */ +#line 218 "glsl_parser.ypp" + { + _mesa_glsl_initialize_types(state); + ;} + break; + + case 3: + +/* Line 1464 of yacc.c */ +#line 222 "glsl_parser.ypp" + { + delete state->symbols; + state->symbols = new(ralloc_parent(state)) glsl_symbol_table; + _mesa_glsl_initialize_types(state); + ;} + break; + + case 5: + +/* Line 1464 of yacc.c */ +#line 232 "glsl_parser.ypp" + { + bool supported = false; + + switch ((yyvsp[(2) - (3)].n)) { + case 100: + state->es_shader = true; + supported = state->Const.GLSL_100ES; + break; + case 110: + supported = state->Const.GLSL_110; + break; + case 120: + supported = state->Const.GLSL_120; + break; + case 130: + supported = state->Const.GLSL_130; + break; + default: + supported = false; + break; + } + + state->language_version = (yyvsp[(2) - (3)].n); + state->version_string = + ralloc_asprintf(state, "GLSL%s %d.%02d", + state->es_shader ? " ES" : "", + state->language_version / 100, + state->language_version % 100); + + if (!supported) { + _mesa_glsl_error(& (yylsp[(2) - (3)]), state, "%s is not supported. " + "Supported versions are: %s\n", + state->version_string, + state->supported_version_string); + } + ;} + break; + + case 10: + +/* Line 1464 of yacc.c */ +#line 276 "glsl_parser.ypp" + { + if (state->language_version < 120) { + _mesa_glsl_warning(& (yylsp[(1) - (2)]), state, + "pragma `invariant(all)' not supported in %s", + state->version_string); + } else { + state->all_invariant = true; + } + ;} + break; + + case 16: + +/* Line 1464 of yacc.c */ +#line 300 "glsl_parser.ypp" + { + if (!_mesa_glsl_process_extension((yyvsp[(2) - (5)].identifier), & (yylsp[(2) - (5)]), (yyvsp[(4) - (5)].identifier), & (yylsp[(4) - (5)]), state)) { + YYERROR; + } + ;} + break; + + case 17: + +/* Line 1464 of yacc.c */ +#line 309 "glsl_parser.ypp" + { + /* FINISHME: The NULL test is required because pragmas are set to + * FINISHME: NULL. (See production rule for external_declaration.) + */ + if ((yyvsp[(1) - (1)].node) != NULL) + state->translation_unit.push_tail(& (yyvsp[(1) - (1)].node)->link); + ;} + break; + + case 18: + +/* Line 1464 of yacc.c */ +#line 317 "glsl_parser.ypp" + { + /* FINISHME: The NULL test is required because pragmas are set to + * FINISHME: NULL. (See production rule for external_declaration.) + */ + if ((yyvsp[(2) - (2)].node) != NULL) + state->translation_unit.push_tail(& (yyvsp[(2) - (2)].node)->link); + ;} + break; + + case 21: + +/* Line 1464 of yacc.c */ +#line 333 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.identifier = (yyvsp[(1) - (1)].identifier); + ;} + break; + + case 22: + +/* Line 1464 of yacc.c */ +#line 340 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.int_constant = (yyvsp[(1) - (1)].n); + ;} + break; + + case 23: + +/* Line 1464 of yacc.c */ +#line 347 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.uint_constant = (yyvsp[(1) - (1)].n); + ;} + break; + + case 24: + +/* Line 1464 of yacc.c */ +#line 354 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.float_constant = (yyvsp[(1) - (1)].real); + ;} + break; + + case 25: + +/* Line 1464 of yacc.c */ +#line 361 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.bool_constant = (yyvsp[(1) - (1)].n); + ;} + break; + + case 26: + +/* Line 1464 of yacc.c */ +#line 368 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(2) - (3)].expression); + ;} + break; + + case 28: + +/* Line 1464 of yacc.c */ +#line 376 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_array_index, (yyvsp[(1) - (4)].expression), (yyvsp[(3) - (4)].expression), NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 29: + +/* Line 1464 of yacc.c */ +#line 382 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (1)].expression); + ;} + break; + + case 30: + +/* Line 1464 of yacc.c */ +#line 386 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->primary_expression.identifier = (yyvsp[(3) - (3)].identifier); + ;} + break; + + case 31: + +/* Line 1464 of yacc.c */ +#line 393 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_post_inc, (yyvsp[(1) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 32: + +/* Line 1464 of yacc.c */ +#line 399 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_post_dec, (yyvsp[(1) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 36: + +/* Line 1464 of yacc.c */ +#line 417 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 41: + +/* Line 1464 of yacc.c */ +#line 436 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (2)].expression); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->expressions.push_tail(& (yyvsp[(2) - (2)].expression)->link); + ;} + break; + + case 42: + +/* Line 1464 of yacc.c */ +#line 442 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (3)].expression); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link); + ;} + break; + + case 44: + +/* Line 1464 of yacc.c */ +#line 458 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_function_expression((yyvsp[(1) - (1)].type_specifier)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 45: + +/* Line 1464 of yacc.c */ +#line 464 "glsl_parser.ypp" + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); + (yyval.expression) = new(ctx) ast_function_expression(callee); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 46: + +/* Line 1464 of yacc.c */ +#line 471 "glsl_parser.ypp" + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); + (yyval.expression) = new(ctx) ast_function_expression(callee); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 51: + +/* Line 1464 of yacc.c */ +#line 491 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (2)].expression); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->expressions.push_tail(& (yyvsp[(2) - (2)].expression)->link); + ;} + break; + + case 52: + +/* Line 1464 of yacc.c */ +#line 497 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (3)].expression); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link); + ;} + break; + + case 53: + +/* Line 1464 of yacc.c */ +#line 509 "glsl_parser.ypp" + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (2)].identifier)); + (yyval.expression) = new(ctx) ast_function_expression(callee); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 55: + +/* Line 1464 of yacc.c */ +#line 521 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_pre_inc, (yyvsp[(2) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 56: + +/* Line 1464 of yacc.c */ +#line 527 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_pre_dec, (yyvsp[(2) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 57: + +/* Line 1464 of yacc.c */ +#line 533 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression((yyvsp[(1) - (2)].n), (yyvsp[(2) - (2)].expression), NULL, NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 58: + +/* Line 1464 of yacc.c */ +#line 542 "glsl_parser.ypp" + { (yyval.n) = ast_plus; ;} + break; + + case 59: + +/* Line 1464 of yacc.c */ +#line 543 "glsl_parser.ypp" + { (yyval.n) = ast_neg; ;} + break; + + case 60: + +/* Line 1464 of yacc.c */ +#line 544 "glsl_parser.ypp" + { (yyval.n) = ast_logic_not; ;} + break; + + case 61: + +/* Line 1464 of yacc.c */ +#line 545 "glsl_parser.ypp" + { (yyval.n) = ast_bit_not; ;} + break; + + case 63: + +/* Line 1464 of yacc.c */ +#line 551 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_mul, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 64: + +/* Line 1464 of yacc.c */ +#line 557 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_div, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 65: + +/* Line 1464 of yacc.c */ +#line 563 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_mod, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 67: + +/* Line 1464 of yacc.c */ +#line 573 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_add, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 68: + +/* Line 1464 of yacc.c */ +#line 579 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_sub, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 70: + +/* Line 1464 of yacc.c */ +#line 589 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_lshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 71: + +/* Line 1464 of yacc.c */ +#line 595 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_rshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 73: + +/* Line 1464 of yacc.c */ +#line 605 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_less, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 74: + +/* Line 1464 of yacc.c */ +#line 611 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_greater, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 75: + +/* Line 1464 of yacc.c */ +#line 617 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_lequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 76: + +/* Line 1464 of yacc.c */ +#line 623 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_gequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 78: + +/* Line 1464 of yacc.c */ +#line 633 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_equal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 79: + +/* Line 1464 of yacc.c */ +#line 639 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_nequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 81: + +/* Line 1464 of yacc.c */ +#line 649 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 83: + +/* Line 1464 of yacc.c */ +#line 659 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 85: + +/* Line 1464 of yacc.c */ +#line 669 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 87: + +/* Line 1464 of yacc.c */ +#line 679 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 89: + +/* Line 1464 of yacc.c */ +#line 689 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 91: + +/* Line 1464 of yacc.c */ +#line 699 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 93: + +/* Line 1464 of yacc.c */ +#line 709 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression(ast_conditional, (yyvsp[(1) - (5)].expression), (yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].expression)); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 95: + +/* Line 1464 of yacc.c */ +#line 719 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.expression) = new(ctx) ast_expression((yyvsp[(2) - (3)].n), (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); + (yyval.expression)->set_location(yylloc); + ;} + break; + + case 96: + +/* Line 1464 of yacc.c */ +#line 727 "glsl_parser.ypp" + { (yyval.n) = ast_assign; ;} + break; + + case 97: + +/* Line 1464 of yacc.c */ +#line 728 "glsl_parser.ypp" + { (yyval.n) = ast_mul_assign; ;} + break; + + case 98: + +/* Line 1464 of yacc.c */ +#line 729 "glsl_parser.ypp" + { (yyval.n) = ast_div_assign; ;} + break; + + case 99: + +/* Line 1464 of yacc.c */ +#line 730 "glsl_parser.ypp" + { (yyval.n) = ast_mod_assign; ;} + break; + + case 100: + +/* Line 1464 of yacc.c */ +#line 731 "glsl_parser.ypp" + { (yyval.n) = ast_add_assign; ;} + break; + + case 101: + +/* Line 1464 of yacc.c */ +#line 732 "glsl_parser.ypp" + { (yyval.n) = ast_sub_assign; ;} + break; + + case 102: + +/* Line 1464 of yacc.c */ +#line 733 "glsl_parser.ypp" + { (yyval.n) = ast_ls_assign; ;} + break; + + case 103: + +/* Line 1464 of yacc.c */ +#line 734 "glsl_parser.ypp" + { (yyval.n) = ast_rs_assign; ;} + break; + + case 104: + +/* Line 1464 of yacc.c */ +#line 735 "glsl_parser.ypp" + { (yyval.n) = ast_and_assign; ;} + break; + + case 105: + +/* Line 1464 of yacc.c */ +#line 736 "glsl_parser.ypp" + { (yyval.n) = ast_xor_assign; ;} + break; + + case 106: + +/* Line 1464 of yacc.c */ +#line 737 "glsl_parser.ypp" + { (yyval.n) = ast_or_assign; ;} + break; + + case 107: + +/* Line 1464 of yacc.c */ +#line 742 "glsl_parser.ypp" + { + (yyval.expression) = (yyvsp[(1) - (1)].expression); + ;} + break; + + case 108: + +/* Line 1464 of yacc.c */ +#line 746 "glsl_parser.ypp" + { + void *ctx = state; + if ((yyvsp[(1) - (3)].expression)->oper != ast_sequence) { + (yyval.expression) = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); + (yyval.expression)->set_location(yylloc); + (yyval.expression)->expressions.push_tail(& (yyvsp[(1) - (3)].expression)->link); + } else { + (yyval.expression) = (yyvsp[(1) - (3)].expression); + } + + (yyval.expression)->expressions.push_tail(& (yyvsp[(3) - (3)].expression)->link); + ;} + break; + + case 110: + +/* Line 1464 of yacc.c */ +#line 766 "glsl_parser.ypp" + { + state->symbols->pop_scope(); + (yyval.node) = (yyvsp[(1) - (2)].function); + ;} + break; + + case 111: + +/* Line 1464 of yacc.c */ +#line 771 "glsl_parser.ypp" + { + (yyval.node) = (yyvsp[(1) - (2)].declarator_list); + ;} + break; + + case 112: + +/* Line 1464 of yacc.c */ +#line 775 "glsl_parser.ypp" + { + (yyvsp[(3) - (4)].type_specifier)->precision = (yyvsp[(2) - (4)].n); + (yyvsp[(3) - (4)].type_specifier)->is_precision_statement = true; + (yyval.node) = (yyvsp[(3) - (4)].type_specifier); + ;} + break; + + case 116: + +/* Line 1464 of yacc.c */ +#line 793 "glsl_parser.ypp" + { + (yyval.function) = (yyvsp[(1) - (2)].function); + (yyval.function)->parameters.push_tail(& (yyvsp[(2) - (2)].parameter_declarator)->link); + ;} + break; + + case 117: + +/* Line 1464 of yacc.c */ +#line 798 "glsl_parser.ypp" + { + (yyval.function) = (yyvsp[(1) - (3)].function); + (yyval.function)->parameters.push_tail(& (yyvsp[(3) - (3)].parameter_declarator)->link); + ;} + break; + + case 118: + +/* Line 1464 of yacc.c */ +#line 806 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.function) = new(ctx) ast_function(); + (yyval.function)->set_location(yylloc); + (yyval.function)->return_type = (yyvsp[(1) - (3)].fully_specified_type); + (yyval.function)->identifier = (yyvsp[(2) - (3)].identifier); + + state->symbols->add_function(new(state) ir_function((yyvsp[(2) - (3)].identifier))); + state->symbols->push_scope(); + ;} + break; + + case 119: + +/* Line 1464 of yacc.c */ +#line 820 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); + (yyval.parameter_declarator)->set_location(yylloc); + (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); + (yyval.parameter_declarator)->type->set_location(yylloc); + (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (2)].type_specifier); + (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (2)].identifier); + ;} + break; + + case 120: + +/* Line 1464 of yacc.c */ +#line 830 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); + (yyval.parameter_declarator)->set_location(yylloc); + (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); + (yyval.parameter_declarator)->type->set_location(yylloc); + (yyval.parameter_declarator)->type->specifier = (yyvsp[(1) - (5)].type_specifier); + (yyval.parameter_declarator)->identifier = (yyvsp[(2) - (5)].identifier); + (yyval.parameter_declarator)->is_array = true; + (yyval.parameter_declarator)->array_size = (yyvsp[(4) - (5)].expression); + ;} + break; + + case 121: + +/* Line 1464 of yacc.c */ +#line 845 "glsl_parser.ypp" + { + (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i; + + (yyval.parameter_declarator) = (yyvsp[(3) - (3)].parameter_declarator); + (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier); + ;} + break; + + case 122: + +/* Line 1464 of yacc.c */ +#line 852 "glsl_parser.ypp" + { + (yyval.parameter_declarator) = (yyvsp[(2) - (2)].parameter_declarator); + (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier); + ;} + break; + + case 123: + +/* Line 1464 of yacc.c */ +#line 857 "glsl_parser.ypp" + { + void *ctx = state; + (yyvsp[(1) - (3)].type_qualifier).flags.i |= (yyvsp[(2) - (3)].type_qualifier).flags.i; + + (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); + (yyval.parameter_declarator)->set_location(yylloc); + (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); + (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (3)].type_qualifier); + (yyval.parameter_declarator)->type->specifier = (yyvsp[(3) - (3)].type_specifier); + ;} + break; + + case 124: + +/* Line 1464 of yacc.c */ +#line 868 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); + (yyval.parameter_declarator)->set_location(yylloc); + (yyval.parameter_declarator)->type = new(ctx) ast_fully_specified_type(); + (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier); + (yyval.parameter_declarator)->type->specifier = (yyvsp[(2) - (2)].type_specifier); + ;} + break; + + case 125: + +/* Line 1464 of yacc.c */ +#line 880 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + ;} + break; + + case 126: + +/* Line 1464 of yacc.c */ +#line 884 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.in = 1; + ;} + break; + + case 127: + +/* Line 1464 of yacc.c */ +#line 889 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.out = 1; + ;} + break; + + case 128: + +/* Line 1464 of yacc.c */ +#line 894 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.in = 1; + (yyval.type_qualifier).flags.q.out = 1; + ;} + break; + + case 131: + +/* Line 1464 of yacc.c */ +#line 908 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (3)].identifier), false, NULL, NULL); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (3)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, (yyvsp[(3) - (3)].identifier), ir_var_auto)); + ;} + break; + + case 132: + +/* Line 1464 of yacc.c */ +#line 918 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), true, NULL, NULL); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, (yyvsp[(3) - (5)].identifier), ir_var_auto)); + ;} + break; + + case 133: + +/* Line 1464 of yacc.c */ +#line 928 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (6)].identifier), true, (yyvsp[(5) - (6)].expression), NULL); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (6)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, (yyvsp[(3) - (6)].identifier), ir_var_auto)); + ;} + break; + + case 134: + +/* Line 1464 of yacc.c */ +#line 938 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (7)].identifier), true, NULL, (yyvsp[(7) - (7)].expression)); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (7)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, (yyvsp[(3) - (7)].identifier), ir_var_auto)); + ;} + break; + + case 135: + +/* Line 1464 of yacc.c */ +#line 948 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (8)].identifier), true, (yyvsp[(5) - (8)].expression), (yyvsp[(8) - (8)].expression)); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (8)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, (yyvsp[(3) - (8)].identifier), ir_var_auto)); + ;} + break; + + case 136: + +/* Line 1464 of yacc.c */ +#line 958 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), false, NULL, (yyvsp[(5) - (5)].expression)); + decl->set_location(yylloc); + + (yyval.declarator_list) = (yyvsp[(1) - (5)].declarator_list); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, (yyvsp[(3) - (5)].identifier), ir_var_auto)); + ;} + break; + + case 137: + +/* Line 1464 of yacc.c */ +#line 972 "glsl_parser.ypp" + { + void *ctx = state; + if ((yyvsp[(1) - (1)].fully_specified_type)->specifier->type_specifier != ast_struct) { + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "empty declaration list\n"); + YYERROR; + } else { + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (1)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + } + ;} + break; + + case 138: + +/* Line 1464 of yacc.c */ +#line 983 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (2)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 139: + +/* Line 1464 of yacc.c */ +#line 992 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), true, NULL, NULL); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 140: + +/* Line 1464 of yacc.c */ +#line 1001 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (5)].identifier), true, (yyvsp[(4) - (5)].expression), NULL); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (5)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 141: + +/* Line 1464 of yacc.c */ +#line 1010 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (6)].identifier), true, NULL, (yyvsp[(6) - (6)].expression)); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (6)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 142: + +/* Line 1464 of yacc.c */ +#line 1019 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (7)].identifier), true, (yyvsp[(4) - (7)].expression), (yyvsp[(7) - (7)].expression)); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (7)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 143: + +/* Line 1464 of yacc.c */ +#line 1028 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); + + (yyval.declarator_list) = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 144: + +/* Line 1464 of yacc.c */ +#line 1037 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); + + (yyval.declarator_list) = new(ctx) ast_declarator_list(NULL); + (yyval.declarator_list)->set_location(yylloc); + (yyval.declarator_list)->invariant = true; + + (yyval.declarator_list)->declarations.push_tail(&decl->link); + ;} + break; + + case 145: + +/* Line 1464 of yacc.c */ +#line 1051 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); + (yyval.fully_specified_type)->set_location(yylloc); + (yyval.fully_specified_type)->specifier = (yyvsp[(1) - (1)].type_specifier); + ;} + break; + + case 146: + +/* Line 1464 of yacc.c */ +#line 1058 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); + (yyval.fully_specified_type)->set_location(yylloc); + (yyval.fully_specified_type)->qualifier = (yyvsp[(1) - (2)].type_qualifier); + (yyval.fully_specified_type)->specifier = (yyvsp[(2) - (2)].type_specifier); + ;} + break; + + case 147: + +/* Line 1464 of yacc.c */ +#line 1069 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(3) - (4)].type_qualifier); + ;} + break; + + case 149: + +/* Line 1464 of yacc.c */ +#line 1077 "glsl_parser.ypp" + { + if (((yyvsp[(1) - (3)].type_qualifier).flags.i & (yyvsp[(3) - (3)].type_qualifier).flags.i) != 0) { + _mesa_glsl_error(& (yylsp[(3) - (3)]), state, + "duplicate layout qualifiers used\n"); + YYERROR; + } + + (yyval.type_qualifier).flags.i = (yyvsp[(1) - (3)].type_qualifier).flags.i | (yyvsp[(3) - (3)].type_qualifier).flags.i; + + if ((yyvsp[(1) - (3)].type_qualifier).flags.q.explicit_location) + (yyval.type_qualifier).location = (yyvsp[(1) - (3)].type_qualifier).location; + + if ((yyvsp[(3) - (3)].type_qualifier).flags.q.explicit_location) + (yyval.type_qualifier).location = (yyvsp[(3) - (3)].type_qualifier).location; + ;} + break; + + case 150: + +/* Line 1464 of yacc.c */ +#line 1096 "glsl_parser.ypp" + { + bool got_one = false; + + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + + /* Layout qualifiers for ARB_fragment_coord_conventions. */ + if (!got_one && state->ARB_fragment_coord_conventions_enable) { + if (strcmp((yyvsp[(1) - (1)].identifier), "origin_upper_left") == 0) { + got_one = true; + (yyval.type_qualifier).flags.q.origin_upper_left = 1; + } else if (strcmp((yyvsp[(1) - (1)].identifier), "pixel_center_integer") == 0) { + got_one = true; + (yyval.type_qualifier).flags.q.pixel_center_integer = 1; + } + + if (got_one && state->ARB_fragment_coord_conventions_warn) { + _mesa_glsl_warning(& (yylsp[(1) - (1)]), state, + "GL_ARB_fragment_coord_conventions layout " + "identifier `%s' used\n", (yyvsp[(1) - (1)].identifier)); + } + } + + /* Layout qualifiers for AMD_conservative_depth. */ + if (!got_one && state->AMD_conservative_depth_enable) { + if (strcmp((yyvsp[(1) - (1)].identifier), "depth_any") == 0) { + got_one = true; + (yyval.type_qualifier).flags.q.depth_any = 1; + } else if (strcmp((yyvsp[(1) - (1)].identifier), "depth_greater") == 0) { + got_one = true; + (yyval.type_qualifier).flags.q.depth_greater = 1; + } else if (strcmp((yyvsp[(1) - (1)].identifier), "depth_less") == 0) { + got_one = true; + (yyval.type_qualifier).flags.q.depth_less = 1; + } else if (strcmp((yyvsp[(1) - (1)].identifier), "depth_unchanged") == 0) { + got_one = true; + (yyval.type_qualifier).flags.q.depth_unchanged = 1; + } + + if (got_one && state->AMD_conservative_depth_warn) { + _mesa_glsl_warning(& (yylsp[(1) - (1)]), state, + "GL_AMD_conservative_depth " + "layout qualifier `%s' is used\n", (yyvsp[(1) - (1)].identifier)); + } + } + + if (!got_one) { + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, "unrecognized layout identifier " + "`%s'\n", (yyvsp[(1) - (1)].identifier)); + YYERROR; + } + ;} + break; + + case 151: + +/* Line 1464 of yacc.c */ +#line 1148 "glsl_parser.ypp" + { + bool got_one = false; + + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + + if (state->ARB_explicit_attrib_location_enable) { + /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and + * FINISHME: GLSL 1.30 (or later) are supported. + */ + if (strcmp("location", (yyvsp[(1) - (3)].identifier)) == 0) { + got_one = true; + + (yyval.type_qualifier).flags.q.explicit_location = 1; + + if ((yyvsp[(3) - (3)].n) >= 0) { + (yyval.type_qualifier).location = (yyvsp[(3) - (3)].n); + } else { + _mesa_glsl_error(& (yylsp[(3) - (3)]), state, + "invalid location %d specified\n", (yyvsp[(3) - (3)].n)); + YYERROR; + } + } + } + + /* If the identifier didn't match any known layout identifiers, + * emit an error. + */ + if (!got_one) { + _mesa_glsl_error(& (yylsp[(1) - (3)]), state, "unrecognized layout identifier " + "`%s'\n", (yyvsp[(1) - (3)].identifier)); + YYERROR; + } else if (state->ARB_explicit_attrib_location_warn) { + _mesa_glsl_warning(& (yylsp[(1) - (3)]), state, + "GL_ARB_explicit_attrib_location layout " + "identifier `%s' used\n", (yyvsp[(1) - (3)].identifier)); + } + ;} + break; + + case 152: + +/* Line 1464 of yacc.c */ +#line 1189 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.smooth = 1; + ;} + break; + + case 153: + +/* Line 1464 of yacc.c */ +#line 1194 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.flat = 1; + ;} + break; + + case 154: + +/* Line 1464 of yacc.c */ +#line 1199 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.noperspective = 1; + ;} + break; + + case 155: + +/* Line 1464 of yacc.c */ +#line 1207 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.constant = 1; + ;} + break; + + case 158: + +/* Line 1464 of yacc.c */ +#line 1217 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier); + (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i; + ;} + break; + + case 160: + +/* Line 1464 of yacc.c */ +#line 1223 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(1) - (2)].type_qualifier); + (yyval.type_qualifier).flags.i |= (yyvsp[(2) - (2)].type_qualifier).flags.i; + ;} + break; + + case 161: + +/* Line 1464 of yacc.c */ +#line 1228 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(2) - (2)].type_qualifier); + (yyval.type_qualifier).flags.q.invariant = 1; + ;} + break; + + case 162: + +/* Line 1464 of yacc.c */ +#line 1233 "glsl_parser.ypp" + { + (yyval.type_qualifier) = (yyvsp[(2) - (3)].type_qualifier); + (yyval.type_qualifier).flags.i |= (yyvsp[(3) - (3)].type_qualifier).flags.i; + (yyval.type_qualifier).flags.q.invariant = 1; + ;} + break; + + case 163: + +/* Line 1464 of yacc.c */ +#line 1239 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.invariant = 1; + ;} + break; + + case 164: + +/* Line 1464 of yacc.c */ +#line 1247 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.constant = 1; + ;} + break; + + case 165: + +/* Line 1464 of yacc.c */ +#line 1252 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.attribute = 1; + ;} + break; + + case 166: + +/* Line 1464 of yacc.c */ +#line 1257 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.varying = 1; + ;} + break; + + case 167: + +/* Line 1464 of yacc.c */ +#line 1262 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.centroid = 1; + (yyval.type_qualifier).flags.q.varying = 1; + ;} + break; + + case 168: + +/* Line 1464 of yacc.c */ +#line 1268 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.in = 1; + ;} + break; + + case 169: + +/* Line 1464 of yacc.c */ +#line 1273 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.out = 1; + ;} + break; + + case 170: + +/* Line 1464 of yacc.c */ +#line 1278 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.in = 1; + ;} + break; + + case 171: + +/* Line 1464 of yacc.c */ +#line 1283 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.centroid = 1; (yyval.type_qualifier).flags.q.out = 1; + ;} + break; + + case 172: + +/* Line 1464 of yacc.c */ +#line 1288 "glsl_parser.ypp" + { + memset(& (yyval.type_qualifier), 0, sizeof((yyval.type_qualifier))); + (yyval.type_qualifier).flags.q.uniform = 1; + ;} + break; + + case 173: + +/* Line 1464 of yacc.c */ +#line 1296 "glsl_parser.ypp" + { + (yyval.type_specifier) = (yyvsp[(1) - (1)].type_specifier); + ;} + break; + + case 174: + +/* Line 1464 of yacc.c */ +#line 1300 "glsl_parser.ypp" + { + (yyval.type_specifier) = (yyvsp[(2) - (2)].type_specifier); + (yyval.type_specifier)->precision = (yyvsp[(1) - (2)].n); + ;} + break; + + case 176: + +/* Line 1464 of yacc.c */ +#line 1309 "glsl_parser.ypp" + { + (yyval.type_specifier) = (yyvsp[(1) - (3)].type_specifier); + (yyval.type_specifier)->is_array = true; + (yyval.type_specifier)->array_size = NULL; + ;} + break; + + case 177: + +/* Line 1464 of yacc.c */ +#line 1315 "glsl_parser.ypp" + { + (yyval.type_specifier) = (yyvsp[(1) - (4)].type_specifier); + (yyval.type_specifier)->is_array = true; + (yyval.type_specifier)->array_size = (yyvsp[(3) - (4)].expression); + ;} + break; + + case 178: + +/* Line 1464 of yacc.c */ +#line 1324 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].n)); + (yyval.type_specifier)->set_location(yylloc); + ;} + break; + + case 179: + +/* Line 1464 of yacc.c */ +#line 1330 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].struct_specifier)); + (yyval.type_specifier)->set_location(yylloc); + ;} + break; + + case 180: + +/* Line 1464 of yacc.c */ +#line 1336 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].identifier)); + (yyval.type_specifier)->set_location(yylloc); + ;} + break; + + case 181: + +/* Line 1464 of yacc.c */ +#line 1344 "glsl_parser.ypp" + { (yyval.n) = ast_void; ;} + break; + + case 182: + +/* Line 1464 of yacc.c */ +#line 1345 "glsl_parser.ypp" + { (yyval.n) = ast_float; ;} + break; + + case 183: + +/* Line 1464 of yacc.c */ +#line 1346 "glsl_parser.ypp" + { (yyval.n) = ast_int; ;} + break; + + case 184: + +/* Line 1464 of yacc.c */ +#line 1347 "glsl_parser.ypp" + { (yyval.n) = ast_uint; ;} + break; + + case 185: + +/* Line 1464 of yacc.c */ +#line 1348 "glsl_parser.ypp" + { (yyval.n) = ast_bool; ;} + break; + + case 186: + +/* Line 1464 of yacc.c */ +#line 1349 "glsl_parser.ypp" + { (yyval.n) = ast_vec2; ;} + break; + + case 187: + +/* Line 1464 of yacc.c */ +#line 1350 "glsl_parser.ypp" + { (yyval.n) = ast_vec3; ;} + break; + + case 188: + +/* Line 1464 of yacc.c */ +#line 1351 "glsl_parser.ypp" + { (yyval.n) = ast_vec4; ;} + break; + + case 189: + +/* Line 1464 of yacc.c */ +#line 1352 "glsl_parser.ypp" + { (yyval.n) = ast_bvec2; ;} + break; + + case 190: + +/* Line 1464 of yacc.c */ +#line 1353 "glsl_parser.ypp" + { (yyval.n) = ast_bvec3; ;} + break; + + case 191: + +/* Line 1464 of yacc.c */ +#line 1354 "glsl_parser.ypp" + { (yyval.n) = ast_bvec4; ;} + break; + + case 192: + +/* Line 1464 of yacc.c */ +#line 1355 "glsl_parser.ypp" + { (yyval.n) = ast_ivec2; ;} + break; + + case 193: + +/* Line 1464 of yacc.c */ +#line 1356 "glsl_parser.ypp" + { (yyval.n) = ast_ivec3; ;} + break; + + case 194: + +/* Line 1464 of yacc.c */ +#line 1357 "glsl_parser.ypp" + { (yyval.n) = ast_ivec4; ;} + break; + + case 195: + +/* Line 1464 of yacc.c */ +#line 1358 "glsl_parser.ypp" + { (yyval.n) = ast_uvec2; ;} + break; + + case 196: + +/* Line 1464 of yacc.c */ +#line 1359 "glsl_parser.ypp" + { (yyval.n) = ast_uvec3; ;} + break; + + case 197: + +/* Line 1464 of yacc.c */ +#line 1360 "glsl_parser.ypp" + { (yyval.n) = ast_uvec4; ;} + break; + + case 198: + +/* Line 1464 of yacc.c */ +#line 1361 "glsl_parser.ypp" + { (yyval.n) = ast_mat2; ;} + break; + + case 199: + +/* Line 1464 of yacc.c */ +#line 1362 "glsl_parser.ypp" + { (yyval.n) = ast_mat2x3; ;} + break; + + case 200: + +/* Line 1464 of yacc.c */ +#line 1363 "glsl_parser.ypp" + { (yyval.n) = ast_mat2x4; ;} + break; + + case 201: + +/* Line 1464 of yacc.c */ +#line 1364 "glsl_parser.ypp" + { (yyval.n) = ast_mat3x2; ;} + break; + + case 202: + +/* Line 1464 of yacc.c */ +#line 1365 "glsl_parser.ypp" + { (yyval.n) = ast_mat3; ;} + break; + + case 203: + +/* Line 1464 of yacc.c */ +#line 1366 "glsl_parser.ypp" + { (yyval.n) = ast_mat3x4; ;} + break; + + case 204: + +/* Line 1464 of yacc.c */ +#line 1367 "glsl_parser.ypp" + { (yyval.n) = ast_mat4x2; ;} + break; + + case 205: + +/* Line 1464 of yacc.c */ +#line 1368 "glsl_parser.ypp" + { (yyval.n) = ast_mat4x3; ;} + break; + + case 206: + +/* Line 1464 of yacc.c */ +#line 1369 "glsl_parser.ypp" + { (yyval.n) = ast_mat4; ;} + break; + + case 207: + +/* Line 1464 of yacc.c */ +#line 1370 "glsl_parser.ypp" + { (yyval.n) = ast_sampler1d; ;} + break; + + case 208: + +/* Line 1464 of yacc.c */ +#line 1371 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2d; ;} + break; + + case 209: + +/* Line 1464 of yacc.c */ +#line 1372 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2drect; ;} + break; + + case 210: + +/* Line 1464 of yacc.c */ +#line 1373 "glsl_parser.ypp" + { (yyval.n) = ast_sampler3d; ;} + break; + + case 211: + +/* Line 1464 of yacc.c */ +#line 1374 "glsl_parser.ypp" + { (yyval.n) = ast_samplercube; ;} + break; + + case 212: + +/* Line 1464 of yacc.c */ +#line 1375 "glsl_parser.ypp" + { (yyval.n) = ast_sampler1dshadow; ;} + break; + + case 213: + +/* Line 1464 of yacc.c */ +#line 1376 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2dshadow; ;} + break; + + case 214: + +/* Line 1464 of yacc.c */ +#line 1377 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2drectshadow; ;} + break; + + case 215: + +/* Line 1464 of yacc.c */ +#line 1378 "glsl_parser.ypp" + { (yyval.n) = ast_samplercubeshadow; ;} + break; + + case 216: + +/* Line 1464 of yacc.c */ +#line 1379 "glsl_parser.ypp" + { (yyval.n) = ast_sampler1darray; ;} + break; + + case 217: + +/* Line 1464 of yacc.c */ +#line 1380 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2darray; ;} + break; + + case 218: + +/* Line 1464 of yacc.c */ +#line 1381 "glsl_parser.ypp" + { (yyval.n) = ast_sampler1darrayshadow; ;} + break; + + case 219: + +/* Line 1464 of yacc.c */ +#line 1382 "glsl_parser.ypp" + { (yyval.n) = ast_sampler2darrayshadow; ;} + break; + + case 220: + +/* Line 1464 of yacc.c */ +#line 1383 "glsl_parser.ypp" + { (yyval.n) = ast_isampler1d; ;} + break; + + case 221: + +/* Line 1464 of yacc.c */ +#line 1384 "glsl_parser.ypp" + { (yyval.n) = ast_isampler2d; ;} + break; + + case 222: + +/* Line 1464 of yacc.c */ +#line 1385 "glsl_parser.ypp" + { (yyval.n) = ast_isampler3d; ;} + break; + + case 223: + +/* Line 1464 of yacc.c */ +#line 1386 "glsl_parser.ypp" + { (yyval.n) = ast_isamplercube; ;} + break; + + case 224: + +/* Line 1464 of yacc.c */ +#line 1387 "glsl_parser.ypp" + { (yyval.n) = ast_isampler1darray; ;} + break; + + case 225: + +/* Line 1464 of yacc.c */ +#line 1388 "glsl_parser.ypp" + { (yyval.n) = ast_isampler2darray; ;} + break; + + case 226: + +/* Line 1464 of yacc.c */ +#line 1389 "glsl_parser.ypp" + { (yyval.n) = ast_usampler1d; ;} + break; + + case 227: + +/* Line 1464 of yacc.c */ +#line 1390 "glsl_parser.ypp" + { (yyval.n) = ast_usampler2d; ;} + break; + + case 228: + +/* Line 1464 of yacc.c */ +#line 1391 "glsl_parser.ypp" + { (yyval.n) = ast_usampler3d; ;} + break; + + case 229: + +/* Line 1464 of yacc.c */ +#line 1392 "glsl_parser.ypp" + { (yyval.n) = ast_usamplercube; ;} + break; + + case 230: + +/* Line 1464 of yacc.c */ +#line 1393 "glsl_parser.ypp" + { (yyval.n) = ast_usampler1darray; ;} + break; + + case 231: + +/* Line 1464 of yacc.c */ +#line 1394 "glsl_parser.ypp" + { (yyval.n) = ast_usampler2darray; ;} + break; + + case 232: + +/* Line 1464 of yacc.c */ +#line 1398 "glsl_parser.ypp" + { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + (yyval.n) = ast_precision_high; + ;} + break; + + case 233: + +/* Line 1464 of yacc.c */ +#line 1408 "glsl_parser.ypp" + { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + (yyval.n) = ast_precision_medium; + ;} + break; + + case 234: + +/* Line 1464 of yacc.c */ +#line 1418 "glsl_parser.ypp" + { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + (yyval.n) = ast_precision_low; + ;} + break; + + case 235: + +/* Line 1464 of yacc.c */ +#line 1432 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.struct_specifier) = new(ctx) ast_struct_specifier((yyvsp[(2) - (5)].identifier), (yyvsp[(4) - (5)].node)); + (yyval.struct_specifier)->set_location(yylloc); + state->symbols->add_type((yyvsp[(2) - (5)].identifier), glsl_type::void_type); + ;} + break; + + case 236: + +/* Line 1464 of yacc.c */ +#line 1439 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.struct_specifier) = new(ctx) ast_struct_specifier(NULL, (yyvsp[(3) - (4)].node)); + (yyval.struct_specifier)->set_location(yylloc); + ;} + break; + + case 237: + +/* Line 1464 of yacc.c */ +#line 1448 "glsl_parser.ypp" + { + (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].declarator_list); + (yyvsp[(1) - (1)].declarator_list)->link.self_link(); + ;} + break; + + case 238: + +/* Line 1464 of yacc.c */ +#line 1453 "glsl_parser.ypp" + { + (yyval.node) = (ast_node *) (yyvsp[(1) - (2)].node); + (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].declarator_list)->link); + ;} + break; + + case 239: + +/* Line 1464 of yacc.c */ +#line 1461 "glsl_parser.ypp" + { + void *ctx = state; + ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); + type->set_location(yylloc); + + type->specifier = (yyvsp[(1) - (3)].type_specifier); + (yyval.declarator_list) = new(ctx) ast_declarator_list(type); + (yyval.declarator_list)->set_location(yylloc); + + (yyval.declarator_list)->declarations.push_degenerate_list_at_head(& (yyvsp[(2) - (3)].declaration)->link); + ;} + break; + + case 240: + +/* Line 1464 of yacc.c */ +#line 1476 "glsl_parser.ypp" + { + (yyval.declaration) = (yyvsp[(1) - (1)].declaration); + (yyvsp[(1) - (1)].declaration)->link.self_link(); + ;} + break; + + case 241: + +/* Line 1464 of yacc.c */ +#line 1481 "glsl_parser.ypp" + { + (yyval.declaration) = (yyvsp[(1) - (3)].declaration); + (yyval.declaration)->link.insert_before(& (yyvsp[(3) - (3)].declaration)->link); + ;} + break; + + case 242: + +/* Line 1464 of yacc.c */ +#line 1489 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (1)].identifier), false, NULL, NULL); + (yyval.declaration)->set_location(yylloc); + state->symbols->add_variable(new(state) ir_variable(NULL, (yyvsp[(1) - (1)].identifier), ir_var_auto)); + ;} + break; + + case 243: + +/* Line 1464 of yacc.c */ +#line 1496 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (4)].identifier), true, (yyvsp[(3) - (4)].expression), NULL); + (yyval.declaration)->set_location(yylloc); + ;} + break; + + case 246: + +/* Line 1464 of yacc.c */ +#line 1514 "glsl_parser.ypp" + { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} + break; + + case 251: + +/* Line 1464 of yacc.c */ +#line 1522 "glsl_parser.ypp" + { (yyval.node) = NULL; ;} + break; + + case 252: + +/* Line 1464 of yacc.c */ +#line 1523 "glsl_parser.ypp" + { (yyval.node) = NULL; ;} + break; + + case 255: + +/* Line 1464 of yacc.c */ +#line 1530 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.compound_statement) = new(ctx) ast_compound_statement(true, NULL); + (yyval.compound_statement)->set_location(yylloc); + ;} + break; + + case 256: + +/* Line 1464 of yacc.c */ +#line 1536 "glsl_parser.ypp" + { + state->symbols->push_scope(); + ;} + break; + + case 257: + +/* Line 1464 of yacc.c */ +#line 1540 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.compound_statement) = new(ctx) ast_compound_statement(true, (yyvsp[(3) - (4)].node)); + (yyval.compound_statement)->set_location(yylloc); + state->symbols->pop_scope(); + ;} + break; + + case 258: + +/* Line 1464 of yacc.c */ +#line 1549 "glsl_parser.ypp" + { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} + break; + + case 260: + +/* Line 1464 of yacc.c */ +#line 1555 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.compound_statement) = new(ctx) ast_compound_statement(false, NULL); + (yyval.compound_statement)->set_location(yylloc); + ;} + break; + + case 261: + +/* Line 1464 of yacc.c */ +#line 1561 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.compound_statement) = new(ctx) ast_compound_statement(false, (yyvsp[(2) - (3)].node)); + (yyval.compound_statement)->set_location(yylloc); + ;} + break; + + case 262: + +/* Line 1464 of yacc.c */ +#line 1570 "glsl_parser.ypp" + { + if ((yyvsp[(1) - (1)].node) == NULL) { + _mesa_glsl_error(& (yylsp[(1) - (1)]), state, " statement\n"); + assert((yyvsp[(1) - (1)].node) != NULL); + } + + (yyval.node) = (yyvsp[(1) - (1)].node); + (yyval.node)->link.self_link(); + ;} + break; + + case 263: + +/* Line 1464 of yacc.c */ +#line 1580 "glsl_parser.ypp" + { + if ((yyvsp[(2) - (2)].node) == NULL) { + _mesa_glsl_error(& (yylsp[(2) - (2)]), state, " statement\n"); + assert((yyvsp[(2) - (2)].node) != NULL); + } + (yyval.node) = (yyvsp[(1) - (2)].node); + (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].node)->link); + ;} + break; + + case 264: + +/* Line 1464 of yacc.c */ +#line 1592 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_expression_statement(NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 265: + +/* Line 1464 of yacc.c */ +#line 1598 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_expression_statement((yyvsp[(1) - (2)].expression)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 266: + +/* Line 1464 of yacc.c */ +#line 1607 "glsl_parser.ypp" + { + (yyval.node) = new(state) ast_selection_statement((yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].selection_rest_statement).then_statement, + (yyvsp[(5) - (5)].selection_rest_statement).else_statement); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 267: + +/* Line 1464 of yacc.c */ +#line 1616 "glsl_parser.ypp" + { + (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (3)].node); + (yyval.selection_rest_statement).else_statement = (yyvsp[(3) - (3)].node); + ;} + break; + + case 268: + +/* Line 1464 of yacc.c */ +#line 1621 "glsl_parser.ypp" + { + (yyval.selection_rest_statement).then_statement = (yyvsp[(1) - (1)].node); + (yyval.selection_rest_statement).else_statement = NULL; + ;} + break; + + case 269: + +/* Line 1464 of yacc.c */ +#line 1629 "glsl_parser.ypp" + { + (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].expression); + ;} + break; + + case 270: + +/* Line 1464 of yacc.c */ +#line 1633 "glsl_parser.ypp" + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); + ast_declarator_list *declarator = new(ctx) ast_declarator_list((yyvsp[(1) - (4)].fully_specified_type)); + decl->set_location(yylloc); + declarator->set_location(yylloc); + + declarator->declarations.push_tail(&decl->link); + (yyval.node) = declarator; + ;} + break; + + case 274: + +/* Line 1464 of yacc.c */ +#line 1656 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, + NULL, (yyvsp[(3) - (5)].node), NULL, (yyvsp[(5) - (5)].node)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 275: + +/* Line 1464 of yacc.c */ +#line 1663 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, + NULL, (yyvsp[(5) - (7)].expression), NULL, (yyvsp[(2) - (7)].node)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 276: + +/* Line 1464 of yacc.c */ +#line 1670 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, + (yyvsp[(3) - (6)].node), (yyvsp[(4) - (6)].for_rest_statement).cond, (yyvsp[(4) - (6)].for_rest_statement).rest, (yyvsp[(6) - (6)].node)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 280: + +/* Line 1464 of yacc.c */ +#line 1686 "glsl_parser.ypp" + { + (yyval.node) = NULL; + ;} + break; + + case 281: + +/* Line 1464 of yacc.c */ +#line 1693 "glsl_parser.ypp" + { + (yyval.for_rest_statement).cond = (yyvsp[(1) - (2)].node); + (yyval.for_rest_statement).rest = NULL; + ;} + break; + + case 282: + +/* Line 1464 of yacc.c */ +#line 1698 "glsl_parser.ypp" + { + (yyval.for_rest_statement).cond = (yyvsp[(1) - (3)].node); + (yyval.for_rest_statement).rest = (yyvsp[(3) - (3)].expression); + ;} + break; + + case 283: + +/* Line 1464 of yacc.c */ +#line 1707 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 284: + +/* Line 1464 of yacc.c */ +#line 1713 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 285: + +/* Line 1464 of yacc.c */ +#line 1719 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 286: + +/* Line 1464 of yacc.c */ +#line 1725 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, (yyvsp[(2) - (3)].expression)); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 287: + +/* Line 1464 of yacc.c */ +#line 1731 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); + (yyval.node)->set_location(yylloc); + ;} + break; + + case 288: + +/* Line 1464 of yacc.c */ +#line 1739 "glsl_parser.ypp" + { (yyval.node) = (yyvsp[(1) - (1)].function_definition); ;} + break; + + case 289: + +/* Line 1464 of yacc.c */ +#line 1740 "glsl_parser.ypp" + { (yyval.node) = (yyvsp[(1) - (1)].node); ;} + break; + + case 290: + +/* Line 1464 of yacc.c */ +#line 1741 "glsl_parser.ypp" + { (yyval.node) = NULL; ;} + break; + + case 291: + +/* Line 1464 of yacc.c */ +#line 1746 "glsl_parser.ypp" + { + void *ctx = state; + (yyval.function_definition) = new(ctx) ast_function_definition(); + (yyval.function_definition)->set_location(yylloc); + (yyval.function_definition)->prototype = (yyvsp[(1) - (2)].function); + (yyval.function_definition)->body = (yyvsp[(2) - (2)].compound_statement); + + state->symbols->pop_scope(); + ;} + break; + + + +/* Line 1464 of yacc.c */ +#line 5240 "glsl_parser.cpp" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + *++yylsp = yyloc; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (&yylloc, state, YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (&yylloc, state, yymsg); + } + else + { + yyerror (&yylloc, state, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + yyerror_range[1] = yylloc; + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, &yylloc, state); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + yyerror_range[1] = yylsp[1-yylen]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + yyerror_range[1] = *yylsp; + yydestruct ("Error: popping", + yystos[yystate], yyvsp, yylsp, state); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + yyerror_range[2] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the lookahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, yyerror_range, 2); + *++yylsp = yyloc; + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (&yylloc, state, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc, state); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, yylsp, state); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + diff --git a/mesalib/src/glsl/glsl_parser.h b/mesalib/src/glsl/glsl_parser.h index 1bf3b3538..da50fdac0 100644 --- a/mesalib/src/glsl/glsl_parser.h +++ b/mesalib/src/glsl/glsl_parser.h @@ -1,298 +1,300 @@ -/* A Bison parser, made by GNU Bison 2.4.3. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2009, 2010 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - ATTRIBUTE = 258, - CONST_TOK = 259, - BOOL_TOK = 260, - FLOAT_TOK = 261, - INT_TOK = 262, - UINT_TOK = 263, - BREAK = 264, - CONTINUE = 265, - DO = 266, - ELSE = 267, - FOR = 268, - IF = 269, - DISCARD = 270, - RETURN = 271, - SWITCH = 272, - CASE = 273, - DEFAULT = 274, - BVEC2 = 275, - BVEC3 = 276, - BVEC4 = 277, - IVEC2 = 278, - IVEC3 = 279, - IVEC4 = 280, - UVEC2 = 281, - UVEC3 = 282, - UVEC4 = 283, - VEC2 = 284, - VEC3 = 285, - VEC4 = 286, - CENTROID = 287, - IN_TOK = 288, - OUT_TOK = 289, - INOUT_TOK = 290, - UNIFORM = 291, - VARYING = 292, - NOPERSPECTIVE = 293, - FLAT = 294, - SMOOTH = 295, - MAT2X2 = 296, - MAT2X3 = 297, - MAT2X4 = 298, - MAT3X2 = 299, - MAT3X3 = 300, - MAT3X4 = 301, - MAT4X2 = 302, - MAT4X3 = 303, - MAT4X4 = 304, - SAMPLER1D = 305, - SAMPLER2D = 306, - SAMPLER3D = 307, - SAMPLERCUBE = 308, - SAMPLER1DSHADOW = 309, - SAMPLER2DSHADOW = 310, - SAMPLERCUBESHADOW = 311, - SAMPLER1DARRAY = 312, - SAMPLER2DARRAY = 313, - SAMPLER1DARRAYSHADOW = 314, - SAMPLER2DARRAYSHADOW = 315, - ISAMPLER1D = 316, - ISAMPLER2D = 317, - ISAMPLER3D = 318, - ISAMPLERCUBE = 319, - ISAMPLER1DARRAY = 320, - ISAMPLER2DARRAY = 321, - USAMPLER1D = 322, - USAMPLER2D = 323, - USAMPLER3D = 324, - USAMPLERCUBE = 325, - USAMPLER1DARRAY = 326, - USAMPLER2DARRAY = 327, - STRUCT = 328, - VOID_TOK = 329, - WHILE = 330, - IDENTIFIER = 331, - FLOATCONSTANT = 332, - INTCONSTANT = 333, - UINTCONSTANT = 334, - BOOLCONSTANT = 335, - FIELD_SELECTION = 336, - LEFT_OP = 337, - RIGHT_OP = 338, - INC_OP = 339, - DEC_OP = 340, - LE_OP = 341, - GE_OP = 342, - EQ_OP = 343, - NE_OP = 344, - AND_OP = 345, - OR_OP = 346, - XOR_OP = 347, - MUL_ASSIGN = 348, - DIV_ASSIGN = 349, - ADD_ASSIGN = 350, - MOD_ASSIGN = 351, - LEFT_ASSIGN = 352, - RIGHT_ASSIGN = 353, - AND_ASSIGN = 354, - XOR_ASSIGN = 355, - OR_ASSIGN = 356, - SUB_ASSIGN = 357, - INVARIANT = 358, - LOWP = 359, - MEDIUMP = 360, - HIGHP = 361, - SUPERP = 362, - PRECISION = 363, - VERSION = 364, - EXTENSION = 365, - LINE = 366, - COLON = 367, - EOL = 368, - INTERFACE = 369, - OUTPUT = 370, - PRAGMA_DEBUG_ON = 371, - PRAGMA_DEBUG_OFF = 372, - PRAGMA_OPTIMIZE_ON = 373, - PRAGMA_OPTIMIZE_OFF = 374, - PRAGMA_INVARIANT_ALL = 375, - LAYOUT_TOK = 376, - ASM = 377, - CLASS = 378, - UNION = 379, - ENUM = 380, - TYPEDEF = 381, - TEMPLATE = 382, - THIS = 383, - PACKED_TOK = 384, - GOTO = 385, - INLINE_TOK = 386, - NOINLINE = 387, - VOLATILE = 388, - PUBLIC_TOK = 389, - STATIC = 390, - EXTERN = 391, - EXTERNAL = 392, - LONG_TOK = 393, - SHORT_TOK = 394, - DOUBLE_TOK = 395, - HALF = 396, - FIXED_TOK = 397, - UNSIGNED = 398, - INPUT_TOK = 399, - OUPTUT = 400, - HVEC2 = 401, - HVEC3 = 402, - HVEC4 = 403, - DVEC2 = 404, - DVEC3 = 405, - DVEC4 = 406, - FVEC2 = 407, - FVEC3 = 408, - FVEC4 = 409, - SAMPLER2DRECT = 410, - SAMPLER3DRECT = 411, - SAMPLER2DRECTSHADOW = 412, - SIZEOF = 413, - CAST = 414, - NAMESPACE = 415, - USING = 416, - ERROR_TOK = 417, - COMMON = 418, - PARTITION = 419, - ACTIVE = 420, - SAMPLERBUFFER = 421, - FILTER = 422, - IMAGE1D = 423, - IMAGE2D = 424, - IMAGE3D = 425, - IMAGECUBE = 426, - IMAGE1DARRAY = 427, - IMAGE2DARRAY = 428, - IIMAGE1D = 429, - IIMAGE2D = 430, - IIMAGE3D = 431, - IIMAGECUBE = 432, - IIMAGE1DARRAY = 433, - IIMAGE2DARRAY = 434, - UIMAGE1D = 435, - UIMAGE2D = 436, - UIMAGE3D = 437, - UIMAGECUBE = 438, - UIMAGE1DARRAY = 439, - UIMAGE2DARRAY = 440, - IMAGE1DSHADOW = 441, - IMAGE2DSHADOW = 442, - IMAGEBUFFER = 443, - IIMAGEBUFFER = 444, - UIMAGEBUFFER = 445, - IMAGE1DARRAYSHADOW = 446, - IMAGE2DARRAYSHADOW = 447, - ROW_MAJOR = 448 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 1685 of yacc.c */ -#line 52 "glsl_parser.ypp" - - int n; - float real; - char *identifier; - - struct ast_type_qualifier type_qualifier; - - ast_node *node; - ast_type_specifier *type_specifier; - ast_fully_specified_type *fully_specified_type; - ast_function *function; - ast_parameter_declarator *parameter_declarator; - ast_function_definition *function_definition; - ast_compound_statement *compound_statement; - ast_expression *expression; - ast_declarator_list *declarator_list; - ast_struct_specifier *struct_specifier; - ast_declaration *declaration; - - struct { - ast_node *cond; - ast_expression *rest; - } for_rest_statement; - - struct { - ast_node *then_statement; - ast_node *else_statement; - } selection_rest_statement; - - - -/* Line 1685 of yacc.c */ -#line 276 "glsl_parser.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - +/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ATTRIBUTE = 258, + CONST_TOK = 259, + BOOL_TOK = 260, + FLOAT_TOK = 261, + INT_TOK = 262, + UINT_TOK = 263, + BREAK = 264, + CONTINUE = 265, + DO = 266, + ELSE = 267, + FOR = 268, + IF = 269, + DISCARD = 270, + RETURN = 271, + SWITCH = 272, + CASE = 273, + DEFAULT = 274, + BVEC2 = 275, + BVEC3 = 276, + BVEC4 = 277, + IVEC2 = 278, + IVEC3 = 279, + IVEC4 = 280, + UVEC2 = 281, + UVEC3 = 282, + UVEC4 = 283, + VEC2 = 284, + VEC3 = 285, + VEC4 = 286, + CENTROID = 287, + IN_TOK = 288, + OUT_TOK = 289, + INOUT_TOK = 290, + UNIFORM = 291, + VARYING = 292, + NOPERSPECTIVE = 293, + FLAT = 294, + SMOOTH = 295, + MAT2X2 = 296, + MAT2X3 = 297, + MAT2X4 = 298, + MAT3X2 = 299, + MAT3X3 = 300, + MAT3X4 = 301, + MAT4X2 = 302, + MAT4X3 = 303, + MAT4X4 = 304, + SAMPLER1D = 305, + SAMPLER2D = 306, + SAMPLER3D = 307, + SAMPLERCUBE = 308, + SAMPLER1DSHADOW = 309, + SAMPLER2DSHADOW = 310, + SAMPLERCUBESHADOW = 311, + SAMPLER1DARRAY = 312, + SAMPLER2DARRAY = 313, + SAMPLER1DARRAYSHADOW = 314, + SAMPLER2DARRAYSHADOW = 315, + ISAMPLER1D = 316, + ISAMPLER2D = 317, + ISAMPLER3D = 318, + ISAMPLERCUBE = 319, + ISAMPLER1DARRAY = 320, + ISAMPLER2DARRAY = 321, + USAMPLER1D = 322, + USAMPLER2D = 323, + USAMPLER3D = 324, + USAMPLERCUBE = 325, + USAMPLER1DARRAY = 326, + USAMPLER2DARRAY = 327, + STRUCT = 328, + VOID_TOK = 329, + WHILE = 330, + IDENTIFIER = 331, + TYPE_IDENTIFIER = 332, + NEW_IDENTIFIER = 333, + FLOATCONSTANT = 334, + INTCONSTANT = 335, + UINTCONSTANT = 336, + BOOLCONSTANT = 337, + FIELD_SELECTION = 338, + LEFT_OP = 339, + RIGHT_OP = 340, + INC_OP = 341, + DEC_OP = 342, + LE_OP = 343, + GE_OP = 344, + EQ_OP = 345, + NE_OP = 346, + AND_OP = 347, + OR_OP = 348, + XOR_OP = 349, + MUL_ASSIGN = 350, + DIV_ASSIGN = 351, + ADD_ASSIGN = 352, + MOD_ASSIGN = 353, + LEFT_ASSIGN = 354, + RIGHT_ASSIGN = 355, + AND_ASSIGN = 356, + XOR_ASSIGN = 357, + OR_ASSIGN = 358, + SUB_ASSIGN = 359, + INVARIANT = 360, + LOWP = 361, + MEDIUMP = 362, + HIGHP = 363, + SUPERP = 364, + PRECISION = 365, + VERSION = 366, + EXTENSION = 367, + LINE = 368, + COLON = 369, + EOL = 370, + INTERFACE = 371, + OUTPUT = 372, + PRAGMA_DEBUG_ON = 373, + PRAGMA_DEBUG_OFF = 374, + PRAGMA_OPTIMIZE_ON = 375, + PRAGMA_OPTIMIZE_OFF = 376, + PRAGMA_INVARIANT_ALL = 377, + LAYOUT_TOK = 378, + ASM = 379, + CLASS = 380, + UNION = 381, + ENUM = 382, + TYPEDEF = 383, + TEMPLATE = 384, + THIS = 385, + PACKED_TOK = 386, + GOTO = 387, + INLINE_TOK = 388, + NOINLINE = 389, + VOLATILE = 390, + PUBLIC_TOK = 391, + STATIC = 392, + EXTERN = 393, + EXTERNAL = 394, + LONG_TOK = 395, + SHORT_TOK = 396, + DOUBLE_TOK = 397, + HALF = 398, + FIXED_TOK = 399, + UNSIGNED = 400, + INPUT_TOK = 401, + OUPTUT = 402, + HVEC2 = 403, + HVEC3 = 404, + HVEC4 = 405, + DVEC2 = 406, + DVEC3 = 407, + DVEC4 = 408, + FVEC2 = 409, + FVEC3 = 410, + FVEC4 = 411, + SAMPLER2DRECT = 412, + SAMPLER3DRECT = 413, + SAMPLER2DRECTSHADOW = 414, + SIZEOF = 415, + CAST = 416, + NAMESPACE = 417, + USING = 418, + ERROR_TOK = 419, + COMMON = 420, + PARTITION = 421, + ACTIVE = 422, + SAMPLERBUFFER = 423, + FILTER = 424, + IMAGE1D = 425, + IMAGE2D = 426, + IMAGE3D = 427, + IMAGECUBE = 428, + IMAGE1DARRAY = 429, + IMAGE2DARRAY = 430, + IIMAGE1D = 431, + IIMAGE2D = 432, + IIMAGE3D = 433, + IIMAGECUBE = 434, + IIMAGE1DARRAY = 435, + IIMAGE2DARRAY = 436, + UIMAGE1D = 437, + UIMAGE2D = 438, + UIMAGE3D = 439, + UIMAGECUBE = 440, + UIMAGE1DARRAY = 441, + UIMAGE2DARRAY = 442, + IMAGE1DSHADOW = 443, + IMAGE2DSHADOW = 444, + IMAGEBUFFER = 445, + IIMAGEBUFFER = 446, + UIMAGEBUFFER = 447, + IMAGE1DARRAYSHADOW = 448, + IMAGE2DARRAYSHADOW = 449, + ROW_MAJOR = 450 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 1685 of yacc.c */ +#line 52 "glsl_parser.ypp" + + int n; + float real; + char *identifier; + + struct ast_type_qualifier type_qualifier; + + ast_node *node; + ast_type_specifier *type_specifier; + ast_fully_specified_type *fully_specified_type; + ast_function *function; + ast_parameter_declarator *parameter_declarator; + ast_function_definition *function_definition; + ast_compound_statement *compound_statement; + ast_expression *expression; + ast_declarator_list *declarator_list; + ast_struct_specifier *struct_specifier; + ast_declaration *declaration; + + struct { + ast_node *cond; + ast_expression *rest; + } for_rest_statement; + + struct { + ast_node *then_statement; + ast_node *else_statement; + } selection_rest_statement; + + + +/* Line 1685 of yacc.c */ +#line 278 "glsl_parser.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + + diff --git a/mesalib/src/glsl/glsl_parser.ypp b/mesalib/src/glsl/glsl_parser.ypp index d0bebc7fe..29849c1e9 100644 --- a/mesalib/src/glsl/glsl_parser.ypp +++ b/mesalib/src/glsl/glsl_parser.ypp @@ -1,1681 +1,1755 @@ -%{ -/* - * Copyright © 2008, 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include -#include -#include -#include - -#include "ast.h" -#include "glsl_parser_extras.h" -#include "glsl_types.h" - -#define YYLEX_PARAM state->scanner - -%} - -%pure-parser -%error-verbose - -%locations -%initial-action { - @$.first_line = 1; - @$.first_column = 1; - @$.last_line = 1; - @$.last_column = 1; - @$.source = 0; -} - -%lex-param {void *scanner} -%parse-param {struct _mesa_glsl_parse_state *state} - -%union { - int n; - float real; - char *identifier; - - struct ast_type_qualifier type_qualifier; - - ast_node *node; - ast_type_specifier *type_specifier; - ast_fully_specified_type *fully_specified_type; - ast_function *function; - ast_parameter_declarator *parameter_declarator; - ast_function_definition *function_definition; - ast_compound_statement *compound_statement; - ast_expression *expression; - ast_declarator_list *declarator_list; - ast_struct_specifier *struct_specifier; - ast_declaration *declaration; - - struct { - ast_node *cond; - ast_expression *rest; - } for_rest_statement; - - struct { - ast_node *then_statement; - ast_node *else_statement; - } selection_rest_statement; -} - -%token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK -%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT -%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 -%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING -%token NOPERSPECTIVE FLAT SMOOTH -%token MAT2X2 MAT2X3 MAT2X4 -%token MAT3X2 MAT3X3 MAT3X4 -%token MAT4X2 MAT4X3 MAT4X4 -%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW -%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW -%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE -%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D -%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY -%token STRUCT VOID_TOK WHILE -%token IDENTIFIER -%token FLOATCONSTANT -%token INTCONSTANT UINTCONSTANT BOOLCONSTANT -%token FIELD_SELECTION -%token LEFT_OP RIGHT_OP -%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP -%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN -%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN -%token SUB_ASSIGN -%token INVARIANT -%token LOWP MEDIUMP HIGHP SUPERP PRECISION - -%token VERSION EXTENSION LINE COLON EOL INTERFACE OUTPUT -%token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF -%token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF -%token PRAGMA_INVARIANT_ALL -%token LAYOUT_TOK - - /* Reserved words that are not actually used in the grammar. - */ -%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED_TOK GOTO -%token INLINE_TOK NOINLINE VOLATILE PUBLIC_TOK STATIC EXTERN EXTERNAL -%token LONG_TOK SHORT_TOK DOUBLE_TOK HALF FIXED_TOK UNSIGNED INPUT_TOK OUPTUT -%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4 -%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW -%token SIZEOF CAST NAMESPACE USING - -%token ERROR_TOK - -%token COMMON PARTITION ACTIVE SAMPLERBUFFER FILTER -%token IMAGE1D IMAGE2D IMAGE3D IMAGECUBE IMAGE1DARRAY IMAGE2DARRAY -%token IIMAGE1D IIMAGE2D IIMAGE3D IIMAGECUBE IIMAGE1DARRAY IIMAGE2DARRAY -%token UIMAGE1D UIMAGE2D UIMAGE3D UIMAGECUBE UIMAGE1DARRAY UIMAGE2DARRAY -%token IMAGE1DSHADOW IMAGE2DSHADOW IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER -%token IMAGE1DARRAYSHADOW IMAGE2DARRAYSHADOW -%token ROW_MAJOR - -%type variable_identifier -%type statement -%type statement_list -%type simple_statement -%type precision_qualifier -%type type_qualifier -%type storage_qualifier -%type interpolation_qualifier -%type layout_qualifier -%type layout_qualifier_id_list layout_qualifier_id -%type type_specifier -%type type_specifier_no_prec -%type type_specifier_nonarray -%type basic_type_specifier_nonarray -%type fully_specified_type -%type function_prototype -%type function_header -%type function_header_with_parameters -%type function_declarator -%type parameter_declarator -%type parameter_declaration -%type parameter_qualifier -%type parameter_type_qualifier -%type parameter_type_specifier -%type function_definition -%type compound_statement_no_new_scope -%type compound_statement -%type statement_no_new_scope -%type expression_statement -%type expression -%type primary_expression -%type assignment_expression -%type conditional_expression -%type logical_or_expression -%type logical_xor_expression -%type logical_and_expression -%type inclusive_or_expression -%type exclusive_or_expression -%type and_expression -%type equality_expression -%type relational_expression -%type shift_expression -%type additive_expression -%type multiplicative_expression -%type unary_expression -%type constant_expression -%type integer_expression -%type postfix_expression -%type function_call_header_with_parameters -%type function_call_header_no_parameters -%type function_call_header -%type function_call_generic -%type function_call_or_method -%type function_call -%type assignment_operator -%type unary_operator -%type function_identifier -%type external_declaration -%type init_declarator_list -%type single_declaration -%type initializer -%type declaration -%type declaration_statement -%type jump_statement -%type struct_specifier -%type struct_declaration_list -%type struct_declaration -%type struct_declarator -%type struct_declarator_list -%type selection_statement -%type selection_rest_statement -%type iteration_statement -%type condition -%type conditionopt -%type for_init_statement -%type for_rest_statement -%% - -translation_unit: - version_statement extension_statement_list - { - _mesa_glsl_initialize_types(state); - } - external_declaration_list - ; - -version_statement: - /* blank - no #version specified: defaults are already set */ - | VERSION INTCONSTANT EOL - { - bool supported = false; - - switch ($2) { - case 100: - state->es_shader = true; - supported = state->Const.GLSL_100ES; - break; - case 110: - supported = state->Const.GLSL_110; - break; - case 120: - supported = state->Const.GLSL_120; - break; - case 130: - supported = state->Const.GLSL_130; - break; - default: - supported = false; - break; - } - - state->language_version = $2; - state->version_string = - ralloc_asprintf(state, "GLSL%s %d.%02d", - state->es_shader ? " ES" : "", - state->language_version / 100, - state->language_version % 100); - - if (!supported) { - _mesa_glsl_error(& @2, state, "%s is not supported. " - "Supported versions are: %s\n", - state->version_string, - state->supported_version_string); - } - } - ; - -pragma_statement: - PRAGMA_DEBUG_ON EOL - | PRAGMA_DEBUG_OFF EOL - | PRAGMA_OPTIMIZE_ON EOL - | PRAGMA_OPTIMIZE_OFF EOL - | PRAGMA_INVARIANT_ALL EOL - { - if (state->language_version < 120) { - _mesa_glsl_warning(& @1, state, - "pragma `invariant(all)' not supported in %s", - state->version_string); - } else { - state->all_invariant = true; - } - } - ; - -extension_statement_list: - - | extension_statement_list extension_statement - ; - -extension_statement: - EXTENSION IDENTIFIER COLON IDENTIFIER EOL - { - if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) { - YYERROR; - } - } - ; - -external_declaration_list: - external_declaration - { - /* FINISHME: The NULL test is required because pragmas are set to - * FINISHME: NULL. (See production rule for external_declaration.) - */ - if ($1 != NULL) - state->translation_unit.push_tail(& $1->link); - } - | external_declaration_list external_declaration - { - /* FINISHME: The NULL test is required because pragmas are set to - * FINISHME: NULL. (See production rule for external_declaration.) - */ - if ($2 != NULL) - state->translation_unit.push_tail(& $2->link); - } - ; - -variable_identifier: - IDENTIFIER - ; - -primary_expression: - variable_identifier - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.identifier = $1; - } - | INTCONSTANT - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.int_constant = $1; - } - | UINTCONSTANT - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.uint_constant = $1; - } - | FLOATCONSTANT - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.float_constant = $1; - } - | BOOLCONSTANT - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.bool_constant = $1; - } - | '(' expression ')' - { - $$ = $2; - } - ; - -postfix_expression: - primary_expression - | postfix_expression '[' integer_expression ']' - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); - $$->set_location(yylloc); - } - | function_call - { - $$ = $1; - } - | postfix_expression '.' IDENTIFIER - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); - $$->set_location(yylloc); - $$->primary_expression.identifier = $3; - } - | postfix_expression INC_OP - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); - $$->set_location(yylloc); - } - | postfix_expression DEC_OP - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); - $$->set_location(yylloc); - } - ; - -integer_expression: - expression - ; - -function_call: - function_call_or_method - ; - -function_call_or_method: - function_call_generic - | postfix_expression '.' function_call_generic - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL); - $$->set_location(yylloc); - } - ; - -function_call_generic: - function_call_header_with_parameters ')' - | function_call_header_no_parameters ')' - ; - -function_call_header_no_parameters: - function_call_header VOID_TOK - | function_call_header - ; - -function_call_header_with_parameters: - function_call_header assignment_expression - { - $$ = $1; - $$->set_location(yylloc); - $$->expressions.push_tail(& $2->link); - } - | function_call_header_with_parameters ',' assignment_expression - { - $$ = $1; - $$->set_location(yylloc); - $$->expressions.push_tail(& $3->link); - } - ; - - // Grammar Note: Constructors look like functions, but lexical - // analysis recognized most of them as keywords. They are now - // recognized through "type_specifier". -function_call_header: - function_identifier '(' - ; - -function_identifier: - type_specifier - { - void *ctx = state; - $$ = new(ctx) ast_function_expression($1); - $$->set_location(yylloc); - } - | IDENTIFIER - { - void *ctx = state; - ast_expression *callee = new(ctx) ast_expression($1); - $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); - } - | FIELD_SELECTION - { - void *ctx = state; - ast_expression *callee = new(ctx) ast_expression($1); - $$ = new(ctx) ast_function_expression(callee); - $$->set_location(yylloc); - } - ; - - // Grammar Note: No traditional style type casts. -unary_expression: - postfix_expression - | INC_OP unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); - $$->set_location(yylloc); - } - | DEC_OP unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); - $$->set_location(yylloc); - } - | unary_operator unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression($1, $2, NULL, NULL); - $$->set_location(yylloc); - } - ; - - // Grammar Note: No '*' or '&' unary ops. Pointers are not supported. -unary_operator: - '+' { $$ = ast_plus; } - | '-' { $$ = ast_neg; } - | '!' { $$ = ast_logic_not; } - | '~' { $$ = ast_bit_not; } - ; - -multiplicative_expression: - unary_expression - | multiplicative_expression '*' unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); - $$->set_location(yylloc); - } - | multiplicative_expression '/' unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); - $$->set_location(yylloc); - } - | multiplicative_expression '%' unary_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); - $$->set_location(yylloc); - } - ; - -additive_expression: - multiplicative_expression - | additive_expression '+' multiplicative_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); - $$->set_location(yylloc); - } - | additive_expression '-' multiplicative_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); - $$->set_location(yylloc); - } - ; - -shift_expression: - additive_expression - | shift_expression LEFT_OP additive_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); - $$->set_location(yylloc); - } - | shift_expression RIGHT_OP additive_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); - $$->set_location(yylloc); - } - ; - -relational_expression: - shift_expression - | relational_expression '<' shift_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); - $$->set_location(yylloc); - } - | relational_expression '>' shift_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); - $$->set_location(yylloc); - } - | relational_expression LE_OP shift_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); - $$->set_location(yylloc); - } - | relational_expression GE_OP shift_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); - $$->set_location(yylloc); - } - ; - -equality_expression: - relational_expression - | equality_expression EQ_OP relational_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); - $$->set_location(yylloc); - } - | equality_expression NE_OP relational_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); - $$->set_location(yylloc); - } - ; - -and_expression: - equality_expression - | and_expression '&' equality_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_bit_and, $1, $3); - $$->set_location(yylloc); - } - ; - -exclusive_or_expression: - and_expression - | exclusive_or_expression '^' and_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); - $$->set_location(yylloc); - } - ; - -inclusive_or_expression: - exclusive_or_expression - | inclusive_or_expression '|' exclusive_or_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); - $$->set_location(yylloc); - } - ; - -logical_and_expression: - inclusive_or_expression - | logical_and_expression AND_OP inclusive_or_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); - $$->set_location(yylloc); - } - ; - -logical_xor_expression: - logical_and_expression - | logical_xor_expression XOR_OP logical_and_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); - $$->set_location(yylloc); - } - ; - -logical_or_expression: - logical_xor_expression - | logical_or_expression OR_OP logical_xor_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); - $$->set_location(yylloc); - } - ; - -conditional_expression: - logical_or_expression - | logical_or_expression '?' expression ':' assignment_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); - $$->set_location(yylloc); - } - ; - -assignment_expression: - conditional_expression - | unary_expression assignment_operator assignment_expression - { - void *ctx = state; - $$ = new(ctx) ast_expression($2, $1, $3, NULL); - $$->set_location(yylloc); - } - ; - -assignment_operator: - '=' { $$ = ast_assign; } - | MUL_ASSIGN { $$ = ast_mul_assign; } - | DIV_ASSIGN { $$ = ast_div_assign; } - | MOD_ASSIGN { $$ = ast_mod_assign; } - | ADD_ASSIGN { $$ = ast_add_assign; } - | SUB_ASSIGN { $$ = ast_sub_assign; } - | LEFT_ASSIGN { $$ = ast_ls_assign; } - | RIGHT_ASSIGN { $$ = ast_rs_assign; } - | AND_ASSIGN { $$ = ast_and_assign; } - | XOR_ASSIGN { $$ = ast_xor_assign; } - | OR_ASSIGN { $$ = ast_or_assign; } - ; - -expression: - assignment_expression - { - $$ = $1; - } - | expression ',' assignment_expression - { - void *ctx = state; - if ($1->oper != ast_sequence) { - $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); - $$->set_location(yylloc); - $$->expressions.push_tail(& $1->link); - } else { - $$ = $1; - } - - $$->expressions.push_tail(& $3->link); - } - ; - -constant_expression: - conditional_expression - ; - -declaration: - function_prototype ';' - { - $$ = $1; - } - | init_declarator_list ';' - { - $$ = $1; - } - | PRECISION precision_qualifier type_specifier_no_prec ';' - { - $3->precision = $2; - $3->is_precision_statement = true; - $$ = $3; - } - ; - -function_prototype: - function_declarator ')' - ; - -function_declarator: - function_header - | function_header_with_parameters - ; - -function_header_with_parameters: - function_header parameter_declaration - { - $$ = $1; - $$->parameters.push_tail(& $2->link); - } - | function_header_with_parameters ',' parameter_declaration - { - $$ = $1; - $$->parameters.push_tail(& $3->link); - } - ; - -function_header: - fully_specified_type IDENTIFIER '(' - { - void *ctx = state; - $$ = new(ctx) ast_function(); - $$->set_location(yylloc); - $$->return_type = $1; - $$->identifier = $2; - } - ; - -parameter_declarator: - type_specifier IDENTIFIER - { - void *ctx = state; - $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); - $$->type = new(ctx) ast_fully_specified_type(); - $$->type->set_location(yylloc); - $$->type->specifier = $1; - $$->identifier = $2; - } - | type_specifier IDENTIFIER '[' constant_expression ']' - { - void *ctx = state; - $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); - $$->type = new(ctx) ast_fully_specified_type(); - $$->type->set_location(yylloc); - $$->type->specifier = $1; - $$->identifier = $2; - $$->is_array = true; - $$->array_size = $4; - } - ; - -parameter_declaration: - parameter_type_qualifier parameter_qualifier parameter_declarator - { - $1.flags.i |= $2.flags.i; - - $$ = $3; - $$->type->qualifier = $1; - } - | parameter_qualifier parameter_declarator - { - $$ = $2; - $$->type->qualifier = $1; - } - | parameter_type_qualifier parameter_qualifier parameter_type_specifier - { - void *ctx = state; - $1.flags.i |= $2.flags.i; - - $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); - $$->type = new(ctx) ast_fully_specified_type(); - $$->type->qualifier = $1; - $$->type->specifier = $3; - } - | parameter_qualifier parameter_type_specifier - { - void *ctx = state; - $$ = new(ctx) ast_parameter_declarator(); - $$->set_location(yylloc); - $$->type = new(ctx) ast_fully_specified_type(); - $$->type->qualifier = $1; - $$->type->specifier = $2; - } - ; - -parameter_qualifier: - /* empty */ - { - memset(& $$, 0, sizeof($$)); - } - | IN_TOK - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.in = 1; - } - | OUT_TOK - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.out = 1; - } - | INOUT_TOK - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.in = 1; - $$.flags.q.out = 1; - } - ; - -parameter_type_specifier: - type_specifier - ; - -init_declarator_list: - single_declaration - | init_declarator_list ',' IDENTIFIER - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '[' ']' - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - | init_declarator_list ',' IDENTIFIER '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5); - decl->set_location(yylloc); - - $$ = $1; - $$->declarations.push_tail(&decl->link); - } - ; - - // Grammar Note: No 'enum', or 'typedef'. -single_declaration: - fully_specified_type - { - void *ctx = state; - if ($1->specifier->type_specifier != ast_struct) { - _mesa_glsl_error(& @1, state, "empty declaration list\n"); - YYERROR; - } else { - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - } - } - | fully_specified_type IDENTIFIER - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '[' ']' - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '[' constant_expression ']' - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '[' ']' '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | fully_specified_type IDENTIFIER '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); - - $$ = new(ctx) ast_declarator_list($1); - $$->set_location(yylloc); - $$->declarations.push_tail(&decl->link); - } - | INVARIANT IDENTIFIER // Vertex only. - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); - - $$ = new(ctx) ast_declarator_list(NULL); - $$->set_location(yylloc); - $$->invariant = true; - - $$->declarations.push_tail(&decl->link); - } - ; - -fully_specified_type: - type_specifier - { - void *ctx = state; - $$ = new(ctx) ast_fully_specified_type(); - $$->set_location(yylloc); - $$->specifier = $1; - } - | type_qualifier type_specifier - { - void *ctx = state; - $$ = new(ctx) ast_fully_specified_type(); - $$->set_location(yylloc); - $$->qualifier = $1; - $$->specifier = $2; - } - ; - -layout_qualifier: - LAYOUT_TOK '(' layout_qualifier_id_list ')' - { - $$ = $3; - } - ; - -layout_qualifier_id_list: - layout_qualifier_id - | layout_qualifier_id_list ',' layout_qualifier_id - { - if (($1.flags.i & $3.flags.i) != 0) { - _mesa_glsl_error(& @3, state, - "duplicate layout qualifiers used\n"); - YYERROR; - } - - $$.flags.i = $1.flags.i | $3.flags.i; - - if ($1.flags.q.explicit_location) - $$.location = $1.location; - - if ($3.flags.q.explicit_location) - $$.location = $3.location; - } - ; - -layout_qualifier_id: - IDENTIFIER - { - bool got_one = false; - - memset(& $$, 0, sizeof($$)); - - /* Layout qualifiers for ARB_fragment_coord_conventions. */ - if (!got_one && state->ARB_fragment_coord_conventions_enable) { - if (strcmp($1, "origin_upper_left") == 0) { - got_one = true; - $$.flags.q.origin_upper_left = 1; - } else if (strcmp($1, "pixel_center_integer") == 0) { - got_one = true; - $$.flags.q.pixel_center_integer = 1; - } - - if (got_one && state->ARB_fragment_coord_conventions_warn) { - _mesa_glsl_warning(& @1, state, - "GL_ARB_fragment_coord_conventions layout " - "identifier `%s' used\n", $1); - } - } - - /* Layout qualifiers for AMD_conservative_depth. */ - if (!got_one && state->AMD_conservative_depth_enable) { - if (strcmp($1, "depth_any") == 0) { - got_one = true; - $$.flags.q.depth_any = 1; - } else if (strcmp($1, "depth_greater") == 0) { - got_one = true; - $$.flags.q.depth_greater = 1; - } else if (strcmp($1, "depth_less") == 0) { - got_one = true; - $$.flags.q.depth_less = 1; - } else if (strcmp($1, "depth_unchanged") == 0) { - got_one = true; - $$.flags.q.depth_unchanged = 1; - } - - if (got_one && state->AMD_conservative_depth_warn) { - _mesa_glsl_warning(& @1, state, - "GL_AMD_conservative_depth " - "layout qualifier `%s' is used\n", $1); - } - } - - if (!got_one) { - _mesa_glsl_error(& @1, state, "unrecognized layout identifier " - "`%s'\n", $1); - YYERROR; - } - } - | IDENTIFIER '=' INTCONSTANT - { - bool got_one = false; - - memset(& $$, 0, sizeof($$)); - - if (state->ARB_explicit_attrib_location_enable) { - /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and - * FINISHME: GLSL 1.30 (or later) are supported. - */ - if (strcmp("location", $1) == 0) { - got_one = true; - - $$.flags.q.explicit_location = 1; - - if ($3 >= 0) { - $$.location = $3; - } else { - _mesa_glsl_error(& @3, state, - "invalid location %d specified\n", $3); - YYERROR; - } - } - } - - /* If the identifier didn't match any known layout identifiers, - * emit an error. - */ - if (!got_one) { - _mesa_glsl_error(& @1, state, "unrecognized layout identifier " - "`%s'\n", $1); - YYERROR; - } else if (state->ARB_explicit_attrib_location_warn) { - _mesa_glsl_warning(& @1, state, - "GL_ARB_explicit_attrib_location layout " - "identifier `%s' used\n", $1); - } - } - ; - -interpolation_qualifier: - SMOOTH - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.smooth = 1; - } - | FLAT - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.flat = 1; - } - | NOPERSPECTIVE - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.noperspective = 1; - } - ; - -parameter_type_qualifier: - CONST_TOK - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.constant = 1; - } - ; - -type_qualifier: - storage_qualifier - | layout_qualifier - | layout_qualifier storage_qualifier - { - $$ = $1; - $$.flags.i |= $2.flags.i; - } - | interpolation_qualifier - | interpolation_qualifier storage_qualifier - { - $$ = $1; - $$.flags.i |= $2.flags.i; - } - | INVARIANT storage_qualifier - { - $$ = $2; - $$.flags.q.invariant = 1; - } - | INVARIANT interpolation_qualifier storage_qualifier - { - $$ = $2; - $$.flags.i |= $3.flags.i; - $$.flags.q.invariant = 1; - } - | INVARIANT - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.invariant = 1; - } - ; - -storage_qualifier: - CONST_TOK - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.constant = 1; - } - | ATTRIBUTE - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.attribute = 1; - } - | VARYING - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.varying = 1; - } - | CENTROID VARYING - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.centroid = 1; - $$.flags.q.varying = 1; - } - | IN_TOK - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.in = 1; - } - | OUT_TOK - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.out = 1; - } - | CENTROID IN_TOK - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.centroid = 1; $$.flags.q.in = 1; - } - | CENTROID OUT_TOK - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.centroid = 1; $$.flags.q.out = 1; - } - | UNIFORM - { - memset(& $$, 0, sizeof($$)); - $$.flags.q.uniform = 1; - } - ; - -type_specifier: - type_specifier_no_prec - { - $$ = $1; - } - | precision_qualifier type_specifier_no_prec - { - $$ = $2; - $$->precision = $1; - } - ; - -type_specifier_no_prec: - type_specifier_nonarray - | type_specifier_nonarray '[' ']' - { - $$ = $1; - $$->is_array = true; - $$->array_size = NULL; - } - | type_specifier_nonarray '[' constant_expression ']' - { - $$ = $1; - $$->is_array = true; - $$->array_size = $3; - } - ; - -type_specifier_nonarray: - basic_type_specifier_nonarray - { - void *ctx = state; - $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); - } - | struct_specifier - { - void *ctx = state; - $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); - } - | IDENTIFIER - { - void *ctx = state; - $$ = new(ctx) ast_type_specifier($1); - $$->set_location(yylloc); - } - ; - -basic_type_specifier_nonarray: - VOID_TOK { $$ = ast_void; } - | FLOAT_TOK { $$ = ast_float; } - | INT_TOK { $$ = ast_int; } - | UINT_TOK { $$ = ast_uint; } - | BOOL_TOK { $$ = ast_bool; } - | VEC2 { $$ = ast_vec2; } - | VEC3 { $$ = ast_vec3; } - | VEC4 { $$ = ast_vec4; } - | BVEC2 { $$ = ast_bvec2; } - | BVEC3 { $$ = ast_bvec3; } - | BVEC4 { $$ = ast_bvec4; } - | IVEC2 { $$ = ast_ivec2; } - | IVEC3 { $$ = ast_ivec3; } - | IVEC4 { $$ = ast_ivec4; } - | UVEC2 { $$ = ast_uvec2; } - | UVEC3 { $$ = ast_uvec3; } - | UVEC4 { $$ = ast_uvec4; } - | MAT2X2 { $$ = ast_mat2; } - | MAT2X3 { $$ = ast_mat2x3; } - | MAT2X4 { $$ = ast_mat2x4; } - | MAT3X2 { $$ = ast_mat3x2; } - | MAT3X3 { $$ = ast_mat3; } - | MAT3X4 { $$ = ast_mat3x4; } - | MAT4X2 { $$ = ast_mat4x2; } - | MAT4X3 { $$ = ast_mat4x3; } - | MAT4X4 { $$ = ast_mat4; } - | SAMPLER1D { $$ = ast_sampler1d; } - | SAMPLER2D { $$ = ast_sampler2d; } - | SAMPLER2DRECT { $$ = ast_sampler2drect; } - | SAMPLER3D { $$ = ast_sampler3d; } - | SAMPLERCUBE { $$ = ast_samplercube; } - | SAMPLER1DSHADOW { $$ = ast_sampler1dshadow; } - | SAMPLER2DSHADOW { $$ = ast_sampler2dshadow; } - | SAMPLER2DRECTSHADOW { $$ = ast_sampler2drectshadow; } - | SAMPLERCUBESHADOW { $$ = ast_samplercubeshadow; } - | SAMPLER1DARRAY { $$ = ast_sampler1darray; } - | SAMPLER2DARRAY { $$ = ast_sampler2darray; } - | SAMPLER1DARRAYSHADOW { $$ = ast_sampler1darrayshadow; } - | SAMPLER2DARRAYSHADOW { $$ = ast_sampler2darrayshadow; } - | ISAMPLER1D { $$ = ast_isampler1d; } - | ISAMPLER2D { $$ = ast_isampler2d; } - | ISAMPLER3D { $$ = ast_isampler3d; } - | ISAMPLERCUBE { $$ = ast_isamplercube; } - | ISAMPLER1DARRAY { $$ = ast_isampler1darray; } - | ISAMPLER2DARRAY { $$ = ast_isampler2darray; } - | USAMPLER1D { $$ = ast_usampler1d; } - | USAMPLER2D { $$ = ast_usampler2d; } - | USAMPLER3D { $$ = ast_usampler3d; } - | USAMPLERCUBE { $$ = ast_usamplercube; } - | USAMPLER1DARRAY { $$ = ast_usampler1darray; } - | USAMPLER2DARRAY { $$ = ast_usampler2darray; } - ; - -precision_qualifier: - HIGHP { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& @1, state, - "precision qualifier forbidden " - "in %s (1.30 or later " - "required)\n", - state->version_string); - - $$ = ast_precision_high; - } - | MEDIUMP { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& @1, state, - "precision qualifier forbidden " - "in %s (1.30 or later " - "required)\n", - state->version_string); - - $$ = ast_precision_medium; - } - | LOWP { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& @1, state, - "precision qualifier forbidden " - "in %s (1.30 or later " - "required)\n", - state->version_string); - - $$ = ast_precision_low; - } - ; - -struct_specifier: - STRUCT IDENTIFIER '{' struct_declaration_list '}' - { - void *ctx = state; - $$ = new(ctx) ast_struct_specifier($2, $4); - $$->set_location(yylloc); - } - | STRUCT '{' struct_declaration_list '}' - { - void *ctx = state; - $$ = new(ctx) ast_struct_specifier(NULL, $3); - $$->set_location(yylloc); - } - ; - -struct_declaration_list: - struct_declaration - { - $$ = (ast_node *) $1; - $1->link.self_link(); - } - | struct_declaration_list struct_declaration - { - $$ = (ast_node *) $1; - $$->link.insert_before(& $2->link); - } - ; - -struct_declaration: - type_specifier struct_declarator_list ';' - { - void *ctx = state; - ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); - type->set_location(yylloc); - - type->specifier = $1; - $$ = new(ctx) ast_declarator_list(type); - $$->set_location(yylloc); - - $$->declarations.push_degenerate_list_at_head(& $2->link); - } - ; - -struct_declarator_list: - struct_declarator - { - $$ = $1; - $1->link.self_link(); - } - | struct_declarator_list ',' struct_declarator - { - $$ = $1; - $$->link.insert_before(& $3->link); - } - ; - -struct_declarator: - IDENTIFIER - { - void *ctx = state; - $$ = new(ctx) ast_declaration($1, false, NULL, NULL); - $$->set_location(yylloc); - } - | IDENTIFIER '[' constant_expression ']' - { - void *ctx = state; - $$ = new(ctx) ast_declaration($1, true, $3, NULL); - $$->set_location(yylloc); - } - ; - -initializer: - assignment_expression - ; - -declaration_statement: - declaration - ; - - // Grammar Note: labeled statements for SWITCH only; 'goto' is not - // supported. -statement: - compound_statement { $$ = (ast_node *) $1; } - | simple_statement - ; - -simple_statement: - declaration_statement - | expression_statement - | selection_statement - | switch_statement { $$ = NULL; } - | case_label { $$ = NULL; } - | iteration_statement - | jump_statement - ; - -compound_statement: - '{' '}' - { - void *ctx = state; - $$ = new(ctx) ast_compound_statement(true, NULL); - $$->set_location(yylloc); - } - | '{' statement_list '}' - { - void *ctx = state; - $$ = new(ctx) ast_compound_statement(true, $2); - $$->set_location(yylloc); - } - ; - -statement_no_new_scope: - compound_statement_no_new_scope { $$ = (ast_node *) $1; } - | simple_statement - ; - -compound_statement_no_new_scope: - '{' '}' - { - void *ctx = state; - $$ = new(ctx) ast_compound_statement(false, NULL); - $$->set_location(yylloc); - } - | '{' statement_list '}' - { - void *ctx = state; - $$ = new(ctx) ast_compound_statement(false, $2); - $$->set_location(yylloc); - } - ; - -statement_list: - statement - { - if ($1 == NULL) { - _mesa_glsl_error(& @1, state, " statement\n"); - assert($1 != NULL); - } - - $$ = $1; - $$->link.self_link(); - } - | statement_list statement - { - if ($2 == NULL) { - _mesa_glsl_error(& @2, state, " statement\n"); - assert($2 != NULL); - } - $$ = $1; - $$->link.insert_before(& $2->link); - } - ; - -expression_statement: - ';' - { - void *ctx = state; - $$ = new(ctx) ast_expression_statement(NULL); - $$->set_location(yylloc); - } - | expression ';' - { - void *ctx = state; - $$ = new(ctx) ast_expression_statement($1); - $$->set_location(yylloc); - } - ; - -selection_statement: - IF '(' expression ')' selection_rest_statement - { - $$ = new(state) ast_selection_statement($3, $5.then_statement, - $5.else_statement); - $$->set_location(yylloc); - } - ; - -selection_rest_statement: - statement ELSE statement - { - $$.then_statement = $1; - $$.else_statement = $3; - } - | statement - { - $$.then_statement = $1; - $$.else_statement = NULL; - } - ; - -condition: - expression - { - $$ = (ast_node *) $1; - } - | fully_specified_type IDENTIFIER '=' initializer - { - void *ctx = state; - ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); - ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); - decl->set_location(yylloc); - declarator->set_location(yylloc); - - declarator->declarations.push_tail(&decl->link); - $$ = declarator; - } - ; - -switch_statement: - SWITCH '(' expression ')' compound_statement - ; - -case_label: - CASE expression ':' - | DEFAULT ':' - ; - -iteration_statement: - WHILE '(' condition ')' statement_no_new_scope - { - void *ctx = state; - $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, - NULL, $3, NULL, $5); - $$->set_location(yylloc); - } - | DO statement WHILE '(' expression ')' ';' - { - void *ctx = state; - $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, - NULL, $5, NULL, $2); - $$->set_location(yylloc); - } - | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope - { - void *ctx = state; - $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, - $3, $4.cond, $4.rest, $6); - $$->set_location(yylloc); - } - ; - -for_init_statement: - expression_statement - | declaration_statement - ; - -conditionopt: - condition - | /* empty */ - { - $$ = NULL; - } - ; - -for_rest_statement: - conditionopt ';' - { - $$.cond = $1; - $$.rest = NULL; - } - | conditionopt ';' expression - { - $$.cond = $1; - $$.rest = $3; - } - ; - - // Grammar Note: No 'goto'. Gotos are not supported. -jump_statement: - CONTINUE ';' - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); - $$->set_location(yylloc); - } - | BREAK ';' - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); - $$->set_location(yylloc); - } - | RETURN ';' - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); - $$->set_location(yylloc); - } - | RETURN expression ';' - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); - $$->set_location(yylloc); - } - | DISCARD ';' // Fragment shader only. - { - void *ctx = state; - $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); - $$->set_location(yylloc); - } - ; - -external_declaration: - function_definition { $$ = $1; } - | declaration { $$ = $1; } - | pragma_statement { $$ = NULL; } - ; - -function_definition: - function_prototype compound_statement_no_new_scope - { - void *ctx = state; - $$ = new(ctx) ast_function_definition(); - $$->set_location(yylloc); - $$->prototype = $1; - $$->body = $2; - } - ; +%{ +/* + * Copyright © 2008, 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include +#include +#include +#include + +#include "ast.h" +#include "glsl_parser_extras.h" +#include "glsl_types.h" + +#define YYLEX_PARAM state->scanner + +%} + +%pure-parser +%error-verbose + +%locations +%initial-action { + @$.first_line = 1; + @$.first_column = 1; + @$.last_line = 1; + @$.last_column = 1; + @$.source = 0; +} + +%lex-param {void *scanner} +%parse-param {struct _mesa_glsl_parse_state *state} + +%union { + int n; + float real; + char *identifier; + + struct ast_type_qualifier type_qualifier; + + ast_node *node; + ast_type_specifier *type_specifier; + ast_fully_specified_type *fully_specified_type; + ast_function *function; + ast_parameter_declarator *parameter_declarator; + ast_function_definition *function_definition; + ast_compound_statement *compound_statement; + ast_expression *expression; + ast_declarator_list *declarator_list; + ast_struct_specifier *struct_specifier; + ast_declaration *declaration; + + struct { + ast_node *cond; + ast_expression *rest; + } for_rest_statement; + + struct { + ast_node *then_statement; + ast_node *else_statement; + } selection_rest_statement; +} + +%token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK +%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 +%token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING +%token NOPERSPECTIVE FLAT SMOOTH +%token MAT2X2 MAT2X3 MAT2X4 +%token MAT3X2 MAT3X3 MAT3X4 +%token MAT4X2 MAT4X3 MAT4X4 +%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW +%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW +%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE +%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D +%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY +%token STRUCT VOID_TOK WHILE +%token IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER +%type any_identifier +%token FLOATCONSTANT +%token INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token FIELD_SELECTION +%token LEFT_OP RIGHT_OP +%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP +%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN +%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN +%token SUB_ASSIGN +%token INVARIANT +%token LOWP MEDIUMP HIGHP SUPERP PRECISION + +%token VERSION EXTENSION LINE COLON EOL INTERFACE OUTPUT +%token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF +%token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF +%token PRAGMA_INVARIANT_ALL +%token LAYOUT_TOK + + /* Reserved words that are not actually used in the grammar. + */ +%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED_TOK GOTO +%token INLINE_TOK NOINLINE VOLATILE PUBLIC_TOK STATIC EXTERN EXTERNAL +%token LONG_TOK SHORT_TOK DOUBLE_TOK HALF FIXED_TOK UNSIGNED INPUT_TOK OUPTUT +%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4 +%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW +%token SIZEOF CAST NAMESPACE USING + +%token ERROR_TOK + +%token COMMON PARTITION ACTIVE SAMPLERBUFFER FILTER +%token IMAGE1D IMAGE2D IMAGE3D IMAGECUBE IMAGE1DARRAY IMAGE2DARRAY +%token IIMAGE1D IIMAGE2D IIMAGE3D IIMAGECUBE IIMAGE1DARRAY IIMAGE2DARRAY +%token UIMAGE1D UIMAGE2D UIMAGE3D UIMAGECUBE UIMAGE1DARRAY UIMAGE2DARRAY +%token IMAGE1DSHADOW IMAGE2DSHADOW IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER +%token IMAGE1DARRAYSHADOW IMAGE2DARRAYSHADOW +%token ROW_MAJOR + +%type variable_identifier +%type statement +%type statement_list +%type simple_statement +%type precision_qualifier +%type type_qualifier +%type storage_qualifier +%type interpolation_qualifier +%type layout_qualifier +%type layout_qualifier_id_list layout_qualifier_id +%type type_specifier +%type type_specifier_no_prec +%type type_specifier_nonarray +%type basic_type_specifier_nonarray +%type fully_specified_type +%type function_prototype +%type function_header +%type function_header_with_parameters +%type function_declarator +%type parameter_declarator +%type parameter_declaration +%type parameter_qualifier +%type parameter_type_qualifier +%type parameter_type_specifier +%type function_definition +%type compound_statement_no_new_scope +%type compound_statement +%type statement_no_new_scope +%type expression_statement +%type expression +%type primary_expression +%type assignment_expression +%type conditional_expression +%type logical_or_expression +%type logical_xor_expression +%type logical_and_expression +%type inclusive_or_expression +%type exclusive_or_expression +%type and_expression +%type equality_expression +%type relational_expression +%type shift_expression +%type additive_expression +%type multiplicative_expression +%type unary_expression +%type constant_expression +%type integer_expression +%type postfix_expression +%type function_call_header_with_parameters +%type function_call_header_no_parameters +%type function_call_header +%type function_call_generic +%type function_call_or_method +%type function_call +%type method_call_generic +%type method_call_header_with_parameters +%type method_call_header_no_parameters +%type method_call_header +%type assignment_operator +%type unary_operator +%type function_identifier +%type external_declaration +%type init_declarator_list +%type single_declaration +%type initializer +%type declaration +%type declaration_statement +%type jump_statement +%type struct_specifier +%type struct_declaration_list +%type struct_declaration +%type struct_declarator +%type struct_declarator_list +%type selection_statement +%type selection_rest_statement +%type iteration_statement +%type condition +%type conditionopt +%type for_init_statement +%type for_rest_statement +%% + +translation_unit: + version_statement extension_statement_list + { + _mesa_glsl_initialize_types(state); + } + external_declaration_list + { + delete state->symbols; + state->symbols = new(ralloc_parent(state)) glsl_symbol_table; + _mesa_glsl_initialize_types(state); + } + ; + +version_statement: + /* blank - no #version specified: defaults are already set */ + | VERSION INTCONSTANT EOL + { + bool supported = false; + + switch ($2) { + case 100: + state->es_shader = true; + supported = state->Const.GLSL_100ES; + break; + case 110: + supported = state->Const.GLSL_110; + break; + case 120: + supported = state->Const.GLSL_120; + break; + case 130: + supported = state->Const.GLSL_130; + break; + default: + supported = false; + break; + } + + state->language_version = $2; + state->version_string = + ralloc_asprintf(state, "GLSL%s %d.%02d", + state->es_shader ? " ES" : "", + state->language_version / 100, + state->language_version % 100); + + if (!supported) { + _mesa_glsl_error(& @2, state, "%s is not supported. " + "Supported versions are: %s\n", + state->version_string, + state->supported_version_string); + } + } + ; + +pragma_statement: + PRAGMA_DEBUG_ON EOL + | PRAGMA_DEBUG_OFF EOL + | PRAGMA_OPTIMIZE_ON EOL + | PRAGMA_OPTIMIZE_OFF EOL + | PRAGMA_INVARIANT_ALL EOL + { + if (state->language_version < 120) { + _mesa_glsl_warning(& @1, state, + "pragma `invariant(all)' not supported in %s", + state->version_string); + } else { + state->all_invariant = true; + } + } + ; + +extension_statement_list: + + | extension_statement_list extension_statement + ; + +any_identifier: + IDENTIFIER + | TYPE_IDENTIFIER + | NEW_IDENTIFIER + ; + +extension_statement: + EXTENSION any_identifier COLON any_identifier EOL + { + if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) { + YYERROR; + } + } + ; + +external_declaration_list: + external_declaration + { + /* FINISHME: The NULL test is required because pragmas are set to + * FINISHME: NULL. (See production rule for external_declaration.) + */ + if ($1 != NULL) + state->translation_unit.push_tail(& $1->link); + } + | external_declaration_list external_declaration + { + /* FINISHME: The NULL test is required because pragmas are set to + * FINISHME: NULL. (See production rule for external_declaration.) + */ + if ($2 != NULL) + state->translation_unit.push_tail(& $2->link); + } + ; + +variable_identifier: + IDENTIFIER + | NEW_IDENTIFIER + ; + +primary_expression: + variable_identifier + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.identifier = $1; + } + | INTCONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.int_constant = $1; + } + | UINTCONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.uint_constant = $1; + } + | FLOATCONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.float_constant = $1; + } + | BOOLCONSTANT + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.bool_constant = $1; + } + | '(' expression ')' + { + $$ = $2; + } + ; + +postfix_expression: + primary_expression + | postfix_expression '[' integer_expression ']' + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); + $$->set_location(yylloc); + } + | function_call + { + $$ = $1; + } + | postfix_expression '.' any_identifier + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); + $$->set_location(yylloc); + $$->primary_expression.identifier = $3; + } + | postfix_expression INC_OP + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); + $$->set_location(yylloc); + } + | postfix_expression DEC_OP + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); + $$->set_location(yylloc); + } + ; + +integer_expression: + expression + ; + +function_call: + function_call_or_method + ; + +function_call_or_method: + function_call_generic + | postfix_expression '.' method_call_generic + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL); + $$->set_location(yylloc); + } + ; + +function_call_generic: + function_call_header_with_parameters ')' + | function_call_header_no_parameters ')' + ; + +function_call_header_no_parameters: + function_call_header VOID_TOK + | function_call_header + ; + +function_call_header_with_parameters: + function_call_header assignment_expression + { + $$ = $1; + $$->set_location(yylloc); + $$->expressions.push_tail(& $2->link); + } + | function_call_header_with_parameters ',' assignment_expression + { + $$ = $1; + $$->set_location(yylloc); + $$->expressions.push_tail(& $3->link); + } + ; + + // Grammar Note: Constructors look like functions, but lexical + // analysis recognized most of them as keywords. They are now + // recognized through "type_specifier". +function_call_header: + function_identifier '(' + ; + +function_identifier: + type_specifier + { + void *ctx = state; + $$ = new(ctx) ast_function_expression($1); + $$->set_location(yylloc); + } + | variable_identifier + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression($1); + $$ = new(ctx) ast_function_expression(callee); + $$->set_location(yylloc); + } + | FIELD_SELECTION + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression($1); + $$ = new(ctx) ast_function_expression(callee); + $$->set_location(yylloc); + } + ; + +method_call_generic: + method_call_header_with_parameters ')' + | method_call_header_no_parameters ')' + ; + +method_call_header_no_parameters: + method_call_header VOID_TOK + | method_call_header + ; + +method_call_header_with_parameters: + method_call_header assignment_expression + { + $$ = $1; + $$->set_location(yylloc); + $$->expressions.push_tail(& $2->link); + } + | method_call_header_with_parameters ',' assignment_expression + { + $$ = $1; + $$->set_location(yylloc); + $$->expressions.push_tail(& $3->link); + } + ; + + // Grammar Note: Constructors look like methods, but lexical + // analysis recognized most of them as keywords. They are now + // recognized through "type_specifier". +method_call_header: + variable_identifier '(' + { + void *ctx = state; + ast_expression *callee = new(ctx) ast_expression($1); + $$ = new(ctx) ast_function_expression(callee); + $$->set_location(yylloc); + } + ; + + // Grammar Note: No traditional style type casts. +unary_expression: + postfix_expression + | INC_OP unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); + $$->set_location(yylloc); + } + | DEC_OP unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); + $$->set_location(yylloc); + } + | unary_operator unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression($1, $2, NULL, NULL); + $$->set_location(yylloc); + } + ; + + // Grammar Note: No '*' or '&' unary ops. Pointers are not supported. +unary_operator: + '+' { $$ = ast_plus; } + | '-' { $$ = ast_neg; } + | '!' { $$ = ast_logic_not; } + | '~' { $$ = ast_bit_not; } + ; + +multiplicative_expression: + unary_expression + | multiplicative_expression '*' unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); + $$->set_location(yylloc); + } + | multiplicative_expression '/' unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); + $$->set_location(yylloc); + } + | multiplicative_expression '%' unary_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); + $$->set_location(yylloc); + } + ; + +additive_expression: + multiplicative_expression + | additive_expression '+' multiplicative_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); + $$->set_location(yylloc); + } + | additive_expression '-' multiplicative_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); + $$->set_location(yylloc); + } + ; + +shift_expression: + additive_expression + | shift_expression LEFT_OP additive_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); + $$->set_location(yylloc); + } + | shift_expression RIGHT_OP additive_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); + $$->set_location(yylloc); + } + ; + +relational_expression: + shift_expression + | relational_expression '<' shift_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); + $$->set_location(yylloc); + } + | relational_expression '>' shift_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); + $$->set_location(yylloc); + } + | relational_expression LE_OP shift_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); + $$->set_location(yylloc); + } + | relational_expression GE_OP shift_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); + $$->set_location(yylloc); + } + ; + +equality_expression: + relational_expression + | equality_expression EQ_OP relational_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); + $$->set_location(yylloc); + } + | equality_expression NE_OP relational_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); + $$->set_location(yylloc); + } + ; + +and_expression: + equality_expression + | and_expression '&' equality_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_bit_and, $1, $3); + $$->set_location(yylloc); + } + ; + +exclusive_or_expression: + and_expression + | exclusive_or_expression '^' and_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); + $$->set_location(yylloc); + } + ; + +inclusive_or_expression: + exclusive_or_expression + | inclusive_or_expression '|' exclusive_or_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); + $$->set_location(yylloc); + } + ; + +logical_and_expression: + inclusive_or_expression + | logical_and_expression AND_OP inclusive_or_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); + $$->set_location(yylloc); + } + ; + +logical_xor_expression: + logical_and_expression + | logical_xor_expression XOR_OP logical_and_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); + $$->set_location(yylloc); + } + ; + +logical_or_expression: + logical_xor_expression + | logical_or_expression OR_OP logical_xor_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); + $$->set_location(yylloc); + } + ; + +conditional_expression: + logical_or_expression + | logical_or_expression '?' expression ':' assignment_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); + $$->set_location(yylloc); + } + ; + +assignment_expression: + conditional_expression + | unary_expression assignment_operator assignment_expression + { + void *ctx = state; + $$ = new(ctx) ast_expression($2, $1, $3, NULL); + $$->set_location(yylloc); + } + ; + +assignment_operator: + '=' { $$ = ast_assign; } + | MUL_ASSIGN { $$ = ast_mul_assign; } + | DIV_ASSIGN { $$ = ast_div_assign; } + | MOD_ASSIGN { $$ = ast_mod_assign; } + | ADD_ASSIGN { $$ = ast_add_assign; } + | SUB_ASSIGN { $$ = ast_sub_assign; } + | LEFT_ASSIGN { $$ = ast_ls_assign; } + | RIGHT_ASSIGN { $$ = ast_rs_assign; } + | AND_ASSIGN { $$ = ast_and_assign; } + | XOR_ASSIGN { $$ = ast_xor_assign; } + | OR_ASSIGN { $$ = ast_or_assign; } + ; + +expression: + assignment_expression + { + $$ = $1; + } + | expression ',' assignment_expression + { + void *ctx = state; + if ($1->oper != ast_sequence) { + $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); + $$->set_location(yylloc); + $$->expressions.push_tail(& $1->link); + } else { + $$ = $1; + } + + $$->expressions.push_tail(& $3->link); + } + ; + +constant_expression: + conditional_expression + ; + +declaration: + function_prototype ';' + { + state->symbols->pop_scope(); + $$ = $1; + } + | init_declarator_list ';' + { + $$ = $1; + } + | PRECISION precision_qualifier type_specifier_no_prec ';' + { + $3->precision = $2; + $3->is_precision_statement = true; + $$ = $3; + } + ; + +function_prototype: + function_declarator ')' + ; + +function_declarator: + function_header + | function_header_with_parameters + ; + +function_header_with_parameters: + function_header parameter_declaration + { + $$ = $1; + $$->parameters.push_tail(& $2->link); + } + | function_header_with_parameters ',' parameter_declaration + { + $$ = $1; + $$->parameters.push_tail(& $3->link); + } + ; + +function_header: + fully_specified_type variable_identifier '(' + { + void *ctx = state; + $$ = new(ctx) ast_function(); + $$->set_location(yylloc); + $$->return_type = $1; + $$->identifier = $2; + + state->symbols->add_function(new(state) ir_function($2)); + state->symbols->push_scope(); + } + ; + +parameter_declarator: + type_specifier any_identifier + { + void *ctx = state; + $$ = new(ctx) ast_parameter_declarator(); + $$->set_location(yylloc); + $$->type = new(ctx) ast_fully_specified_type(); + $$->type->set_location(yylloc); + $$->type->specifier = $1; + $$->identifier = $2; + } + | type_specifier any_identifier '[' constant_expression ']' + { + void *ctx = state; + $$ = new(ctx) ast_parameter_declarator(); + $$->set_location(yylloc); + $$->type = new(ctx) ast_fully_specified_type(); + $$->type->set_location(yylloc); + $$->type->specifier = $1; + $$->identifier = $2; + $$->is_array = true; + $$->array_size = $4; + } + ; + +parameter_declaration: + parameter_type_qualifier parameter_qualifier parameter_declarator + { + $1.flags.i |= $2.flags.i; + + $$ = $3; + $$->type->qualifier = $1; + } + | parameter_qualifier parameter_declarator + { + $$ = $2; + $$->type->qualifier = $1; + } + | parameter_type_qualifier parameter_qualifier parameter_type_specifier + { + void *ctx = state; + $1.flags.i |= $2.flags.i; + + $$ = new(ctx) ast_parameter_declarator(); + $$->set_location(yylloc); + $$->type = new(ctx) ast_fully_specified_type(); + $$->type->qualifier = $1; + $$->type->specifier = $3; + } + | parameter_qualifier parameter_type_specifier + { + void *ctx = state; + $$ = new(ctx) ast_parameter_declarator(); + $$->set_location(yylloc); + $$->type = new(ctx) ast_fully_specified_type(); + $$->type->qualifier = $1; + $$->type->specifier = $2; + } + ; + +parameter_qualifier: + /* empty */ + { + memset(& $$, 0, sizeof($$)); + } + | IN_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.in = 1; + } + | OUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.out = 1; + } + | INOUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.in = 1; + $$.flags.q.out = 1; + } + ; + +parameter_type_specifier: + type_specifier + ; + +init_declarator_list: + single_declaration + | init_declarator_list ',' any_identifier + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); + } + | init_declarator_list ',' any_identifier '[' ']' + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); + } + | init_declarator_list ',' any_identifier '[' constant_expression ']' + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); + } + | init_declarator_list ',' any_identifier '[' ']' '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); + } + | init_declarator_list ',' any_identifier '[' constant_expression ']' '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); + } + | init_declarator_list ',' any_identifier '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5); + decl->set_location(yylloc); + + $$ = $1; + $$->declarations.push_tail(&decl->link); + state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); + } + ; + + // Grammar Note: No 'enum', or 'typedef'. +single_declaration: + fully_specified_type + { + void *ctx = state; + if ($1->specifier->type_specifier != ast_struct) { + _mesa_glsl_error(& @1, state, "empty declaration list\n"); + YYERROR; + } else { + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + } + } + | fully_specified_type any_identifier + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type any_identifier '[' ']' + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type any_identifier '[' constant_expression ']' + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type any_identifier '[' ']' '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type any_identifier '[' constant_expression ']' '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | fully_specified_type any_identifier '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); + + $$ = new(ctx) ast_declarator_list($1); + $$->set_location(yylloc); + $$->declarations.push_tail(&decl->link); + } + | INVARIANT variable_identifier // Vertex only. + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); + + $$ = new(ctx) ast_declarator_list(NULL); + $$->set_location(yylloc); + $$->invariant = true; + + $$->declarations.push_tail(&decl->link); + } + ; + +fully_specified_type: + type_specifier + { + void *ctx = state; + $$ = new(ctx) ast_fully_specified_type(); + $$->set_location(yylloc); + $$->specifier = $1; + } + | type_qualifier type_specifier + { + void *ctx = state; + $$ = new(ctx) ast_fully_specified_type(); + $$->set_location(yylloc); + $$->qualifier = $1; + $$->specifier = $2; + } + ; + +layout_qualifier: + LAYOUT_TOK '(' layout_qualifier_id_list ')' + { + $$ = $3; + } + ; + +layout_qualifier_id_list: + layout_qualifier_id + | layout_qualifier_id_list ',' layout_qualifier_id + { + if (($1.flags.i & $3.flags.i) != 0) { + _mesa_glsl_error(& @3, state, + "duplicate layout qualifiers used\n"); + YYERROR; + } + + $$.flags.i = $1.flags.i | $3.flags.i; + + if ($1.flags.q.explicit_location) + $$.location = $1.location; + + if ($3.flags.q.explicit_location) + $$.location = $3.location; + } + ; + +layout_qualifier_id: + any_identifier + { + bool got_one = false; + + memset(& $$, 0, sizeof($$)); + + /* Layout qualifiers for ARB_fragment_coord_conventions. */ + if (!got_one && state->ARB_fragment_coord_conventions_enable) { + if (strcmp($1, "origin_upper_left") == 0) { + got_one = true; + $$.flags.q.origin_upper_left = 1; + } else if (strcmp($1, "pixel_center_integer") == 0) { + got_one = true; + $$.flags.q.pixel_center_integer = 1; + } + + if (got_one && state->ARB_fragment_coord_conventions_warn) { + _mesa_glsl_warning(& @1, state, + "GL_ARB_fragment_coord_conventions layout " + "identifier `%s' used\n", $1); + } + } + + /* Layout qualifiers for AMD_conservative_depth. */ + if (!got_one && state->AMD_conservative_depth_enable) { + if (strcmp($1, "depth_any") == 0) { + got_one = true; + $$.flags.q.depth_any = 1; + } else if (strcmp($1, "depth_greater") == 0) { + got_one = true; + $$.flags.q.depth_greater = 1; + } else if (strcmp($1, "depth_less") == 0) { + got_one = true; + $$.flags.q.depth_less = 1; + } else if (strcmp($1, "depth_unchanged") == 0) { + got_one = true; + $$.flags.q.depth_unchanged = 1; + } + + if (got_one && state->AMD_conservative_depth_warn) { + _mesa_glsl_warning(& @1, state, + "GL_AMD_conservative_depth " + "layout qualifier `%s' is used\n", $1); + } + } + + if (!got_one) { + _mesa_glsl_error(& @1, state, "unrecognized layout identifier " + "`%s'\n", $1); + YYERROR; + } + } + | any_identifier '=' INTCONSTANT + { + bool got_one = false; + + memset(& $$, 0, sizeof($$)); + + if (state->ARB_explicit_attrib_location_enable) { + /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and + * FINISHME: GLSL 1.30 (or later) are supported. + */ + if (strcmp("location", $1) == 0) { + got_one = true; + + $$.flags.q.explicit_location = 1; + + if ($3 >= 0) { + $$.location = $3; + } else { + _mesa_glsl_error(& @3, state, + "invalid location %d specified\n", $3); + YYERROR; + } + } + } + + /* If the identifier didn't match any known layout identifiers, + * emit an error. + */ + if (!got_one) { + _mesa_glsl_error(& @1, state, "unrecognized layout identifier " + "`%s'\n", $1); + YYERROR; + } else if (state->ARB_explicit_attrib_location_warn) { + _mesa_glsl_warning(& @1, state, + "GL_ARB_explicit_attrib_location layout " + "identifier `%s' used\n", $1); + } + } + ; + +interpolation_qualifier: + SMOOTH + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.smooth = 1; + } + | FLAT + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.flat = 1; + } + | NOPERSPECTIVE + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.noperspective = 1; + } + ; + +parameter_type_qualifier: + CONST_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.constant = 1; + } + ; + +type_qualifier: + storage_qualifier + | layout_qualifier + | layout_qualifier storage_qualifier + { + $$ = $1; + $$.flags.i |= $2.flags.i; + } + | interpolation_qualifier + | interpolation_qualifier storage_qualifier + { + $$ = $1; + $$.flags.i |= $2.flags.i; + } + | INVARIANT storage_qualifier + { + $$ = $2; + $$.flags.q.invariant = 1; + } + | INVARIANT interpolation_qualifier storage_qualifier + { + $$ = $2; + $$.flags.i |= $3.flags.i; + $$.flags.q.invariant = 1; + } + | INVARIANT + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.invariant = 1; + } + ; + +storage_qualifier: + CONST_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.constant = 1; + } + | ATTRIBUTE + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.attribute = 1; + } + | VARYING + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.varying = 1; + } + | CENTROID VARYING + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.centroid = 1; + $$.flags.q.varying = 1; + } + | IN_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.in = 1; + } + | OUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.out = 1; + } + | CENTROID IN_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.centroid = 1; $$.flags.q.in = 1; + } + | CENTROID OUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.centroid = 1; $$.flags.q.out = 1; + } + | UNIFORM + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.uniform = 1; + } + ; + +type_specifier: + type_specifier_no_prec + { + $$ = $1; + } + | precision_qualifier type_specifier_no_prec + { + $$ = $2; + $$->precision = $1; + } + ; + +type_specifier_no_prec: + type_specifier_nonarray + | type_specifier_nonarray '[' ']' + { + $$ = $1; + $$->is_array = true; + $$->array_size = NULL; + } + | type_specifier_nonarray '[' constant_expression ']' + { + $$ = $1; + $$->is_array = true; + $$->array_size = $3; + } + ; + +type_specifier_nonarray: + basic_type_specifier_nonarray + { + void *ctx = state; + $$ = new(ctx) ast_type_specifier($1); + $$->set_location(yylloc); + } + | struct_specifier + { + void *ctx = state; + $$ = new(ctx) ast_type_specifier($1); + $$->set_location(yylloc); + } + | TYPE_IDENTIFIER + { + void *ctx = state; + $$ = new(ctx) ast_type_specifier($1); + $$->set_location(yylloc); + } + ; + +basic_type_specifier_nonarray: + VOID_TOK { $$ = ast_void; } + | FLOAT_TOK { $$ = ast_float; } + | INT_TOK { $$ = ast_int; } + | UINT_TOK { $$ = ast_uint; } + | BOOL_TOK { $$ = ast_bool; } + | VEC2 { $$ = ast_vec2; } + | VEC3 { $$ = ast_vec3; } + | VEC4 { $$ = ast_vec4; } + | BVEC2 { $$ = ast_bvec2; } + | BVEC3 { $$ = ast_bvec3; } + | BVEC4 { $$ = ast_bvec4; } + | IVEC2 { $$ = ast_ivec2; } + | IVEC3 { $$ = ast_ivec3; } + | IVEC4 { $$ = ast_ivec4; } + | UVEC2 { $$ = ast_uvec2; } + | UVEC3 { $$ = ast_uvec3; } + | UVEC4 { $$ = ast_uvec4; } + | MAT2X2 { $$ = ast_mat2; } + | MAT2X3 { $$ = ast_mat2x3; } + | MAT2X4 { $$ = ast_mat2x4; } + | MAT3X2 { $$ = ast_mat3x2; } + | MAT3X3 { $$ = ast_mat3; } + | MAT3X4 { $$ = ast_mat3x4; } + | MAT4X2 { $$ = ast_mat4x2; } + | MAT4X3 { $$ = ast_mat4x3; } + | MAT4X4 { $$ = ast_mat4; } + | SAMPLER1D { $$ = ast_sampler1d; } + | SAMPLER2D { $$ = ast_sampler2d; } + | SAMPLER2DRECT { $$ = ast_sampler2drect; } + | SAMPLER3D { $$ = ast_sampler3d; } + | SAMPLERCUBE { $$ = ast_samplercube; } + | SAMPLER1DSHADOW { $$ = ast_sampler1dshadow; } + | SAMPLER2DSHADOW { $$ = ast_sampler2dshadow; } + | SAMPLER2DRECTSHADOW { $$ = ast_sampler2drectshadow; } + | SAMPLERCUBESHADOW { $$ = ast_samplercubeshadow; } + | SAMPLER1DARRAY { $$ = ast_sampler1darray; } + | SAMPLER2DARRAY { $$ = ast_sampler2darray; } + | SAMPLER1DARRAYSHADOW { $$ = ast_sampler1darrayshadow; } + | SAMPLER2DARRAYSHADOW { $$ = ast_sampler2darrayshadow; } + | ISAMPLER1D { $$ = ast_isampler1d; } + | ISAMPLER2D { $$ = ast_isampler2d; } + | ISAMPLER3D { $$ = ast_isampler3d; } + | ISAMPLERCUBE { $$ = ast_isamplercube; } + | ISAMPLER1DARRAY { $$ = ast_isampler1darray; } + | ISAMPLER2DARRAY { $$ = ast_isampler2darray; } + | USAMPLER1D { $$ = ast_usampler1d; } + | USAMPLER2D { $$ = ast_usampler2d; } + | USAMPLER3D { $$ = ast_usampler3d; } + | USAMPLERCUBE { $$ = ast_usamplercube; } + | USAMPLER1DARRAY { $$ = ast_usampler1darray; } + | USAMPLER2DARRAY { $$ = ast_usampler2darray; } + ; + +precision_qualifier: + HIGHP { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& @1, state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + $$ = ast_precision_high; + } + | MEDIUMP { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& @1, state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + $$ = ast_precision_medium; + } + | LOWP { + if (!state->es_shader && state->language_version < 130) + _mesa_glsl_error(& @1, state, + "precision qualifier forbidden " + "in %s (1.30 or later " + "required)\n", + state->version_string); + + $$ = ast_precision_low; + } + ; + +struct_specifier: + STRUCT any_identifier '{' struct_declaration_list '}' + { + void *ctx = state; + $$ = new(ctx) ast_struct_specifier($2, $4); + $$->set_location(yylloc); + state->symbols->add_type($2, glsl_type::void_type); + } + | STRUCT '{' struct_declaration_list '}' + { + void *ctx = state; + $$ = new(ctx) ast_struct_specifier(NULL, $3); + $$->set_location(yylloc); + } + ; + +struct_declaration_list: + struct_declaration + { + $$ = (ast_node *) $1; + $1->link.self_link(); + } + | struct_declaration_list struct_declaration + { + $$ = (ast_node *) $1; + $$->link.insert_before(& $2->link); + } + ; + +struct_declaration: + type_specifier struct_declarator_list ';' + { + void *ctx = state; + ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); + type->set_location(yylloc); + + type->specifier = $1; + $$ = new(ctx) ast_declarator_list(type); + $$->set_location(yylloc); + + $$->declarations.push_degenerate_list_at_head(& $2->link); + } + ; + +struct_declarator_list: + struct_declarator + { + $$ = $1; + $1->link.self_link(); + } + | struct_declarator_list ',' struct_declarator + { + $$ = $1; + $$->link.insert_before(& $3->link); + } + ; + +struct_declarator: + any_identifier + { + void *ctx = state; + $$ = new(ctx) ast_declaration($1, false, NULL, NULL); + $$->set_location(yylloc); + state->symbols->add_variable(new(state) ir_variable(NULL, $1, ir_var_auto)); + } + | any_identifier '[' constant_expression ']' + { + void *ctx = state; + $$ = new(ctx) ast_declaration($1, true, $3, NULL); + $$->set_location(yylloc); + } + ; + +initializer: + assignment_expression + ; + +declaration_statement: + declaration + ; + + // Grammar Note: labeled statements for SWITCH only; 'goto' is not + // supported. +statement: + compound_statement { $$ = (ast_node *) $1; } + | simple_statement + ; + +simple_statement: + declaration_statement + | expression_statement + | selection_statement + | switch_statement { $$ = NULL; } + | case_label { $$ = NULL; } + | iteration_statement + | jump_statement + ; + +compound_statement: + '{' '}' + { + void *ctx = state; + $$ = new(ctx) ast_compound_statement(true, NULL); + $$->set_location(yylloc); + } + | '{' + { + state->symbols->push_scope(); + } + statement_list '}' + { + void *ctx = state; + $$ = new(ctx) ast_compound_statement(true, $3); + $$->set_location(yylloc); + state->symbols->pop_scope(); + } + ; + +statement_no_new_scope: + compound_statement_no_new_scope { $$ = (ast_node *) $1; } + | simple_statement + ; + +compound_statement_no_new_scope: + '{' '}' + { + void *ctx = state; + $$ = new(ctx) ast_compound_statement(false, NULL); + $$->set_location(yylloc); + } + | '{' statement_list '}' + { + void *ctx = state; + $$ = new(ctx) ast_compound_statement(false, $2); + $$->set_location(yylloc); + } + ; + +statement_list: + statement + { + if ($1 == NULL) { + _mesa_glsl_error(& @1, state, " statement\n"); + assert($1 != NULL); + } + + $$ = $1; + $$->link.self_link(); + } + | statement_list statement + { + if ($2 == NULL) { + _mesa_glsl_error(& @2, state, " statement\n"); + assert($2 != NULL); + } + $$ = $1; + $$->link.insert_before(& $2->link); + } + ; + +expression_statement: + ';' + { + void *ctx = state; + $$ = new(ctx) ast_expression_statement(NULL); + $$->set_location(yylloc); + } + | expression ';' + { + void *ctx = state; + $$ = new(ctx) ast_expression_statement($1); + $$->set_location(yylloc); + } + ; + +selection_statement: + IF '(' expression ')' selection_rest_statement + { + $$ = new(state) ast_selection_statement($3, $5.then_statement, + $5.else_statement); + $$->set_location(yylloc); + } + ; + +selection_rest_statement: + statement ELSE statement + { + $$.then_statement = $1; + $$.else_statement = $3; + } + | statement + { + $$.then_statement = $1; + $$.else_statement = NULL; + } + ; + +condition: + expression + { + $$ = (ast_node *) $1; + } + | fully_specified_type any_identifier '=' initializer + { + void *ctx = state; + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); + ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); + decl->set_location(yylloc); + declarator->set_location(yylloc); + + declarator->declarations.push_tail(&decl->link); + $$ = declarator; + } + ; + +switch_statement: + SWITCH '(' expression ')' compound_statement + ; + +case_label: + CASE expression ':' + | DEFAULT ':' + ; + +iteration_statement: + WHILE '(' condition ')' statement_no_new_scope + { + void *ctx = state; + $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, + NULL, $3, NULL, $5); + $$->set_location(yylloc); + } + | DO statement WHILE '(' expression ')' ';' + { + void *ctx = state; + $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, + NULL, $5, NULL, $2); + $$->set_location(yylloc); + } + | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope + { + void *ctx = state; + $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, + $3, $4.cond, $4.rest, $6); + $$->set_location(yylloc); + } + ; + +for_init_statement: + expression_statement + | declaration_statement + ; + +conditionopt: + condition + | /* empty */ + { + $$ = NULL; + } + ; + +for_rest_statement: + conditionopt ';' + { + $$.cond = $1; + $$.rest = NULL; + } + | conditionopt ';' expression + { + $$.cond = $1; + $$.rest = $3; + } + ; + + // Grammar Note: No 'goto'. Gotos are not supported. +jump_statement: + CONTINUE ';' + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); + $$->set_location(yylloc); + } + | BREAK ';' + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); + $$->set_location(yylloc); + } + | RETURN ';' + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); + $$->set_location(yylloc); + } + | RETURN expression ';' + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); + $$->set_location(yylloc); + } + | DISCARD ';' // Fragment shader only. + { + void *ctx = state; + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); + $$->set_location(yylloc); + } + ; + +external_declaration: + function_definition { $$ = $1; } + | declaration { $$ = $1; } + | pragma_statement { $$ = NULL; } + ; + +function_definition: + function_prototype compound_statement_no_new_scope + { + void *ctx = state; + $$ = new(ctx) ast_function_definition(); + $$->set_location(yylloc); + $$->prototype = $1; + $$->body = $2; + + state->symbols->pop_scope(); + } + ; diff --git a/mesalib/src/mesa/Makefile b/mesalib/src/mesa/Makefile index a6025e990..36cbdd994 100644 --- a/mesalib/src/mesa/Makefile +++ b/mesalib/src/mesa/Makefile @@ -1,188 +1,224 @@ -# src/mesa/Makefile - -TOP = ../.. -include $(TOP)/configs/current - -MESA_LIBS := libmesa.a libmesagallium.a -DEPENDS := depend - -MESA_OBJ_DIR := . - - -include sources.mak - -# adjust object dirs -MESA_OBJECTS := $(addprefix $(MESA_OBJ_DIR)/, $(MESA_OBJECTS)) -MESA_GALLIUM_OBJECTS := $(addprefix $(MESA_OBJ_DIR)/, $(MESA_GALLIUM_OBJECTS)) - -# define preprocessor flags -MESA_CPPFLAGS := $(API_DEFINES) $(DEFINES) - -# append include dirs -MESA_CPPFLAGS += $(INCLUDE_DIRS) - -# tidy compiler flags -CFLAGS := $(filter-out $(DEFINES), $(CFLAGS)) -CXXFLAGS := $(filter-out $(DEFINES), $(CXXFLAGS)) - -# LLVM is needed for the state tracker -MESA_CFLAGS := $(LLVM_CFLAGS) - -define mesa-cc-c - @mkdir -p $(dir $@) - $(CC) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_CFLAGS) $(CFLAGS) -endef - -define mesa-cxx-c - @mkdir -p $(dir $@) - $(CXX) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_CFLAGS) $(CXXFLAGS) -endef - -$(MESA_OBJ_DIR)/%.o: %.c - $(call mesa-cc-c,MESA) - -$(MESA_OBJ_DIR)/%.o: %.cpp - $(call mesa-cxx-c,MESA) - -$(MESA_OBJ_DIR)/%.o: %.S - $(call mesa-cc-c,MESA) - -# Default: build dependencies, then asm_subdirs, GLSL built-in lib, -# then convenience libs (.a) and finally the device drivers: -default: $(DEPENDS) asm_subdirs $(MESA_LIBS) driver_subdirs - -main/api_exec_es1.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py - $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES1.1 > $@ - -main/api_exec_es2.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py - $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES2.0 > $@ - -###################################################################### -# Helper libraries used by many drivers: - -# Make archive of core mesa object files -libmesa.a: $(MESA_OBJECTS) $(GLSL_LIBS) - @ $(MKLIB) -o mesa -static $(MESA_OBJECTS) $(GLSL_LIBS) - -# Make archive of subset of core mesa object files for gallium -libmesagallium.a: $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS) - @ $(MKLIB) -o mesagallium -static $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS) - -###################################################################### -# Device drivers -driver_subdirs: $(MESA_LIBS) - @ (cd drivers && $(MAKE)) - - -###################################################################### -# Assembly subdirs -asm_subdirs: - @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \ - (cd x86 && $(MAKE)) || exit 1 ; \ - fi - @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \ - (cd x86 && $(MAKE)) || exit 1 ; \ - (cd x86-64 && $(MAKE)) || exit 1 ; \ - fi - - -###################################################################### -# Dependency generation - -depend: $(ALL_SOURCES) - @ echo "running $(MKDEP)" - @ touch depend - @$(MKDEP) $(MKDEP_OPTIONS) -p$(MESA_OBJ_DIR)/ $(MESA_CPPFLAGS) \ - $(ALL_SOURCES) > /dev/null 2>/dev/null - -###################################################################### -# Installation rules - -# this isn't fleshed out yet but is probably the way to go in the future -new_install: - (cd drivers && $(MAKE) install) - - -# XXX replace this with new_install above someday -install: default - @for driver in $(DRIVER_DIRS) ; do \ - case "$$driver" in \ - osmesa) if [ "$(DRIVER_DIRS)" = osmesa ]; then \ - $(MAKE) install-headers install-osmesa || exit 1 ; \ - else \ - $(MAKE) install-osmesa || exit 1 ; \ - fi ;; \ - dri) $(MAKE) install-libgl install-dri || exit 1 ;; \ - *) $(MAKE) install-libgl || exit 1 ;; \ - esac ; \ - done - -pcedit = \ - -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ - -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \ - -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \ - -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' \ - - -gl_pcedit = sed \ - $(pcedit) \ - -e 's,@GL_PC_REQ_PRIV@,$(GL_PC_REQ_PRIV),' \ - -e 's,@GL_PC_LIB_PRIV@,$(GL_PC_LIB_PRIV),' \ - -e 's,@GL_PC_CFLAGS@,$(GL_PC_CFLAGS),' \ - -e 's,@GLX_TLS@,$(GLX_TLS),' \ - -e 's,@GL_LIB@,$(GL_LIB),' - -gl.pc: gl.pc.in - $(gl_pcedit) $< > $@ - -osmesa_pcedit = sed \ - $(pcedit) \ - -e 's,@OSMESA_LIB@,$(OSMESA_LIB),' \ - -e 's,@OSMESA_PC_REQ@,$(OSMESA_PC_REQ),' \ - -e 's,@OSMESA_PC_LIB_PRIV@,$(OSMESA_PC_LIB_PRIV),' - -osmesa.pc: osmesa.pc.in - $(osmesa_pcedit) $< > $@ - -install-headers: - $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/GL - $(INSTALL) -m 644 $(TOP)/include/GL/*.h \ - $(DESTDIR)$(INSTALL_INC_DIR)/GL - -install-libgl: default gl.pc install-headers - $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig - $(MINSTALL) $(TOP)/$(LIB_DIR)/$(GL_LIB_GLOB) \ - $(DESTDIR)$(INSTALL_LIB_DIR) - $(INSTALL) -m 644 gl.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig - -install-osmesa: default osmesa.pc - $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig - $(MINSTALL) $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_GLOB) \ - $(DESTDIR)$(INSTALL_LIB_DIR) - $(INSTALL) -m 644 osmesa.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig - -install-dri: default - cd drivers/dri && $(MAKE) install - - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h - -clean: - -rm -f */*.o - -rm -f */*/*.o - -rm -f depend depend.bak libmesa.a libmesagallium.a - -rm -f drivers/*/*.o - -rm -f *.pc - -@cd drivers/dri && $(MAKE) clean - -@cd drivers/x11 && $(MAKE) clean - -@cd drivers/osmesa && $(MAKE) clean - -@cd x86 && $(MAKE) clean - -@cd x86-64 && $(MAKE) clean - - --include $(DEPENDS) +# src/mesa/Makefile + +TOP = ../.. +include $(TOP)/configs/current + +MESA_LIBS := libmesa.a libmesagallium.a +DEPENDS := depend + +MESA_OBJ_DIR := . +DRICORE_OBJ_DIR := objs-dricore + +include sources.mak + +# adjust object dirs +MESA_OBJECTS := $(addprefix $(MESA_OBJ_DIR)/, $(MESA_OBJECTS)) +MESA_GALLIUM_OBJECTS := $(addprefix $(MESA_OBJ_DIR)/, $(MESA_GALLIUM_OBJECTS)) + +DRICORE_OBJECTS := $(addprefix $(DRICORE_OBJ_DIR)/, $(MESA_OBJECTS)) + +# define preprocessor flags +MESA_CPPFLAGS := $(API_DEFINES) $(DEFINES) + +# append include dirs +MESA_CPPFLAGS += $(INCLUDE_DIRS) + +DRICORE_CPPFLAGS = $(MESA_CPPFLAGS) + +# tidy compiler flags +CFLAGS := $(filter-out $(DEFINES), $(CFLAGS)) +CXXFLAGS := $(filter-out $(DEFINES), $(CXXFLAGS)) + +# LLVM is needed for the state tracker +MESA_CFLAGS := $(LLVM_CFLAGS) $(CFLAGS) +DRICORE_CFLAGS := $(LLVM_CFLAGS) $(DRI_CFLAGS) + +MESA_CXXFLAGS := $(LLVM_CFLAGS) $(CXXFLAGS) +DRICORE_CXXFLAGS := $(LLVM_CFLAGS) $(DRI_CXXFLAGS) + +define mesa-cc-c + @mkdir -p $(dir $@) + $(CC) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_CFLAGS) +endef + +define mesa-cxx-c + @mkdir -p $(dir $@) + $(CXX) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_CFLAGS) $($(1)_CXXFLAGS) +endef + +$(MESA_OBJ_DIR)/%.o: %.c + $(call mesa-cc-c,MESA) + +$(MESA_OBJ_DIR)/%.o: %.cpp + $(call mesa-cxx-c,MESA) + +$(MESA_OBJ_DIR)/%.o: %.S + $(call mesa-cc-c,MESA) + +$(DRICORE_OBJ_DIR)/%.o: %.c + $(call mesa-cc-c,DRICORE) + +$(DRICORE_OBJ_DIR)/%.o: %.cpp + $(call mesa-cxx-c,DRICORE) + +$(DRICORE_OBJ_DIR)/%.o: %.S + $(call mesa-cc-c,DRICORE) + +# Default: build dependencies, then asm_subdirs, GLSL built-in lib, +# then convenience libs (.a) and finally the device drivers: +default: $(DEPENDS) asm_subdirs $(MESA_LIBS) $(DRICORE_LIBS) driver_subdirs + +main/api_exec_es1.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py + $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES1.1 > $@ + +main/api_exec_es2.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py + $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES2.0 > $@ + +###################################################################### +# Helper libraries used by many drivers: + +# Make archive of core mesa object files +libmesa.a: $(MESA_OBJECTS) $(GLSL_LIBS) + @ $(MKLIB) -o mesa -static $(MESA_OBJECTS) $(GLSL_LIBS) + +# Shared dricore library for classic DRI drivers +$(TOP)/$(LIB_DIR)/libdricore.so: $(DRICORE_OBJECTS) $(DRICORE_GLSL_LIBS) + @$(MKLIB) -o $@ -linker '$(CXX)' -ldflags '$(LDFLAGS)' \ + -cplusplus -noprefix \ + -install $(TOP)/$(LIB_DIR) -id $(DRI_DRIVER_INSTALL_DIR)/$@.dylib \ + $(DRICORE_LIB_DEPS) $(DRICORE_OBJECTS) + +# Make archive of subset of core mesa object files for gallium +libmesagallium.a: $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS) + @ $(MKLIB) -o mesagallium -static $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS) + +###################################################################### +# Device drivers +driver_subdirs: $(MESA_LIBS) $(DRICORE_LIBS) + @ (cd drivers && $(MAKE)) + + +###################################################################### +# Assembly subdirs +asm_subdirs: + @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \ + (cd x86 && $(MAKE)) || exit 1 ; \ + fi + @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \ + (cd x86 && $(MAKE)) || exit 1 ; \ + (cd x86-64 && $(MAKE)) || exit 1 ; \ + fi + + +###################################################################### +# Dependency generation + +depend: $(ALL_SOURCES) + @ echo "running $(MKDEP)" + @ touch depend + @$(MKDEP) $(MKDEP_OPTIONS) -p$(MESA_OBJ_DIR)/ $(MESA_CPPFLAGS) \ + $(ALL_SOURCES) > /dev/null 2>/dev/null + +###################################################################### +# Installation rules + +# this isn't fleshed out yet but is probably the way to go in the future +new_install: + (cd drivers && $(MAKE) install) + +ifneq (,$(DRICORE_LIBS)) +DRICORE_INSTALL_TARGET = install-dricore +endif + +# XXX replace this with new_install above someday +install: default $(DRICORE_INSTALL_TARGET) + @for driver in $(DRIVER_DIRS) ; do \ + case "$$driver" in \ + osmesa) if [ "$(DRIVER_DIRS)" = osmesa ]; then \ + $(MAKE) install-headers install-osmesa || exit 1 ; \ + else \ + $(MAKE) install-osmesa || exit 1 ; \ + fi ;; \ + dri) $(MAKE) install-libgl install-dri || exit 1 ;; \ + *) $(MAKE) install-libgl || exit 1 ;; \ + esac ; \ + done + +pcedit = \ + -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ + -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \ + -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \ + -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' \ + + +gl_pcedit = sed \ + $(pcedit) \ + -e 's,@GL_PC_REQ_PRIV@,$(GL_PC_REQ_PRIV),' \ + -e 's,@GL_PC_LIB_PRIV@,$(GL_PC_LIB_PRIV),' \ + -e 's,@GL_PC_CFLAGS@,$(GL_PC_CFLAGS),' \ + -e 's,@GLX_TLS@,$(GLX_TLS),' \ + -e 's,@GL_LIB@,$(GL_LIB),' + +gl.pc: gl.pc.in + $(gl_pcedit) $< > $@ + +osmesa_pcedit = sed \ + $(pcedit) \ + -e 's,@OSMESA_LIB@,$(OSMESA_LIB),' \ + -e 's,@OSMESA_PC_REQ@,$(OSMESA_PC_REQ),' \ + -e 's,@OSMESA_PC_LIB_PRIV@,$(OSMESA_PC_LIB_PRIV),' + +osmesa.pc: osmesa.pc.in + $(osmesa_pcedit) $< > $@ + +install-headers: + $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/GL + $(INSTALL) -m 644 $(TOP)/include/GL/*.h \ + $(DESTDIR)$(INSTALL_INC_DIR)/GL + +install-libgl: default gl.pc install-headers + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig + $(MINSTALL) $(TOP)/$(LIB_DIR)/$(GL_LIB_GLOB) \ + $(DESTDIR)$(INSTALL_LIB_DIR) + $(INSTALL) -m 644 gl.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig + +install-osmesa: default osmesa.pc + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig + $(MINSTALL) $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_GLOB) \ + $(DESTDIR)$(INSTALL_LIB_DIR) + $(INSTALL) -m 644 osmesa.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig + +install-dri: default + cd drivers/dri && $(MAKE) install + +# We don't need MINSTALL here because we're not installing symbolic links +install-dricore: default + $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(DRICORE_LIBS) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h + +clean-dricore: + -rm -f libdricore.so + -rm -f $(DRICORE_LIBS) + -rm -rf $(DRICORE_OBJ_DIR) + +clean: clean-dricore + -rm -f */*.o + -rm -f */*/*.o + -rm -f depend depend.bak libmesa.a libmesagallium.a + -rm -f drivers/*/*.o + -rm -f *.pc + -@cd drivers/dri && $(MAKE) clean + -@cd drivers/x11 && $(MAKE) clean + -@cd drivers/osmesa && $(MAKE) clean + -@cd x86 && $(MAKE) clean + -@cd x86-64 && $(MAKE) clean + + +-include $(DEPENDS) diff --git a/mesalib/src/mesa/drivers/dri/Makefile.template b/mesalib/src/mesa/drivers/dri/Makefile.template index 6be554af7..588210f8a 100644 --- a/mesalib/src/mesa/drivers/dri/Makefile.template +++ b/mesalib/src/mesa/drivers/dri/Makefile.template @@ -1,7 +1,5 @@ # -*-makefile-*- -MESA_MODULES = $(TOP)/src/mesa/libmesa.a - COMMON_GALLIUM_SOURCES = \ ../common/utils.c \ ../common/vblank.c \ @@ -39,13 +37,13 @@ CXXFLAGS += $(API_DEFINES) ##### RULES ##### .c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + $(CC) -c $(INCLUDES) $(DRI_CFLAGS) $(DRIVER_DEFINES) $< -o $@ .cpp.o: - $(CC) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + $(CC) -c $(INCLUDES) $(DRI_CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ .S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + $(CC) -c $(INCLUDES) $(DRI_CFLAGS) $(DRIVER_DEFINES) $< -o $@ ##### TARGETS ##### @@ -57,10 +55,10 @@ default: subdirs lib lib: symlinks subdirs depend @$(MAKE) $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) -$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(EXTRA_MODULES) Makefile \ +$(LIBNAME): $(OBJECTS) $(EXTRA_MODULES) $(MESA_MODULES) Makefile \ $(TOP)/src/mesa/drivers/dri/Makefile.template $(TOP)/src/mesa/drivers/dri/common/dri_test.o $(MKLIB) -o $@.tmp -noprefix -linker '$(CXX)' -ldflags '$(LDFLAGS)' \ - $(OBJECTS) $(MESA_MODULES) $(EXTRA_MODULES) $(DRI_LIB_DEPS) + $(OBJECTS) $(EXTRA_MODULES) $(DRI_LIB_DEPS) $(CXX) $(CFLAGS) -o $@.test $(TOP)/src/mesa/drivers/dri/common/dri_test.o $@.tmp $(DRI_LIB_DEPS) @rm -f $@.test mv -f $@.tmp $@ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c index aaed87028..256ffcc38 100644 --- a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c @@ -62,7 +62,6 @@ #include "swrast/s_depth.h" #include "swrast/s_lines.h" #include "swrast/s_triangle.h" -#include "swrast/s_trispan.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" diff --git a/mesalib/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c b/mesalib/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c index 36ebe9f31..02f0dfacd 100644 --- a/mesalib/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c +++ b/mesalib/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c @@ -61,7 +61,6 @@ #include "swrast/s_depth.h" #include "swrast/s_lines.h" #include "swrast/s_triangle.h" -#include "swrast/s_trispan.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 6f0aac6ee..020595bd0 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1,3371 +1,3369 @@ -/* - * Mesa 3-D graphics library - * Version: 7.7 - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file mtypes.h - * Main Mesa data structures. - * - * Please try to mark derived values with a leading underscore ('_'). - */ - -#ifndef MTYPES_H -#define MTYPES_H - - -#include "main/glheader.h" -#include "main/config.h" -#include "main/mfeatures.h" -#include "glapi/glapi.h" -#include "math/m_matrix.h" /* GLmatrix */ -#include "main/simple_list.h" /* struct simple_node */ -#include "main/formats.h" /* MESA_FORMAT_COUNT */ - - -/** - * Color channel data type. - */ -#if CHAN_BITS == 8 - typedef GLubyte GLchan; -#define CHAN_MAX 255 -#define CHAN_MAXF 255.0F -#define CHAN_TYPE GL_UNSIGNED_BYTE -#elif CHAN_BITS == 16 - typedef GLushort GLchan; -#define CHAN_MAX 65535 -#define CHAN_MAXF 65535.0F -#define CHAN_TYPE GL_UNSIGNED_SHORT -#elif CHAN_BITS == 32 - typedef GLfloat GLchan; -#define CHAN_MAX 1.0 -#define CHAN_MAXF 1.0F -#define CHAN_TYPE GL_FLOAT -#else -#error "illegal number of color channel bits" -#endif - - -/** - * Stencil buffer data type. - */ -#if STENCIL_BITS==8 - typedef GLubyte GLstencil; -#elif STENCIL_BITS==16 - typedef GLushort GLstencil; -#else -# error "illegal number of stencil bits" -#endif - - -/** - * \name 64-bit extension of GLbitfield. - */ -/*@{*/ -typedef GLuint64 GLbitfield64; - -/** Set a single bit */ -#define BITFIELD64_BIT(b) (1ULL << (b)) - - -/** - * \name Some forward type declarations - */ -/*@{*/ -struct _mesa_HashTable; -struct gl_attrib_node; -struct gl_list_extensions; -struct gl_meta_state; -struct gl_pixelstore_attrib; -struct gl_program_cache; -struct gl_texture_format; -struct gl_texture_image; -struct gl_texture_object; -struct gl_context; -struct st_context; -/*@}*/ - - -/** Extra draw modes beyond GL_POINTS, GL_TRIANGLE_FAN, etc */ -#define PRIM_OUTSIDE_BEGIN_END (GL_POLYGON+1) -#define PRIM_INSIDE_UNKNOWN_PRIM (GL_POLYGON+2) -#define PRIM_UNKNOWN (GL_POLYGON+3) - - -/** - * Shader stages. Note that these will become 5 with tessellation. - * These MUST have the same values as gallium's PIPE_SHADER_* - */ -typedef enum -{ - MESA_SHADER_VERTEX = 0, - MESA_SHADER_FRAGMENT = 1, - MESA_SHADER_GEOMETRY = 2, - MESA_SHADER_TYPES = 3 -} gl_shader_type; - - - -/** - * Indexes for vertex program attributes. - * GL_NV_vertex_program aliases generic attributes over the conventional - * attributes. In GL_ARB_vertex_program shader the aliasing is optional. - * In GL_ARB_vertex_shader / OpenGL 2.0 the aliasing is disallowed (the - * generic attributes are distinct/separate). - */ -typedef enum -{ - VERT_ATTRIB_POS = 0, - VERT_ATTRIB_WEIGHT = 1, - VERT_ATTRIB_NORMAL = 2, - VERT_ATTRIB_COLOR0 = 3, - VERT_ATTRIB_COLOR1 = 4, - VERT_ATTRIB_FOG = 5, - VERT_ATTRIB_COLOR_INDEX = 6, - VERT_ATTRIB_POINT_SIZE = 6, /*alias*/ - VERT_ATTRIB_EDGEFLAG = 7, - VERT_ATTRIB_TEX0 = 8, - VERT_ATTRIB_TEX1 = 9, - VERT_ATTRIB_TEX2 = 10, - VERT_ATTRIB_TEX3 = 11, - VERT_ATTRIB_TEX4 = 12, - VERT_ATTRIB_TEX5 = 13, - VERT_ATTRIB_TEX6 = 14, - VERT_ATTRIB_TEX7 = 15, - VERT_ATTRIB_GENERIC0 = 16, - VERT_ATTRIB_GENERIC1 = 17, - VERT_ATTRIB_GENERIC2 = 18, - VERT_ATTRIB_GENERIC3 = 19, - VERT_ATTRIB_GENERIC4 = 20, - VERT_ATTRIB_GENERIC5 = 21, - VERT_ATTRIB_GENERIC6 = 22, - VERT_ATTRIB_GENERIC7 = 23, - VERT_ATTRIB_GENERIC8 = 24, - VERT_ATTRIB_GENERIC9 = 25, - VERT_ATTRIB_GENERIC10 = 26, - VERT_ATTRIB_GENERIC11 = 27, - VERT_ATTRIB_GENERIC12 = 28, - VERT_ATTRIB_GENERIC13 = 29, - VERT_ATTRIB_GENERIC14 = 30, - VERT_ATTRIB_GENERIC15 = 31, - VERT_ATTRIB_MAX = 32 -} gl_vert_attrib; - -/** - * Bitflags for vertex attributes. - * These are used in bitfields in many places. - */ -/*@{*/ -#define VERT_BIT_POS (1 << VERT_ATTRIB_POS) -#define VERT_BIT_WEIGHT (1 << VERT_ATTRIB_WEIGHT) -#define VERT_BIT_NORMAL (1 << VERT_ATTRIB_NORMAL) -#define VERT_BIT_COLOR0 (1 << VERT_ATTRIB_COLOR0) -#define VERT_BIT_COLOR1 (1 << VERT_ATTRIB_COLOR1) -#define VERT_BIT_FOG (1 << VERT_ATTRIB_FOG) -#define VERT_BIT_COLOR_INDEX (1 << VERT_ATTRIB_COLOR_INDEX) -#define VERT_BIT_EDGEFLAG (1 << VERT_ATTRIB_EDGEFLAG) -#define VERT_BIT_TEX0 (1 << VERT_ATTRIB_TEX0) -#define VERT_BIT_TEX1 (1 << VERT_ATTRIB_TEX1) -#define VERT_BIT_TEX2 (1 << VERT_ATTRIB_TEX2) -#define VERT_BIT_TEX3 (1 << VERT_ATTRIB_TEX3) -#define VERT_BIT_TEX4 (1 << VERT_ATTRIB_TEX4) -#define VERT_BIT_TEX5 (1 << VERT_ATTRIB_TEX5) -#define VERT_BIT_TEX6 (1 << VERT_ATTRIB_TEX6) -#define VERT_BIT_TEX7 (1 << VERT_ATTRIB_TEX7) -#define VERT_BIT_GENERIC0 (1 << VERT_ATTRIB_GENERIC0) -#define VERT_BIT_GENERIC1 (1 << VERT_ATTRIB_GENERIC1) -#define VERT_BIT_GENERIC2 (1 << VERT_ATTRIB_GENERIC2) -#define VERT_BIT_GENERIC3 (1 << VERT_ATTRIB_GENERIC3) -#define VERT_BIT_GENERIC4 (1 << VERT_ATTRIB_GENERIC4) -#define VERT_BIT_GENERIC5 (1 << VERT_ATTRIB_GENERIC5) -#define VERT_BIT_GENERIC6 (1 << VERT_ATTRIB_GENERIC6) -#define VERT_BIT_GENERIC7 (1 << VERT_ATTRIB_GENERIC7) -#define VERT_BIT_GENERIC8 (1 << VERT_ATTRIB_GENERIC8) -#define VERT_BIT_GENERIC9 (1 << VERT_ATTRIB_GENERIC9) -#define VERT_BIT_GENERIC10 (1 << VERT_ATTRIB_GENERIC10) -#define VERT_BIT_GENERIC11 (1 << VERT_ATTRIB_GENERIC11) -#define VERT_BIT_GENERIC12 (1 << VERT_ATTRIB_GENERIC12) -#define VERT_BIT_GENERIC13 (1 << VERT_ATTRIB_GENERIC13) -#define VERT_BIT_GENERIC14 (1 << VERT_ATTRIB_GENERIC14) -#define VERT_BIT_GENERIC15 (1 << VERT_ATTRIB_GENERIC15) - -#define VERT_BIT_TEX(u) (1 << (VERT_ATTRIB_TEX0 + (u))) -#define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g))) -/*@}*/ - - -/** - * Indexes for vertex program result attributes - */ -typedef enum -{ - VERT_RESULT_HPOS = 0, - VERT_RESULT_COL0 = 1, - VERT_RESULT_COL1 = 2, - VERT_RESULT_FOGC = 3, - VERT_RESULT_TEX0 = 4, - VERT_RESULT_TEX1 = 5, - VERT_RESULT_TEX2 = 6, - VERT_RESULT_TEX3 = 7, - VERT_RESULT_TEX4 = 8, - VERT_RESULT_TEX5 = 9, - VERT_RESULT_TEX6 = 10, - VERT_RESULT_TEX7 = 11, - VERT_RESULT_PSIZ = 12, - VERT_RESULT_BFC0 = 13, - VERT_RESULT_BFC1 = 14, - VERT_RESULT_EDGE = 15, - VERT_RESULT_VAR0 = 16, /**< shader varying */ - VERT_RESULT_MAX = (VERT_RESULT_VAR0 + MAX_VARYING) -} gl_vert_result; - - -/*********************************************/ - -/** - * Indexes for geometry program attributes. - */ -typedef enum -{ - GEOM_ATTRIB_POSITION = 0, - GEOM_ATTRIB_COLOR0 = 1, - GEOM_ATTRIB_COLOR1 = 2, - GEOM_ATTRIB_SECONDARY_COLOR0 = 3, - GEOM_ATTRIB_SECONDARY_COLOR1 = 4, - GEOM_ATTRIB_FOG_FRAG_COORD = 5, - GEOM_ATTRIB_POINT_SIZE = 6, - GEOM_ATTRIB_CLIP_VERTEX = 7, - GEOM_ATTRIB_PRIMITIVE_ID = 8, - GEOM_ATTRIB_TEX_COORD = 9, - - GEOM_ATTRIB_VAR0 = 16, - GEOM_ATTRIB_MAX = (GEOM_ATTRIB_VAR0 + MAX_VARYING) -} gl_geom_attrib; - -/** - * Bitflags for geometry attributes. - * These are used in bitfields in many places. - */ -/*@{*/ -#define GEOM_BIT_COLOR0 (1 << GEOM_ATTRIB_COLOR0) -#define GEOM_BIT_COLOR1 (1 << GEOM_ATTRIB_COLOR1) -#define GEOM_BIT_SCOLOR0 (1 << GEOM_ATTRIB_SECONDARY_COLOR0) -#define GEOM_BIT_SCOLOR1 (1 << GEOM_ATTRIB_SECONDARY_COLOR1) -#define GEOM_BIT_TEX_COORD (1 << GEOM_ATTRIB_TEX_COORD) -#define GEOM_BIT_FOG_COORD (1 << GEOM_ATTRIB_FOG_FRAG_COORD) -#define GEOM_BIT_POSITION (1 << GEOM_ATTRIB_POSITION) -#define GEOM_BIT_POINT_SIDE (1 << GEOM_ATTRIB_POINT_SIZE) -#define GEOM_BIT_CLIP_VERTEX (1 << GEOM_ATTRIB_CLIP_VERTEX) -#define GEOM_BIT_PRIM_ID (1 << GEOM_ATTRIB_PRIMITIVE_ID) -#define GEOM_BIT_VAR0 (1 << GEOM_ATTRIB_VAR0) - -#define GEOM_BIT_VAR(g) (1 << (GEOM_BIT_VAR0 + (g))) -/*@}*/ - - -/** - * Indexes for geometry program result attributes - */ -typedef enum -{ - GEOM_RESULT_POS = 0, - GEOM_RESULT_COL0 = 1, - GEOM_RESULT_COL1 = 2, - GEOM_RESULT_SCOL0 = 3, - GEOM_RESULT_SCOL1 = 4, - GEOM_RESULT_FOGC = 5, - GEOM_RESULT_TEX0 = 6, - GEOM_RESULT_TEX1 = 7, - GEOM_RESULT_TEX2 = 8, - GEOM_RESULT_TEX3 = 9, - GEOM_RESULT_TEX4 = 10, - GEOM_RESULT_TEX5 = 11, - GEOM_RESULT_TEX6 = 12, - GEOM_RESULT_TEX7 = 13, - GEOM_RESULT_PSIZ = 14, - GEOM_RESULT_CLPV = 15, - GEOM_RESULT_PRID = 16, - GEOM_RESULT_LAYR = 17, - GEOM_RESULT_VAR0 = 18, /**< shader varying, should really be 16 */ - /* ### we need to -2 because var0 is 18 instead 16 like in the others */ - GEOM_RESULT_MAX = (GEOM_RESULT_VAR0 + MAX_VARYING - 2) -} gl_geom_result; - - -/** - * Indexes for fragment program input attributes. - */ -typedef enum -{ - FRAG_ATTRIB_WPOS = 0, - FRAG_ATTRIB_COL0 = 1, - FRAG_ATTRIB_COL1 = 2, - FRAG_ATTRIB_FOGC = 3, - FRAG_ATTRIB_TEX0 = 4, - FRAG_ATTRIB_TEX1 = 5, - FRAG_ATTRIB_TEX2 = 6, - FRAG_ATTRIB_TEX3 = 7, - FRAG_ATTRIB_TEX4 = 8, - FRAG_ATTRIB_TEX5 = 9, - FRAG_ATTRIB_TEX6 = 10, - FRAG_ATTRIB_TEX7 = 11, - FRAG_ATTRIB_FACE = 12, /**< front/back face */ - FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */ - FRAG_ATTRIB_VAR0 = 14, /**< shader varying */ - FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING) -} gl_frag_attrib; - -/** - * Bitflags for fragment program input attributes. - */ -/*@{*/ -#define FRAG_BIT_WPOS (1 << FRAG_ATTRIB_WPOS) -#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0) -#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1) -#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC) -#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE) -#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC) -#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0) -#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1) -#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2) -#define FRAG_BIT_TEX3 (1 << FRAG_ATTRIB_TEX3) -#define FRAG_BIT_TEX4 (1 << FRAG_ATTRIB_TEX4) -#define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5) -#define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6) -#define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7) -#define FRAG_BIT_VAR0 (1 << FRAG_ATTRIB_VAR0) - -#define FRAG_BIT_TEX(U) (FRAG_BIT_TEX0 << (U)) -#define FRAG_BIT_VAR(V) (FRAG_BIT_VAR0 << (V)) - -#define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \ - FRAG_BIT_TEX1| \ - FRAG_BIT_TEX2| \ - FRAG_BIT_TEX3| \ - FRAG_BIT_TEX4| \ - FRAG_BIT_TEX5| \ - FRAG_BIT_TEX6| \ - FRAG_BIT_TEX7) -/*@}*/ - - -/** - * Fragment program results - */ -typedef enum -{ - FRAG_RESULT_DEPTH = 0, - FRAG_RESULT_STENCIL = 1, - FRAG_RESULT_COLOR = 2, - FRAG_RESULT_DATA0 = 3, - FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS) -} gl_frag_result; - - -/** - * Indexes for all renderbuffers - */ -typedef enum -{ - /* the four standard color buffers */ - BUFFER_FRONT_LEFT, - BUFFER_BACK_LEFT, - BUFFER_FRONT_RIGHT, - BUFFER_BACK_RIGHT, - BUFFER_DEPTH, - BUFFER_STENCIL, - BUFFER_ACCUM, - /* optional aux buffer */ - BUFFER_AUX0, - /* generic renderbuffers */ - BUFFER_COLOR0, - BUFFER_COLOR1, - BUFFER_COLOR2, - BUFFER_COLOR3, - BUFFER_COLOR4, - BUFFER_COLOR5, - BUFFER_COLOR6, - BUFFER_COLOR7, - BUFFER_COUNT -} gl_buffer_index; - -/** - * Bit flags for all renderbuffers - */ -#define BUFFER_BIT_FRONT_LEFT (1 << BUFFER_FRONT_LEFT) -#define BUFFER_BIT_BACK_LEFT (1 << BUFFER_BACK_LEFT) -#define BUFFER_BIT_FRONT_RIGHT (1 << BUFFER_FRONT_RIGHT) -#define BUFFER_BIT_BACK_RIGHT (1 << BUFFER_BACK_RIGHT) -#define BUFFER_BIT_AUX0 (1 << BUFFER_AUX0) -#define BUFFER_BIT_AUX1 (1 << BUFFER_AUX1) -#define BUFFER_BIT_AUX2 (1 << BUFFER_AUX2) -#define BUFFER_BIT_AUX3 (1 << BUFFER_AUX3) -#define BUFFER_BIT_DEPTH (1 << BUFFER_DEPTH) -#define BUFFER_BIT_STENCIL (1 << BUFFER_STENCIL) -#define BUFFER_BIT_ACCUM (1 << BUFFER_ACCUM) -#define BUFFER_BIT_COLOR0 (1 << BUFFER_COLOR0) -#define BUFFER_BIT_COLOR1 (1 << BUFFER_COLOR1) -#define BUFFER_BIT_COLOR2 (1 << BUFFER_COLOR2) -#define BUFFER_BIT_COLOR3 (1 << BUFFER_COLOR3) -#define BUFFER_BIT_COLOR4 (1 << BUFFER_COLOR4) -#define BUFFER_BIT_COLOR5 (1 << BUFFER_COLOR5) -#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6) -#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7) - -/** - * Mask of all the color buffer bits (but not accum). - */ -#define BUFFER_BITS_COLOR (BUFFER_BIT_FRONT_LEFT | \ - BUFFER_BIT_BACK_LEFT | \ - BUFFER_BIT_FRONT_RIGHT | \ - BUFFER_BIT_BACK_RIGHT | \ - BUFFER_BIT_AUX0 | \ - BUFFER_BIT_COLOR0 | \ - BUFFER_BIT_COLOR1 | \ - BUFFER_BIT_COLOR2 | \ - BUFFER_BIT_COLOR3 | \ - BUFFER_BIT_COLOR4 | \ - BUFFER_BIT_COLOR5 | \ - BUFFER_BIT_COLOR6 | \ - BUFFER_BIT_COLOR7) - - -/** - * Framebuffer configuration (aka visual / pixelformat) - * Note: some of these fields should be boolean, but it appears that - * code in drivers/dri/common/util.c requires int-sized fields. - */ -struct gl_config -{ - GLboolean rgbMode; - GLboolean floatMode; - GLboolean colorIndexMode; /* XXX is this used anywhere? */ - GLuint doubleBufferMode; - GLuint stereoMode; - - GLboolean haveAccumBuffer; - GLboolean haveDepthBuffer; - GLboolean haveStencilBuffer; - - GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ - GLuint redMask, greenMask, blueMask, alphaMask; - GLint rgbBits; /* total bits for rgb */ - GLint indexBits; /* total bits for colorindex */ - - GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; - GLint depthBits; - GLint stencilBits; - - GLint numAuxBuffers; - - GLint level; - - /* EXT_visual_rating / GLX 1.2 */ - GLint visualRating; - - /* EXT_visual_info / GLX 1.2 */ - GLint transparentPixel; - /* colors are floats scaled to ints */ - GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha; - GLint transparentIndex; - - /* ARB_multisample / SGIS_multisample */ - GLint sampleBuffers; - GLint samples; - - /* SGIX_pbuffer / GLX 1.3 */ - GLint maxPbufferWidth; - GLint maxPbufferHeight; - GLint maxPbufferPixels; - GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */ - GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */ - - /* OML_swap_method */ - GLint swapMethod; - - /* EXT_texture_from_pixmap */ - GLint bindToTextureRgb; - GLint bindToTextureRgba; - GLint bindToMipmapTexture; - GLint bindToTextureTargets; - GLint yInverted; - - /* EXT_framebuffer_sRGB */ - GLint sRGBCapable; -}; - - -/** - * Data structure for color tables - */ -struct gl_color_table -{ - GLenum InternalFormat; /**< The user-specified format */ - GLenum _BaseFormat; /**< GL_ALPHA, GL_RGBA, GL_RGB, etc */ - GLuint Size; /**< number of entries in table */ - GLfloat *TableF; /**< Color table, floating point values */ - GLubyte *TableUB; /**< Color table, ubyte values */ - GLubyte RedSize; - GLubyte GreenSize; - GLubyte BlueSize; - GLubyte AlphaSize; - GLubyte LuminanceSize; - GLubyte IntensitySize; -}; - - -/** - * \name Bit flags used for updating material values. - */ -/*@{*/ -#define MAT_ATTRIB_FRONT_AMBIENT 0 -#define MAT_ATTRIB_BACK_AMBIENT 1 -#define MAT_ATTRIB_FRONT_DIFFUSE 2 -#define MAT_ATTRIB_BACK_DIFFUSE 3 -#define MAT_ATTRIB_FRONT_SPECULAR 4 -#define MAT_ATTRIB_BACK_SPECULAR 5 -#define MAT_ATTRIB_FRONT_EMISSION 6 -#define MAT_ATTRIB_BACK_EMISSION 7 -#define MAT_ATTRIB_FRONT_SHININESS 8 -#define MAT_ATTRIB_BACK_SHININESS 9 -#define MAT_ATTRIB_FRONT_INDEXES 10 -#define MAT_ATTRIB_BACK_INDEXES 11 -#define MAT_ATTRIB_MAX 12 - -#define MAT_ATTRIB_AMBIENT(f) (MAT_ATTRIB_FRONT_AMBIENT+(f)) -#define MAT_ATTRIB_DIFFUSE(f) (MAT_ATTRIB_FRONT_DIFFUSE+(f)) -#define MAT_ATTRIB_SPECULAR(f) (MAT_ATTRIB_FRONT_SPECULAR+(f)) -#define MAT_ATTRIB_EMISSION(f) (MAT_ATTRIB_FRONT_EMISSION+(f)) -#define MAT_ATTRIB_SHININESS(f)(MAT_ATTRIB_FRONT_SHININESS+(f)) -#define MAT_ATTRIB_INDEXES(f) (MAT_ATTRIB_FRONT_INDEXES+(f)) - -#define MAT_INDEX_AMBIENT 0 -#define MAT_INDEX_DIFFUSE 1 -#define MAT_INDEX_SPECULAR 2 - -#define MAT_BIT_FRONT_AMBIENT (1< ) */ - GLfloat _NormSpotDirection[4]; /**< normalized spotlight direction */ - GLfloat _VP_inf_spot_attenuation; - - GLfloat _SpotExpTable[EXP_TABLE_SIZE][2]; /**< to replace a pow() call */ - GLfloat _MatAmbient[2][3]; /**< material ambient * light ambient */ - GLfloat _MatDiffuse[2][3]; /**< material diffuse * light diffuse */ - GLfloat _MatSpecular[2][3]; /**< material spec * light specular */ - GLfloat _dli; /**< CI diffuse light intensity */ - GLfloat _sli; /**< CI specular light intensity */ - /*@}*/ -}; - - -/** - * Light model state. - */ -struct gl_lightmodel -{ - GLfloat Ambient[4]; /**< ambient color */ - GLboolean LocalViewer; /**< Local (or infinite) view point? */ - GLboolean TwoSide; /**< Two (or one) sided lighting? */ - GLenum ColorControl; /**< either GL_SINGLE_COLOR - * or GL_SEPARATE_SPECULAR_COLOR */ -}; - - -/** - * Material state. - */ -struct gl_material -{ - GLfloat Attrib[MAT_ATTRIB_MAX][4]; -}; - - -/** - * Accumulation buffer attribute group (GL_ACCUM_BUFFER_BIT) - */ -struct gl_accum_attrib -{ - GLfloat ClearColor[4]; /**< Accumulation buffer clear color */ -}; - - -/** - * Color buffer attribute group (GL_COLOR_BUFFER_BIT). - */ -struct gl_colorbuffer_attrib -{ - GLuint ClearIndex; /**< Index to use for glClear */ - GLclampf ClearColor[4]; /**< Color to use for glClear */ - - GLuint IndexMask; /**< Color index write mask */ - GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */ - - GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */ - - /** - * \name alpha testing - */ - /*@{*/ - GLboolean AlphaEnabled; /**< Alpha test enabled flag */ - GLenum AlphaFunc; /**< Alpha test function */ - GLclampf AlphaRef; /**< Alpha reference value */ - /*@}*/ - - /** - * \name Blending - */ - /*@{*/ - GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */ - GLfloat BlendColor[4]; /**< Blending color */ - struct - { - GLenum SrcRGB; /**< RGB blend source term */ - GLenum DstRGB; /**< RGB blend dest term */ - GLenum SrcA; /**< Alpha blend source term */ - GLenum DstA; /**< Alpha blend dest term */ - GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */ - GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */ - } Blend[MAX_DRAW_BUFFERS]; - /** Are the blend func terms currently different for each buffer/target? */ - GLboolean _BlendFuncPerBuffer; - /** Are the blend equations currently different for each buffer/target? */ - GLboolean _BlendEquationPerBuffer; - /*@}*/ - - /** - * \name Logic op - */ - /*@{*/ - GLenum LogicOp; /**< Logic operator */ - GLboolean IndexLogicOpEnabled; /**< Color index logic op enabled flag */ - GLboolean ColorLogicOpEnabled; /**< RGBA logic op enabled flag */ - GLboolean _LogicOpEnabled; /**< RGBA logic op + EXT_blend_logic_op enabled flag */ - /*@}*/ - - GLboolean DitherFlag; /**< Dither enable flag */ - - GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */ - GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */ - - GLboolean sRGBEnabled; /**< Framebuffer sRGB blending/updating requested */ -}; - - -/** - * Current attribute group (GL_CURRENT_BIT). - */ -struct gl_current_attrib -{ - /** - * \name Current vertex attributes. - * \note Values are valid only after FLUSH_VERTICES has been called. - * \note Index and Edgeflag current values are stored as floats in the - * SIX and SEVEN attribute slots. - */ - GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Position, color, texcoords, etc */ - - /** - * \name Current raster position attributes (always valid). - * \note This set of attributes is very similar to the SWvertex struct. - */ - /*@{*/ - GLfloat RasterPos[4]; - GLfloat RasterDistance; - GLfloat RasterColor[4]; - GLfloat RasterSecondaryColor[4]; - GLfloat RasterTexCoords[MAX_TEXTURE_COORD_UNITS][4]; - GLboolean RasterPosValid; - /*@}*/ -}; - - -/** - * Depth buffer attribute group (GL_DEPTH_BUFFER_BIT). - */ -struct gl_depthbuffer_attrib -{ - GLenum Func; /**< Function for depth buffer compare */ - GLclampd Clear; /**< Value to clear depth buffer to */ - GLboolean Test; /**< Depth buffering enabled flag */ - GLboolean Mask; /**< Depth buffer writable? */ - GLboolean BoundsTest; /**< GL_EXT_depth_bounds_test */ - GLfloat BoundsMin, BoundsMax;/**< GL_EXT_depth_bounds_test */ -}; - - -/** - * Evaluator attribute group (GL_EVAL_BIT). - */ -struct gl_eval_attrib -{ - /** - * \name Enable bits - */ - /*@{*/ - GLboolean Map1Color4; - GLboolean Map1Index; - GLboolean Map1Normal; - GLboolean Map1TextureCoord1; - GLboolean Map1TextureCoord2; - GLboolean Map1TextureCoord3; - GLboolean Map1TextureCoord4; - GLboolean Map1Vertex3; - GLboolean Map1Vertex4; - GLboolean Map1Attrib[16]; /* GL_NV_vertex_program */ - GLboolean Map2Color4; - GLboolean Map2Index; - GLboolean Map2Normal; - GLboolean Map2TextureCoord1; - GLboolean Map2TextureCoord2; - GLboolean Map2TextureCoord3; - GLboolean Map2TextureCoord4; - GLboolean Map2Vertex3; - GLboolean Map2Vertex4; - GLboolean Map2Attrib[16]; /* GL_NV_vertex_program */ - GLboolean AutoNormal; - /*@}*/ - - /** - * \name Map Grid endpoints and divisions and calculated du values - */ - /*@{*/ - GLint MapGrid1un; - GLfloat MapGrid1u1, MapGrid1u2, MapGrid1du; - GLint MapGrid2un, MapGrid2vn; - GLfloat MapGrid2u1, MapGrid2u2, MapGrid2du; - GLfloat MapGrid2v1, MapGrid2v2, MapGrid2dv; - /*@}*/ -}; - - -/** - * Fog attribute group (GL_FOG_BIT). - */ -struct gl_fog_attrib -{ - GLboolean Enabled; /**< Fog enabled flag */ - GLfloat Color[4]; /**< Fog color */ - GLfloat Density; /**< Density >= 0.0 */ - GLfloat Start; /**< Start distance in eye coords */ - GLfloat End; /**< End distance in eye coords */ - GLfloat Index; /**< Fog index */ - GLenum Mode; /**< Fog mode */ - GLboolean ColorSumEnabled; - GLenum FogCoordinateSource; /**< GL_EXT_fog_coord */ - GLfloat _Scale; /**< (End == Start) ? 1.0 : 1.0 / (End - Start) */ -}; - - -/** - * \brief Layout qualifiers for gl_FragDepth. - * - * Extension AMD_conservative_depth allows gl_FragDepth to be redeclared with - * a layout qualifier. - * - * \see enum ir_depth_layout - */ -enum gl_frag_depth_layout { - FRAG_DEPTH_LAYOUT_NONE, /**< No layout is specified. */ - FRAG_DEPTH_LAYOUT_ANY, - FRAG_DEPTH_LAYOUT_GREATER, - FRAG_DEPTH_LAYOUT_LESS, - FRAG_DEPTH_LAYOUT_UNCHANGED -}; - - -/** - * Hint attribute group (GL_HINT_BIT). - * - * Values are always one of GL_FASTEST, GL_NICEST, or GL_DONT_CARE. - */ -struct gl_hint_attrib -{ - GLenum PerspectiveCorrection; - GLenum PointSmooth; - GLenum LineSmooth; - GLenum PolygonSmooth; - GLenum Fog; - GLenum ClipVolumeClipping; /**< GL_EXT_clip_volume_hint */ - GLenum TextureCompression; /**< GL_ARB_texture_compression */ - GLenum GenerateMipmap; /**< GL_SGIS_generate_mipmap */ - GLenum FragmentShaderDerivative; /**< GL_ARB_fragment_shader */ -}; - -/** - * Light state flags. - */ -/*@{*/ -#define LIGHT_SPOT 0x1 -#define LIGHT_LOCAL_VIEWER 0x2 -#define LIGHT_POSITIONAL 0x4 -#define LIGHT_NEED_VERTICES (LIGHT_POSITIONAL|LIGHT_LOCAL_VIEWER) -/*@}*/ - - -/** - * Lighting attribute group (GL_LIGHT_BIT). - */ -struct gl_light_attrib -{ - struct gl_light Light[MAX_LIGHTS]; /**< Array of light sources */ - struct gl_lightmodel Model; /**< Lighting model */ - - /** - * Must flush FLUSH_VERTICES before referencing: - */ - /*@{*/ - struct gl_material Material; /**< Includes front & back values */ - /*@}*/ - - GLboolean Enabled; /**< Lighting enabled flag */ - GLenum ShadeModel; /**< GL_FLAT or GL_SMOOTH */ - GLenum ProvokingVertex; /**< GL_EXT_provoking_vertex */ - GLenum ColorMaterialFace; /**< GL_FRONT, BACK or FRONT_AND_BACK */ - GLenum ColorMaterialMode; /**< GL_AMBIENT, GL_DIFFUSE, etc */ - GLbitfield ColorMaterialBitmask; /**< bitmask formed from Face and Mode */ - GLboolean ColorMaterialEnabled; - GLenum ClampVertexColor; - - struct gl_light EnabledList; /**< List sentinel */ - - /** - * Derived state for optimizations: - */ - /*@{*/ - GLboolean _NeedEyeCoords; - GLboolean _NeedVertices; /**< Use fast shader? */ - GLbitfield _Flags; /**< LIGHT_* flags, see above */ - GLfloat _BaseColor[2][3]; - /*@}*/ -}; - - -/** - * Line attribute group (GL_LINE_BIT). - */ -struct gl_line_attrib -{ - GLboolean SmoothFlag; /**< GL_LINE_SMOOTH enabled? */ - GLboolean StippleFlag; /**< GL_LINE_STIPPLE enabled? */ - GLushort StipplePattern; /**< Stipple pattern */ - GLint StippleFactor; /**< Stipple repeat factor */ - GLfloat Width; /**< Line width */ -}; - - -/** - * Display list attribute group (GL_LIST_BIT). - */ -struct gl_list_attrib -{ - GLuint ListBase; -}; - - -/** - * Multisample attribute group (GL_MULTISAMPLE_BIT). - */ -struct gl_multisample_attrib -{ - GLboolean Enabled; - GLboolean _Enabled; /**< true if Enabled and multisample buffer */ - GLboolean SampleAlphaToCoverage; - GLboolean SampleAlphaToOne; - GLboolean SampleCoverage; - GLfloat SampleCoverageValue; - GLboolean SampleCoverageInvert; -}; - - -/** - * A pixelmap (see glPixelMap) - */ -struct gl_pixelmap -{ - GLint Size; - GLfloat Map[MAX_PIXEL_MAP_TABLE]; - GLubyte Map8[MAX_PIXEL_MAP_TABLE]; /**< converted to 8-bit color */ -}; - - -/** - * Collection of all pixelmaps - */ -struct gl_pixelmaps -{ - struct gl_pixelmap RtoR; /**< i.e. GL_PIXEL_MAP_R_TO_R */ - struct gl_pixelmap GtoG; - struct gl_pixelmap BtoB; - struct gl_pixelmap AtoA; - struct gl_pixelmap ItoR; - struct gl_pixelmap ItoG; - struct gl_pixelmap ItoB; - struct gl_pixelmap ItoA; - struct gl_pixelmap ItoI; - struct gl_pixelmap StoS; -}; - - -/** - * Pixel attribute group (GL_PIXEL_MODE_BIT). - */ -struct gl_pixel_attrib -{ - GLenum ReadBuffer; /**< source buffer for glRead/CopyPixels() */ - - /*--- Begin Pixel Transfer State ---*/ - /* Fields are in the order in which they're applied... */ - - /** Scale & Bias (index shift, offset) */ - /*@{*/ - GLfloat RedBias, RedScale; - GLfloat GreenBias, GreenScale; - GLfloat BlueBias, BlueScale; - GLfloat AlphaBias, AlphaScale; - GLfloat DepthBias, DepthScale; - GLint IndexShift, IndexOffset; - /*@}*/ - - /* Pixel Maps */ - /* Note: actual pixel maps are not part of this attrib group */ - GLboolean MapColorFlag; - GLboolean MapStencilFlag; - - /*--- End Pixel Transfer State ---*/ - - /** glPixelZoom */ - GLfloat ZoomX, ZoomY; - - /** GL_SGI_texture_color_table */ - GLfloat TextureColorTableScale[4]; /**< RGBA */ - GLfloat TextureColorTableBias[4]; /**< RGBA */ -}; - - -/** - * Point attribute group (GL_POINT_BIT). - */ -struct gl_point_attrib -{ - GLboolean SmoothFlag; /**< True if GL_POINT_SMOOTH is enabled */ - GLfloat Size; /**< User-specified point size */ - GLfloat Params[3]; /**< GL_EXT_point_parameters */ - GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */ - GLfloat Threshold; /**< GL_EXT_point_parameters */ - GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */ - GLboolean PointSprite; /**< GL_NV/ARB_point_sprite */ - GLboolean CoordReplace[MAX_TEXTURE_COORD_UNITS]; /**< GL_ARB_point_sprite*/ - GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */ - GLenum SpriteOrigin; /**< GL_ARB_point_sprite */ -}; - - -/** - * Polygon attribute group (GL_POLYGON_BIT). - */ -struct gl_polygon_attrib -{ - GLenum FrontFace; /**< Either GL_CW or GL_CCW */ - GLenum FrontMode; /**< Either GL_POINT, GL_LINE or GL_FILL */ - GLenum BackMode; /**< Either GL_POINT, GL_LINE or GL_FILL */ - GLboolean _FrontBit; /**< 0=GL_CCW, 1=GL_CW */ - GLboolean CullFlag; /**< Culling on/off flag */ - GLboolean SmoothFlag; /**< True if GL_POLYGON_SMOOTH is enabled */ - GLboolean StippleFlag; /**< True if GL_POLYGON_STIPPLE is enabled */ - GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */ - GLfloat OffsetFactor; /**< Polygon offset factor, from user */ - GLfloat OffsetUnits; /**< Polygon offset units, from user */ - GLboolean OffsetPoint; /**< Offset in GL_POINT mode */ - GLboolean OffsetLine; /**< Offset in GL_LINE mode */ - GLboolean OffsetFill; /**< Offset in GL_FILL mode */ -}; - - -/** - * Scissor attributes (GL_SCISSOR_BIT). - */ -struct gl_scissor_attrib -{ - GLboolean Enabled; /**< Scissor test enabled? */ - GLint X, Y; /**< Lower left corner of box */ - GLsizei Width, Height; /**< Size of box */ -}; - - -/** - * Stencil attribute group (GL_STENCIL_BUFFER_BIT). - * - * Three sets of stencil data are tracked so that OpenGL 2.0, - * GL_EXT_stencil_two_side, and GL_ATI_separate_stencil can all be supported - * simultaneously. In each of the stencil state arrays, element 0 corresponds - * to GL_FRONT. Element 1 corresponds to the OpenGL 2.0 / - * GL_ATI_separate_stencil GL_BACK state. Element 2 corresponds to the - * GL_EXT_stencil_two_side GL_BACK state. - * - * The derived value \c _BackFace is either 1 or 2 depending on whether or - * not GL_STENCIL_TEST_TWO_SIDE_EXT is enabled. - * - * The derived value \c _TestTwoSide is set when the front-face and back-face - * stencil state are different. - */ -struct gl_stencil_attrib -{ - GLboolean Enabled; /**< Enabled flag */ - GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */ - GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */ - GLboolean _Enabled; /**< Enabled and stencil buffer present */ - GLboolean _TestTwoSide; - GLubyte _BackFace; /**< Current back stencil state (1 or 2) */ - GLenum Function[3]; /**< Stencil function */ - GLenum FailFunc[3]; /**< Fail function */ - GLenum ZPassFunc[3]; /**< Depth buffer pass function */ - GLenum ZFailFunc[3]; /**< Depth buffer fail function */ - GLint Ref[3]; /**< Reference value */ - GLuint ValueMask[3]; /**< Value mask */ - GLuint WriteMask[3]; /**< Write mask */ - GLuint Clear; /**< Clear value */ -}; - - -/** - * An index for each type of texture object. These correspond to the GL - * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc. - * Note: the order is from highest priority to lowest priority. - */ -typedef enum -{ - TEXTURE_2D_ARRAY_INDEX, - TEXTURE_1D_ARRAY_INDEX, - TEXTURE_CUBE_INDEX, - TEXTURE_3D_INDEX, - TEXTURE_RECT_INDEX, - TEXTURE_2D_INDEX, - TEXTURE_1D_INDEX, - NUM_TEXTURE_TARGETS -} gl_texture_index; - - -/** - * Bit flags for each type of texture object - * Used for Texture.Unit[]._ReallyEnabled flags. - */ -/*@{*/ -#define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX) -#define TEXTURE_1D_ARRAY_BIT (1 << TEXTURE_1D_ARRAY_INDEX) -#define TEXTURE_CUBE_BIT (1 << TEXTURE_CUBE_INDEX) -#define TEXTURE_3D_BIT (1 << TEXTURE_3D_INDEX) -#define TEXTURE_RECT_BIT (1 << TEXTURE_RECT_INDEX) -#define TEXTURE_2D_BIT (1 << TEXTURE_2D_INDEX) -#define TEXTURE_1D_BIT (1 << TEXTURE_1D_INDEX) -/*@}*/ - - -/** - * TexGenEnabled flags. - */ -/*@{*/ -#define S_BIT 1 -#define T_BIT 2 -#define R_BIT 4 -#define Q_BIT 8 -#define STR_BITS (S_BIT | T_BIT | R_BIT) -/*@}*/ - - -/** - * Bit flag versions of the corresponding GL_ constants. - */ -/*@{*/ -#define TEXGEN_SPHERE_MAP 0x1 -#define TEXGEN_OBJ_LINEAR 0x2 -#define TEXGEN_EYE_LINEAR 0x4 -#define TEXGEN_REFLECTION_MAP_NV 0x8 -#define TEXGEN_NORMAL_MAP_NV 0x10 - -#define TEXGEN_NEED_NORMALS (TEXGEN_SPHERE_MAP | \ - TEXGEN_REFLECTION_MAP_NV | \ - TEXGEN_NORMAL_MAP_NV) -#define TEXGEN_NEED_EYE_COORD (TEXGEN_SPHERE_MAP | \ - TEXGEN_REFLECTION_MAP_NV | \ - TEXGEN_NORMAL_MAP_NV | \ - TEXGEN_EYE_LINEAR) -/*@}*/ - - - -/** Tex-gen enabled for texture unit? */ -#define ENABLE_TEXGEN(unit) (1 << (unit)) - -/** Non-identity texture matrix for texture unit? */ -#define ENABLE_TEXMAT(unit) (1 << (unit)) - - -/** - * Texel fetch function prototype. We use texel fetch functions to - * extract RGBA, color indexes and depth components out of 1D, 2D and 3D - * texture images. These functions help to isolate us from the gritty - * details of all the various texture image encodings. - * - * \param texImage texture image. - * \param col texel column. - * \param row texel row. - * \param img texel image level/layer. - * \param texelOut output texel (up to 4 GLchans) - */ -typedef void (*FetchTexelFuncC)( const struct gl_texture_image *texImage, - GLint col, GLint row, GLint img, - GLchan *texelOut ); - -/** - * As above, but returns floats. - * Used for depth component images and for upcoming signed/float - * texture images. - */ -typedef void (*FetchTexelFuncF)( const struct gl_texture_image *texImage, - GLint col, GLint row, GLint img, - GLfloat *texelOut ); - - -typedef void (*StoreTexelFunc)(struct gl_texture_image *texImage, - GLint col, GLint row, GLint img, - const void *texel); - - -/** - * Texture image state. Describes the dimensions of a texture image, - * the texel format and pointers to Texel Fetch functions. - */ -struct gl_texture_image -{ - GLint InternalFormat; /**< Internal format as given by the user */ - GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_ALPHA, - * GL_LUMINANCE, GL_LUMINANCE_ALPHA, - * GL_INTENSITY, GL_COLOR_INDEX, - * GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT - * only. Used for choosing TexEnv arithmetic. - */ - GLuint TexFormat; /**< The actual format: MESA_FORMAT_x */ - - GLuint Border; /**< 0 or 1 */ - GLuint Width; /**< = 2^WidthLog2 + 2*Border */ - GLuint Height; /**< = 2^HeightLog2 + 2*Border */ - GLuint Depth; /**< = 2^DepthLog2 + 2*Border */ - GLuint Width2; /**< = Width - 2*Border */ - GLuint Height2; /**< = Height - 2*Border */ - GLuint Depth2; /**< = Depth - 2*Border */ - GLuint WidthLog2; /**< = log2(Width2) */ - GLuint HeightLog2; /**< = log2(Height2) */ - GLuint DepthLog2; /**< = log2(Depth2) */ - GLuint MaxLog2; /**< = MAX(WidthLog2, HeightLog2) */ - GLfloat WidthScale; /**< used for mipmap LOD computation */ - GLfloat HeightScale; /**< used for mipmap LOD computation */ - GLfloat DepthScale; /**< used for mipmap LOD computation */ - GLboolean IsClientData; /**< Data owned by client? */ - GLboolean _IsPowerOfTwo; /**< Are all dimensions powers of two? */ - - struct gl_texture_object *TexObject; /**< Pointer back to parent object */ - - FetchTexelFuncC FetchTexelc; /**< GLchan texel fetch function pointer */ - FetchTexelFuncF FetchTexelf; /**< Float texel fetch function pointer */ - - GLuint RowStride; /**< Padded width in units of texels */ - GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to - each 2D slice in 'Data', in texels */ - GLvoid *Data; /**< Image data, accessed via FetchTexel() */ - - /** - * \name For device driver: - */ - /*@{*/ - void *DriverData; /**< Arbitrary device driver data */ - /*@}*/ -}; - - -/** - * Indexes for cube map faces. - */ -typedef enum -{ - FACE_POS_X = 0, - FACE_NEG_X = 1, - FACE_POS_Y = 2, - FACE_NEG_Y = 3, - FACE_POS_Z = 4, - FACE_NEG_Z = 5, - MAX_FACES = 6 -} gl_face_index; - - -/** - * Texture object state. Contains the array of mipmap images, border color, - * wrap modes, filter modes, shadow/texcompare state, and the per-texture - * color palette. - */ -struct gl_texture_object -{ - _glthread_Mutex Mutex; /**< for thread safety */ - GLint RefCount; /**< reference count */ - GLuint Name; /**< the user-visible texture object ID */ - GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ - GLfloat Priority; /**< in [0,1] */ - union { - GLfloat f[4]; - GLuint ui[4]; - GLint i[4]; - } BorderColor; /**< Interpreted according to texture format */ - GLenum WrapS; /**< S-axis texture image wrap mode */ - GLenum WrapT; /**< T-axis texture image wrap mode */ - GLenum WrapR; /**< R-axis texture image wrap mode */ - GLenum MinFilter; /**< minification filter */ - GLenum MagFilter; /**< magnification filter */ - GLfloat MinLod; /**< min lambda, OpenGL 1.2 */ - GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */ - GLfloat LodBias; /**< OpenGL 1.4 */ - GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */ - GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */ - GLfloat MaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ - GLenum CompareMode; /**< GL_ARB_shadow */ - GLenum CompareFunc; /**< GL_ARB_shadow */ - GLfloat CompareFailValue; /**< GL_ARB_shadow_ambient */ - GLenum DepthMode; /**< GL_ARB_depth_texture */ - GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ - GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */ - GLint CropRect[4]; /**< GL_OES_draw_texture */ - GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */ - GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */ - GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */ - GLboolean _Complete; /**< Is texture object complete? */ - GLboolean _RenderToTexture; /**< Any rendering to this texture? */ - GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ - GLenum sRGBDecode; /**< GL_DECODE_EXT or GL_SKIP_DECODE_EXT */ - - /** Actual texture images, indexed by [cube face] and [mipmap level] */ - struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS]; - - /** GL_EXT_paletted_texture */ - struct gl_color_table Palette; - - /** - * \name For device driver. - * Note: instead of attaching driver data to this pointer, it's preferable - * to instead use this struct as a base class for your own texture object - * class. Driver->NewTextureObject() can be used to implement the - * allocation. - */ - void *DriverData; /**< Arbitrary device driver data */ -}; - - -/** Up to four combiner sources are possible with GL_NV_texture_env_combine4 */ -#define MAX_COMBINER_TERMS 4 - - -/** - * Texture combine environment state. - */ -struct gl_tex_env_combine_state -{ - GLenum ModeRGB; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */ - GLenum ModeA; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */ - /** Source terms: GL_PRIMARY_COLOR, GL_TEXTURE, etc */ - GLenum SourceRGB[MAX_COMBINER_TERMS]; - GLenum SourceA[MAX_COMBINER_TERMS]; - /** Source operands: GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, etc */ - GLenum OperandRGB[MAX_COMBINER_TERMS]; - GLenum OperandA[MAX_COMBINER_TERMS]; - GLuint ScaleShiftRGB; /**< 0, 1 or 2 */ - GLuint ScaleShiftA; /**< 0, 1 or 2 */ - GLuint _NumArgsRGB; /**< Number of inputs used for the RGB combiner */ - GLuint _NumArgsA; /**< Number of inputs used for the A combiner */ -}; - - -/** - * Texture coord generation state. - */ -struct gl_texgen -{ - GLenum Mode; /**< GL_EYE_LINEAR, GL_SPHERE_MAP, etc */ - GLbitfield _ModeBit; /**< TEXGEN_x bit corresponding to Mode */ - GLfloat ObjectPlane[4]; - GLfloat EyePlane[4]; -}; - - -/** - * Texture unit state. Contains enable flags, texture environment/function/ - * combiners, texgen state, pointers to current texture objects and - * post-filter color tables. - */ -struct gl_texture_unit -{ - GLbitfield Enabled; /**< bitmask of TEXTURE_*_BIT flags */ - GLbitfield _ReallyEnabled; /**< 0 or exactly one of TEXTURE_*_BIT flags */ - - GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */ - GLfloat EnvColor[4]; - - struct gl_texgen GenS; - struct gl_texgen GenT; - struct gl_texgen GenR; - struct gl_texgen GenQ; - GLbitfield TexGenEnabled; /**< Bitwise-OR of [STRQ]_BIT values */ - GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */ - - GLfloat LodBias; /**< for biasing mipmap levels */ - GLenum BumpTarget; - GLfloat RotMatrix[4]; /* 2x2 matrix */ - - /** - * \name GL_EXT_texture_env_combine - */ - struct gl_tex_env_combine_state Combine; - - /** - * Derived state based on \c EnvMode and the \c BaseFormat of the - * currently enabled texture. - */ - struct gl_tex_env_combine_state _EnvMode; - - /** - * Currently enabled combiner state. This will point to either - * \c Combine or \c _EnvMode. - */ - struct gl_tex_env_combine_state *_CurrentCombine; - - /** Current texture object pointers */ - struct gl_texture_object *CurrentTex[NUM_TEXTURE_TARGETS]; - - /** Points to highest priority, complete and enabled texture object */ - struct gl_texture_object *_Current; - - /** GL_SGI_texture_color_table */ - /*@{*/ - struct gl_color_table ColorTable; - struct gl_color_table ProxyColorTable; - GLboolean ColorTableEnabled; - /*@}*/ -}; - - -/** - * Texture attribute group (GL_TEXTURE_BIT). - */ -struct gl_texture_attrib -{ - GLuint CurrentUnit; /**< GL_ACTIVE_TEXTURE */ - struct gl_texture_unit Unit[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; - - struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS]; - - /** GL_ARB_seamless_cubemap */ - GLboolean CubeMapSeamless; - - /** GL_EXT_shared_texture_palette */ - GLboolean SharedPalette; - struct gl_color_table Palette; - - /** Texture units/samplers used by vertex or fragment texturing */ - GLbitfield _EnabledUnits; - - /** Texture coord units/sets used for fragment texturing */ - GLbitfield _EnabledCoordUnits; - - /** Texture coord units that have texgen enabled */ - GLbitfield _TexGenEnabled; - - /** Texture coord units that have non-identity matrices */ - GLbitfield _TexMatEnabled; - - /** Bitwise-OR of all Texture.Unit[i]._GenFlags */ - GLbitfield _GenFlags; -}; - - -/** - * Transformation attribute group (GL_TRANSFORM_BIT). - */ -struct gl_transform_attrib -{ - GLenum MatrixMode; /**< Matrix mode */ - GLfloat EyeUserPlane[MAX_CLIP_PLANES][4]; /**< User clip planes */ - GLfloat _ClipUserPlane[MAX_CLIP_PLANES][4]; /**< derived */ - GLbitfield ClipPlanesEnabled; /**< on/off bitmask */ - GLboolean Normalize; /**< Normalize all normals? */ - GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */ - GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */ - GLboolean DepthClamp; /**< GL_ARB_depth_clamp */ - - GLfloat CullEyePos[4]; - GLfloat CullObjPos[4]; -}; - - -/** - * Viewport attribute group (GL_VIEWPORT_BIT). - */ -struct gl_viewport_attrib -{ - GLint X, Y; /**< position */ - GLsizei Width, Height; /**< size */ - GLfloat Near, Far; /**< Depth buffer range */ - GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */ -}; - - -/** - * GL_ARB_vertex/pixel_buffer_object buffer object - */ -struct gl_buffer_object -{ - _glthread_Mutex Mutex; - GLint RefCount; - GLuint Name; - GLenum Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */ - GLsizeiptrARB Size; /**< Size of buffer storage in bytes */ - GLubyte *Data; /**< Location of storage either in RAM or VRAM. */ - /** Fields describing a mapped buffer */ - /*@{*/ - GLbitfield AccessFlags; /**< Mask of GL_MAP_x_BIT flags */ - GLvoid *Pointer; /**< User-space address of mapping */ - GLintptr Offset; /**< Mapped offset */ - GLsizeiptr Length; /**< Mapped length */ - /*@}*/ - GLboolean Written; /**< Ever written to? (for debugging) */ - GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ -}; - - -/** - * Client pixel packing/unpacking attributes - */ -struct gl_pixelstore_attrib -{ - GLint Alignment; - GLint RowLength; - GLint SkipPixels; - GLint SkipRows; - GLint ImageHeight; - GLint SkipImages; - GLboolean SwapBytes; - GLboolean LsbFirst; - GLboolean ClientStorage; /**< GL_APPLE_client_storage */ - GLboolean Invert; /**< GL_MESA_pack_invert */ - struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */ -}; - - -/** - * Client vertex array attributes - */ -struct gl_client_array -{ - GLint Size; /**< components per element (1,2,3,4) */ - GLenum Type; /**< datatype: GL_FLOAT, GL_INT, etc */ - GLenum Format; /**< default: GL_RGBA, but may be GL_BGRA */ - GLsizei Stride; /**< user-specified stride */ - GLsizei StrideB; /**< actual stride in bytes */ - const GLubyte *Ptr; /**< Points to array data */ - GLboolean Enabled; /**< Enabled flag is a boolean */ - GLboolean Normalized; /**< GL_ARB_vertex_program */ - GLboolean Integer; /**< Integer-valued? */ - GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */ - GLuint _ElementSize; /**< size of each element in bytes */ - - struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */ - GLuint _MaxElement; /**< max element index into array buffer + 1 */ -}; - - -/** - * Collection of vertex arrays. Defined by the GL_APPLE_vertex_array_object - * extension, but a nice encapsulation in any case. - */ -struct gl_array_object -{ - /** Name of the array object as received from glGenVertexArrayAPPLE. */ - GLuint Name; - - GLint RefCount; - _glthread_Mutex Mutex; - GLboolean VBOonly; /**< require all arrays to live in VBOs? */ - - /** Conventional vertex arrays */ - /*@{*/ - struct gl_client_array Vertex; - struct gl_client_array Weight; - struct gl_client_array Normal; - struct gl_client_array Color; - struct gl_client_array SecondaryColor; - struct gl_client_array FogCoord; - struct gl_client_array Index; - struct gl_client_array EdgeFlag; - struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS]; - struct gl_client_array PointSize; - /*@}*/ - - /** - * Generic arrays for vertex programs/shaders. - * For NV vertex programs, these attributes alias and take priority - * over the conventional attribs above. For ARB vertex programs and - * GLSL vertex shaders, these attributes are separate. - */ - struct gl_client_array VertexAttrib[MAX_VERTEX_GENERIC_ATTRIBS]; - - /** Mask of _NEW_ARRAY_* values indicating which arrays are enabled */ - GLbitfield _Enabled; - - /** - * Min of all enabled arrays' _MaxElement. When arrays reside inside VBOs - * we can determine the max legal (in bounds) glDrawElements array index. - */ - GLuint _MaxElement; -}; - - -/** - * Vertex array state - */ -struct gl_array_attrib -{ - /** Currently bound array object. See _mesa_BindVertexArrayAPPLE() */ - struct gl_array_object *ArrayObj; - - /** The default vertex array object */ - struct gl_array_object *DefaultArrayObj; - - /** Array objects (GL_ARB/APPLE_vertex_array_object) */ - struct _mesa_HashTable *Objects; - - GLint ActiveTexture; /**< Client Active Texture */ - GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */ - GLuint LockCount; /**< GL_EXT_compiled_vertex_array */ - - /** GL 3.1 (slightly different from GL_NV_primitive_restart) */ - GLboolean PrimitiveRestart; - GLuint RestartIndex; - - GLbitfield NewState; /**< mask of _NEW_ARRAY_* values */ - - /* GL_ARB_vertex_buffer_object */ - struct gl_buffer_object *ArrayBufferObj; - struct gl_buffer_object *ElementArrayBufferObj; -}; - - -/** - * Feedback buffer state - */ -struct gl_feedback -{ - GLenum Type; - GLbitfield _Mask; /**< FB_* bits */ - GLfloat *Buffer; - GLuint BufferSize; - GLuint Count; -}; - - -/** - * Selection buffer state - */ -struct gl_selection -{ - GLuint *Buffer; /**< selection buffer */ - GLuint BufferSize; /**< size of the selection buffer */ - GLuint BufferCount; /**< number of values in the selection buffer */ - GLuint Hits; /**< number of records in the selection buffer */ - GLuint NameStackDepth; /**< name stack depth */ - GLuint NameStack[MAX_NAME_STACK_DEPTH]; /**< name stack */ - GLboolean HitFlag; /**< hit flag */ - GLfloat HitMinZ; /**< minimum hit depth */ - GLfloat HitMaxZ; /**< maximum hit depth */ -}; - - -/** - * 1-D Evaluator control points - */ -struct gl_1d_map -{ - GLuint Order; /**< Number of control points */ - GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */ - GLfloat *Points; /**< Points to contiguous control points */ -}; - - -/** - * 2-D Evaluator control points - */ -struct gl_2d_map -{ - GLuint Uorder; /**< Number of control points in U dimension */ - GLuint Vorder; /**< Number of control points in V dimension */ - GLfloat u1, u2, du; - GLfloat v1, v2, dv; - GLfloat *Points; /**< Points to contiguous control points */ -}; - - -/** - * All evaluator control point state - */ -struct gl_evaluators -{ - /** - * \name 1-D maps - */ - /*@{*/ - struct gl_1d_map Map1Vertex3; - struct gl_1d_map Map1Vertex4; - struct gl_1d_map Map1Index; - struct gl_1d_map Map1Color4; - struct gl_1d_map Map1Normal; - struct gl_1d_map Map1Texture1; - struct gl_1d_map Map1Texture2; - struct gl_1d_map Map1Texture3; - struct gl_1d_map Map1Texture4; - struct gl_1d_map Map1Attrib[16]; /**< GL_NV_vertex_program */ - /*@}*/ - - /** - * \name 2-D maps - */ - /*@{*/ - struct gl_2d_map Map2Vertex3; - struct gl_2d_map Map2Vertex4; - struct gl_2d_map Map2Index; - struct gl_2d_map Map2Color4; - struct gl_2d_map Map2Normal; - struct gl_2d_map Map2Texture1; - struct gl_2d_map Map2Texture2; - struct gl_2d_map Map2Texture3; - struct gl_2d_map Map2Texture4; - struct gl_2d_map Map2Attrib[16]; /**< GL_NV_vertex_program */ - /*@}*/ -}; - - -/** - * Names of the various vertex/fragment program register files, etc. - * - * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c) - * All values should fit in a 4-bit field. - * - * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM, - * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to - * be "uniform" variables since they can only be set outside glBegin/End. - * They're also all stored in the same Parameters array. - */ -typedef enum -{ - PROGRAM_TEMPORARY, /**< machine->Temporary[] */ - PROGRAM_INPUT, /**< machine->Inputs[] */ - PROGRAM_OUTPUT, /**< machine->Outputs[] */ - PROGRAM_VARYING, /**< machine->Inputs[]/Outputs[] */ - PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */ - PROGRAM_ENV_PARAM, /**< gl_program->Parameters[] */ - PROGRAM_STATE_VAR, /**< gl_program->Parameters[] */ - PROGRAM_NAMED_PARAM, /**< gl_program->Parameters[] */ - PROGRAM_CONSTANT, /**< gl_program->Parameters[] */ - PROGRAM_UNIFORM, /**< gl_program->Parameters[] */ - PROGRAM_WRITE_ONLY, /**< A dummy, write-only register */ - PROGRAM_ADDRESS, /**< machine->AddressReg */ - PROGRAM_SAMPLER, /**< for shader samplers, compile-time only */ - PROGRAM_SYSTEM_VALUE,/**< InstanceId, PrimitiveID, etc. */ - PROGRAM_UNDEFINED, /**< Invalid/TBD value */ - PROGRAM_FILE_MAX -} gl_register_file; - - -/** - * If the register file is PROGRAM_SYSTEM_VALUE, the register index will be - * one of these values. - */ -typedef enum -{ - SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */ - SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */ - SYSTEM_VALUE_MAX /**< Number of values */ -} gl_system_value; - - -/** Vertex and fragment instructions */ -struct prog_instruction; -struct gl_program_parameter_list; -struct gl_uniform_list; - - -/** - * Base class for any kind of program object - */ -struct gl_program -{ - GLuint Id; - GLubyte *String; /**< Null-terminated program text */ - GLint RefCount; - GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */ - GLenum Format; /**< String encoding format */ - GLboolean Resident; - - struct prog_instruction *Instructions; - - GLbitfield InputsRead; /**< Bitmask of which input regs are read */ - GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */ - GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */ - GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */ - GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */ - GLbitfield TexturesUsed[MAX_TEXTURE_UNITS]; /**< TEXTURE_x_BIT bitmask */ - GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */ - GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */ - - - /** Named parameters, constants, etc. from program text */ - struct gl_program_parameter_list *Parameters; - /** Numbered local parameters */ - GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4]; - - /** Vertex/fragment shader varying vars */ - struct gl_program_parameter_list *Varying; - /** Vertex program user-defined attributes */ - struct gl_program_parameter_list *Attributes; - - /** Map from sampler unit to texture unit (set by glUniform1i()) */ - GLubyte SamplerUnits[MAX_SAMPLERS]; - /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */ - gl_texture_index SamplerTargets[MAX_SAMPLERS]; - - /** Bitmask of which register files are read/written with indirect - * addressing. Mask of (1 << PROGRAM_x) bits. - */ - GLbitfield IndirectRegisterFiles; - - /** Logical counts */ - /*@{*/ - GLuint NumInstructions; - GLuint NumTemporaries; - GLuint NumParameters; - GLuint NumAttributes; - GLuint NumAddressRegs; - GLuint NumAluInstructions; - GLuint NumTexInstructions; - GLuint NumTexIndirections; - /*@}*/ - /** Native, actual h/w counts */ - /*@{*/ - GLuint NumNativeInstructions; - GLuint NumNativeTemporaries; - GLuint NumNativeParameters; - GLuint NumNativeAttributes; - GLuint NumNativeAddressRegs; - GLuint NumNativeAluInstructions; - GLuint NumNativeTexInstructions; - GLuint NumNativeTexIndirections; - /*@}*/ -}; - - -/** Vertex program object */ -struct gl_vertex_program -{ - struct gl_program Base; /**< base class */ - GLboolean IsNVProgram; /**< is this a GL_NV_vertex_program program? */ - GLboolean IsPositionInvariant; -}; - - -/** Geometry program object */ -struct gl_geometry_program -{ - struct gl_program Base; /**< base class */ - - GLint VerticesOut; - GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB, - GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */ - GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */ -}; - - -/** Fragment program object */ -struct gl_fragment_program -{ - struct gl_program Base; /**< base class */ - GLenum FogOption; - GLboolean UsesKill; /**< shader uses KIL instruction */ - GLboolean OriginUpperLeft; - GLboolean PixelCenterInteger; - enum gl_frag_depth_layout FragDepthLayout; -}; - - -/** - * State common to vertex and fragment programs. - */ -struct gl_program_state -{ - GLint ErrorPos; /* GL_PROGRAM_ERROR_POSITION_ARB/NV */ - const char *ErrorString; /* GL_PROGRAM_ERROR_STRING_ARB/NV */ -}; - - -/** - * Context state for vertex programs. - */ -struct gl_vertex_program_state -{ - GLboolean Enabled; /**< User-set GL_VERTEX_PROGRAM_ARB/NV flag */ - GLboolean _Enabled; /**< Enabled and _valid_ user program? */ - GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */ - GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */ - struct gl_vertex_program *Current; /**< User-bound vertex program */ - - /** Currently enabled and valid vertex program (including internal - * programs, user-defined vertex programs and GLSL vertex shaders). - * This is the program we must use when rendering. - */ - struct gl_vertex_program *_Current; - - GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ - - /* For GL_NV_vertex_program only: */ - GLenum TrackMatrix[MAX_PROGRAM_ENV_PARAMS / 4]; - GLenum TrackMatrixTransform[MAX_PROGRAM_ENV_PARAMS / 4]; - - /** Should fixed-function T&L be implemented with a vertex prog? */ - GLboolean _MaintainTnlProgram; - - /** Program to emulate fixed-function T&L (see above) */ - struct gl_vertex_program *_TnlProgram; - - /** Cache of fixed-function programs */ - struct gl_program_cache *Cache; - - GLboolean _Overriden; -}; - - -/** - * Context state for geometry programs. - */ -struct gl_geometry_program_state -{ - GLboolean Enabled; /**< GL_ARB_GEOMETRY_SHADER4 */ - GLboolean _Enabled; /**< Enabled and valid program? */ - struct gl_geometry_program *Current; /**< user-bound geometry program */ - - /** Currently enabled and valid program (including internal programs - * and compiled shader programs). - */ - struct gl_geometry_program *_Current; - - GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ - - /** Cache of fixed-function programs */ - struct gl_program_cache *Cache; -}; - -/** - * Context state for fragment programs. - */ -struct gl_fragment_program_state -{ - GLboolean Enabled; /**< User-set fragment program enable flag */ - GLboolean _Enabled; /**< Enabled and _valid_ user program? */ - struct gl_fragment_program *Current; /**< User-bound fragment program */ - - /** Currently enabled and valid fragment program (including internal - * programs, user-defined fragment programs and GLSL fragment shaders). - * This is the program we must use when rendering. - */ - struct gl_fragment_program *_Current; - - GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ - - /** Should fixed-function texturing be implemented with a fragment prog? */ - GLboolean _MaintainTexEnvProgram; - - /** Program to emulate fixed-function texture env/combine (see above) */ - struct gl_fragment_program *_TexEnvProgram; - - /** Cache of fixed-function programs */ - struct gl_program_cache *Cache; -}; - - -/** - * ATI_fragment_shader runtime state - */ -#define ATI_FS_INPUT_PRIMARY 0 -#define ATI_FS_INPUT_SECONDARY 1 - -struct atifs_instruction; -struct atifs_setupinst; - -/** - * ATI fragment shader - */ -struct ati_fragment_shader -{ - GLuint Id; - GLint RefCount; - struct atifs_instruction *Instructions[2]; - struct atifs_setupinst *SetupInst[2]; - GLfloat Constants[8][4]; - GLbitfield LocalConstDef; /**< Indicates which constants have been set */ - GLubyte numArithInstr[2]; - GLubyte regsAssigned[2]; - GLubyte NumPasses; /**< 1 or 2 */ - GLubyte cur_pass; - GLubyte last_optype; - GLboolean interpinp1; - GLboolean isValid; - GLuint swizzlerq; -}; - -/** - * Context state for GL_ATI_fragment_shader - */ -struct gl_ati_fragment_shader_state -{ - GLboolean Enabled; - GLboolean _Enabled; /**< enabled and valid shader? */ - GLboolean Compiling; - GLfloat GlobalConstants[8][4]; - struct ati_fragment_shader *Current; -}; - - -/** - * Occlusion/timer query object. - */ -struct gl_query_object -{ - GLenum Target; /**< The query target, when active */ - GLuint Id; /**< hash table ID/name */ - GLuint64EXT Result; /**< the counter */ - GLboolean Active; /**< inside Begin/EndQuery */ - GLboolean Ready; /**< result is ready? */ -}; - - -/** - * Context state for query objects. - */ -struct gl_query_state -{ - struct _mesa_HashTable *QueryObjects; - struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */ - struct gl_query_object *CurrentTimerObject; /* GL_EXT_timer_query */ - - /** GL_NV_conditional_render */ - struct gl_query_object *CondRenderQuery; - - /** GL_EXT_transform_feedback */ - struct gl_query_object *PrimitivesGenerated; - struct gl_query_object *PrimitivesWritten; - - /** GL_ARB_timer_query */ - struct gl_query_object *TimeElapsed; - - GLenum CondRenderMode; -}; - - -/** Sync object state */ -struct gl_sync_object { - struct simple_node link; - GLenum Type; /**< GL_SYNC_FENCE */ - GLuint Name; /**< Fence name */ - GLint RefCount; /**< Reference count */ - GLboolean DeletePending; /**< Object was deleted while there were still - * live references (e.g., sync not yet finished) - */ - GLenum SyncCondition; - GLbitfield Flags; /**< Flags passed to glFenceSync */ - GLuint StatusFlag:1; /**< Has the sync object been signaled? */ -}; - - -/** Set by #pragma directives */ -struct gl_sl_pragmas -{ - GLboolean IgnoreOptimize; /**< ignore #pragma optimize(on/off) ? */ - GLboolean IgnoreDebug; /**< ignore #pragma debug(on/off) ? */ - GLboolean Optimize; /**< defaults on */ - GLboolean Debug; /**< defaults off */ -}; - - -/** - * A GLSL vertex or fragment shader object. - */ -struct gl_shader -{ - GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB (first field!) */ - GLuint Name; /**< AKA the handle */ - GLint RefCount; /**< Reference count */ - GLboolean DeletePending; - GLboolean CompileStatus; - GLboolean Main; /**< shader defines main() */ - GLboolean UnresolvedRefs; - const GLchar *Source; /**< Source code string */ - GLuint SourceChecksum; /**< for debug/logging purposes */ - struct gl_program *Program; /**< Post-compile assembly code */ - GLchar *InfoLog; - struct gl_sl_pragmas Pragmas; - - unsigned Version; /**< GLSL version used for linking */ - - struct exec_list *ir; - struct glsl_symbol_table *symbols; - - /** Shaders containing built-in functions that are used for linking. */ - struct gl_shader *builtins_to_link[16]; - unsigned num_builtins_to_link; -}; - - -/** - * A GLSL program object. - * Basically a linked collection of vertex and fragment shaders. - */ -struct gl_shader_program -{ - GLenum Type; /**< Always GL_SHADER_PROGRAM (internal token) */ - GLuint Name; /**< aka handle or ID */ - GLint RefCount; /**< Reference count */ - GLboolean DeletePending; - - GLuint NumShaders; /**< number of attached shaders */ - struct gl_shader **Shaders; /**< List of attached the shaders */ - - /** User-defined attribute bindings (glBindAttribLocation) */ - struct gl_program_parameter_list *Attributes; - - /** Transform feedback varyings */ - struct { - GLenum BufferMode; - GLuint NumVarying; - GLchar **VaryingNames; /**< Array [NumVarying] of char * */ - } TransformFeedback; - - /** Geometry shader state - copied into gl_geometry_program at link time */ - struct { - GLint VerticesOut; - GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB, - GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */ - GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */ - } Geom; - - /* post-link info: */ - struct gl_vertex_program *VertexProgram; /**< Linked vertex program */ - struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */ - struct gl_geometry_program *GeometryProgram; /**< Linked geometry prog */ - struct gl_uniform_list *Uniforms; - struct gl_program_parameter_list *Varying; - GLboolean LinkStatus; /**< GL_LINK_STATUS */ - GLboolean Validated; - GLboolean _Used; /**< Ever used for drawing? */ - GLchar *InfoLog; - - unsigned Version; /**< GLSL version used for linking */ - - /** - * Per-stage shaders resulting from the first stage of linking. - * - * Set of linked shaders for this program. The array is accessed using the - * \c MESA_SHADER_* defines. Entries for non-existent stages will be - * \c NULL. - */ - struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES]; -}; - - -#define GLSL_DUMP 0x1 /**< Dump shaders to stdout */ -#define GLSL_LOG 0x2 /**< Write shaders to files */ -#define GLSL_OPT 0x4 /**< Force optimizations (override pragmas) */ -#define GLSL_NO_OPT 0x8 /**< Force no optimizations (override pragmas) */ -#define GLSL_UNIFORMS 0x10 /**< Print glUniform calls */ -#define GLSL_NOP_VERT 0x20 /**< Force no-op vertex shaders */ -#define GLSL_NOP_FRAG 0x40 /**< Force no-op fragment shaders */ -#define GLSL_USE_PROG 0x80 /**< Log glUseProgram calls */ - - -/** - * Context state for GLSL vertex/fragment shaders. - */ -struct gl_shader_state -{ - /** - * Programs used for rendering - * - * There is a separate program set for each shader stage. If - * GL_EXT_separate_shader_objects is not supported, each of these must point - * to \c NULL or to the same program. - */ - struct gl_shader_program *CurrentVertexProgram; - struct gl_shader_program *CurrentGeometryProgram; - struct gl_shader_program *CurrentFragmentProgram; - - /** - * Program used by glUniform calls. - * - * Explicitly set by \c glUseProgram and \c glActiveProgramEXT. - */ - struct gl_shader_program *ActiveProgram; - - void *MemPool; - - GLbitfield Flags; /**< Mask of GLSL_x flags */ -}; - -/** - * Compiler options for a single GLSL shaders type - */ -struct gl_shader_compiler_options -{ - /** Driver-selectable options: */ - GLboolean EmitCondCodes; /**< Use condition codes? */ - GLboolean EmitNVTempInitialization; /**< 0-fill NV temp registers */ - /** - * Attempts to flatten all ir_if (OPCODE_IF) for GPUs that can't - * support control flow. - */ - GLboolean EmitNoIfs; - GLboolean EmitNoLoops; - GLboolean EmitNoFunctions; - GLboolean EmitNoCont; /**< Emit CONT opcode? */ - GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */ - GLboolean EmitNoNoise; /**< Emit NOISE opcodes? */ - GLboolean EmitNoPow; /**< Emit POW opcodes? */ - - /** - * \name Forms of indirect addressing the driver cannot do. - */ - /*@{*/ - GLboolean EmitNoIndirectInput; /**< No indirect addressing of inputs */ - GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */ - GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */ - GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */ - /*@}*/ - - GLuint MaxUnrollIterations; - - struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */ -}; - -/** - * Transform feedback object state - */ -struct gl_transform_feedback_object -{ - GLuint Name; /**< AKA the object ID */ - GLint RefCount; - GLboolean Active; /**< Is transform feedback enabled? */ - GLboolean Paused; /**< Is transform feedback paused? */ - - /** The feedback buffers */ - GLuint BufferNames[MAX_FEEDBACK_ATTRIBS]; - struct gl_buffer_object *Buffers[MAX_FEEDBACK_ATTRIBS]; - - /** Start of feedback data in dest buffer */ - GLintptr Offset[MAX_FEEDBACK_ATTRIBS]; - /** Max data to put into dest buffer (in bytes) */ - GLsizeiptr Size[MAX_FEEDBACK_ATTRIBS]; -}; - - -/** - * Context state for transform feedback. - */ -struct gl_transform_feedback -{ - GLenum Mode; /**< GL_POINTS, GL_LINES or GL_TRIANGLES */ - - GLboolean RasterDiscard; /**< GL_RASTERIZER_DISCARD */ - - /** The general binding point (GL_TRANSFORM_FEEDBACK_BUFFER) */ - struct gl_buffer_object *CurrentBuffer; - - /** The table of all transform feedback objects */ - struct _mesa_HashTable *Objects; - - /** The current xform-fb object (GL_TRANSFORM_FEEDBACK_BINDING) */ - struct gl_transform_feedback_object *CurrentObject; - - /** The default xform-fb object (Name==0) */ - struct gl_transform_feedback_object *DefaultObject; -}; - - - -/** - * State which can be shared by multiple contexts: - */ -struct gl_shared_state -{ - _glthread_Mutex Mutex; /**< for thread safety */ - GLint RefCount; /**< Reference count */ - struct _mesa_HashTable *DisplayList; /**< Display lists hash table */ - struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */ - - /** Default texture objects (shared by all texture units) */ - struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS]; - - /** Fallback texture used when a bound texture is incomplete */ - struct gl_texture_object *FallbackTex; - - /** - * \name Thread safety and statechange notification for texture - * objects. - * - * \todo Improve the granularity of locking. - */ - /*@{*/ - _glthread_Mutex TexMutex; /**< texobj thread safety */ - GLuint TextureStateStamp; /**< state notification for shared tex */ - /*@}*/ - - /** Default buffer object for vertex arrays that aren't in VBOs */ - struct gl_buffer_object *NullBufferObj; - - /** - * \name Vertex/geometry/fragment programs - */ - /*@{*/ - struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */ - struct gl_vertex_program *DefaultVertexProgram; - struct gl_fragment_program *DefaultFragmentProgram; - struct gl_geometry_program *DefaultGeometryProgram; - /*@}*/ - - /* GL_ATI_fragment_shader */ - struct _mesa_HashTable *ATIShaders; - struct ati_fragment_shader *DefaultFragmentShader; - - struct _mesa_HashTable *BufferObjects; - - /** Table of both gl_shader and gl_shader_program objects */ - struct _mesa_HashTable *ShaderObjects; - - /* GL_EXT_framebuffer_object */ - struct _mesa_HashTable *RenderBuffers; - struct _mesa_HashTable *FrameBuffers; - - /* GL_ARB_sync */ - struct simple_node SyncObjects; - - void *DriverData; /**< Device driver shared state */ -}; - - - - -/** - * A renderbuffer stores colors or depth values or stencil values. - * A framebuffer object will have a collection of these. - * Data are read/written to the buffer with a handful of Get/Put functions. - * - * Instances of this object are allocated with the Driver's NewRenderbuffer - * hook. Drivers will likely wrap this class inside a driver-specific - * class to simulate inheritance. - */ -struct gl_renderbuffer -{ -#define RB_MAGIC 0xaabbccdd - int Magic; /** XXX TEMPORARY DEBUG INFO */ - _glthread_Mutex Mutex; /**< for thread safety */ - GLuint ClassID; /**< Useful for drivers */ - GLuint Name; - GLint RefCount; - GLuint Width, Height; - GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ - - GLenum InternalFormat; /**< The user-specified format */ - GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or - GL_STENCIL_INDEX. */ - GLuint Format; /**< The actual format: MESA_FORMAT_x */ - - GLubyte NumSamples; - - GLenum DataType; /**< Type of values passed to the Get/Put functions */ - GLvoid *Data; /**< This may not be used by some kinds of RBs */ - - /* Used to wrap one renderbuffer around another: */ - struct gl_renderbuffer *Wrapped; - - /* Delete this renderbuffer */ - void (*Delete)(struct gl_renderbuffer *rb); - - /* Allocate new storage for this renderbuffer */ - GLboolean (*AllocStorage)(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height); - - /* Lock/Unlock are called before/after calling the Get/Put functions. - * Not sure this is the right place for these yet. - void (*Lock)(struct gl_context *ctx, struct gl_renderbuffer *rb); - void (*Unlock)(struct gl_context *ctx, struct gl_renderbuffer *rb); - */ - - /* Return a pointer to the element/pixel at (x,y). - * Should return NULL if the buffer memory can't be directly addressed. - */ - void *(*GetPointer)(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLint x, GLint y); - - /* Get/Read a row of values. - * The values will be of format _BaseFormat and type DataType. - */ - void (*GetRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, void *values); - - /* Get/Read values at arbitrary locations. - * The values will be of format _BaseFormat and type DataType. - */ - void (*GetValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values); - - /* Put/Write a row of values. - * The values will be of format _BaseFormat and type DataType. - */ - void (*PutRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask); - - /* Put/Write a row of RGB values. This is a special-case routine that's - * only used for RGBA renderbuffers when the source data is GL_RGB. That's - * a common case for glDrawPixels and some triangle routines. - * The values will be of format GL_RGB and type DataType. - */ - void (*PutRowRGB)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask); - - - /* Put/Write a row of identical values. - * The values will be of format _BaseFormat and type DataType. - */ - void (*PutMonoRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *value, const GLubyte *mask); - - /* Put/Write values at arbitrary locations. - * The values will be of format _BaseFormat and type DataType. - */ - void (*PutValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], const void *values, - const GLubyte *mask); - /* Put/Write identical values at arbitrary locations. - * The values will be of format _BaseFormat and type DataType. - */ - void (*PutMonoValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *value, const GLubyte *mask); -}; - - -/** - * A renderbuffer attachment points to either a texture object (and specifies - * a mipmap level, cube face or 3D texture slice) or points to a renderbuffer. - */ -struct gl_renderbuffer_attachment -{ - GLenum Type; /**< \c GL_NONE or \c GL_TEXTURE or \c GL_RENDERBUFFER_EXT */ - GLboolean Complete; - - /** - * If \c Type is \c GL_RENDERBUFFER_EXT, this stores a pointer to the - * application supplied renderbuffer object. - */ - struct gl_renderbuffer *Renderbuffer; - - /** - * If \c Type is \c GL_TEXTURE, this stores a pointer to the application - * supplied texture object. - */ - struct gl_texture_object *Texture; - GLuint TextureLevel; /**< Attached mipmap level. */ - GLuint CubeMapFace; /**< 0 .. 5, for cube map textures. */ - GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D - * and 2D array textures */ -}; - - -/** - * A framebuffer is a collection of renderbuffers (color, depth, stencil, etc). - * In C++ terms, think of this as a base class from which device drivers - * will make derived classes. - */ -struct gl_framebuffer -{ - _glthread_Mutex Mutex; /**< for thread safety */ - /** - * If zero, this is a window system framebuffer. If non-zero, this - * is a FBO framebuffer; note that for some devices (i.e. those with - * a natural pixel coordinate system for FBOs that differs from the - * OpenGL/Mesa coordinate system), this means that the viewport, - * polygon face orientation, and polygon stipple will have to be inverted. - */ - GLuint Name; - - GLint RefCount; - GLboolean DeletePending; - - /** - * The framebuffer's visual. Immutable if this is a window system buffer. - * Computed from attachments if user-made FBO. - */ - struct gl_config Visual; - - GLboolean Initialized; - - GLuint Width, Height; /**< size of frame buffer in pixels */ - - /** \name Drawing bounds (Intersection of buffer size and scissor box) */ - /*@{*/ - GLint _Xmin, _Xmax; /**< inclusive */ - GLint _Ymin, _Ymax; /**< exclusive */ - /*@}*/ - - /** \name Derived Z buffer stuff */ - /*@{*/ - GLuint _DepthMax; /**< Max depth buffer value */ - GLfloat _DepthMaxF; /**< Float max depth buffer value */ - GLfloat _MRD; /**< minimum resolvable difference in Z values */ - /*@}*/ - - /** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */ - GLenum _Status; - - /** Integer color values */ - GLboolean _IntegerColor; - - /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */ - struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT]; - - /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER - * attribute group and GL_PIXEL attribute group, respectively. - */ - GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS]; - GLenum ColorReadBuffer; - - /** Computed from ColorDraw/ReadBuffer above */ - GLuint _NumColorDrawBuffers; - GLint _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS]; /**< BUFFER_x or -1 */ - GLint _ColorReadBufferIndex; /* -1 = None */ - struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS]; - struct gl_renderbuffer *_ColorReadBuffer; - - /** The Actual depth/stencil buffers to use. May be wrappers around the - * depth/stencil buffers attached above. */ - struct gl_renderbuffer *_DepthBuffer; - struct gl_renderbuffer *_StencilBuffer; - - /** Delete this framebuffer */ - void (*Delete)(struct gl_framebuffer *fb); -}; - - -/** - * Precision info for shader datatypes. See glGetShaderPrecisionFormat(). - */ -struct gl_precision -{ - GLushort RangeMin; /**< min value exponent */ - GLushort RangeMax; /**< max value exponent */ - GLushort Precision; /**< number of mantissa bits */ -}; - - -/** - * Limits for vertex and fragment programs/shaders. - */ -struct gl_program_constants -{ - /* logical limits */ - GLuint MaxInstructions; - GLuint MaxAluInstructions; - GLuint MaxTexInstructions; - GLuint MaxTexIndirections; - GLuint MaxAttribs; - GLuint MaxTemps; - GLuint MaxAddressRegs; - GLuint MaxParameters; - GLuint MaxLocalParams; - GLuint MaxEnvParams; - /* native/hardware limits */ - GLuint MaxNativeInstructions; - GLuint MaxNativeAluInstructions; - GLuint MaxNativeTexInstructions; - GLuint MaxNativeTexIndirections; - GLuint MaxNativeAttribs; - GLuint MaxNativeTemps; - GLuint MaxNativeAddressRegs; - GLuint MaxNativeParameters; - /* For shaders */ - GLuint MaxUniformComponents; - /* GL_ARB_geometry_shader4 */ - GLuint MaxGeometryTextureImageUnits; - GLuint MaxGeometryVaryingComponents; - GLuint MaxVertexVaryingComponents; - GLuint MaxGeometryUniformComponents; - GLuint MaxGeometryOutputVertices; - GLuint MaxGeometryTotalOutputComponents; - /* ES 2.0 and GL_ARB_ES2_compatibility */ - struct gl_precision LowFloat, MediumFloat, HighFloat; - struct gl_precision LowInt, MediumInt, HighInt; -}; - - -/** - * Constants which may be overridden by device driver during context creation - * but are never changed after that. - */ -struct gl_constants -{ - GLint MaxTextureMbytes; /**< Max memory per image, in MB */ - GLint MaxTextureLevels; /**< Max mipmap levels. */ - GLint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */ - GLint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */ - GLint MaxArrayTextureLayers; /**< Max layers in array textures */ - GLint MaxTextureRectSize; /**< Max rectangle texture size, in pixes */ - GLuint MaxTextureCoordUnits; - GLuint MaxTextureImageUnits; - GLuint MaxVertexTextureImageUnits; - GLuint MaxCombinedTextureImageUnits; - GLuint MaxTextureUnits; /**< = MIN(CoordUnits, ImageUnits) */ - GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ - GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */ - - GLuint MaxArrayLockSize; - - GLint SubPixelBits; - - GLfloat MinPointSize, MaxPointSize; /**< aliased */ - GLfloat MinPointSizeAA, MaxPointSizeAA; /**< antialiased */ - GLfloat PointSizeGranularity; - GLfloat MinLineWidth, MaxLineWidth; /**< aliased */ - GLfloat MinLineWidthAA, MaxLineWidthAA; /**< antialiased */ - GLfloat LineWidthGranularity; - - GLuint MaxColorTableSize; - - GLuint MaxClipPlanes; - GLuint MaxLights; - GLfloat MaxShininess; /**< GL_NV_light_max_exponent */ - GLfloat MaxSpotExponent; /**< GL_NV_light_max_exponent */ - - GLuint MaxViewportWidth, MaxViewportHeight; - - struct gl_program_constants VertexProgram; /**< GL_ARB_vertex_program */ - struct gl_program_constants FragmentProgram; /**< GL_ARB_fragment_program */ - struct gl_program_constants GeometryProgram; /**< GL_ARB_geometry_shader4 */ - GLuint MaxProgramMatrices; - GLuint MaxProgramMatrixStackDepth; - - /** vertex array / buffer object bounds checking */ - GLboolean CheckArrayBounds; - - GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */ - - GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */ - GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */ - GLuint MaxSamples; /**< GL_ARB_framebuffer_object */ - - GLuint MaxVarying; /**< Number of float[4] varying parameters */ - - GLuint GLSLVersion; /**< GLSL version supported (ex: 120 = 1.20) */ - - /** Which texture units support GL_ATI_envmap_bumpmap as targets */ - GLbitfield SupportedBumpUnits; - - /** - * Maximum amount of time, measured in nanseconds, that the server can wait. - */ - GLuint64 MaxServerWaitTimeout; - - /** GL_EXT_provoking_vertex */ - GLboolean QuadsFollowProvokingVertexConvention; - - /** OpenGL version 3.0 */ - GLbitfield ContextFlags; /**< Ex: GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT */ - - /** OpenGL version 3.2 */ - GLbitfield ProfileMask; /**< Mask of CONTEXT_x_PROFILE_BIT */ - - /** GL_EXT_transform_feedback */ - GLuint MaxTransformFeedbackSeparateAttribs; - GLuint MaxTransformFeedbackSeparateComponents; - GLuint MaxTransformFeedbackInterleavedComponents; - - /** GL_EXT_gpu_shader4 */ - GLint MinProgramTexelOffset, MaxProgramTexelOffset; - - /* GL_EXT_framebuffer_sRGB */ - GLboolean sRGBCapable; /* can enable sRGB blend/update on FBOs */ -}; - - -/** - * Enable flag for each OpenGL extension. Different device drivers will - * enable different extensions at runtime. - */ -struct gl_extensions -{ - GLboolean dummy; /* don't remove this! */ - GLboolean dummy_true; /* Set true by _mesa_init_extensions(). */ - GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */ - GLboolean ARB_ES2_compatibility; - GLboolean ARB_blend_func_extended; - GLboolean ARB_copy_buffer; - GLboolean ARB_depth_buffer_float; - GLboolean ARB_depth_clamp; - GLboolean ARB_depth_texture; - GLboolean ARB_draw_buffers; - GLboolean ARB_draw_buffers_blend; - GLboolean ARB_draw_elements_base_vertex; - GLboolean ARB_draw_instanced; - GLboolean ARB_fragment_coord_conventions; - GLboolean ARB_fragment_program; - GLboolean ARB_fragment_program_shadow; - GLboolean ARB_fragment_shader; - GLboolean ARB_framebuffer_object; - GLboolean ARB_explicit_attrib_location; - GLboolean ARB_geometry_shader4; - GLboolean ARB_half_float_pixel; - GLboolean ARB_half_float_vertex; - GLboolean ARB_instanced_arrays; - GLboolean ARB_map_buffer_range; - GLboolean ARB_multisample; - GLboolean ARB_multitexture; - GLboolean ARB_occlusion_query; - GLboolean ARB_occlusion_query2; - GLboolean ARB_point_sprite; - GLboolean ARB_sampler_objects; - GLboolean ARB_seamless_cube_map; - GLboolean ARB_shader_objects; - GLboolean ARB_shader_stencil_export; - GLboolean ARB_shading_language_100; - GLboolean ARB_shadow; - GLboolean ARB_shadow_ambient; - GLboolean ARB_sync; - GLboolean ARB_texture_border_clamp; - GLboolean ARB_texture_buffer_object; - GLboolean ARB_texture_compression; - GLboolean ARB_texture_compression_rgtc; - GLboolean ARB_texture_cube_map; - GLboolean ARB_texture_env_combine; - GLboolean ARB_texture_env_crossbar; - GLboolean ARB_texture_env_dot3; - GLboolean ARB_texture_float; - GLboolean ARB_texture_mirrored_repeat; - GLboolean ARB_texture_multisample; - GLboolean ARB_texture_non_power_of_two; - GLboolean ARB_texture_rg; - GLboolean ARB_texture_rgb10_a2ui; - GLboolean ARB_timer_query; - GLboolean ARB_transform_feedback2; - GLboolean ARB_transpose_matrix; - GLboolean ARB_uniform_buffer_object; - GLboolean ARB_vertex_array_object; - GLboolean ARB_vertex_buffer_object; - GLboolean ARB_vertex_program; - GLboolean ARB_vertex_shader; - GLboolean ARB_vertex_type_2_10_10_10_rev; - GLboolean ARB_window_pos; - GLboolean EXT_abgr; - GLboolean EXT_bgra; - GLboolean EXT_blend_color; - GLboolean EXT_blend_equation_separate; - GLboolean EXT_blend_func_separate; - GLboolean EXT_blend_logic_op; - GLboolean EXT_blend_minmax; - GLboolean EXT_blend_subtract; - GLboolean EXT_clip_volume_hint; - GLboolean EXT_compiled_vertex_array; - GLboolean EXT_copy_texture; - GLboolean EXT_depth_bounds_test; - GLboolean EXT_draw_buffers2; - GLboolean EXT_draw_range_elements; - GLboolean EXT_fog_coord; - GLboolean EXT_framebuffer_blit; - GLboolean EXT_framebuffer_multisample; - GLboolean EXT_framebuffer_object; - GLboolean EXT_framebuffer_sRGB; - GLboolean EXT_gpu_program_parameters; - GLboolean EXT_gpu_shader4; - GLboolean EXT_multi_draw_arrays; - GLboolean EXT_paletted_texture; - GLboolean EXT_packed_depth_stencil; - GLboolean EXT_packed_float; - GLboolean EXT_packed_pixels; - GLboolean EXT_pixel_buffer_object; - GLboolean EXT_point_parameters; - GLboolean EXT_polygon_offset; - GLboolean EXT_provoking_vertex; - GLboolean EXT_rescale_normal; - GLboolean EXT_shadow_funcs; - GLboolean EXT_secondary_color; - GLboolean EXT_separate_shader_objects; - GLboolean EXT_separate_specular_color; - GLboolean EXT_shared_texture_palette; - GLboolean EXT_stencil_wrap; - GLboolean EXT_stencil_two_side; - GLboolean EXT_subtexture; - GLboolean EXT_texture; - GLboolean EXT_texture_object; - GLboolean EXT_texture3D; - GLboolean EXT_texture_array; - GLboolean EXT_texture_compression_s3tc; - GLboolean EXT_texture_env_add; - GLboolean EXT_texture_env_combine; - GLboolean EXT_texture_env_dot3; - GLboolean EXT_texture_filter_anisotropic; - GLboolean EXT_texture_integer; - GLboolean EXT_texture_lod_bias; - GLboolean EXT_texture_mirror_clamp; - GLboolean EXT_texture_shared_exponent; - GLboolean EXT_texture_sRGB; - GLboolean EXT_texture_sRGB_decode; - GLboolean EXT_texture_swizzle; - GLboolean EXT_transform_feedback; - GLboolean EXT_timer_query; - GLboolean EXT_vertex_array; - GLboolean EXT_vertex_array_bgra; - GLboolean EXT_vertex_array_set; - GLboolean OES_standard_derivatives; - /* vendor extensions */ - GLboolean AMD_conservative_depth; - GLboolean APPLE_client_storage; - GLboolean APPLE_packed_pixels; - GLboolean APPLE_vertex_array_object; - GLboolean APPLE_object_purgeable; - GLboolean ATI_envmap_bumpmap; - GLboolean ATI_texture_mirror_once; - GLboolean ATI_texture_env_combine3; - GLboolean ATI_fragment_shader; - GLboolean ATI_separate_stencil; - GLboolean IBM_rasterpos_clip; - GLboolean IBM_multimode_draw_arrays; - GLboolean MESA_pack_invert; - GLboolean MESA_resize_buffers; - GLboolean MESA_ycbcr_texture; - GLboolean MESA_texture_array; - GLboolean MESA_texture_signed_rgba; - GLboolean NV_blend_square; - GLboolean NV_conditional_render; - GLboolean NV_fragment_program; - GLboolean NV_fragment_program_option; - GLboolean NV_light_max_exponent; - GLboolean NV_point_sprite; - GLboolean NV_primitive_restart; - GLboolean NV_texgen_reflection; - GLboolean NV_texture_env_combine4; - GLboolean NV_texture_rectangle; - GLboolean NV_vertex_program; - GLboolean NV_vertex_program1_1; - GLboolean OES_read_format; - GLboolean SGI_texture_color_table; - GLboolean SGIS_generate_mipmap; - GLboolean SGIS_texture_edge_clamp; - GLboolean SGIS_texture_lod; - GLboolean TDFX_texture_compression_FXT1; - GLboolean S3_s3tc; - GLboolean OES_EGL_image; - GLboolean OES_draw_texture; - GLboolean EXT_texture_format_BGRA8888; - GLboolean extension_sentinel; - /** The extension string */ - const GLubyte *String; - /** Number of supported extensions */ - GLuint Count; -}; - - -/** - * A stack of matrices (projection, modelview, color, texture, etc). - */ -struct gl_matrix_stack -{ - GLmatrix *Top; /**< points into Stack */ - GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */ - GLuint Depth; /**< 0 <= Depth < MaxDepth */ - GLuint MaxDepth; /**< size of Stack[] array */ - GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */ -}; - - -/** - * \name Bits for image transfer operations - * \sa __struct gl_contextRec::ImageTransferState. - */ -/*@{*/ -#define IMAGE_SCALE_BIAS_BIT 0x1 -#define IMAGE_SHIFT_OFFSET_BIT 0x2 -#define IMAGE_MAP_COLOR_BIT 0x4 -#define IMAGE_CLAMP_BIT 0x800 - - -/** Pixel Transfer ops */ -#define IMAGE_BITS (IMAGE_SCALE_BIAS_BIT | \ - IMAGE_SHIFT_OFFSET_BIT | \ - IMAGE_MAP_COLOR_BIT) - -/** - * \name Bits to indicate what state has changed. - */ -/*@{*/ -#define _NEW_MODELVIEW (1 << 0) /**< gl_context::ModelView */ -#define _NEW_PROJECTION (1 << 1) /**< gl_context::Projection */ -#define _NEW_TEXTURE_MATRIX (1 << 2) /**< gl_context::TextureMatrix */ -#define _NEW_COLOR (1 << 3) /**< gl_context::Color */ -#define _NEW_DEPTH (1 << 4) /**< gl_context::Depth */ -#define _NEW_EVAL (1 << 5) /**< gl_context::Eval, EvalMap */ -#define _NEW_FOG (1 << 6) /**< gl_context::Fog */ -#define _NEW_HINT (1 << 7) /**< gl_context::Hint */ -#define _NEW_LIGHT (1 << 8) /**< gl_context::Light */ -#define _NEW_LINE (1 << 9) /**< gl_context::Line */ -#define _NEW_PIXEL (1 << 10) /**< gl_context::Pixel */ -#define _NEW_POINT (1 << 11) /**< gl_context::Point */ -#define _NEW_POLYGON (1 << 12) /**< gl_context::Polygon */ -#define _NEW_POLYGONSTIPPLE (1 << 13) /**< gl_context::PolygonStipple */ -#define _NEW_SCISSOR (1 << 14) /**< gl_context::Scissor */ -#define _NEW_STENCIL (1 << 15) /**< gl_context::Stencil */ -#define _NEW_TEXTURE (1 << 16) /**< gl_context::Texture */ -#define _NEW_TRANSFORM (1 << 17) /**< gl_context::Transform */ -#define _NEW_VIEWPORT (1 << 18) /**< gl_context::Viewport */ -#define _NEW_PACKUNPACK (1 << 19) /**< gl_context::Pack, Unpack */ -#define _NEW_ARRAY (1 << 20) /**< gl_context::Array */ -#define _NEW_RENDERMODE (1 << 21) /**< gl_context::RenderMode, etc */ -#define _NEW_BUFFERS (1 << 22) /**< gl_context::Visual, DrawBuffer, */ -#define _NEW_CURRENT_ATTRIB (1 << 23) /**< gl_context::Current */ -#define _NEW_MULTISAMPLE (1 << 24) /**< gl_context::Multisample */ -#define _NEW_TRACK_MATRIX (1 << 25) /**< gl_context::VertexProgram */ -#define _NEW_PROGRAM (1 << 26) /**< New program/shader state */ -#define _NEW_PROGRAM_CONSTANTS (1 << 27) -#define _NEW_BUFFER_OBJECT (1 << 28) -#define _NEW_ALL ~0 -/*@}*/ - - -/** - * \name Bits to track array state changes - * - * Also used to summarize array enabled. - */ -/*@{*/ -#define _NEW_ARRAY_VERTEX VERT_BIT_POS -#define _NEW_ARRAY_WEIGHT VERT_BIT_WEIGHT -#define _NEW_ARRAY_NORMAL VERT_BIT_NORMAL -#define _NEW_ARRAY_COLOR0 VERT_BIT_COLOR0 -#define _NEW_ARRAY_COLOR1 VERT_BIT_COLOR1 -#define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG -#define _NEW_ARRAY_INDEX VERT_BIT_COLOR_INDEX -#define _NEW_ARRAY_EDGEFLAG VERT_BIT_EDGEFLAG -#define _NEW_ARRAY_POINT_SIZE VERT_BIT_COLOR_INDEX /* aliased */ -#define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0 -#define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1 -#define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2 -#define _NEW_ARRAY_TEXCOORD_3 VERT_BIT_TEX3 -#define _NEW_ARRAY_TEXCOORD_4 VERT_BIT_TEX4 -#define _NEW_ARRAY_TEXCOORD_5 VERT_BIT_TEX5 -#define _NEW_ARRAY_TEXCOORD_6 VERT_BIT_TEX6 -#define _NEW_ARRAY_TEXCOORD_7 VERT_BIT_TEX7 -#define _NEW_ARRAY_ATTRIB_0 VERT_BIT_GENERIC0 /* start at bit 16 */ -#define _NEW_ARRAY_ALL 0xffffffff - - -#define _NEW_ARRAY_TEXCOORD(i) (_NEW_ARRAY_TEXCOORD_0 << (i)) -#define _NEW_ARRAY_ATTRIB(i) (_NEW_ARRAY_ATTRIB_0 << (i)) -/*@}*/ - - - -/** - * \name A bunch of flags that we think might be useful to drivers. - * - * Set in the __struct gl_contextRec::_TriangleCaps bitfield. - */ -/*@{*/ -#define DD_FLATSHADE 0x1 -#define DD_SEPARATE_SPECULAR 0x2 -#define DD_TRI_CULL_FRONT_BACK 0x4 /* special case on some hw */ -#define DD_TRI_LIGHT_TWOSIDE 0x8 -#define DD_TRI_UNFILLED 0x10 -#define DD_TRI_SMOOTH 0x20 -#define DD_TRI_STIPPLE 0x40 -#define DD_TRI_OFFSET 0x80 -#define DD_LINE_SMOOTH 0x100 -#define DD_LINE_STIPPLE 0x200 -#define DD_POINT_SMOOTH 0x400 -#define DD_POINT_ATTEN 0x800 -#define DD_TRI_TWOSTENCIL 0x1000 -/*@}*/ - - -/** - * \name Define the state changes under which each of these bits might change - */ -/*@{*/ -#define _DD_NEW_FLATSHADE _NEW_LIGHT -#define _DD_NEW_SEPARATE_SPECULAR (_NEW_LIGHT | _NEW_FOG | _NEW_PROGRAM) -#define _DD_NEW_TRI_CULL_FRONT_BACK _NEW_POLYGON -#define _DD_NEW_TRI_LIGHT_TWOSIDE _NEW_LIGHT -#define _DD_NEW_TRI_UNFILLED _NEW_POLYGON -#define _DD_NEW_TRI_SMOOTH _NEW_POLYGON -#define _DD_NEW_TRI_STIPPLE _NEW_POLYGON -#define _DD_NEW_TRI_OFFSET _NEW_POLYGON -#define _DD_NEW_LINE_SMOOTH _NEW_LINE -#define _DD_NEW_LINE_STIPPLE _NEW_LINE -#define _DD_NEW_LINE_WIDTH _NEW_LINE -#define _DD_NEW_POINT_SMOOTH _NEW_POINT -#define _DD_NEW_POINT_SIZE _NEW_POINT -#define _DD_NEW_POINT_ATTEN _NEW_POINT -/*@}*/ - - -/** - * Composite state flags - */ -/*@{*/ -#define _MESA_NEW_NEED_EYE_COORDS (_NEW_LIGHT | \ - _NEW_TEXTURE | \ - _NEW_POINT | \ - _NEW_PROGRAM | \ - _NEW_MODELVIEW) - -#define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \ - _NEW_TEXTURE) - -#define _MESA_NEW_TRANSFER_STATE (_NEW_PIXEL) -/*@}*/ - - - - -/* This has to be included here. */ -#include "dd.h" - - -/** - * Display list flags. - * Strictly this is a tnl-private concept, but it doesn't seem - * worthwhile adding a tnl private structure just to hold this one bit - * of information: - */ -#define DLIST_DANGLING_REFS 0x1 - - -/** Opaque declaration of display list payload data type */ -union gl_dlist_node; - - -/** - * Provide a location where information about a display list can be - * collected. Could be extended with driverPrivate structures, - * etc. in the future. - */ -struct gl_display_list -{ - GLuint Name; - GLbitfield Flags; /**< DLIST_x flags */ - /** The dlist commands are in a linked list of nodes */ - union gl_dlist_node *Head; -}; - - -/** - * State used during display list compilation and execution. - */ -struct gl_dlist_state -{ - GLuint CallDepth; /**< Current recursion calling depth */ - - struct gl_display_list *CurrentList; /**< List currently being compiled */ - union gl_dlist_node *CurrentBlock; /**< Pointer to current block of nodes */ - GLuint CurrentPos; /**< Index into current block of nodes */ - - GLvertexformat ListVtxfmt; - - GLubyte ActiveAttribSize[VERT_ATTRIB_MAX]; - GLfloat CurrentAttrib[VERT_ATTRIB_MAX][4]; - - GLubyte ActiveMaterialSize[MAT_ATTRIB_MAX]; - GLfloat CurrentMaterial[MAT_ATTRIB_MAX][4]; - - GLubyte ActiveIndex; - GLfloat CurrentIndex; - - GLubyte ActiveEdgeFlag; - GLboolean CurrentEdgeFlag; - - struct { - /* State known to have been set by the currently-compiling display - * list. Used to eliminate some redundant state changes. - */ - GLenum ShadeModel; - } Current; -}; - - -/** - * Enum for the OpenGL APIs we know about and may support. - */ -typedef enum -{ - API_OPENGL, - API_OPENGLES, - API_OPENGLES2 -} gl_api; - - -/** - * Mesa rendering context. - * - * This is the central context data structure for Mesa. Almost all - * OpenGL state is contained in this structure. - * Think of this as a base class from which device drivers will derive - * sub classes. - * - * The struct gl_context typedef names this structure. - */ -struct gl_context -{ - /** State possibly shared with other contexts in the address space */ - struct gl_shared_state *Shared; - - /** \name API function pointer tables */ - /*@{*/ - gl_api API; - struct _glapi_table *Save; /**< Display list save functions */ - struct _glapi_table *Exec; /**< Execute functions */ - struct _glapi_table *CurrentDispatch; /**< == Save or Exec !! */ - /*@}*/ - - struct gl_config Visual; - struct gl_framebuffer *DrawBuffer; /**< buffer for writing */ - struct gl_framebuffer *ReadBuffer; /**< buffer for reading */ - struct gl_framebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */ - struct gl_framebuffer *WinSysReadBuffer; /**< set with MakeCurrent */ - - /** - * Device driver function pointer table - */ - struct dd_function_table Driver; - - void *DriverCtx; /**< Points to device driver context/state */ - - /** Core/Driver constants */ - struct gl_constants Const; - - /** \name The various 4x4 matrix stacks */ - /*@{*/ - struct gl_matrix_stack ModelviewMatrixStack; - struct gl_matrix_stack ProjectionMatrixStack; - struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS]; - struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES]; - struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */ - /*@}*/ - - /** Combined modelview and projection matrix */ - GLmatrix _ModelProjectMatrix; - - /** \name Display lists */ - struct gl_dlist_state ListState; - - GLboolean ExecuteFlag; /**< Execute GL commands? */ - GLboolean CompileFlag; /**< Compile GL commands into display list? */ - - /** Extension information */ - struct gl_extensions Extensions; - - /** Version info */ - GLuint VersionMajor, VersionMinor; - char *VersionString; - - /** \name State attribute stack (for glPush/PopAttrib) */ - /*@{*/ - GLuint AttribStackDepth; - struct gl_attrib_node *AttribStack[MAX_ATTRIB_STACK_DEPTH]; - /*@}*/ - - /** \name Renderer attribute groups - * - * We define a struct for each attribute group to make pushing and popping - * attributes easy. Also it's a good organization. - */ - /*@{*/ - struct gl_accum_attrib Accum; /**< Accum buffer attributes */ - struct gl_colorbuffer_attrib Color; /**< Color buffer attributes */ - struct gl_current_attrib Current; /**< Current attributes */ - struct gl_depthbuffer_attrib Depth; /**< Depth buffer attributes */ - struct gl_eval_attrib Eval; /**< Eval attributes */ - struct gl_fog_attrib Fog; /**< Fog attributes */ - struct gl_hint_attrib Hint; /**< Hint attributes */ - struct gl_light_attrib Light; /**< Light attributes */ - struct gl_line_attrib Line; /**< Line attributes */ - struct gl_list_attrib List; /**< List attributes */ - struct gl_multisample_attrib Multisample; - struct gl_pixel_attrib Pixel; /**< Pixel attributes */ - struct gl_point_attrib Point; /**< Point attributes */ - struct gl_polygon_attrib Polygon; /**< Polygon attributes */ - GLuint PolygonStipple[32]; /**< Polygon stipple */ - struct gl_scissor_attrib Scissor; /**< Scissor attributes */ - struct gl_stencil_attrib Stencil; /**< Stencil buffer attributes */ - struct gl_texture_attrib Texture; /**< Texture attributes */ - struct gl_transform_attrib Transform; /**< Transformation attributes */ - struct gl_viewport_attrib Viewport; /**< Viewport attributes */ - /*@}*/ - - /** \name Client attribute stack */ - /*@{*/ - GLuint ClientAttribStackDepth; - struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH]; - /*@}*/ - - /** \name Client attribute groups */ - /*@{*/ - struct gl_array_attrib Array; /**< Vertex arrays */ - struct gl_pixelstore_attrib Pack; /**< Pixel packing */ - struct gl_pixelstore_attrib Unpack; /**< Pixel unpacking */ - struct gl_pixelstore_attrib DefaultPacking; /**< Default params */ - /*@}*/ - - /** \name Other assorted state (not pushed/popped on attribute stack) */ - /*@{*/ - struct gl_pixelmaps PixelMaps; - - struct gl_evaluators EvalMap; /**< All evaluators */ - struct gl_feedback Feedback; /**< Feedback */ - struct gl_selection Select; /**< Selection */ - - struct gl_program_state Program; /**< general program state */ - struct gl_vertex_program_state VertexProgram; - struct gl_fragment_program_state FragmentProgram; - struct gl_geometry_program_state GeometryProgram; - struct gl_ati_fragment_shader_state ATIFragmentShader; - - struct gl_shader_state Shader; /**< GLSL shader object state */ - struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_TYPES]; - - struct gl_query_state Query; /**< occlusion, timer queries */ - - struct gl_transform_feedback TransformFeedback; - - struct gl_buffer_object *CopyReadBuffer; /**< GL_ARB_copy_buffer */ - struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */ - /*@}*/ - - struct gl_meta_state *Meta; /**< for "meta" operations */ - - /* GL_EXT_framebuffer_object */ - struct gl_renderbuffer *CurrentRenderbuffer; - - GLenum ErrorValue; /**< Last error code */ - - /** - * Recognize and silence repeated error debug messages in buggy apps. - */ - const char *ErrorDebugFmtString; - GLuint ErrorDebugCount; - - GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ - GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ - - GLboolean ViewportInitialized; /**< has viewport size been initialized? */ - - GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */ - - /** \name Derived state */ - /*@{*/ - /** Bitwise-or of DD_* flags. Note that this bitfield may be used before - * state validation so they need to always be current. - */ - GLbitfield _TriangleCaps; - GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */ - GLfloat _EyeZDir[3]; - GLfloat _ModelViewInvScale; - GLboolean _NeedEyeCoords; - GLboolean _ForceEyeCoords; - - GLuint TextureStateTimestamp; /**< detect changes to shared state */ - - struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */ - struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ - /**@}*/ - - struct gl_list_extensions *ListExt; /**< driver dlist extensions */ - - /** \name For debugging/development only */ - /*@{*/ - GLboolean FirstTimeCurrent; - /*@}*/ - - /** Dither disable via MESA_NO_DITHER env var */ - GLboolean NoDither; - - /** software compression/decompression supported or not */ - GLboolean Mesa_DXTn; - - GLboolean TextureFormatSupported[MESA_FORMAT_COUNT]; - - /** - * Use dp4 (rather than mul/mad) instructions for position - * transformation? - */ - GLboolean mvp_with_dp4; - - /** - * \name Hooks for module contexts. - * - * These will eventually live in the driver or elsewhere. - */ - /*@{*/ - void *swrast_context; - void *swsetup_context; - void *swtnl_context; - void *swtnl_im; - struct st_context *st; - void *aelt_context; - /*@}*/ -}; - - -#ifdef DEBUG -extern int MESA_VERBOSE; -extern int MESA_DEBUG_FLAGS; -# define MESA_FUNCTION __FUNCTION__ -#else -# define MESA_VERBOSE 0 -# define MESA_DEBUG_FLAGS 0 -# define MESA_FUNCTION "a function" -# ifndef NDEBUG -# define NDEBUG -# endif -#endif - - -/** The MESA_VERBOSE var is a bitmask of these flags */ -enum _verbose -{ - VERBOSE_VARRAY = 0x0001, - VERBOSE_TEXTURE = 0x0002, - VERBOSE_MATERIAL = 0x0004, - VERBOSE_PIPELINE = 0x0008, - VERBOSE_DRIVER = 0x0010, - VERBOSE_STATE = 0x0020, - VERBOSE_API = 0x0040, - VERBOSE_DISPLAY_LIST = 0x0100, - VERBOSE_LIGHTING = 0x0200, - VERBOSE_PRIMS = 0x0400, - VERBOSE_VERTS = 0x0800, - VERBOSE_DISASSEM = 0x1000, - VERBOSE_DRAW = 0x2000, - VERBOSE_SWAPBUFFERS = 0x4000 -}; - - -/** The MESA_DEBUG_FLAGS var is a bitmask of these flags */ -enum _debug -{ - DEBUG_ALWAYS_FLUSH = 0x1 -}; - - - -#endif /* MTYPES_H */ +/* + * Mesa 3-D graphics library + * Version: 7.7 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file mtypes.h + * Main Mesa data structures. + * + * Please try to mark derived values with a leading underscore ('_'). + */ + +#ifndef MTYPES_H +#define MTYPES_H + + +#include "main/glheader.h" +#include "main/config.h" +#include "main/mfeatures.h" +#include "glapi/glapi.h" +#include "math/m_matrix.h" /* GLmatrix */ +#include "main/simple_list.h" /* struct simple_node */ +#include "main/formats.h" /* MESA_FORMAT_COUNT */ + + +/** + * Color channel data type. + */ +#if CHAN_BITS == 8 + typedef GLubyte GLchan; +#define CHAN_MAX 255 +#define CHAN_MAXF 255.0F +#define CHAN_TYPE GL_UNSIGNED_BYTE +#elif CHAN_BITS == 16 + typedef GLushort GLchan; +#define CHAN_MAX 65535 +#define CHAN_MAXF 65535.0F +#define CHAN_TYPE GL_UNSIGNED_SHORT +#elif CHAN_BITS == 32 + typedef GLfloat GLchan; +#define CHAN_MAX 1.0 +#define CHAN_MAXF 1.0F +#define CHAN_TYPE GL_FLOAT +#else +#error "illegal number of color channel bits" +#endif + + +/** + * Stencil buffer data type. + */ +#if STENCIL_BITS==8 + typedef GLubyte GLstencil; +#elif STENCIL_BITS==16 + typedef GLushort GLstencil; +#else +# error "illegal number of stencil bits" +#endif + + +/** + * \name 64-bit extension of GLbitfield. + */ +/*@{*/ +typedef GLuint64 GLbitfield64; + +/** Set a single bit */ +#define BITFIELD64_BIT(b) (1ULL << (b)) + + +/** + * \name Some forward type declarations + */ +/*@{*/ +struct _mesa_HashTable; +struct gl_attrib_node; +struct gl_list_extensions; +struct gl_meta_state; +struct gl_pixelstore_attrib; +struct gl_program_cache; +struct gl_texture_format; +struct gl_texture_image; +struct gl_texture_object; +struct gl_context; +struct st_context; +/*@}*/ + + +/** Extra draw modes beyond GL_POINTS, GL_TRIANGLE_FAN, etc */ +#define PRIM_OUTSIDE_BEGIN_END (GL_POLYGON+1) +#define PRIM_INSIDE_UNKNOWN_PRIM (GL_POLYGON+2) +#define PRIM_UNKNOWN (GL_POLYGON+3) + + +/** + * Shader stages. Note that these will become 5 with tessellation. + * These MUST have the same values as gallium's PIPE_SHADER_* + */ +typedef enum +{ + MESA_SHADER_VERTEX = 0, + MESA_SHADER_FRAGMENT = 1, + MESA_SHADER_GEOMETRY = 2, + MESA_SHADER_TYPES = 3 +} gl_shader_type; + + + +/** + * Indexes for vertex program attributes. + * GL_NV_vertex_program aliases generic attributes over the conventional + * attributes. In GL_ARB_vertex_program shader the aliasing is optional. + * In GL_ARB_vertex_shader / OpenGL 2.0 the aliasing is disallowed (the + * generic attributes are distinct/separate). + */ +typedef enum +{ + VERT_ATTRIB_POS = 0, + VERT_ATTRIB_WEIGHT = 1, + VERT_ATTRIB_NORMAL = 2, + VERT_ATTRIB_COLOR0 = 3, + VERT_ATTRIB_COLOR1 = 4, + VERT_ATTRIB_FOG = 5, + VERT_ATTRIB_COLOR_INDEX = 6, + VERT_ATTRIB_POINT_SIZE = 6, /*alias*/ + VERT_ATTRIB_EDGEFLAG = 7, + VERT_ATTRIB_TEX0 = 8, + VERT_ATTRIB_TEX1 = 9, + VERT_ATTRIB_TEX2 = 10, + VERT_ATTRIB_TEX3 = 11, + VERT_ATTRIB_TEX4 = 12, + VERT_ATTRIB_TEX5 = 13, + VERT_ATTRIB_TEX6 = 14, + VERT_ATTRIB_TEX7 = 15, + VERT_ATTRIB_GENERIC0 = 16, + VERT_ATTRIB_GENERIC1 = 17, + VERT_ATTRIB_GENERIC2 = 18, + VERT_ATTRIB_GENERIC3 = 19, + VERT_ATTRIB_GENERIC4 = 20, + VERT_ATTRIB_GENERIC5 = 21, + VERT_ATTRIB_GENERIC6 = 22, + VERT_ATTRIB_GENERIC7 = 23, + VERT_ATTRIB_GENERIC8 = 24, + VERT_ATTRIB_GENERIC9 = 25, + VERT_ATTRIB_GENERIC10 = 26, + VERT_ATTRIB_GENERIC11 = 27, + VERT_ATTRIB_GENERIC12 = 28, + VERT_ATTRIB_GENERIC13 = 29, + VERT_ATTRIB_GENERIC14 = 30, + VERT_ATTRIB_GENERIC15 = 31, + VERT_ATTRIB_MAX = 32 +} gl_vert_attrib; + +/** + * Bitflags for vertex attributes. + * These are used in bitfields in many places. + */ +/*@{*/ +#define VERT_BIT_POS (1 << VERT_ATTRIB_POS) +#define VERT_BIT_WEIGHT (1 << VERT_ATTRIB_WEIGHT) +#define VERT_BIT_NORMAL (1 << VERT_ATTRIB_NORMAL) +#define VERT_BIT_COLOR0 (1 << VERT_ATTRIB_COLOR0) +#define VERT_BIT_COLOR1 (1 << VERT_ATTRIB_COLOR1) +#define VERT_BIT_FOG (1 << VERT_ATTRIB_FOG) +#define VERT_BIT_COLOR_INDEX (1 << VERT_ATTRIB_COLOR_INDEX) +#define VERT_BIT_EDGEFLAG (1 << VERT_ATTRIB_EDGEFLAG) +#define VERT_BIT_TEX0 (1 << VERT_ATTRIB_TEX0) +#define VERT_BIT_TEX1 (1 << VERT_ATTRIB_TEX1) +#define VERT_BIT_TEX2 (1 << VERT_ATTRIB_TEX2) +#define VERT_BIT_TEX3 (1 << VERT_ATTRIB_TEX3) +#define VERT_BIT_TEX4 (1 << VERT_ATTRIB_TEX4) +#define VERT_BIT_TEX5 (1 << VERT_ATTRIB_TEX5) +#define VERT_BIT_TEX6 (1 << VERT_ATTRIB_TEX6) +#define VERT_BIT_TEX7 (1 << VERT_ATTRIB_TEX7) +#define VERT_BIT_GENERIC0 (1 << VERT_ATTRIB_GENERIC0) +#define VERT_BIT_GENERIC1 (1 << VERT_ATTRIB_GENERIC1) +#define VERT_BIT_GENERIC2 (1 << VERT_ATTRIB_GENERIC2) +#define VERT_BIT_GENERIC3 (1 << VERT_ATTRIB_GENERIC3) +#define VERT_BIT_GENERIC4 (1 << VERT_ATTRIB_GENERIC4) +#define VERT_BIT_GENERIC5 (1 << VERT_ATTRIB_GENERIC5) +#define VERT_BIT_GENERIC6 (1 << VERT_ATTRIB_GENERIC6) +#define VERT_BIT_GENERIC7 (1 << VERT_ATTRIB_GENERIC7) +#define VERT_BIT_GENERIC8 (1 << VERT_ATTRIB_GENERIC8) +#define VERT_BIT_GENERIC9 (1 << VERT_ATTRIB_GENERIC9) +#define VERT_BIT_GENERIC10 (1 << VERT_ATTRIB_GENERIC10) +#define VERT_BIT_GENERIC11 (1 << VERT_ATTRIB_GENERIC11) +#define VERT_BIT_GENERIC12 (1 << VERT_ATTRIB_GENERIC12) +#define VERT_BIT_GENERIC13 (1 << VERT_ATTRIB_GENERIC13) +#define VERT_BIT_GENERIC14 (1 << VERT_ATTRIB_GENERIC14) +#define VERT_BIT_GENERIC15 (1 << VERT_ATTRIB_GENERIC15) + +#define VERT_BIT_TEX(u) (1 << (VERT_ATTRIB_TEX0 + (u))) +#define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g))) +/*@}*/ + + +/** + * Indexes for vertex program result attributes + */ +typedef enum +{ + VERT_RESULT_HPOS = 0, + VERT_RESULT_COL0 = 1, + VERT_RESULT_COL1 = 2, + VERT_RESULT_FOGC = 3, + VERT_RESULT_TEX0 = 4, + VERT_RESULT_TEX1 = 5, + VERT_RESULT_TEX2 = 6, + VERT_RESULT_TEX3 = 7, + VERT_RESULT_TEX4 = 8, + VERT_RESULT_TEX5 = 9, + VERT_RESULT_TEX6 = 10, + VERT_RESULT_TEX7 = 11, + VERT_RESULT_PSIZ = 12, + VERT_RESULT_BFC0 = 13, + VERT_RESULT_BFC1 = 14, + VERT_RESULT_EDGE = 15, + VERT_RESULT_VAR0 = 16, /**< shader varying */ + VERT_RESULT_MAX = (VERT_RESULT_VAR0 + MAX_VARYING) +} gl_vert_result; + + +/*********************************************/ + +/** + * Indexes for geometry program attributes. + */ +typedef enum +{ + GEOM_ATTRIB_POSITION = 0, + GEOM_ATTRIB_COLOR0 = 1, + GEOM_ATTRIB_COLOR1 = 2, + GEOM_ATTRIB_SECONDARY_COLOR0 = 3, + GEOM_ATTRIB_SECONDARY_COLOR1 = 4, + GEOM_ATTRIB_FOG_FRAG_COORD = 5, + GEOM_ATTRIB_POINT_SIZE = 6, + GEOM_ATTRIB_CLIP_VERTEX = 7, + GEOM_ATTRIB_PRIMITIVE_ID = 8, + GEOM_ATTRIB_TEX_COORD = 9, + + GEOM_ATTRIB_VAR0 = 16, + GEOM_ATTRIB_MAX = (GEOM_ATTRIB_VAR0 + MAX_VARYING) +} gl_geom_attrib; + +/** + * Bitflags for geometry attributes. + * These are used in bitfields in many places. + */ +/*@{*/ +#define GEOM_BIT_COLOR0 (1 << GEOM_ATTRIB_COLOR0) +#define GEOM_BIT_COLOR1 (1 << GEOM_ATTRIB_COLOR1) +#define GEOM_BIT_SCOLOR0 (1 << GEOM_ATTRIB_SECONDARY_COLOR0) +#define GEOM_BIT_SCOLOR1 (1 << GEOM_ATTRIB_SECONDARY_COLOR1) +#define GEOM_BIT_TEX_COORD (1 << GEOM_ATTRIB_TEX_COORD) +#define GEOM_BIT_FOG_COORD (1 << GEOM_ATTRIB_FOG_FRAG_COORD) +#define GEOM_BIT_POSITION (1 << GEOM_ATTRIB_POSITION) +#define GEOM_BIT_POINT_SIDE (1 << GEOM_ATTRIB_POINT_SIZE) +#define GEOM_BIT_CLIP_VERTEX (1 << GEOM_ATTRIB_CLIP_VERTEX) +#define GEOM_BIT_PRIM_ID (1 << GEOM_ATTRIB_PRIMITIVE_ID) +#define GEOM_BIT_VAR0 (1 << GEOM_ATTRIB_VAR0) + +#define GEOM_BIT_VAR(g) (1 << (GEOM_BIT_VAR0 + (g))) +/*@}*/ + + +/** + * Indexes for geometry program result attributes + */ +typedef enum +{ + GEOM_RESULT_POS = 0, + GEOM_RESULT_COL0 = 1, + GEOM_RESULT_COL1 = 2, + GEOM_RESULT_SCOL0 = 3, + GEOM_RESULT_SCOL1 = 4, + GEOM_RESULT_FOGC = 5, + GEOM_RESULT_TEX0 = 6, + GEOM_RESULT_TEX1 = 7, + GEOM_RESULT_TEX2 = 8, + GEOM_RESULT_TEX3 = 9, + GEOM_RESULT_TEX4 = 10, + GEOM_RESULT_TEX5 = 11, + GEOM_RESULT_TEX6 = 12, + GEOM_RESULT_TEX7 = 13, + GEOM_RESULT_PSIZ = 14, + GEOM_RESULT_CLPV = 15, + GEOM_RESULT_PRID = 16, + GEOM_RESULT_LAYR = 17, + GEOM_RESULT_VAR0 = 18, /**< shader varying, should really be 16 */ + /* ### we need to -2 because var0 is 18 instead 16 like in the others */ + GEOM_RESULT_MAX = (GEOM_RESULT_VAR0 + MAX_VARYING - 2) +} gl_geom_result; + + +/** + * Indexes for fragment program input attributes. + */ +typedef enum +{ + FRAG_ATTRIB_WPOS = 0, + FRAG_ATTRIB_COL0 = 1, + FRAG_ATTRIB_COL1 = 2, + FRAG_ATTRIB_FOGC = 3, + FRAG_ATTRIB_TEX0 = 4, + FRAG_ATTRIB_TEX1 = 5, + FRAG_ATTRIB_TEX2 = 6, + FRAG_ATTRIB_TEX3 = 7, + FRAG_ATTRIB_TEX4 = 8, + FRAG_ATTRIB_TEX5 = 9, + FRAG_ATTRIB_TEX6 = 10, + FRAG_ATTRIB_TEX7 = 11, + FRAG_ATTRIB_FACE = 12, /**< front/back face */ + FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */ + FRAG_ATTRIB_VAR0 = 14, /**< shader varying */ + FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING) +} gl_frag_attrib; + +/** + * Bitflags for fragment program input attributes. + */ +/*@{*/ +#define FRAG_BIT_WPOS (1 << FRAG_ATTRIB_WPOS) +#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0) +#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1) +#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC) +#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE) +#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC) +#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0) +#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1) +#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2) +#define FRAG_BIT_TEX3 (1 << FRAG_ATTRIB_TEX3) +#define FRAG_BIT_TEX4 (1 << FRAG_ATTRIB_TEX4) +#define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5) +#define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6) +#define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7) +#define FRAG_BIT_VAR0 (1 << FRAG_ATTRIB_VAR0) + +#define FRAG_BIT_TEX(U) (FRAG_BIT_TEX0 << (U)) +#define FRAG_BIT_VAR(V) (FRAG_BIT_VAR0 << (V)) + +#define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \ + FRAG_BIT_TEX1| \ + FRAG_BIT_TEX2| \ + FRAG_BIT_TEX3| \ + FRAG_BIT_TEX4| \ + FRAG_BIT_TEX5| \ + FRAG_BIT_TEX6| \ + FRAG_BIT_TEX7) +/*@}*/ + + +/** + * Fragment program results + */ +typedef enum +{ + FRAG_RESULT_DEPTH = 0, + FRAG_RESULT_STENCIL = 1, + FRAG_RESULT_COLOR = 2, + FRAG_RESULT_DATA0 = 3, + FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS) +} gl_frag_result; + + +/** + * Indexes for all renderbuffers + */ +typedef enum +{ + /* the four standard color buffers */ + BUFFER_FRONT_LEFT, + BUFFER_BACK_LEFT, + BUFFER_FRONT_RIGHT, + BUFFER_BACK_RIGHT, + BUFFER_DEPTH, + BUFFER_STENCIL, + BUFFER_ACCUM, + /* optional aux buffer */ + BUFFER_AUX0, + /* generic renderbuffers */ + BUFFER_COLOR0, + BUFFER_COLOR1, + BUFFER_COLOR2, + BUFFER_COLOR3, + BUFFER_COLOR4, + BUFFER_COLOR5, + BUFFER_COLOR6, + BUFFER_COLOR7, + BUFFER_COUNT +} gl_buffer_index; + +/** + * Bit flags for all renderbuffers + */ +#define BUFFER_BIT_FRONT_LEFT (1 << BUFFER_FRONT_LEFT) +#define BUFFER_BIT_BACK_LEFT (1 << BUFFER_BACK_LEFT) +#define BUFFER_BIT_FRONT_RIGHT (1 << BUFFER_FRONT_RIGHT) +#define BUFFER_BIT_BACK_RIGHT (1 << BUFFER_BACK_RIGHT) +#define BUFFER_BIT_AUX0 (1 << BUFFER_AUX0) +#define BUFFER_BIT_AUX1 (1 << BUFFER_AUX1) +#define BUFFER_BIT_AUX2 (1 << BUFFER_AUX2) +#define BUFFER_BIT_AUX3 (1 << BUFFER_AUX3) +#define BUFFER_BIT_DEPTH (1 << BUFFER_DEPTH) +#define BUFFER_BIT_STENCIL (1 << BUFFER_STENCIL) +#define BUFFER_BIT_ACCUM (1 << BUFFER_ACCUM) +#define BUFFER_BIT_COLOR0 (1 << BUFFER_COLOR0) +#define BUFFER_BIT_COLOR1 (1 << BUFFER_COLOR1) +#define BUFFER_BIT_COLOR2 (1 << BUFFER_COLOR2) +#define BUFFER_BIT_COLOR3 (1 << BUFFER_COLOR3) +#define BUFFER_BIT_COLOR4 (1 << BUFFER_COLOR4) +#define BUFFER_BIT_COLOR5 (1 << BUFFER_COLOR5) +#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6) +#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7) + +/** + * Mask of all the color buffer bits (but not accum). + */ +#define BUFFER_BITS_COLOR (BUFFER_BIT_FRONT_LEFT | \ + BUFFER_BIT_BACK_LEFT | \ + BUFFER_BIT_FRONT_RIGHT | \ + BUFFER_BIT_BACK_RIGHT | \ + BUFFER_BIT_AUX0 | \ + BUFFER_BIT_COLOR0 | \ + BUFFER_BIT_COLOR1 | \ + BUFFER_BIT_COLOR2 | \ + BUFFER_BIT_COLOR3 | \ + BUFFER_BIT_COLOR4 | \ + BUFFER_BIT_COLOR5 | \ + BUFFER_BIT_COLOR6 | \ + BUFFER_BIT_COLOR7) + + +/** + * Framebuffer configuration (aka visual / pixelformat) + * Note: some of these fields should be boolean, but it appears that + * code in drivers/dri/common/util.c requires int-sized fields. + */ +struct gl_config +{ + GLboolean rgbMode; + GLboolean floatMode; + GLboolean colorIndexMode; /* XXX is this used anywhere? */ + GLuint doubleBufferMode; + GLuint stereoMode; + + GLboolean haveAccumBuffer; + GLboolean haveDepthBuffer; + GLboolean haveStencilBuffer; + + GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ + GLuint redMask, greenMask, blueMask, alphaMask; + GLint rgbBits; /* total bits for rgb */ + GLint indexBits; /* total bits for colorindex */ + + GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; + GLint depthBits; + GLint stencilBits; + + GLint numAuxBuffers; + + GLint level; + + /* EXT_visual_rating / GLX 1.2 */ + GLint visualRating; + + /* EXT_visual_info / GLX 1.2 */ + GLint transparentPixel; + /* colors are floats scaled to ints */ + GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha; + GLint transparentIndex; + + /* ARB_multisample / SGIS_multisample */ + GLint sampleBuffers; + GLint samples; + + /* SGIX_pbuffer / GLX 1.3 */ + GLint maxPbufferWidth; + GLint maxPbufferHeight; + GLint maxPbufferPixels; + GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */ + GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */ + + /* OML_swap_method */ + GLint swapMethod; + + /* EXT_texture_from_pixmap */ + GLint bindToTextureRgb; + GLint bindToTextureRgba; + GLint bindToMipmapTexture; + GLint bindToTextureTargets; + GLint yInverted; + + /* EXT_framebuffer_sRGB */ + GLint sRGBCapable; +}; + + +/** + * Data structure for color tables + */ +struct gl_color_table +{ + GLenum InternalFormat; /**< The user-specified format */ + GLenum _BaseFormat; /**< GL_ALPHA, GL_RGBA, GL_RGB, etc */ + GLuint Size; /**< number of entries in table */ + GLfloat *TableF; /**< Color table, floating point values */ + GLubyte *TableUB; /**< Color table, ubyte values */ + GLubyte RedSize; + GLubyte GreenSize; + GLubyte BlueSize; + GLubyte AlphaSize; + GLubyte LuminanceSize; + GLubyte IntensitySize; +}; + + +/** + * \name Bit flags used for updating material values. + */ +/*@{*/ +#define MAT_ATTRIB_FRONT_AMBIENT 0 +#define MAT_ATTRIB_BACK_AMBIENT 1 +#define MAT_ATTRIB_FRONT_DIFFUSE 2 +#define MAT_ATTRIB_BACK_DIFFUSE 3 +#define MAT_ATTRIB_FRONT_SPECULAR 4 +#define MAT_ATTRIB_BACK_SPECULAR 5 +#define MAT_ATTRIB_FRONT_EMISSION 6 +#define MAT_ATTRIB_BACK_EMISSION 7 +#define MAT_ATTRIB_FRONT_SHININESS 8 +#define MAT_ATTRIB_BACK_SHININESS 9 +#define MAT_ATTRIB_FRONT_INDEXES 10 +#define MAT_ATTRIB_BACK_INDEXES 11 +#define MAT_ATTRIB_MAX 12 + +#define MAT_ATTRIB_AMBIENT(f) (MAT_ATTRIB_FRONT_AMBIENT+(f)) +#define MAT_ATTRIB_DIFFUSE(f) (MAT_ATTRIB_FRONT_DIFFUSE+(f)) +#define MAT_ATTRIB_SPECULAR(f) (MAT_ATTRIB_FRONT_SPECULAR+(f)) +#define MAT_ATTRIB_EMISSION(f) (MAT_ATTRIB_FRONT_EMISSION+(f)) +#define MAT_ATTRIB_SHININESS(f)(MAT_ATTRIB_FRONT_SHININESS+(f)) +#define MAT_ATTRIB_INDEXES(f) (MAT_ATTRIB_FRONT_INDEXES+(f)) + +#define MAT_INDEX_AMBIENT 0 +#define MAT_INDEX_DIFFUSE 1 +#define MAT_INDEX_SPECULAR 2 + +#define MAT_BIT_FRONT_AMBIENT (1< ) */ + GLfloat _NormSpotDirection[4]; /**< normalized spotlight direction */ + GLfloat _VP_inf_spot_attenuation; + + GLfloat _SpotExpTable[EXP_TABLE_SIZE][2]; /**< to replace a pow() call */ + GLfloat _MatAmbient[2][3]; /**< material ambient * light ambient */ + GLfloat _MatDiffuse[2][3]; /**< material diffuse * light diffuse */ + GLfloat _MatSpecular[2][3]; /**< material spec * light specular */ + GLfloat _dli; /**< CI diffuse light intensity */ + GLfloat _sli; /**< CI specular light intensity */ + /*@}*/ +}; + + +/** + * Light model state. + */ +struct gl_lightmodel +{ + GLfloat Ambient[4]; /**< ambient color */ + GLboolean LocalViewer; /**< Local (or infinite) view point? */ + GLboolean TwoSide; /**< Two (or one) sided lighting? */ + GLenum ColorControl; /**< either GL_SINGLE_COLOR + * or GL_SEPARATE_SPECULAR_COLOR */ +}; + + +/** + * Material state. + */ +struct gl_material +{ + GLfloat Attrib[MAT_ATTRIB_MAX][4]; +}; + + +/** + * Accumulation buffer attribute group (GL_ACCUM_BUFFER_BIT) + */ +struct gl_accum_attrib +{ + GLfloat ClearColor[4]; /**< Accumulation buffer clear color */ +}; + + +/** + * Color buffer attribute group (GL_COLOR_BUFFER_BIT). + */ +struct gl_colorbuffer_attrib +{ + GLuint ClearIndex; /**< Index to use for glClear */ + GLclampf ClearColor[4]; /**< Color to use for glClear */ + + GLuint IndexMask; /**< Color index write mask */ + GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */ + + GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */ + + /** + * \name alpha testing + */ + /*@{*/ + GLboolean AlphaEnabled; /**< Alpha test enabled flag */ + GLenum AlphaFunc; /**< Alpha test function */ + GLclampf AlphaRef; /**< Alpha reference value */ + /*@}*/ + + /** + * \name Blending + */ + /*@{*/ + GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */ + GLfloat BlendColor[4]; /**< Blending color */ + struct + { + GLenum SrcRGB; /**< RGB blend source term */ + GLenum DstRGB; /**< RGB blend dest term */ + GLenum SrcA; /**< Alpha blend source term */ + GLenum DstA; /**< Alpha blend dest term */ + GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */ + GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */ + } Blend[MAX_DRAW_BUFFERS]; + /** Are the blend func terms currently different for each buffer/target? */ + GLboolean _BlendFuncPerBuffer; + /** Are the blend equations currently different for each buffer/target? */ + GLboolean _BlendEquationPerBuffer; + /*@}*/ + + /** + * \name Logic op + */ + /*@{*/ + GLenum LogicOp; /**< Logic operator */ + GLboolean IndexLogicOpEnabled; /**< Color index logic op enabled flag */ + GLboolean ColorLogicOpEnabled; /**< RGBA logic op enabled flag */ + GLboolean _LogicOpEnabled; /**< RGBA logic op + EXT_blend_logic_op enabled flag */ + /*@}*/ + + GLboolean DitherFlag; /**< Dither enable flag */ + + GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */ + GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */ + + GLboolean sRGBEnabled; /**< Framebuffer sRGB blending/updating requested */ +}; + + +/** + * Current attribute group (GL_CURRENT_BIT). + */ +struct gl_current_attrib +{ + /** + * \name Current vertex attributes. + * \note Values are valid only after FLUSH_VERTICES has been called. + * \note Index and Edgeflag current values are stored as floats in the + * SIX and SEVEN attribute slots. + */ + GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Position, color, texcoords, etc */ + + /** + * \name Current raster position attributes (always valid). + * \note This set of attributes is very similar to the SWvertex struct. + */ + /*@{*/ + GLfloat RasterPos[4]; + GLfloat RasterDistance; + GLfloat RasterColor[4]; + GLfloat RasterSecondaryColor[4]; + GLfloat RasterTexCoords[MAX_TEXTURE_COORD_UNITS][4]; + GLboolean RasterPosValid; + /*@}*/ +}; + + +/** + * Depth buffer attribute group (GL_DEPTH_BUFFER_BIT). + */ +struct gl_depthbuffer_attrib +{ + GLenum Func; /**< Function for depth buffer compare */ + GLclampd Clear; /**< Value to clear depth buffer to */ + GLboolean Test; /**< Depth buffering enabled flag */ + GLboolean Mask; /**< Depth buffer writable? */ + GLboolean BoundsTest; /**< GL_EXT_depth_bounds_test */ + GLfloat BoundsMin, BoundsMax;/**< GL_EXT_depth_bounds_test */ +}; + + +/** + * Evaluator attribute group (GL_EVAL_BIT). + */ +struct gl_eval_attrib +{ + /** + * \name Enable bits + */ + /*@{*/ + GLboolean Map1Color4; + GLboolean Map1Index; + GLboolean Map1Normal; + GLboolean Map1TextureCoord1; + GLboolean Map1TextureCoord2; + GLboolean Map1TextureCoord3; + GLboolean Map1TextureCoord4; + GLboolean Map1Vertex3; + GLboolean Map1Vertex4; + GLboolean Map1Attrib[16]; /* GL_NV_vertex_program */ + GLboolean Map2Color4; + GLboolean Map2Index; + GLboolean Map2Normal; + GLboolean Map2TextureCoord1; + GLboolean Map2TextureCoord2; + GLboolean Map2TextureCoord3; + GLboolean Map2TextureCoord4; + GLboolean Map2Vertex3; + GLboolean Map2Vertex4; + GLboolean Map2Attrib[16]; /* GL_NV_vertex_program */ + GLboolean AutoNormal; + /*@}*/ + + /** + * \name Map Grid endpoints and divisions and calculated du values + */ + /*@{*/ + GLint MapGrid1un; + GLfloat MapGrid1u1, MapGrid1u2, MapGrid1du; + GLint MapGrid2un, MapGrid2vn; + GLfloat MapGrid2u1, MapGrid2u2, MapGrid2du; + GLfloat MapGrid2v1, MapGrid2v2, MapGrid2dv; + /*@}*/ +}; + + +/** + * Fog attribute group (GL_FOG_BIT). + */ +struct gl_fog_attrib +{ + GLboolean Enabled; /**< Fog enabled flag */ + GLfloat Color[4]; /**< Fog color */ + GLfloat Density; /**< Density >= 0.0 */ + GLfloat Start; /**< Start distance in eye coords */ + GLfloat End; /**< End distance in eye coords */ + GLfloat Index; /**< Fog index */ + GLenum Mode; /**< Fog mode */ + GLboolean ColorSumEnabled; + GLenum FogCoordinateSource; /**< GL_EXT_fog_coord */ + GLfloat _Scale; /**< (End == Start) ? 1.0 : 1.0 / (End - Start) */ +}; + + +/** + * \brief Layout qualifiers for gl_FragDepth. + * + * Extension AMD_conservative_depth allows gl_FragDepth to be redeclared with + * a layout qualifier. + * + * \see enum ir_depth_layout + */ +enum gl_frag_depth_layout { + FRAG_DEPTH_LAYOUT_NONE, /**< No layout is specified. */ + FRAG_DEPTH_LAYOUT_ANY, + FRAG_DEPTH_LAYOUT_GREATER, + FRAG_DEPTH_LAYOUT_LESS, + FRAG_DEPTH_LAYOUT_UNCHANGED +}; + + +/** + * Hint attribute group (GL_HINT_BIT). + * + * Values are always one of GL_FASTEST, GL_NICEST, or GL_DONT_CARE. + */ +struct gl_hint_attrib +{ + GLenum PerspectiveCorrection; + GLenum PointSmooth; + GLenum LineSmooth; + GLenum PolygonSmooth; + GLenum Fog; + GLenum ClipVolumeClipping; /**< GL_EXT_clip_volume_hint */ + GLenum TextureCompression; /**< GL_ARB_texture_compression */ + GLenum GenerateMipmap; /**< GL_SGIS_generate_mipmap */ + GLenum FragmentShaderDerivative; /**< GL_ARB_fragment_shader */ +}; + +/** + * Light state flags. + */ +/*@{*/ +#define LIGHT_SPOT 0x1 +#define LIGHT_LOCAL_VIEWER 0x2 +#define LIGHT_POSITIONAL 0x4 +#define LIGHT_NEED_VERTICES (LIGHT_POSITIONAL|LIGHT_LOCAL_VIEWER) +/*@}*/ + + +/** + * Lighting attribute group (GL_LIGHT_BIT). + */ +struct gl_light_attrib +{ + struct gl_light Light[MAX_LIGHTS]; /**< Array of light sources */ + struct gl_lightmodel Model; /**< Lighting model */ + + /** + * Must flush FLUSH_VERTICES before referencing: + */ + /*@{*/ + struct gl_material Material; /**< Includes front & back values */ + /*@}*/ + + GLboolean Enabled; /**< Lighting enabled flag */ + GLenum ShadeModel; /**< GL_FLAT or GL_SMOOTH */ + GLenum ProvokingVertex; /**< GL_EXT_provoking_vertex */ + GLenum ColorMaterialFace; /**< GL_FRONT, BACK or FRONT_AND_BACK */ + GLenum ColorMaterialMode; /**< GL_AMBIENT, GL_DIFFUSE, etc */ + GLbitfield ColorMaterialBitmask; /**< bitmask formed from Face and Mode */ + GLboolean ColorMaterialEnabled; + GLenum ClampVertexColor; + + struct gl_light EnabledList; /**< List sentinel */ + + /** + * Derived state for optimizations: + */ + /*@{*/ + GLboolean _NeedEyeCoords; + GLboolean _NeedVertices; /**< Use fast shader? */ + GLbitfield _Flags; /**< LIGHT_* flags, see above */ + GLfloat _BaseColor[2][3]; + /*@}*/ +}; + + +/** + * Line attribute group (GL_LINE_BIT). + */ +struct gl_line_attrib +{ + GLboolean SmoothFlag; /**< GL_LINE_SMOOTH enabled? */ + GLboolean StippleFlag; /**< GL_LINE_STIPPLE enabled? */ + GLushort StipplePattern; /**< Stipple pattern */ + GLint StippleFactor; /**< Stipple repeat factor */ + GLfloat Width; /**< Line width */ +}; + + +/** + * Display list attribute group (GL_LIST_BIT). + */ +struct gl_list_attrib +{ + GLuint ListBase; +}; + + +/** + * Multisample attribute group (GL_MULTISAMPLE_BIT). + */ +struct gl_multisample_attrib +{ + GLboolean Enabled; + GLboolean _Enabled; /**< true if Enabled and multisample buffer */ + GLboolean SampleAlphaToCoverage; + GLboolean SampleAlphaToOne; + GLboolean SampleCoverage; + GLfloat SampleCoverageValue; + GLboolean SampleCoverageInvert; +}; + + +/** + * A pixelmap (see glPixelMap) + */ +struct gl_pixelmap +{ + GLint Size; + GLfloat Map[MAX_PIXEL_MAP_TABLE]; + GLubyte Map8[MAX_PIXEL_MAP_TABLE]; /**< converted to 8-bit color */ +}; + + +/** + * Collection of all pixelmaps + */ +struct gl_pixelmaps +{ + struct gl_pixelmap RtoR; /**< i.e. GL_PIXEL_MAP_R_TO_R */ + struct gl_pixelmap GtoG; + struct gl_pixelmap BtoB; + struct gl_pixelmap AtoA; + struct gl_pixelmap ItoR; + struct gl_pixelmap ItoG; + struct gl_pixelmap ItoB; + struct gl_pixelmap ItoA; + struct gl_pixelmap ItoI; + struct gl_pixelmap StoS; +}; + + +/** + * Pixel attribute group (GL_PIXEL_MODE_BIT). + */ +struct gl_pixel_attrib +{ + GLenum ReadBuffer; /**< source buffer for glRead/CopyPixels() */ + + /*--- Begin Pixel Transfer State ---*/ + /* Fields are in the order in which they're applied... */ + + /** Scale & Bias (index shift, offset) */ + /*@{*/ + GLfloat RedBias, RedScale; + GLfloat GreenBias, GreenScale; + GLfloat BlueBias, BlueScale; + GLfloat AlphaBias, AlphaScale; + GLfloat DepthBias, DepthScale; + GLint IndexShift, IndexOffset; + /*@}*/ + + /* Pixel Maps */ + /* Note: actual pixel maps are not part of this attrib group */ + GLboolean MapColorFlag; + GLboolean MapStencilFlag; + + /*--- End Pixel Transfer State ---*/ + + /** glPixelZoom */ + GLfloat ZoomX, ZoomY; + + /** GL_SGI_texture_color_table */ + GLfloat TextureColorTableScale[4]; /**< RGBA */ + GLfloat TextureColorTableBias[4]; /**< RGBA */ +}; + + +/** + * Point attribute group (GL_POINT_BIT). + */ +struct gl_point_attrib +{ + GLboolean SmoothFlag; /**< True if GL_POINT_SMOOTH is enabled */ + GLfloat Size; /**< User-specified point size */ + GLfloat Params[3]; /**< GL_EXT_point_parameters */ + GLfloat MinSize, MaxSize; /**< GL_EXT_point_parameters */ + GLfloat Threshold; /**< GL_EXT_point_parameters */ + GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */ + GLboolean PointSprite; /**< GL_NV/ARB_point_sprite */ + GLboolean CoordReplace[MAX_TEXTURE_COORD_UNITS]; /**< GL_ARB_point_sprite*/ + GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */ + GLenum SpriteOrigin; /**< GL_ARB_point_sprite */ +}; + + +/** + * Polygon attribute group (GL_POLYGON_BIT). + */ +struct gl_polygon_attrib +{ + GLenum FrontFace; /**< Either GL_CW or GL_CCW */ + GLenum FrontMode; /**< Either GL_POINT, GL_LINE or GL_FILL */ + GLenum BackMode; /**< Either GL_POINT, GL_LINE or GL_FILL */ + GLboolean _FrontBit; /**< 0=GL_CCW, 1=GL_CW */ + GLboolean CullFlag; /**< Culling on/off flag */ + GLboolean SmoothFlag; /**< True if GL_POLYGON_SMOOTH is enabled */ + GLboolean StippleFlag; /**< True if GL_POLYGON_STIPPLE is enabled */ + GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */ + GLfloat OffsetFactor; /**< Polygon offset factor, from user */ + GLfloat OffsetUnits; /**< Polygon offset units, from user */ + GLboolean OffsetPoint; /**< Offset in GL_POINT mode */ + GLboolean OffsetLine; /**< Offset in GL_LINE mode */ + GLboolean OffsetFill; /**< Offset in GL_FILL mode */ +}; + + +/** + * Scissor attributes (GL_SCISSOR_BIT). + */ +struct gl_scissor_attrib +{ + GLboolean Enabled; /**< Scissor test enabled? */ + GLint X, Y; /**< Lower left corner of box */ + GLsizei Width, Height; /**< Size of box */ +}; + + +/** + * Stencil attribute group (GL_STENCIL_BUFFER_BIT). + * + * Three sets of stencil data are tracked so that OpenGL 2.0, + * GL_EXT_stencil_two_side, and GL_ATI_separate_stencil can all be supported + * simultaneously. In each of the stencil state arrays, element 0 corresponds + * to GL_FRONT. Element 1 corresponds to the OpenGL 2.0 / + * GL_ATI_separate_stencil GL_BACK state. Element 2 corresponds to the + * GL_EXT_stencil_two_side GL_BACK state. + * + * The derived value \c _BackFace is either 1 or 2 depending on whether or + * not GL_STENCIL_TEST_TWO_SIDE_EXT is enabled. + * + * The derived value \c _TestTwoSide is set when the front-face and back-face + * stencil state are different. + */ +struct gl_stencil_attrib +{ + GLboolean Enabled; /**< Enabled flag */ + GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */ + GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */ + GLboolean _Enabled; /**< Enabled and stencil buffer present */ + GLboolean _TestTwoSide; + GLubyte _BackFace; /**< Current back stencil state (1 or 2) */ + GLenum Function[3]; /**< Stencil function */ + GLenum FailFunc[3]; /**< Fail function */ + GLenum ZPassFunc[3]; /**< Depth buffer pass function */ + GLenum ZFailFunc[3]; /**< Depth buffer fail function */ + GLint Ref[3]; /**< Reference value */ + GLuint ValueMask[3]; /**< Value mask */ + GLuint WriteMask[3]; /**< Write mask */ + GLuint Clear; /**< Clear value */ +}; + + +/** + * An index for each type of texture object. These correspond to the GL + * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc. + * Note: the order is from highest priority to lowest priority. + */ +typedef enum +{ + TEXTURE_2D_ARRAY_INDEX, + TEXTURE_1D_ARRAY_INDEX, + TEXTURE_CUBE_INDEX, + TEXTURE_3D_INDEX, + TEXTURE_RECT_INDEX, + TEXTURE_2D_INDEX, + TEXTURE_1D_INDEX, + NUM_TEXTURE_TARGETS +} gl_texture_index; + + +/** + * Bit flags for each type of texture object + * Used for Texture.Unit[]._ReallyEnabled flags. + */ +/*@{*/ +#define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX) +#define TEXTURE_1D_ARRAY_BIT (1 << TEXTURE_1D_ARRAY_INDEX) +#define TEXTURE_CUBE_BIT (1 << TEXTURE_CUBE_INDEX) +#define TEXTURE_3D_BIT (1 << TEXTURE_3D_INDEX) +#define TEXTURE_RECT_BIT (1 << TEXTURE_RECT_INDEX) +#define TEXTURE_2D_BIT (1 << TEXTURE_2D_INDEX) +#define TEXTURE_1D_BIT (1 << TEXTURE_1D_INDEX) +/*@}*/ + + +/** + * TexGenEnabled flags. + */ +/*@{*/ +#define S_BIT 1 +#define T_BIT 2 +#define R_BIT 4 +#define Q_BIT 8 +#define STR_BITS (S_BIT | T_BIT | R_BIT) +/*@}*/ + + +/** + * Bit flag versions of the corresponding GL_ constants. + */ +/*@{*/ +#define TEXGEN_SPHERE_MAP 0x1 +#define TEXGEN_OBJ_LINEAR 0x2 +#define TEXGEN_EYE_LINEAR 0x4 +#define TEXGEN_REFLECTION_MAP_NV 0x8 +#define TEXGEN_NORMAL_MAP_NV 0x10 + +#define TEXGEN_NEED_NORMALS (TEXGEN_SPHERE_MAP | \ + TEXGEN_REFLECTION_MAP_NV | \ + TEXGEN_NORMAL_MAP_NV) +#define TEXGEN_NEED_EYE_COORD (TEXGEN_SPHERE_MAP | \ + TEXGEN_REFLECTION_MAP_NV | \ + TEXGEN_NORMAL_MAP_NV | \ + TEXGEN_EYE_LINEAR) +/*@}*/ + + + +/** Tex-gen enabled for texture unit? */ +#define ENABLE_TEXGEN(unit) (1 << (unit)) + +/** Non-identity texture matrix for texture unit? */ +#define ENABLE_TEXMAT(unit) (1 << (unit)) + + +/** + * Texel fetch function prototype. We use texel fetch functions to + * extract RGBA, color indexes and depth components out of 1D, 2D and 3D + * texture images. These functions help to isolate us from the gritty + * details of all the various texture image encodings. + * + * \param texImage texture image. + * \param col texel column. + * \param row texel row. + * \param img texel image level/layer. + * \param texelOut output texel (up to 4 GLchans) + */ +typedef void (*FetchTexelFuncC)( const struct gl_texture_image *texImage, + GLint col, GLint row, GLint img, + GLchan *texelOut ); + +/** + * As above, but returns floats. + * Used for depth component images and for upcoming signed/float + * texture images. + */ +typedef void (*FetchTexelFuncF)( const struct gl_texture_image *texImage, + GLint col, GLint row, GLint img, + GLfloat *texelOut ); + + +typedef void (*StoreTexelFunc)(struct gl_texture_image *texImage, + GLint col, GLint row, GLint img, + const void *texel); + + +/** + * Texture image state. Describes the dimensions of a texture image, + * the texel format and pointers to Texel Fetch functions. + */ +struct gl_texture_image +{ + GLint InternalFormat; /**< Internal format as given by the user */ + GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_ALPHA, + * GL_LUMINANCE, GL_LUMINANCE_ALPHA, + * GL_INTENSITY, GL_COLOR_INDEX, + * GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT + * only. Used for choosing TexEnv arithmetic. + */ + GLuint TexFormat; /**< The actual format: MESA_FORMAT_x */ + + GLuint Border; /**< 0 or 1 */ + GLuint Width; /**< = 2^WidthLog2 + 2*Border */ + GLuint Height; /**< = 2^HeightLog2 + 2*Border */ + GLuint Depth; /**< = 2^DepthLog2 + 2*Border */ + GLuint Width2; /**< = Width - 2*Border */ + GLuint Height2; /**< = Height - 2*Border */ + GLuint Depth2; /**< = Depth - 2*Border */ + GLuint WidthLog2; /**< = log2(Width2) */ + GLuint HeightLog2; /**< = log2(Height2) */ + GLuint DepthLog2; /**< = log2(Depth2) */ + GLuint MaxLog2; /**< = MAX(WidthLog2, HeightLog2) */ + GLfloat WidthScale; /**< used for mipmap LOD computation */ + GLfloat HeightScale; /**< used for mipmap LOD computation */ + GLfloat DepthScale; /**< used for mipmap LOD computation */ + GLboolean IsClientData; /**< Data owned by client? */ + GLboolean _IsPowerOfTwo; /**< Are all dimensions powers of two? */ + + struct gl_texture_object *TexObject; /**< Pointer back to parent object */ + + FetchTexelFuncC FetchTexelc; /**< GLchan texel fetch function pointer */ + FetchTexelFuncF FetchTexelf; /**< Float texel fetch function pointer */ + + GLuint RowStride; /**< Padded width in units of texels */ + GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to + each 2D slice in 'Data', in texels */ + GLvoid *Data; /**< Image data, accessed via FetchTexel() */ + + /** + * \name For device driver: + */ + /*@{*/ + void *DriverData; /**< Arbitrary device driver data */ + /*@}*/ +}; + + +/** + * Indexes for cube map faces. + */ +typedef enum +{ + FACE_POS_X = 0, + FACE_NEG_X = 1, + FACE_POS_Y = 2, + FACE_NEG_Y = 3, + FACE_POS_Z = 4, + FACE_NEG_Z = 5, + MAX_FACES = 6 +} gl_face_index; + + +/** + * Texture object state. Contains the array of mipmap images, border color, + * wrap modes, filter modes, shadow/texcompare state, and the per-texture + * color palette. + */ +struct gl_texture_object +{ + _glthread_Mutex Mutex; /**< for thread safety */ + GLint RefCount; /**< reference count */ + GLuint Name; /**< the user-visible texture object ID */ + GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ + GLfloat Priority; /**< in [0,1] */ + union { + GLfloat f[4]; + GLuint ui[4]; + GLint i[4]; + } BorderColor; /**< Interpreted according to texture format */ + GLenum WrapS; /**< S-axis texture image wrap mode */ + GLenum WrapT; /**< T-axis texture image wrap mode */ + GLenum WrapR; /**< R-axis texture image wrap mode */ + GLenum MinFilter; /**< minification filter */ + GLenum MagFilter; /**< magnification filter */ + GLfloat MinLod; /**< min lambda, OpenGL 1.2 */ + GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */ + GLfloat LodBias; /**< OpenGL 1.4 */ + GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */ + GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */ + GLfloat MaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ + GLenum CompareMode; /**< GL_ARB_shadow */ + GLenum CompareFunc; /**< GL_ARB_shadow */ + GLfloat CompareFailValue; /**< GL_ARB_shadow_ambient */ + GLenum DepthMode; /**< GL_ARB_depth_texture */ + GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ + GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */ + GLint CropRect[4]; /**< GL_OES_draw_texture */ + GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */ + GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */ + GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */ + GLboolean _Complete; /**< Is texture object complete? */ + GLboolean _RenderToTexture; /**< Any rendering to this texture? */ + GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ + GLenum sRGBDecode; /**< GL_DECODE_EXT or GL_SKIP_DECODE_EXT */ + + /** Actual texture images, indexed by [cube face] and [mipmap level] */ + struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS]; + + /** GL_EXT_paletted_texture */ + struct gl_color_table Palette; + + /** + * \name For device driver. + * Note: instead of attaching driver data to this pointer, it's preferable + * to instead use this struct as a base class for your own texture object + * class. Driver->NewTextureObject() can be used to implement the + * allocation. + */ + void *DriverData; /**< Arbitrary device driver data */ +}; + + +/** Up to four combiner sources are possible with GL_NV_texture_env_combine4 */ +#define MAX_COMBINER_TERMS 4 + + +/** + * Texture combine environment state. + */ +struct gl_tex_env_combine_state +{ + GLenum ModeRGB; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */ + GLenum ModeA; /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */ + /** Source terms: GL_PRIMARY_COLOR, GL_TEXTURE, etc */ + GLenum SourceRGB[MAX_COMBINER_TERMS]; + GLenum SourceA[MAX_COMBINER_TERMS]; + /** Source operands: GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, etc */ + GLenum OperandRGB[MAX_COMBINER_TERMS]; + GLenum OperandA[MAX_COMBINER_TERMS]; + GLuint ScaleShiftRGB; /**< 0, 1 or 2 */ + GLuint ScaleShiftA; /**< 0, 1 or 2 */ + GLuint _NumArgsRGB; /**< Number of inputs used for the RGB combiner */ + GLuint _NumArgsA; /**< Number of inputs used for the A combiner */ +}; + + +/** + * Texture coord generation state. + */ +struct gl_texgen +{ + GLenum Mode; /**< GL_EYE_LINEAR, GL_SPHERE_MAP, etc */ + GLbitfield _ModeBit; /**< TEXGEN_x bit corresponding to Mode */ + GLfloat ObjectPlane[4]; + GLfloat EyePlane[4]; +}; + + +/** + * Texture unit state. Contains enable flags, texture environment/function/ + * combiners, texgen state, pointers to current texture objects and + * post-filter color tables. + */ +struct gl_texture_unit +{ + GLbitfield Enabled; /**< bitmask of TEXTURE_*_BIT flags */ + GLbitfield _ReallyEnabled; /**< 0 or exactly one of TEXTURE_*_BIT flags */ + + GLenum EnvMode; /**< GL_MODULATE, GL_DECAL, GL_BLEND, etc. */ + GLfloat EnvColor[4]; + + struct gl_texgen GenS; + struct gl_texgen GenT; + struct gl_texgen GenR; + struct gl_texgen GenQ; + GLbitfield TexGenEnabled; /**< Bitwise-OR of [STRQ]_BIT values */ + GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */ + + GLfloat LodBias; /**< for biasing mipmap levels */ + GLenum BumpTarget; + GLfloat RotMatrix[4]; /* 2x2 matrix */ + + /** + * \name GL_EXT_texture_env_combine + */ + struct gl_tex_env_combine_state Combine; + + /** + * Derived state based on \c EnvMode and the \c BaseFormat of the + * currently enabled texture. + */ + struct gl_tex_env_combine_state _EnvMode; + + /** + * Currently enabled combiner state. This will point to either + * \c Combine or \c _EnvMode. + */ + struct gl_tex_env_combine_state *_CurrentCombine; + + /** Current texture object pointers */ + struct gl_texture_object *CurrentTex[NUM_TEXTURE_TARGETS]; + + /** Points to highest priority, complete and enabled texture object */ + struct gl_texture_object *_Current; + + /** GL_SGI_texture_color_table */ + /*@{*/ + struct gl_color_table ColorTable; + struct gl_color_table ProxyColorTable; + GLboolean ColorTableEnabled; + /*@}*/ +}; + + +/** + * Texture attribute group (GL_TEXTURE_BIT). + */ +struct gl_texture_attrib +{ + GLuint CurrentUnit; /**< GL_ACTIVE_TEXTURE */ + struct gl_texture_unit Unit[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; + + struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS]; + + /** GL_ARB_seamless_cubemap */ + GLboolean CubeMapSeamless; + + /** GL_EXT_shared_texture_palette */ + GLboolean SharedPalette; + struct gl_color_table Palette; + + /** Texture units/samplers used by vertex or fragment texturing */ + GLbitfield _EnabledUnits; + + /** Texture coord units/sets used for fragment texturing */ + GLbitfield _EnabledCoordUnits; + + /** Texture coord units that have texgen enabled */ + GLbitfield _TexGenEnabled; + + /** Texture coord units that have non-identity matrices */ + GLbitfield _TexMatEnabled; + + /** Bitwise-OR of all Texture.Unit[i]._GenFlags */ + GLbitfield _GenFlags; +}; + + +/** + * Transformation attribute group (GL_TRANSFORM_BIT). + */ +struct gl_transform_attrib +{ + GLenum MatrixMode; /**< Matrix mode */ + GLfloat EyeUserPlane[MAX_CLIP_PLANES][4]; /**< User clip planes */ + GLfloat _ClipUserPlane[MAX_CLIP_PLANES][4]; /**< derived */ + GLbitfield ClipPlanesEnabled; /**< on/off bitmask */ + GLboolean Normalize; /**< Normalize all normals? */ + GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */ + GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */ + GLboolean DepthClamp; /**< GL_ARB_depth_clamp */ + + GLfloat CullEyePos[4]; + GLfloat CullObjPos[4]; +}; + + +/** + * Viewport attribute group (GL_VIEWPORT_BIT). + */ +struct gl_viewport_attrib +{ + GLint X, Y; /**< position */ + GLsizei Width, Height; /**< size */ + GLfloat Near, Far; /**< Depth buffer range */ + GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */ +}; + + +/** + * GL_ARB_vertex/pixel_buffer_object buffer object + */ +struct gl_buffer_object +{ + _glthread_Mutex Mutex; + GLint RefCount; + GLuint Name; + GLenum Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */ + GLsizeiptrARB Size; /**< Size of buffer storage in bytes */ + GLubyte *Data; /**< Location of storage either in RAM or VRAM. */ + /** Fields describing a mapped buffer */ + /*@{*/ + GLbitfield AccessFlags; /**< Mask of GL_MAP_x_BIT flags */ + GLvoid *Pointer; /**< User-space address of mapping */ + GLintptr Offset; /**< Mapped offset */ + GLsizeiptr Length; /**< Mapped length */ + /*@}*/ + GLboolean Written; /**< Ever written to? (for debugging) */ + GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ +}; + + +/** + * Client pixel packing/unpacking attributes + */ +struct gl_pixelstore_attrib +{ + GLint Alignment; + GLint RowLength; + GLint SkipPixels; + GLint SkipRows; + GLint ImageHeight; + GLint SkipImages; + GLboolean SwapBytes; + GLboolean LsbFirst; + GLboolean ClientStorage; /**< GL_APPLE_client_storage */ + GLboolean Invert; /**< GL_MESA_pack_invert */ + struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */ +}; + + +/** + * Client vertex array attributes + */ +struct gl_client_array +{ + GLint Size; /**< components per element (1,2,3,4) */ + GLenum Type; /**< datatype: GL_FLOAT, GL_INT, etc */ + GLenum Format; /**< default: GL_RGBA, but may be GL_BGRA */ + GLsizei Stride; /**< user-specified stride */ + GLsizei StrideB; /**< actual stride in bytes */ + const GLubyte *Ptr; /**< Points to array data */ + GLboolean Enabled; /**< Enabled flag is a boolean */ + GLboolean Normalized; /**< GL_ARB_vertex_program */ + GLboolean Integer; /**< Integer-valued? */ + GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */ + GLuint _ElementSize; /**< size of each element in bytes */ + + struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */ + GLuint _MaxElement; /**< max element index into array buffer + 1 */ +}; + + +/** + * Collection of vertex arrays. Defined by the GL_APPLE_vertex_array_object + * extension, but a nice encapsulation in any case. + */ +struct gl_array_object +{ + /** Name of the array object as received from glGenVertexArrayAPPLE. */ + GLuint Name; + + GLint RefCount; + _glthread_Mutex Mutex; + GLboolean VBOonly; /**< require all arrays to live in VBOs? */ + + /** Conventional vertex arrays */ + /*@{*/ + struct gl_client_array Vertex; + struct gl_client_array Weight; + struct gl_client_array Normal; + struct gl_client_array Color; + struct gl_client_array SecondaryColor; + struct gl_client_array FogCoord; + struct gl_client_array Index; + struct gl_client_array EdgeFlag; + struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS]; + struct gl_client_array PointSize; + /*@}*/ + + /** + * Generic arrays for vertex programs/shaders. + * For NV vertex programs, these attributes alias and take priority + * over the conventional attribs above. For ARB vertex programs and + * GLSL vertex shaders, these attributes are separate. + */ + struct gl_client_array VertexAttrib[MAX_VERTEX_GENERIC_ATTRIBS]; + + /** Mask of _NEW_ARRAY_* values indicating which arrays are enabled */ + GLbitfield _Enabled; + + /** + * Min of all enabled arrays' _MaxElement. When arrays reside inside VBOs + * we can determine the max legal (in bounds) glDrawElements array index. + */ + GLuint _MaxElement; +}; + + +/** + * Vertex array state + */ +struct gl_array_attrib +{ + /** Currently bound array object. See _mesa_BindVertexArrayAPPLE() */ + struct gl_array_object *ArrayObj; + + /** The default vertex array object */ + struct gl_array_object *DefaultArrayObj; + + /** Array objects (GL_ARB/APPLE_vertex_array_object) */ + struct _mesa_HashTable *Objects; + + GLint ActiveTexture; /**< Client Active Texture */ + GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */ + GLuint LockCount; /**< GL_EXT_compiled_vertex_array */ + + /** GL 3.1 (slightly different from GL_NV_primitive_restart) */ + GLboolean PrimitiveRestart; + GLuint RestartIndex; + + GLbitfield NewState; /**< mask of _NEW_ARRAY_* values */ + + /* GL_ARB_vertex_buffer_object */ + struct gl_buffer_object *ArrayBufferObj; + struct gl_buffer_object *ElementArrayBufferObj; +}; + + +/** + * Feedback buffer state + */ +struct gl_feedback +{ + GLenum Type; + GLbitfield _Mask; /**< FB_* bits */ + GLfloat *Buffer; + GLuint BufferSize; + GLuint Count; +}; + + +/** + * Selection buffer state + */ +struct gl_selection +{ + GLuint *Buffer; /**< selection buffer */ + GLuint BufferSize; /**< size of the selection buffer */ + GLuint BufferCount; /**< number of values in the selection buffer */ + GLuint Hits; /**< number of records in the selection buffer */ + GLuint NameStackDepth; /**< name stack depth */ + GLuint NameStack[MAX_NAME_STACK_DEPTH]; /**< name stack */ + GLboolean HitFlag; /**< hit flag */ + GLfloat HitMinZ; /**< minimum hit depth */ + GLfloat HitMaxZ; /**< maximum hit depth */ +}; + + +/** + * 1-D Evaluator control points + */ +struct gl_1d_map +{ + GLuint Order; /**< Number of control points */ + GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */ + GLfloat *Points; /**< Points to contiguous control points */ +}; + + +/** + * 2-D Evaluator control points + */ +struct gl_2d_map +{ + GLuint Uorder; /**< Number of control points in U dimension */ + GLuint Vorder; /**< Number of control points in V dimension */ + GLfloat u1, u2, du; + GLfloat v1, v2, dv; + GLfloat *Points; /**< Points to contiguous control points */ +}; + + +/** + * All evaluator control point state + */ +struct gl_evaluators +{ + /** + * \name 1-D maps + */ + /*@{*/ + struct gl_1d_map Map1Vertex3; + struct gl_1d_map Map1Vertex4; + struct gl_1d_map Map1Index; + struct gl_1d_map Map1Color4; + struct gl_1d_map Map1Normal; + struct gl_1d_map Map1Texture1; + struct gl_1d_map Map1Texture2; + struct gl_1d_map Map1Texture3; + struct gl_1d_map Map1Texture4; + struct gl_1d_map Map1Attrib[16]; /**< GL_NV_vertex_program */ + /*@}*/ + + /** + * \name 2-D maps + */ + /*@{*/ + struct gl_2d_map Map2Vertex3; + struct gl_2d_map Map2Vertex4; + struct gl_2d_map Map2Index; + struct gl_2d_map Map2Color4; + struct gl_2d_map Map2Normal; + struct gl_2d_map Map2Texture1; + struct gl_2d_map Map2Texture2; + struct gl_2d_map Map2Texture3; + struct gl_2d_map Map2Texture4; + struct gl_2d_map Map2Attrib[16]; /**< GL_NV_vertex_program */ + /*@}*/ +}; + + +/** + * Names of the various vertex/fragment program register files, etc. + * + * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c) + * All values should fit in a 4-bit field. + * + * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM, + * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to + * be "uniform" variables since they can only be set outside glBegin/End. + * They're also all stored in the same Parameters array. + */ +typedef enum +{ + PROGRAM_TEMPORARY, /**< machine->Temporary[] */ + PROGRAM_INPUT, /**< machine->Inputs[] */ + PROGRAM_OUTPUT, /**< machine->Outputs[] */ + PROGRAM_VARYING, /**< machine->Inputs[]/Outputs[] */ + PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */ + PROGRAM_ENV_PARAM, /**< gl_program->Parameters[] */ + PROGRAM_STATE_VAR, /**< gl_program->Parameters[] */ + PROGRAM_NAMED_PARAM, /**< gl_program->Parameters[] */ + PROGRAM_CONSTANT, /**< gl_program->Parameters[] */ + PROGRAM_UNIFORM, /**< gl_program->Parameters[] */ + PROGRAM_WRITE_ONLY, /**< A dummy, write-only register */ + PROGRAM_ADDRESS, /**< machine->AddressReg */ + PROGRAM_SAMPLER, /**< for shader samplers, compile-time only */ + PROGRAM_SYSTEM_VALUE,/**< InstanceId, PrimitiveID, etc. */ + PROGRAM_UNDEFINED, /**< Invalid/TBD value */ + PROGRAM_FILE_MAX +} gl_register_file; + + +/** + * If the register file is PROGRAM_SYSTEM_VALUE, the register index will be + * one of these values. + */ +typedef enum +{ + SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */ + SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */ + SYSTEM_VALUE_MAX /**< Number of values */ +} gl_system_value; + + +/** Vertex and fragment instructions */ +struct prog_instruction; +struct gl_program_parameter_list; +struct gl_uniform_list; + + +/** + * Base class for any kind of program object + */ +struct gl_program +{ + GLuint Id; + GLubyte *String; /**< Null-terminated program text */ + GLint RefCount; + GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */ + GLenum Format; /**< String encoding format */ + GLboolean Resident; + + struct prog_instruction *Instructions; + + GLbitfield InputsRead; /**< Bitmask of which input regs are read */ + GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */ + GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */ + GLbitfield InputFlags[MAX_PROGRAM_INPUTS]; /**< PROG_PARAM_BIT_x flags */ + GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */ + GLbitfield TexturesUsed[MAX_TEXTURE_UNITS]; /**< TEXTURE_x_BIT bitmask */ + GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */ + GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */ + + + /** Named parameters, constants, etc. from program text */ + struct gl_program_parameter_list *Parameters; + /** Numbered local parameters */ + GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4]; + + /** Vertex/fragment shader varying vars */ + struct gl_program_parameter_list *Varying; + /** Vertex program user-defined attributes */ + struct gl_program_parameter_list *Attributes; + + /** Map from sampler unit to texture unit (set by glUniform1i()) */ + GLubyte SamplerUnits[MAX_SAMPLERS]; + /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */ + gl_texture_index SamplerTargets[MAX_SAMPLERS]; + + /** Bitmask of which register files are read/written with indirect + * addressing. Mask of (1 << PROGRAM_x) bits. + */ + GLbitfield IndirectRegisterFiles; + + /** Logical counts */ + /*@{*/ + GLuint NumInstructions; + GLuint NumTemporaries; + GLuint NumParameters; + GLuint NumAttributes; + GLuint NumAddressRegs; + GLuint NumAluInstructions; + GLuint NumTexInstructions; + GLuint NumTexIndirections; + /*@}*/ + /** Native, actual h/w counts */ + /*@{*/ + GLuint NumNativeInstructions; + GLuint NumNativeTemporaries; + GLuint NumNativeParameters; + GLuint NumNativeAttributes; + GLuint NumNativeAddressRegs; + GLuint NumNativeAluInstructions; + GLuint NumNativeTexInstructions; + GLuint NumNativeTexIndirections; + /*@}*/ +}; + + +/** Vertex program object */ +struct gl_vertex_program +{ + struct gl_program Base; /**< base class */ + GLboolean IsNVProgram; /**< is this a GL_NV_vertex_program program? */ + GLboolean IsPositionInvariant; +}; + + +/** Geometry program object */ +struct gl_geometry_program +{ + struct gl_program Base; /**< base class */ + + GLint VerticesOut; + GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB, + GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */ + GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */ +}; + + +/** Fragment program object */ +struct gl_fragment_program +{ + struct gl_program Base; /**< base class */ + GLenum FogOption; + GLboolean UsesKill; /**< shader uses KIL instruction */ + GLboolean OriginUpperLeft; + GLboolean PixelCenterInteger; + enum gl_frag_depth_layout FragDepthLayout; +}; + + +/** + * State common to vertex and fragment programs. + */ +struct gl_program_state +{ + GLint ErrorPos; /* GL_PROGRAM_ERROR_POSITION_ARB/NV */ + const char *ErrorString; /* GL_PROGRAM_ERROR_STRING_ARB/NV */ +}; + + +/** + * Context state for vertex programs. + */ +struct gl_vertex_program_state +{ + GLboolean Enabled; /**< User-set GL_VERTEX_PROGRAM_ARB/NV flag */ + GLboolean _Enabled; /**< Enabled and _valid_ user program? */ + GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */ + GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */ + struct gl_vertex_program *Current; /**< User-bound vertex program */ + + /** Currently enabled and valid vertex program (including internal + * programs, user-defined vertex programs and GLSL vertex shaders). + * This is the program we must use when rendering. + */ + struct gl_vertex_program *_Current; + + GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ + + /* For GL_NV_vertex_program only: */ + GLenum TrackMatrix[MAX_PROGRAM_ENV_PARAMS / 4]; + GLenum TrackMatrixTransform[MAX_PROGRAM_ENV_PARAMS / 4]; + + /** Should fixed-function T&L be implemented with a vertex prog? */ + GLboolean _MaintainTnlProgram; + + /** Program to emulate fixed-function T&L (see above) */ + struct gl_vertex_program *_TnlProgram; + + /** Cache of fixed-function programs */ + struct gl_program_cache *Cache; + + GLboolean _Overriden; +}; + + +/** + * Context state for geometry programs. + */ +struct gl_geometry_program_state +{ + GLboolean Enabled; /**< GL_ARB_GEOMETRY_SHADER4 */ + GLboolean _Enabled; /**< Enabled and valid program? */ + struct gl_geometry_program *Current; /**< user-bound geometry program */ + + /** Currently enabled and valid program (including internal programs + * and compiled shader programs). + */ + struct gl_geometry_program *_Current; + + GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ + + /** Cache of fixed-function programs */ + struct gl_program_cache *Cache; +}; + +/** + * Context state for fragment programs. + */ +struct gl_fragment_program_state +{ + GLboolean Enabled; /**< User-set fragment program enable flag */ + GLboolean _Enabled; /**< Enabled and _valid_ user program? */ + struct gl_fragment_program *Current; /**< User-bound fragment program */ + + /** Currently enabled and valid fragment program (including internal + * programs, user-defined fragment programs and GLSL fragment shaders). + * This is the program we must use when rendering. + */ + struct gl_fragment_program *_Current; + + GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ + + /** Should fixed-function texturing be implemented with a fragment prog? */ + GLboolean _MaintainTexEnvProgram; + + /** Program to emulate fixed-function texture env/combine (see above) */ + struct gl_fragment_program *_TexEnvProgram; + + /** Cache of fixed-function programs */ + struct gl_program_cache *Cache; +}; + + +/** + * ATI_fragment_shader runtime state + */ +#define ATI_FS_INPUT_PRIMARY 0 +#define ATI_FS_INPUT_SECONDARY 1 + +struct atifs_instruction; +struct atifs_setupinst; + +/** + * ATI fragment shader + */ +struct ati_fragment_shader +{ + GLuint Id; + GLint RefCount; + struct atifs_instruction *Instructions[2]; + struct atifs_setupinst *SetupInst[2]; + GLfloat Constants[8][4]; + GLbitfield LocalConstDef; /**< Indicates which constants have been set */ + GLubyte numArithInstr[2]; + GLubyte regsAssigned[2]; + GLubyte NumPasses; /**< 1 or 2 */ + GLubyte cur_pass; + GLubyte last_optype; + GLboolean interpinp1; + GLboolean isValid; + GLuint swizzlerq; +}; + +/** + * Context state for GL_ATI_fragment_shader + */ +struct gl_ati_fragment_shader_state +{ + GLboolean Enabled; + GLboolean _Enabled; /**< enabled and valid shader? */ + GLboolean Compiling; + GLfloat GlobalConstants[8][4]; + struct ati_fragment_shader *Current; +}; + + +/** + * Occlusion/timer query object. + */ +struct gl_query_object +{ + GLenum Target; /**< The query target, when active */ + GLuint Id; /**< hash table ID/name */ + GLuint64EXT Result; /**< the counter */ + GLboolean Active; /**< inside Begin/EndQuery */ + GLboolean Ready; /**< result is ready? */ +}; + + +/** + * Context state for query objects. + */ +struct gl_query_state +{ + struct _mesa_HashTable *QueryObjects; + struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */ + struct gl_query_object *CurrentTimerObject; /* GL_EXT_timer_query */ + + /** GL_NV_conditional_render */ + struct gl_query_object *CondRenderQuery; + + /** GL_EXT_transform_feedback */ + struct gl_query_object *PrimitivesGenerated; + struct gl_query_object *PrimitivesWritten; + + /** GL_ARB_timer_query */ + struct gl_query_object *TimeElapsed; + + GLenum CondRenderMode; +}; + + +/** Sync object state */ +struct gl_sync_object { + struct simple_node link; + GLenum Type; /**< GL_SYNC_FENCE */ + GLuint Name; /**< Fence name */ + GLint RefCount; /**< Reference count */ + GLboolean DeletePending; /**< Object was deleted while there were still + * live references (e.g., sync not yet finished) + */ + GLenum SyncCondition; + GLbitfield Flags; /**< Flags passed to glFenceSync */ + GLuint StatusFlag:1; /**< Has the sync object been signaled? */ +}; + + +/** Set by #pragma directives */ +struct gl_sl_pragmas +{ + GLboolean IgnoreOptimize; /**< ignore #pragma optimize(on/off) ? */ + GLboolean IgnoreDebug; /**< ignore #pragma debug(on/off) ? */ + GLboolean Optimize; /**< defaults on */ + GLboolean Debug; /**< defaults off */ +}; + + +/** + * A GLSL vertex or fragment shader object. + */ +struct gl_shader +{ + GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB (first field!) */ + GLuint Name; /**< AKA the handle */ + GLint RefCount; /**< Reference count */ + GLboolean DeletePending; + GLboolean CompileStatus; + const GLchar *Source; /**< Source code string */ + GLuint SourceChecksum; /**< for debug/logging purposes */ + struct gl_program *Program; /**< Post-compile assembly code */ + GLchar *InfoLog; + struct gl_sl_pragmas Pragmas; + + unsigned Version; /**< GLSL version used for linking */ + + struct exec_list *ir; + struct glsl_symbol_table *symbols; + + /** Shaders containing built-in functions that are used for linking. */ + struct gl_shader *builtins_to_link[16]; + unsigned num_builtins_to_link; +}; + + +/** + * A GLSL program object. + * Basically a linked collection of vertex and fragment shaders. + */ +struct gl_shader_program +{ + GLenum Type; /**< Always GL_SHADER_PROGRAM (internal token) */ + GLuint Name; /**< aka handle or ID */ + GLint RefCount; /**< Reference count */ + GLboolean DeletePending; + + GLuint NumShaders; /**< number of attached shaders */ + struct gl_shader **Shaders; /**< List of attached the shaders */ + + /** User-defined attribute bindings (glBindAttribLocation) */ + struct gl_program_parameter_list *Attributes; + + /** Transform feedback varyings */ + struct { + GLenum BufferMode; + GLuint NumVarying; + GLchar **VaryingNames; /**< Array [NumVarying] of char * */ + } TransformFeedback; + + /** Geometry shader state - copied into gl_geometry_program at link time */ + struct { + GLint VerticesOut; + GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB, + GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */ + GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */ + } Geom; + + /* post-link info: */ + struct gl_vertex_program *VertexProgram; /**< Linked vertex program */ + struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */ + struct gl_geometry_program *GeometryProgram; /**< Linked geometry prog */ + struct gl_uniform_list *Uniforms; + struct gl_program_parameter_list *Varying; + GLboolean LinkStatus; /**< GL_LINK_STATUS */ + GLboolean Validated; + GLboolean _Used; /**< Ever used for drawing? */ + GLchar *InfoLog; + + unsigned Version; /**< GLSL version used for linking */ + + /** + * Per-stage shaders resulting from the first stage of linking. + * + * Set of linked shaders for this program. The array is accessed using the + * \c MESA_SHADER_* defines. Entries for non-existent stages will be + * \c NULL. + */ + struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES]; +}; + + +#define GLSL_DUMP 0x1 /**< Dump shaders to stdout */ +#define GLSL_LOG 0x2 /**< Write shaders to files */ +#define GLSL_OPT 0x4 /**< Force optimizations (override pragmas) */ +#define GLSL_NO_OPT 0x8 /**< Force no optimizations (override pragmas) */ +#define GLSL_UNIFORMS 0x10 /**< Print glUniform calls */ +#define GLSL_NOP_VERT 0x20 /**< Force no-op vertex shaders */ +#define GLSL_NOP_FRAG 0x40 /**< Force no-op fragment shaders */ +#define GLSL_USE_PROG 0x80 /**< Log glUseProgram calls */ + + +/** + * Context state for GLSL vertex/fragment shaders. + */ +struct gl_shader_state +{ + /** + * Programs used for rendering + * + * There is a separate program set for each shader stage. If + * GL_EXT_separate_shader_objects is not supported, each of these must point + * to \c NULL or to the same program. + */ + struct gl_shader_program *CurrentVertexProgram; + struct gl_shader_program *CurrentGeometryProgram; + struct gl_shader_program *CurrentFragmentProgram; + + /** + * Program used by glUniform calls. + * + * Explicitly set by \c glUseProgram and \c glActiveProgramEXT. + */ + struct gl_shader_program *ActiveProgram; + + void *MemPool; + + GLbitfield Flags; /**< Mask of GLSL_x flags */ +}; + +/** + * Compiler options for a single GLSL shaders type + */ +struct gl_shader_compiler_options +{ + /** Driver-selectable options: */ + GLboolean EmitCondCodes; /**< Use condition codes? */ + GLboolean EmitNVTempInitialization; /**< 0-fill NV temp registers */ + /** + * Attempts to flatten all ir_if (OPCODE_IF) for GPUs that can't + * support control flow. + */ + GLboolean EmitNoIfs; + GLboolean EmitNoLoops; + GLboolean EmitNoFunctions; + GLboolean EmitNoCont; /**< Emit CONT opcode? */ + GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */ + GLboolean EmitNoNoise; /**< Emit NOISE opcodes? */ + GLboolean EmitNoPow; /**< Emit POW opcodes? */ + + /** + * \name Forms of indirect addressing the driver cannot do. + */ + /*@{*/ + GLboolean EmitNoIndirectInput; /**< No indirect addressing of inputs */ + GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */ + GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */ + GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */ + /*@}*/ + + GLuint MaxUnrollIterations; + + struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */ +}; + +/** + * Transform feedback object state + */ +struct gl_transform_feedback_object +{ + GLuint Name; /**< AKA the object ID */ + GLint RefCount; + GLboolean Active; /**< Is transform feedback enabled? */ + GLboolean Paused; /**< Is transform feedback paused? */ + + /** The feedback buffers */ + GLuint BufferNames[MAX_FEEDBACK_ATTRIBS]; + struct gl_buffer_object *Buffers[MAX_FEEDBACK_ATTRIBS]; + + /** Start of feedback data in dest buffer */ + GLintptr Offset[MAX_FEEDBACK_ATTRIBS]; + /** Max data to put into dest buffer (in bytes) */ + GLsizeiptr Size[MAX_FEEDBACK_ATTRIBS]; +}; + + +/** + * Context state for transform feedback. + */ +struct gl_transform_feedback +{ + GLenum Mode; /**< GL_POINTS, GL_LINES or GL_TRIANGLES */ + + GLboolean RasterDiscard; /**< GL_RASTERIZER_DISCARD */ + + /** The general binding point (GL_TRANSFORM_FEEDBACK_BUFFER) */ + struct gl_buffer_object *CurrentBuffer; + + /** The table of all transform feedback objects */ + struct _mesa_HashTable *Objects; + + /** The current xform-fb object (GL_TRANSFORM_FEEDBACK_BINDING) */ + struct gl_transform_feedback_object *CurrentObject; + + /** The default xform-fb object (Name==0) */ + struct gl_transform_feedback_object *DefaultObject; +}; + + + +/** + * State which can be shared by multiple contexts: + */ +struct gl_shared_state +{ + _glthread_Mutex Mutex; /**< for thread safety */ + GLint RefCount; /**< Reference count */ + struct _mesa_HashTable *DisplayList; /**< Display lists hash table */ + struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */ + + /** Default texture objects (shared by all texture units) */ + struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS]; + + /** Fallback texture used when a bound texture is incomplete */ + struct gl_texture_object *FallbackTex; + + /** + * \name Thread safety and statechange notification for texture + * objects. + * + * \todo Improve the granularity of locking. + */ + /*@{*/ + _glthread_Mutex TexMutex; /**< texobj thread safety */ + GLuint TextureStateStamp; /**< state notification for shared tex */ + /*@}*/ + + /** Default buffer object for vertex arrays that aren't in VBOs */ + struct gl_buffer_object *NullBufferObj; + + /** + * \name Vertex/geometry/fragment programs + */ + /*@{*/ + struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */ + struct gl_vertex_program *DefaultVertexProgram; + struct gl_fragment_program *DefaultFragmentProgram; + struct gl_geometry_program *DefaultGeometryProgram; + /*@}*/ + + /* GL_ATI_fragment_shader */ + struct _mesa_HashTable *ATIShaders; + struct ati_fragment_shader *DefaultFragmentShader; + + struct _mesa_HashTable *BufferObjects; + + /** Table of both gl_shader and gl_shader_program objects */ + struct _mesa_HashTable *ShaderObjects; + + /* GL_EXT_framebuffer_object */ + struct _mesa_HashTable *RenderBuffers; + struct _mesa_HashTable *FrameBuffers; + + /* GL_ARB_sync */ + struct simple_node SyncObjects; + + void *DriverData; /**< Device driver shared state */ +}; + + + + +/** + * A renderbuffer stores colors or depth values or stencil values. + * A framebuffer object will have a collection of these. + * Data are read/written to the buffer with a handful of Get/Put functions. + * + * Instances of this object are allocated with the Driver's NewRenderbuffer + * hook. Drivers will likely wrap this class inside a driver-specific + * class to simulate inheritance. + */ +struct gl_renderbuffer +{ +#define RB_MAGIC 0xaabbccdd + int Magic; /** XXX TEMPORARY DEBUG INFO */ + _glthread_Mutex Mutex; /**< for thread safety */ + GLuint ClassID; /**< Useful for drivers */ + GLuint Name; + GLint RefCount; + GLuint Width, Height; + GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ + + GLenum InternalFormat; /**< The user-specified format */ + GLenum _BaseFormat; /**< Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or + GL_STENCIL_INDEX. */ + GLuint Format; /**< The actual format: MESA_FORMAT_x */ + + GLubyte NumSamples; + + GLenum DataType; /**< Type of values passed to the Get/Put functions */ + GLvoid *Data; /**< This may not be used by some kinds of RBs */ + + /* Used to wrap one renderbuffer around another: */ + struct gl_renderbuffer *Wrapped; + + /* Delete this renderbuffer */ + void (*Delete)(struct gl_renderbuffer *rb); + + /* Allocate new storage for this renderbuffer */ + GLboolean (*AllocStorage)(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height); + + /* Lock/Unlock are called before/after calling the Get/Put functions. + * Not sure this is the right place for these yet. + void (*Lock)(struct gl_context *ctx, struct gl_renderbuffer *rb); + void (*Unlock)(struct gl_context *ctx, struct gl_renderbuffer *rb); + */ + + /* Return a pointer to the element/pixel at (x,y). + * Should return NULL if the buffer memory can't be directly addressed. + */ + void *(*GetPointer)(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y); + + /* Get/Read a row of values. + * The values will be of format _BaseFormat and type DataType. + */ + void (*GetRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values); + + /* Get/Read values at arbitrary locations. + * The values will be of format _BaseFormat and type DataType. + */ + void (*GetValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values); + + /* Put/Write a row of values. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask); + + /* Put/Write a row of RGB values. This is a special-case routine that's + * only used for RGBA renderbuffers when the source data is GL_RGB. That's + * a common case for glDrawPixels and some triangle routines. + * The values will be of format GL_RGB and type DataType. + */ + void (*PutRowRGB)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask); + + + /* Put/Write a row of identical values. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutMonoRow)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask); + + /* Put/Write values at arbitrary locations. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask); + /* Put/Write identical values at arbitrary locations. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutMonoValues)(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask); +}; + + +/** + * A renderbuffer attachment points to either a texture object (and specifies + * a mipmap level, cube face or 3D texture slice) or points to a renderbuffer. + */ +struct gl_renderbuffer_attachment +{ + GLenum Type; /**< \c GL_NONE or \c GL_TEXTURE or \c GL_RENDERBUFFER_EXT */ + GLboolean Complete; + + /** + * If \c Type is \c GL_RENDERBUFFER_EXT, this stores a pointer to the + * application supplied renderbuffer object. + */ + struct gl_renderbuffer *Renderbuffer; + + /** + * If \c Type is \c GL_TEXTURE, this stores a pointer to the application + * supplied texture object. + */ + struct gl_texture_object *Texture; + GLuint TextureLevel; /**< Attached mipmap level. */ + GLuint CubeMapFace; /**< 0 .. 5, for cube map textures. */ + GLuint Zoffset; /**< Slice for 3D textures, or layer for both 1D + * and 2D array textures */ +}; + + +/** + * A framebuffer is a collection of renderbuffers (color, depth, stencil, etc). + * In C++ terms, think of this as a base class from which device drivers + * will make derived classes. + */ +struct gl_framebuffer +{ + _glthread_Mutex Mutex; /**< for thread safety */ + /** + * If zero, this is a window system framebuffer. If non-zero, this + * is a FBO framebuffer; note that for some devices (i.e. those with + * a natural pixel coordinate system for FBOs that differs from the + * OpenGL/Mesa coordinate system), this means that the viewport, + * polygon face orientation, and polygon stipple will have to be inverted. + */ + GLuint Name; + + GLint RefCount; + GLboolean DeletePending; + + /** + * The framebuffer's visual. Immutable if this is a window system buffer. + * Computed from attachments if user-made FBO. + */ + struct gl_config Visual; + + GLboolean Initialized; + + GLuint Width, Height; /**< size of frame buffer in pixels */ + + /** \name Drawing bounds (Intersection of buffer size and scissor box) */ + /*@{*/ + GLint _Xmin, _Xmax; /**< inclusive */ + GLint _Ymin, _Ymax; /**< exclusive */ + /*@}*/ + + /** \name Derived Z buffer stuff */ + /*@{*/ + GLuint _DepthMax; /**< Max depth buffer value */ + GLfloat _DepthMaxF; /**< Float max depth buffer value */ + GLfloat _MRD; /**< minimum resolvable difference in Z values */ + /*@}*/ + + /** One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */ + GLenum _Status; + + /** Integer color values */ + GLboolean _IntegerColor; + + /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */ + struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT]; + + /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER + * attribute group and GL_PIXEL attribute group, respectively. + */ + GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS]; + GLenum ColorReadBuffer; + + /** Computed from ColorDraw/ReadBuffer above */ + GLuint _NumColorDrawBuffers; + GLint _ColorDrawBufferIndexes[MAX_DRAW_BUFFERS]; /**< BUFFER_x or -1 */ + GLint _ColorReadBufferIndex; /* -1 = None */ + struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS]; + struct gl_renderbuffer *_ColorReadBuffer; + + /** The Actual depth/stencil buffers to use. May be wrappers around the + * depth/stencil buffers attached above. */ + struct gl_renderbuffer *_DepthBuffer; + struct gl_renderbuffer *_StencilBuffer; + + /** Delete this framebuffer */ + void (*Delete)(struct gl_framebuffer *fb); +}; + + +/** + * Precision info for shader datatypes. See glGetShaderPrecisionFormat(). + */ +struct gl_precision +{ + GLushort RangeMin; /**< min value exponent */ + GLushort RangeMax; /**< max value exponent */ + GLushort Precision; /**< number of mantissa bits */ +}; + + +/** + * Limits for vertex and fragment programs/shaders. + */ +struct gl_program_constants +{ + /* logical limits */ + GLuint MaxInstructions; + GLuint MaxAluInstructions; + GLuint MaxTexInstructions; + GLuint MaxTexIndirections; + GLuint MaxAttribs; + GLuint MaxTemps; + GLuint MaxAddressRegs; + GLuint MaxParameters; + GLuint MaxLocalParams; + GLuint MaxEnvParams; + /* native/hardware limits */ + GLuint MaxNativeInstructions; + GLuint MaxNativeAluInstructions; + GLuint MaxNativeTexInstructions; + GLuint MaxNativeTexIndirections; + GLuint MaxNativeAttribs; + GLuint MaxNativeTemps; + GLuint MaxNativeAddressRegs; + GLuint MaxNativeParameters; + /* For shaders */ + GLuint MaxUniformComponents; + /* GL_ARB_geometry_shader4 */ + GLuint MaxGeometryTextureImageUnits; + GLuint MaxGeometryVaryingComponents; + GLuint MaxVertexVaryingComponents; + GLuint MaxGeometryUniformComponents; + GLuint MaxGeometryOutputVertices; + GLuint MaxGeometryTotalOutputComponents; + /* ES 2.0 and GL_ARB_ES2_compatibility */ + struct gl_precision LowFloat, MediumFloat, HighFloat; + struct gl_precision LowInt, MediumInt, HighInt; +}; + + +/** + * Constants which may be overridden by device driver during context creation + * but are never changed after that. + */ +struct gl_constants +{ + GLint MaxTextureMbytes; /**< Max memory per image, in MB */ + GLint MaxTextureLevels; /**< Max mipmap levels. */ + GLint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */ + GLint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */ + GLint MaxArrayTextureLayers; /**< Max layers in array textures */ + GLint MaxTextureRectSize; /**< Max rectangle texture size, in pixes */ + GLuint MaxTextureCoordUnits; + GLuint MaxTextureImageUnits; + GLuint MaxVertexTextureImageUnits; + GLuint MaxCombinedTextureImageUnits; + GLuint MaxTextureUnits; /**< = MIN(CoordUnits, ImageUnits) */ + GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ + GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */ + + GLuint MaxArrayLockSize; + + GLint SubPixelBits; + + GLfloat MinPointSize, MaxPointSize; /**< aliased */ + GLfloat MinPointSizeAA, MaxPointSizeAA; /**< antialiased */ + GLfloat PointSizeGranularity; + GLfloat MinLineWidth, MaxLineWidth; /**< aliased */ + GLfloat MinLineWidthAA, MaxLineWidthAA; /**< antialiased */ + GLfloat LineWidthGranularity; + + GLuint MaxColorTableSize; + + GLuint MaxClipPlanes; + GLuint MaxLights; + GLfloat MaxShininess; /**< GL_NV_light_max_exponent */ + GLfloat MaxSpotExponent; /**< GL_NV_light_max_exponent */ + + GLuint MaxViewportWidth, MaxViewportHeight; + + struct gl_program_constants VertexProgram; /**< GL_ARB_vertex_program */ + struct gl_program_constants FragmentProgram; /**< GL_ARB_fragment_program */ + struct gl_program_constants GeometryProgram; /**< GL_ARB_geometry_shader4 */ + GLuint MaxProgramMatrices; + GLuint MaxProgramMatrixStackDepth; + + /** vertex array / buffer object bounds checking */ + GLboolean CheckArrayBounds; + + GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */ + + GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */ + GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */ + GLuint MaxSamples; /**< GL_ARB_framebuffer_object */ + + GLuint MaxVarying; /**< Number of float[4] varying parameters */ + + GLuint GLSLVersion; /**< GLSL version supported (ex: 120 = 1.20) */ + + /** Which texture units support GL_ATI_envmap_bumpmap as targets */ + GLbitfield SupportedBumpUnits; + + /** + * Maximum amount of time, measured in nanseconds, that the server can wait. + */ + GLuint64 MaxServerWaitTimeout; + + /** GL_EXT_provoking_vertex */ + GLboolean QuadsFollowProvokingVertexConvention; + + /** OpenGL version 3.0 */ + GLbitfield ContextFlags; /**< Ex: GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT */ + + /** OpenGL version 3.2 */ + GLbitfield ProfileMask; /**< Mask of CONTEXT_x_PROFILE_BIT */ + + /** GL_EXT_transform_feedback */ + GLuint MaxTransformFeedbackSeparateAttribs; + GLuint MaxTransformFeedbackSeparateComponents; + GLuint MaxTransformFeedbackInterleavedComponents; + + /** GL_EXT_gpu_shader4 */ + GLint MinProgramTexelOffset, MaxProgramTexelOffset; + + /* GL_EXT_framebuffer_sRGB */ + GLboolean sRGBCapable; /* can enable sRGB blend/update on FBOs */ +}; + + +/** + * Enable flag for each OpenGL extension. Different device drivers will + * enable different extensions at runtime. + */ +struct gl_extensions +{ + GLboolean dummy; /* don't remove this! */ + GLboolean dummy_true; /* Set true by _mesa_init_extensions(). */ + GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */ + GLboolean ARB_ES2_compatibility; + GLboolean ARB_blend_func_extended; + GLboolean ARB_copy_buffer; + GLboolean ARB_depth_buffer_float; + GLboolean ARB_depth_clamp; + GLboolean ARB_depth_texture; + GLboolean ARB_draw_buffers; + GLboolean ARB_draw_buffers_blend; + GLboolean ARB_draw_elements_base_vertex; + GLboolean ARB_draw_instanced; + GLboolean ARB_fragment_coord_conventions; + GLboolean ARB_fragment_program; + GLboolean ARB_fragment_program_shadow; + GLboolean ARB_fragment_shader; + GLboolean ARB_framebuffer_object; + GLboolean ARB_explicit_attrib_location; + GLboolean ARB_geometry_shader4; + GLboolean ARB_half_float_pixel; + GLboolean ARB_half_float_vertex; + GLboolean ARB_instanced_arrays; + GLboolean ARB_map_buffer_range; + GLboolean ARB_multisample; + GLboolean ARB_multitexture; + GLboolean ARB_occlusion_query; + GLboolean ARB_occlusion_query2; + GLboolean ARB_point_sprite; + GLboolean ARB_sampler_objects; + GLboolean ARB_seamless_cube_map; + GLboolean ARB_shader_objects; + GLboolean ARB_shader_stencil_export; + GLboolean ARB_shading_language_100; + GLboolean ARB_shadow; + GLboolean ARB_shadow_ambient; + GLboolean ARB_sync; + GLboolean ARB_texture_border_clamp; + GLboolean ARB_texture_buffer_object; + GLboolean ARB_texture_compression; + GLboolean ARB_texture_compression_rgtc; + GLboolean ARB_texture_cube_map; + GLboolean ARB_texture_env_combine; + GLboolean ARB_texture_env_crossbar; + GLboolean ARB_texture_env_dot3; + GLboolean ARB_texture_float; + GLboolean ARB_texture_mirrored_repeat; + GLboolean ARB_texture_multisample; + GLboolean ARB_texture_non_power_of_two; + GLboolean ARB_texture_rg; + GLboolean ARB_texture_rgb10_a2ui; + GLboolean ARB_timer_query; + GLboolean ARB_transform_feedback2; + GLboolean ARB_transpose_matrix; + GLboolean ARB_uniform_buffer_object; + GLboolean ARB_vertex_array_object; + GLboolean ARB_vertex_buffer_object; + GLboolean ARB_vertex_program; + GLboolean ARB_vertex_shader; + GLboolean ARB_vertex_type_2_10_10_10_rev; + GLboolean ARB_window_pos; + GLboolean EXT_abgr; + GLboolean EXT_bgra; + GLboolean EXT_blend_color; + GLboolean EXT_blend_equation_separate; + GLboolean EXT_blend_func_separate; + GLboolean EXT_blend_logic_op; + GLboolean EXT_blend_minmax; + GLboolean EXT_blend_subtract; + GLboolean EXT_clip_volume_hint; + GLboolean EXT_compiled_vertex_array; + GLboolean EXT_copy_texture; + GLboolean EXT_depth_bounds_test; + GLboolean EXT_draw_buffers2; + GLboolean EXT_draw_range_elements; + GLboolean EXT_fog_coord; + GLboolean EXT_framebuffer_blit; + GLboolean EXT_framebuffer_multisample; + GLboolean EXT_framebuffer_object; + GLboolean EXT_framebuffer_sRGB; + GLboolean EXT_gpu_program_parameters; + GLboolean EXT_gpu_shader4; + GLboolean EXT_multi_draw_arrays; + GLboolean EXT_paletted_texture; + GLboolean EXT_packed_depth_stencil; + GLboolean EXT_packed_float; + GLboolean EXT_packed_pixels; + GLboolean EXT_pixel_buffer_object; + GLboolean EXT_point_parameters; + GLboolean EXT_polygon_offset; + GLboolean EXT_provoking_vertex; + GLboolean EXT_rescale_normal; + GLboolean EXT_shadow_funcs; + GLboolean EXT_secondary_color; + GLboolean EXT_separate_shader_objects; + GLboolean EXT_separate_specular_color; + GLboolean EXT_shared_texture_palette; + GLboolean EXT_stencil_wrap; + GLboolean EXT_stencil_two_side; + GLboolean EXT_subtexture; + GLboolean EXT_texture; + GLboolean EXT_texture_object; + GLboolean EXT_texture3D; + GLboolean EXT_texture_array; + GLboolean EXT_texture_compression_s3tc; + GLboolean EXT_texture_env_add; + GLboolean EXT_texture_env_combine; + GLboolean EXT_texture_env_dot3; + GLboolean EXT_texture_filter_anisotropic; + GLboolean EXT_texture_integer; + GLboolean EXT_texture_lod_bias; + GLboolean EXT_texture_mirror_clamp; + GLboolean EXT_texture_shared_exponent; + GLboolean EXT_texture_sRGB; + GLboolean EXT_texture_sRGB_decode; + GLboolean EXT_texture_swizzle; + GLboolean EXT_transform_feedback; + GLboolean EXT_timer_query; + GLboolean EXT_vertex_array; + GLboolean EXT_vertex_array_bgra; + GLboolean EXT_vertex_array_set; + GLboolean OES_standard_derivatives; + /* vendor extensions */ + GLboolean AMD_conservative_depth; + GLboolean APPLE_client_storage; + GLboolean APPLE_packed_pixels; + GLboolean APPLE_vertex_array_object; + GLboolean APPLE_object_purgeable; + GLboolean ATI_envmap_bumpmap; + GLboolean ATI_texture_mirror_once; + GLboolean ATI_texture_env_combine3; + GLboolean ATI_fragment_shader; + GLboolean ATI_separate_stencil; + GLboolean IBM_rasterpos_clip; + GLboolean IBM_multimode_draw_arrays; + GLboolean MESA_pack_invert; + GLboolean MESA_resize_buffers; + GLboolean MESA_ycbcr_texture; + GLboolean MESA_texture_array; + GLboolean MESA_texture_signed_rgba; + GLboolean NV_blend_square; + GLboolean NV_conditional_render; + GLboolean NV_fragment_program; + GLboolean NV_fragment_program_option; + GLboolean NV_light_max_exponent; + GLboolean NV_point_sprite; + GLboolean NV_primitive_restart; + GLboolean NV_texgen_reflection; + GLboolean NV_texture_env_combine4; + GLboolean NV_texture_rectangle; + GLboolean NV_vertex_program; + GLboolean NV_vertex_program1_1; + GLboolean OES_read_format; + GLboolean SGI_texture_color_table; + GLboolean SGIS_generate_mipmap; + GLboolean SGIS_texture_edge_clamp; + GLboolean SGIS_texture_lod; + GLboolean TDFX_texture_compression_FXT1; + GLboolean S3_s3tc; + GLboolean OES_EGL_image; + GLboolean OES_draw_texture; + GLboolean EXT_texture_format_BGRA8888; + GLboolean extension_sentinel; + /** The extension string */ + const GLubyte *String; + /** Number of supported extensions */ + GLuint Count; +}; + + +/** + * A stack of matrices (projection, modelview, color, texture, etc). + */ +struct gl_matrix_stack +{ + GLmatrix *Top; /**< points into Stack */ + GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */ + GLuint Depth; /**< 0 <= Depth < MaxDepth */ + GLuint MaxDepth; /**< size of Stack[] array */ + GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */ +}; + + +/** + * \name Bits for image transfer operations + * \sa __struct gl_contextRec::ImageTransferState. + */ +/*@{*/ +#define IMAGE_SCALE_BIAS_BIT 0x1 +#define IMAGE_SHIFT_OFFSET_BIT 0x2 +#define IMAGE_MAP_COLOR_BIT 0x4 +#define IMAGE_CLAMP_BIT 0x800 + + +/** Pixel Transfer ops */ +#define IMAGE_BITS (IMAGE_SCALE_BIAS_BIT | \ + IMAGE_SHIFT_OFFSET_BIT | \ + IMAGE_MAP_COLOR_BIT) + +/** + * \name Bits to indicate what state has changed. + */ +/*@{*/ +#define _NEW_MODELVIEW (1 << 0) /**< gl_context::ModelView */ +#define _NEW_PROJECTION (1 << 1) /**< gl_context::Projection */ +#define _NEW_TEXTURE_MATRIX (1 << 2) /**< gl_context::TextureMatrix */ +#define _NEW_COLOR (1 << 3) /**< gl_context::Color */ +#define _NEW_DEPTH (1 << 4) /**< gl_context::Depth */ +#define _NEW_EVAL (1 << 5) /**< gl_context::Eval, EvalMap */ +#define _NEW_FOG (1 << 6) /**< gl_context::Fog */ +#define _NEW_HINT (1 << 7) /**< gl_context::Hint */ +#define _NEW_LIGHT (1 << 8) /**< gl_context::Light */ +#define _NEW_LINE (1 << 9) /**< gl_context::Line */ +#define _NEW_PIXEL (1 << 10) /**< gl_context::Pixel */ +#define _NEW_POINT (1 << 11) /**< gl_context::Point */ +#define _NEW_POLYGON (1 << 12) /**< gl_context::Polygon */ +#define _NEW_POLYGONSTIPPLE (1 << 13) /**< gl_context::PolygonStipple */ +#define _NEW_SCISSOR (1 << 14) /**< gl_context::Scissor */ +#define _NEW_STENCIL (1 << 15) /**< gl_context::Stencil */ +#define _NEW_TEXTURE (1 << 16) /**< gl_context::Texture */ +#define _NEW_TRANSFORM (1 << 17) /**< gl_context::Transform */ +#define _NEW_VIEWPORT (1 << 18) /**< gl_context::Viewport */ +#define _NEW_PACKUNPACK (1 << 19) /**< gl_context::Pack, Unpack */ +#define _NEW_ARRAY (1 << 20) /**< gl_context::Array */ +#define _NEW_RENDERMODE (1 << 21) /**< gl_context::RenderMode, etc */ +#define _NEW_BUFFERS (1 << 22) /**< gl_context::Visual, DrawBuffer, */ +#define _NEW_CURRENT_ATTRIB (1 << 23) /**< gl_context::Current */ +#define _NEW_MULTISAMPLE (1 << 24) /**< gl_context::Multisample */ +#define _NEW_TRACK_MATRIX (1 << 25) /**< gl_context::VertexProgram */ +#define _NEW_PROGRAM (1 << 26) /**< New program/shader state */ +#define _NEW_PROGRAM_CONSTANTS (1 << 27) +#define _NEW_BUFFER_OBJECT (1 << 28) +#define _NEW_ALL ~0 +/*@}*/ + + +/** + * \name Bits to track array state changes + * + * Also used to summarize array enabled. + */ +/*@{*/ +#define _NEW_ARRAY_VERTEX VERT_BIT_POS +#define _NEW_ARRAY_WEIGHT VERT_BIT_WEIGHT +#define _NEW_ARRAY_NORMAL VERT_BIT_NORMAL +#define _NEW_ARRAY_COLOR0 VERT_BIT_COLOR0 +#define _NEW_ARRAY_COLOR1 VERT_BIT_COLOR1 +#define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG +#define _NEW_ARRAY_INDEX VERT_BIT_COLOR_INDEX +#define _NEW_ARRAY_EDGEFLAG VERT_BIT_EDGEFLAG +#define _NEW_ARRAY_POINT_SIZE VERT_BIT_COLOR_INDEX /* aliased */ +#define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0 +#define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1 +#define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2 +#define _NEW_ARRAY_TEXCOORD_3 VERT_BIT_TEX3 +#define _NEW_ARRAY_TEXCOORD_4 VERT_BIT_TEX4 +#define _NEW_ARRAY_TEXCOORD_5 VERT_BIT_TEX5 +#define _NEW_ARRAY_TEXCOORD_6 VERT_BIT_TEX6 +#define _NEW_ARRAY_TEXCOORD_7 VERT_BIT_TEX7 +#define _NEW_ARRAY_ATTRIB_0 VERT_BIT_GENERIC0 /* start at bit 16 */ +#define _NEW_ARRAY_ALL 0xffffffff + + +#define _NEW_ARRAY_TEXCOORD(i) (_NEW_ARRAY_TEXCOORD_0 << (i)) +#define _NEW_ARRAY_ATTRIB(i) (_NEW_ARRAY_ATTRIB_0 << (i)) +/*@}*/ + + + +/** + * \name A bunch of flags that we think might be useful to drivers. + * + * Set in the __struct gl_contextRec::_TriangleCaps bitfield. + */ +/*@{*/ +#define DD_FLATSHADE 0x1 +#define DD_SEPARATE_SPECULAR 0x2 +#define DD_TRI_CULL_FRONT_BACK 0x4 /* special case on some hw */ +#define DD_TRI_LIGHT_TWOSIDE 0x8 +#define DD_TRI_UNFILLED 0x10 +#define DD_TRI_SMOOTH 0x20 +#define DD_TRI_STIPPLE 0x40 +#define DD_TRI_OFFSET 0x80 +#define DD_LINE_SMOOTH 0x100 +#define DD_LINE_STIPPLE 0x200 +#define DD_POINT_SMOOTH 0x400 +#define DD_POINT_ATTEN 0x800 +#define DD_TRI_TWOSTENCIL 0x1000 +/*@}*/ + + +/** + * \name Define the state changes under which each of these bits might change + */ +/*@{*/ +#define _DD_NEW_FLATSHADE _NEW_LIGHT +#define _DD_NEW_SEPARATE_SPECULAR (_NEW_LIGHT | _NEW_FOG | _NEW_PROGRAM) +#define _DD_NEW_TRI_CULL_FRONT_BACK _NEW_POLYGON +#define _DD_NEW_TRI_LIGHT_TWOSIDE _NEW_LIGHT +#define _DD_NEW_TRI_UNFILLED _NEW_POLYGON +#define _DD_NEW_TRI_SMOOTH _NEW_POLYGON +#define _DD_NEW_TRI_STIPPLE _NEW_POLYGON +#define _DD_NEW_TRI_OFFSET _NEW_POLYGON +#define _DD_NEW_LINE_SMOOTH _NEW_LINE +#define _DD_NEW_LINE_STIPPLE _NEW_LINE +#define _DD_NEW_LINE_WIDTH _NEW_LINE +#define _DD_NEW_POINT_SMOOTH _NEW_POINT +#define _DD_NEW_POINT_SIZE _NEW_POINT +#define _DD_NEW_POINT_ATTEN _NEW_POINT +/*@}*/ + + +/** + * Composite state flags + */ +/*@{*/ +#define _MESA_NEW_NEED_EYE_COORDS (_NEW_LIGHT | \ + _NEW_TEXTURE | \ + _NEW_POINT | \ + _NEW_PROGRAM | \ + _NEW_MODELVIEW) + +#define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \ + _NEW_TEXTURE) + +#define _MESA_NEW_TRANSFER_STATE (_NEW_PIXEL) +/*@}*/ + + + + +/* This has to be included here. */ +#include "dd.h" + + +/** + * Display list flags. + * Strictly this is a tnl-private concept, but it doesn't seem + * worthwhile adding a tnl private structure just to hold this one bit + * of information: + */ +#define DLIST_DANGLING_REFS 0x1 + + +/** Opaque declaration of display list payload data type */ +union gl_dlist_node; + + +/** + * Provide a location where information about a display list can be + * collected. Could be extended with driverPrivate structures, + * etc. in the future. + */ +struct gl_display_list +{ + GLuint Name; + GLbitfield Flags; /**< DLIST_x flags */ + /** The dlist commands are in a linked list of nodes */ + union gl_dlist_node *Head; +}; + + +/** + * State used during display list compilation and execution. + */ +struct gl_dlist_state +{ + GLuint CallDepth; /**< Current recursion calling depth */ + + struct gl_display_list *CurrentList; /**< List currently being compiled */ + union gl_dlist_node *CurrentBlock; /**< Pointer to current block of nodes */ + GLuint CurrentPos; /**< Index into current block of nodes */ + + GLvertexformat ListVtxfmt; + + GLubyte ActiveAttribSize[VERT_ATTRIB_MAX]; + GLfloat CurrentAttrib[VERT_ATTRIB_MAX][4]; + + GLubyte ActiveMaterialSize[MAT_ATTRIB_MAX]; + GLfloat CurrentMaterial[MAT_ATTRIB_MAX][4]; + + GLubyte ActiveIndex; + GLfloat CurrentIndex; + + GLubyte ActiveEdgeFlag; + GLboolean CurrentEdgeFlag; + + struct { + /* State known to have been set by the currently-compiling display + * list. Used to eliminate some redundant state changes. + */ + GLenum ShadeModel; + } Current; +}; + + +/** + * Enum for the OpenGL APIs we know about and may support. + */ +typedef enum +{ + API_OPENGL, + API_OPENGLES, + API_OPENGLES2 +} gl_api; + + +/** + * Mesa rendering context. + * + * This is the central context data structure for Mesa. Almost all + * OpenGL state is contained in this structure. + * Think of this as a base class from which device drivers will derive + * sub classes. + * + * The struct gl_context typedef names this structure. + */ +struct gl_context +{ + /** State possibly shared with other contexts in the address space */ + struct gl_shared_state *Shared; + + /** \name API function pointer tables */ + /*@{*/ + gl_api API; + struct _glapi_table *Save; /**< Display list save functions */ + struct _glapi_table *Exec; /**< Execute functions */ + struct _glapi_table *CurrentDispatch; /**< == Save or Exec !! */ + /*@}*/ + + struct gl_config Visual; + struct gl_framebuffer *DrawBuffer; /**< buffer for writing */ + struct gl_framebuffer *ReadBuffer; /**< buffer for reading */ + struct gl_framebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */ + struct gl_framebuffer *WinSysReadBuffer; /**< set with MakeCurrent */ + + /** + * Device driver function pointer table + */ + struct dd_function_table Driver; + + void *DriverCtx; /**< Points to device driver context/state */ + + /** Core/Driver constants */ + struct gl_constants Const; + + /** \name The various 4x4 matrix stacks */ + /*@{*/ + struct gl_matrix_stack ModelviewMatrixStack; + struct gl_matrix_stack ProjectionMatrixStack; + struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS]; + struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES]; + struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */ + /*@}*/ + + /** Combined modelview and projection matrix */ + GLmatrix _ModelProjectMatrix; + + /** \name Display lists */ + struct gl_dlist_state ListState; + + GLboolean ExecuteFlag; /**< Execute GL commands? */ + GLboolean CompileFlag; /**< Compile GL commands into display list? */ + + /** Extension information */ + struct gl_extensions Extensions; + + /** Version info */ + GLuint VersionMajor, VersionMinor; + char *VersionString; + + /** \name State attribute stack (for glPush/PopAttrib) */ + /*@{*/ + GLuint AttribStackDepth; + struct gl_attrib_node *AttribStack[MAX_ATTRIB_STACK_DEPTH]; + /*@}*/ + + /** \name Renderer attribute groups + * + * We define a struct for each attribute group to make pushing and popping + * attributes easy. Also it's a good organization. + */ + /*@{*/ + struct gl_accum_attrib Accum; /**< Accum buffer attributes */ + struct gl_colorbuffer_attrib Color; /**< Color buffer attributes */ + struct gl_current_attrib Current; /**< Current attributes */ + struct gl_depthbuffer_attrib Depth; /**< Depth buffer attributes */ + struct gl_eval_attrib Eval; /**< Eval attributes */ + struct gl_fog_attrib Fog; /**< Fog attributes */ + struct gl_hint_attrib Hint; /**< Hint attributes */ + struct gl_light_attrib Light; /**< Light attributes */ + struct gl_line_attrib Line; /**< Line attributes */ + struct gl_list_attrib List; /**< List attributes */ + struct gl_multisample_attrib Multisample; + struct gl_pixel_attrib Pixel; /**< Pixel attributes */ + struct gl_point_attrib Point; /**< Point attributes */ + struct gl_polygon_attrib Polygon; /**< Polygon attributes */ + GLuint PolygonStipple[32]; /**< Polygon stipple */ + struct gl_scissor_attrib Scissor; /**< Scissor attributes */ + struct gl_stencil_attrib Stencil; /**< Stencil buffer attributes */ + struct gl_texture_attrib Texture; /**< Texture attributes */ + struct gl_transform_attrib Transform; /**< Transformation attributes */ + struct gl_viewport_attrib Viewport; /**< Viewport attributes */ + /*@}*/ + + /** \name Client attribute stack */ + /*@{*/ + GLuint ClientAttribStackDepth; + struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH]; + /*@}*/ + + /** \name Client attribute groups */ + /*@{*/ + struct gl_array_attrib Array; /**< Vertex arrays */ + struct gl_pixelstore_attrib Pack; /**< Pixel packing */ + struct gl_pixelstore_attrib Unpack; /**< Pixel unpacking */ + struct gl_pixelstore_attrib DefaultPacking; /**< Default params */ + /*@}*/ + + /** \name Other assorted state (not pushed/popped on attribute stack) */ + /*@{*/ + struct gl_pixelmaps PixelMaps; + + struct gl_evaluators EvalMap; /**< All evaluators */ + struct gl_feedback Feedback; /**< Feedback */ + struct gl_selection Select; /**< Selection */ + + struct gl_program_state Program; /**< general program state */ + struct gl_vertex_program_state VertexProgram; + struct gl_fragment_program_state FragmentProgram; + struct gl_geometry_program_state GeometryProgram; + struct gl_ati_fragment_shader_state ATIFragmentShader; + + struct gl_shader_state Shader; /**< GLSL shader object state */ + struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_TYPES]; + + struct gl_query_state Query; /**< occlusion, timer queries */ + + struct gl_transform_feedback TransformFeedback; + + struct gl_buffer_object *CopyReadBuffer; /**< GL_ARB_copy_buffer */ + struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */ + /*@}*/ + + struct gl_meta_state *Meta; /**< for "meta" operations */ + + /* GL_EXT_framebuffer_object */ + struct gl_renderbuffer *CurrentRenderbuffer; + + GLenum ErrorValue; /**< Last error code */ + + /** + * Recognize and silence repeated error debug messages in buggy apps. + */ + const char *ErrorDebugFmtString; + GLuint ErrorDebugCount; + + GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ + GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ + + GLboolean ViewportInitialized; /**< has viewport size been initialized? */ + + GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */ + + /** \name Derived state */ + /*@{*/ + /** Bitwise-or of DD_* flags. Note that this bitfield may be used before + * state validation so they need to always be current. + */ + GLbitfield _TriangleCaps; + GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */ + GLfloat _EyeZDir[3]; + GLfloat _ModelViewInvScale; + GLboolean _NeedEyeCoords; + GLboolean _ForceEyeCoords; + + GLuint TextureStateTimestamp; /**< detect changes to shared state */ + + struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */ + struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ + /**@}*/ + + struct gl_list_extensions *ListExt; /**< driver dlist extensions */ + + /** \name For debugging/development only */ + /*@{*/ + GLboolean FirstTimeCurrent; + /*@}*/ + + /** Dither disable via MESA_NO_DITHER env var */ + GLboolean NoDither; + + /** software compression/decompression supported or not */ + GLboolean Mesa_DXTn; + + GLboolean TextureFormatSupported[MESA_FORMAT_COUNT]; + + /** + * Use dp4 (rather than mul/mad) instructions for position + * transformation? + */ + GLboolean mvp_with_dp4; + + /** + * \name Hooks for module contexts. + * + * These will eventually live in the driver or elsewhere. + */ + /*@{*/ + void *swrast_context; + void *swsetup_context; + void *swtnl_context; + void *swtnl_im; + struct st_context *st; + void *aelt_context; + /*@}*/ +}; + + +#ifdef DEBUG +extern int MESA_VERBOSE; +extern int MESA_DEBUG_FLAGS; +# define MESA_FUNCTION __FUNCTION__ +#else +# define MESA_VERBOSE 0 +# define MESA_DEBUG_FLAGS 0 +# define MESA_FUNCTION "a function" +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + + +/** The MESA_VERBOSE var is a bitmask of these flags */ +enum _verbose +{ + VERBOSE_VARRAY = 0x0001, + VERBOSE_TEXTURE = 0x0002, + VERBOSE_MATERIAL = 0x0004, + VERBOSE_PIPELINE = 0x0008, + VERBOSE_DRIVER = 0x0010, + VERBOSE_STATE = 0x0020, + VERBOSE_API = 0x0040, + VERBOSE_DISPLAY_LIST = 0x0100, + VERBOSE_LIGHTING = 0x0200, + VERBOSE_PRIMS = 0x0400, + VERBOSE_VERTS = 0x0800, + VERBOSE_DISASSEM = 0x1000, + VERBOSE_DRAW = 0x2000, + VERBOSE_SWAPBUFFERS = 0x4000 +}; + + +/** The MESA_DEBUG_FLAGS var is a bitmask of these flags */ +enum _debug +{ + DEBUG_ALWAYS_FLUSH = 0x1 +}; + + + +#endif /* MTYPES_H */ diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index d0ec23fc8..aa5f007e9 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -1,3267 +1,3270 @@ -/* - * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. - * Copyright (C) 2008 VMware, Inc. All Rights Reserved. - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file ir_to_mesa.cpp - * - * Translate GLSL IR to Mesa's gl_program representation. - */ - -#include -#include "main/compiler.h" -#include "ir.h" -#include "ir_visitor.h" -#include "ir_print_visitor.h" -#include "ir_expression_flattening.h" -#include "glsl_types.h" -#include "glsl_parser_extras.h" -#include "../glsl/program.h" -#include "ir_optimization.h" -#include "ast.h" - -extern "C" { -#include "main/mtypes.h" -#include "main/shaderapi.h" -#include "main/shaderobj.h" -#include "main/uniforms.h" -#include "program/hash_table.h" -#include "program/prog_instruction.h" -#include "program/prog_optimize.h" -#include "program/prog_print.h" -#include "program/program.h" -#include "program/prog_uniform.h" -#include "program/prog_parameter.h" -#include "program/sampler.h" -} - -static int swizzle_for_size(int size); - -/** - * This struct is a corresponding struct to Mesa prog_src_register, with - * wider fields. - */ -typedef struct ir_to_mesa_src_reg { - ir_to_mesa_src_reg(int file, int index, const glsl_type *type) - { - this->file = (gl_register_file) file; - this->index = index; - if (type && (type->is_scalar() || type->is_vector() || type->is_matrix())) - this->swizzle = swizzle_for_size(type->vector_elements); - else - this->swizzle = SWIZZLE_XYZW; - this->negate = 0; - this->reladdr = NULL; - } - - ir_to_mesa_src_reg() - { - this->file = PROGRAM_UNDEFINED; - this->index = 0; - this->swizzle = 0; - this->negate = 0; - this->reladdr = NULL; - } - - gl_register_file file; /**< PROGRAM_* from Mesa */ - int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ - GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ - int negate; /**< NEGATE_XYZW mask from mesa */ - /** Register index should be offset by the integer in this reg. */ - ir_to_mesa_src_reg *reladdr; -} ir_to_mesa_src_reg; - -typedef struct ir_to_mesa_dst_reg { - int file; /**< PROGRAM_* from Mesa */ - int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ - int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ - GLuint cond_mask:4; - /** Register index should be offset by the integer in this reg. */ - ir_to_mesa_src_reg *reladdr; -} ir_to_mesa_dst_reg; - -extern ir_to_mesa_src_reg ir_to_mesa_undef; - -class ir_to_mesa_instruction : public exec_node { -public: - /* Callers of this ralloc-based new need not call delete. It's - * easier to just ralloc_free 'ctx' (or any of its ancestors). */ - static void* operator new(size_t size, void *ctx) - { - void *node; - - node = rzalloc_size(ctx, size); - assert(node != NULL); - - return node; - } - - enum prog_opcode op; - ir_to_mesa_dst_reg dst_reg; - ir_to_mesa_src_reg src_reg[3]; - /** Pointer to the ir source this tree came from for debugging */ - ir_instruction *ir; - GLboolean cond_update; - bool saturate; - int sampler; /**< sampler index */ - int tex_target; /**< One of TEXTURE_*_INDEX */ - GLboolean tex_shadow; - - class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */ -}; - -class variable_storage : public exec_node { -public: - variable_storage(ir_variable *var, gl_register_file file, int index) - : file(file), index(index), var(var) - { - /* empty */ - } - - gl_register_file file; - int index; - ir_variable *var; /* variable that maps to this, if any */ -}; - -class function_entry : public exec_node { -public: - ir_function_signature *sig; - - /** - * identifier of this function signature used by the program. - * - * At the point that Mesa instructions for function calls are - * generated, we don't know the address of the first instruction of - * the function body. So we make the BranchTarget that is called a - * small integer and rewrite them during set_branchtargets(). - */ - int sig_id; - - /** - * Pointer to first instruction of the function body. - * - * Set during function body emits after main() is processed. - */ - ir_to_mesa_instruction *bgn_inst; - - /** - * Index of the first instruction of the function body in actual - * Mesa IR. - * - * Set after convertion from ir_to_mesa_instruction to prog_instruction. - */ - int inst; - - /** Storage for the return value. */ - ir_to_mesa_src_reg return_reg; -}; - -class ir_to_mesa_visitor : public ir_visitor { -public: - ir_to_mesa_visitor(); - ~ir_to_mesa_visitor(); - - function_entry *current_function; - - struct gl_context *ctx; - struct gl_program *prog; - struct gl_shader_program *shader_program; - struct gl_shader_compiler_options *options; - - int next_temp; - - variable_storage *find_variable_storage(ir_variable *var); - - function_entry *get_function_signature(ir_function_signature *sig); - - ir_to_mesa_src_reg get_temp(const glsl_type *type); - void reladdr_to_temp(ir_instruction *ir, - ir_to_mesa_src_reg *reg, int *num_reladdr); - - struct ir_to_mesa_src_reg src_reg_for_float(float val); - - /** - * \name Visit methods - * - * As typical for the visitor pattern, there must be one \c visit method for - * each concrete subclass of \c ir_instruction. Virtual base classes within - * the hierarchy should not have \c visit methods. - */ - /*@{*/ - virtual void visit(ir_variable *); - virtual void visit(ir_loop *); - virtual void visit(ir_loop_jump *); - virtual void visit(ir_function_signature *); - virtual void visit(ir_function *); - virtual void visit(ir_expression *); - virtual void visit(ir_swizzle *); - virtual void visit(ir_dereference_variable *); - virtual void visit(ir_dereference_array *); - virtual void visit(ir_dereference_record *); - virtual void visit(ir_assignment *); - virtual void visit(ir_constant *); - virtual void visit(ir_call *); - virtual void visit(ir_return *); - virtual void visit(ir_discard *); - virtual void visit(ir_texture *); - virtual void visit(ir_if *); - /*@}*/ - - struct ir_to_mesa_src_reg result; - - /** List of variable_storage */ - exec_list variables; - - /** List of function_entry */ - exec_list function_signatures; - int next_signature_id; - - /** List of ir_to_mesa_instruction */ - exec_list instructions; - - ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir, - enum prog_opcode op); - - ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0); - - ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0, - ir_to_mesa_src_reg src1); - - ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0, - ir_to_mesa_src_reg src1, - ir_to_mesa_src_reg src2); - - /** - * Emit the correct dot-product instruction for the type of arguments - * - * \sa ir_to_mesa_emit_op2 - */ - void ir_to_mesa_emit_dp(ir_instruction *ir, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0, - ir_to_mesa_src_reg src1, - unsigned elements); - - void ir_to_mesa_emit_scalar_op1(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0); - - void ir_to_mesa_emit_scalar_op2(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0, - ir_to_mesa_src_reg src1); - - void emit_scs(ir_instruction *ir, enum prog_opcode op, - ir_to_mesa_dst_reg dst, - const ir_to_mesa_src_reg &src); - - GLboolean try_emit_mad(ir_expression *ir, - int mul_operand); - GLboolean try_emit_sat(ir_expression *ir); - - void emit_swz(ir_expression *ir); - - bool process_move_condition(ir_rvalue *ir); - - void copy_propagate(void); - - void *mem_ctx; -}; - -ir_to_mesa_src_reg ir_to_mesa_undef = ir_to_mesa_src_reg(PROGRAM_UNDEFINED, 0, NULL); - -ir_to_mesa_dst_reg ir_to_mesa_undef_dst = { - PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL, -}; - -ir_to_mesa_dst_reg ir_to_mesa_address_reg = { - PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL -}; - -static void -fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); - -static void -fail_link(struct gl_shader_program *prog, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - ralloc_vasprintf_append(&prog->InfoLog, fmt, args); - va_end(args); - - prog->LinkStatus = GL_FALSE; -} - -static int -swizzle_for_size(int size) -{ - int size_swizzles[4] = { - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), - }; - - assert((size >= 1) && (size <= 4)); - return size_swizzles[size - 1]; -} - -ir_to_mesa_instruction * -ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0, - ir_to_mesa_src_reg src1, - ir_to_mesa_src_reg src2) -{ - ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); - int num_reladdr = 0; - - /* If we have to do relative addressing, we want to load the ARL - * reg directly for one of the regs, and preload the other reladdr - * sources into temps. - */ - num_reladdr += dst.reladdr != NULL; - num_reladdr += src0.reladdr != NULL; - num_reladdr += src1.reladdr != NULL; - num_reladdr += src2.reladdr != NULL; - - reladdr_to_temp(ir, &src2, &num_reladdr); - reladdr_to_temp(ir, &src1, &num_reladdr); - reladdr_to_temp(ir, &src0, &num_reladdr); - - if (dst.reladdr) { - ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, - *dst.reladdr); - - num_reladdr--; - } - assert(num_reladdr == 0); - - inst->op = op; - inst->dst_reg = dst; - inst->src_reg[0] = src0; - inst->src_reg[1] = src1; - inst->src_reg[2] = src2; - inst->ir = ir; - - inst->function = NULL; - - this->instructions.push_tail(inst); - - return inst; -} - - -ir_to_mesa_instruction * -ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0, - ir_to_mesa_src_reg src1) -{ - return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef); -} - -ir_to_mesa_instruction * -ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0) -{ - assert(dst.writemask != 0); - return ir_to_mesa_emit_op3(ir, op, dst, - src0, ir_to_mesa_undef, ir_to_mesa_undef); -} - -ir_to_mesa_instruction * -ir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir, - enum prog_opcode op) -{ - return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst, - ir_to_mesa_undef, - ir_to_mesa_undef, - ir_to_mesa_undef); -} - -void -ir_to_mesa_visitor::ir_to_mesa_emit_dp(ir_instruction *ir, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0, - ir_to_mesa_src_reg src1, - unsigned elements) -{ - static const gl_inst_opcode dot_opcodes[] = { - OPCODE_DP2, OPCODE_DP3, OPCODE_DP4 - }; - - ir_to_mesa_emit_op3(ir, dot_opcodes[elements - 2], - dst, src0, src1, ir_to_mesa_undef); -} - -inline ir_to_mesa_dst_reg -ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg) -{ - ir_to_mesa_dst_reg dst_reg; - - dst_reg.file = reg.file; - dst_reg.index = reg.index; - dst_reg.writemask = WRITEMASK_XYZW; - dst_reg.cond_mask = COND_TR; - dst_reg.reladdr = reg.reladdr; - - return dst_reg; -} - -inline ir_to_mesa_src_reg -ir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg) -{ - return ir_to_mesa_src_reg(reg.file, reg.index, NULL); -} - -/** - * Emits Mesa scalar opcodes to produce unique answers across channels. - * - * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X - * channel determines the result across all channels. So to do a vec4 - * of this operation, we want to emit a scalar per source channel used - * to produce dest channels. - */ -void -ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg orig_src0, - ir_to_mesa_src_reg orig_src1) -{ - int i, j; - int done_mask = ~dst.writemask; - - /* Mesa RCP is a scalar operation splatting results to all channels, - * like ARB_fp/vp. So emit as many RCPs as necessary to cover our - * dst channels. - */ - for (i = 0; i < 4; i++) { - GLuint this_mask = (1 << i); - ir_to_mesa_instruction *inst; - ir_to_mesa_src_reg src0 = orig_src0; - ir_to_mesa_src_reg src1 = orig_src1; - - if (done_mask & this_mask) - continue; - - GLuint src0_swiz = GET_SWZ(src0.swizzle, i); - GLuint src1_swiz = GET_SWZ(src1.swizzle, i); - for (j = i + 1; j < 4; j++) { - /* If there is another enabled component in the destination that is - * derived from the same inputs, generate its value on this pass as - * well. - */ - if (!(done_mask & (1 << j)) && - GET_SWZ(src0.swizzle, j) == src0_swiz && - GET_SWZ(src1.swizzle, j) == src1_swiz) { - this_mask |= (1 << j); - } - } - src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, - src0_swiz, src0_swiz); - src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, - src1_swiz, src1_swiz); - - inst = ir_to_mesa_emit_op2(ir, op, - dst, - src0, - src1); - inst->dst_reg.writemask = this_mask; - done_mask |= this_mask; - } -} - -void -ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir, - enum prog_opcode op, - ir_to_mesa_dst_reg dst, - ir_to_mesa_src_reg src0) -{ - ir_to_mesa_src_reg undef = ir_to_mesa_undef; - - undef.swizzle = SWIZZLE_XXXX; - - ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef); -} - -/** - * Emit an OPCODE_SCS instruction - * - * The \c SCS opcode functions a bit differently than the other Mesa (or - * ARB_fragment_program) opcodes. Instead of splatting its result across all - * four components of the destination, it writes one value to the \c x - * component and another value to the \c y component. - * - * \param ir IR instruction being processed - * \param op Either \c OPCODE_SIN or \c OPCODE_COS depending on which - * value is desired. - * \param dst Destination register - * \param src Source register - */ -void -ir_to_mesa_visitor::emit_scs(ir_instruction *ir, enum prog_opcode op, - ir_to_mesa_dst_reg dst, - const ir_to_mesa_src_reg &src) -{ - /* Vertex programs cannot use the SCS opcode. - */ - if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { - ir_to_mesa_emit_scalar_op1(ir, op, dst, src); - return; - } - - const unsigned component = (op == OPCODE_SIN) ? 0 : 1; - const unsigned scs_mask = (1U << component); - int done_mask = ~dst.writemask; - ir_to_mesa_src_reg tmp; - - assert(op == OPCODE_SIN || op == OPCODE_COS); - - /* If there are compnents in the destination that differ from the component - * that will be written by the SCS instrution, we'll need a temporary. - */ - if (scs_mask != unsigned(dst.writemask)) { - tmp = get_temp(glsl_type::vec4_type); - } - - for (unsigned i = 0; i < 4; i++) { - unsigned this_mask = (1U << i); - ir_to_mesa_src_reg src0 = src; - - if ((done_mask & this_mask) != 0) - continue; - - /* The source swizzle specified which component of the source generates - * sine / cosine for the current component in the destination. The SCS - * instruction requires that this value be swizzle to the X component. - * Replace the current swizzle with a swizzle that puts the source in - * the X component. - */ - unsigned src0_swiz = GET_SWZ(src.swizzle, i); - - src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, - src0_swiz, src0_swiz); - for (unsigned j = i + 1; j < 4; j++) { - /* If there is another enabled component in the destination that is - * derived from the same inputs, generate its value on this pass as - * well. - */ - if (!(done_mask & (1 << j)) && - GET_SWZ(src0.swizzle, j) == src0_swiz) { - this_mask |= (1 << j); - } - } - - if (this_mask != scs_mask) { - ir_to_mesa_instruction *inst; - ir_to_mesa_dst_reg tmp_dst = ir_to_mesa_dst_reg_from_src(tmp); - - /* Emit the SCS instruction. - */ - inst = ir_to_mesa_emit_op1(ir, OPCODE_SCS, tmp_dst, src0); - inst->dst_reg.writemask = scs_mask; - - /* Move the result of the SCS instruction to the desired location in - * the destination. - */ - tmp.swizzle = MAKE_SWIZZLE4(component, component, - component, component); - inst = ir_to_mesa_emit_op1(ir, OPCODE_SCS, dst, tmp); - inst->dst_reg.writemask = this_mask; - } else { - /* Emit the SCS instruction to write directly to the destination. - */ - ir_to_mesa_instruction *inst = - ir_to_mesa_emit_op1(ir, OPCODE_SCS, dst, src0); - inst->dst_reg.writemask = scs_mask; - } - - done_mask |= this_mask; - } -} - -struct ir_to_mesa_src_reg -ir_to_mesa_visitor::src_reg_for_float(float val) -{ - ir_to_mesa_src_reg src_reg(PROGRAM_CONSTANT, -1, NULL); - - src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, - &val, 1, &src_reg.swizzle); - - return src_reg; -} - -static int -type_size(const struct glsl_type *type) -{ - unsigned int i; - int size; - - switch (type->base_type) { - case GLSL_TYPE_UINT: - case GLSL_TYPE_INT: - case GLSL_TYPE_FLOAT: - case GLSL_TYPE_BOOL: - if (type->is_matrix()) { - return type->matrix_columns; - } else { - /* Regardless of size of vector, it gets a vec4. This is bad - * packing for things like floats, but otherwise arrays become a - * mess. Hopefully a later pass over the code can pack scalars - * down if appropriate. - */ - return 1; - } - case GLSL_TYPE_ARRAY: - assert(type->length > 0); - return type_size(type->fields.array) * type->length; - case GLSL_TYPE_STRUCT: - size = 0; - for (i = 0; i < type->length; i++) { - size += type_size(type->fields.structure[i].type); - } - return size; - case GLSL_TYPE_SAMPLER: - /* Samplers take up one slot in UNIFORMS[], but they're baked in - * at link time. - */ - return 1; - default: - assert(0); - return 0; - } -} - -/** - * In the initial pass of codegen, we assign temporary numbers to - * intermediate results. (not SSA -- variable assignments will reuse - * storage). Actual register allocation for the Mesa VM occurs in a - * pass over the Mesa IR later. - */ -ir_to_mesa_src_reg -ir_to_mesa_visitor::get_temp(const glsl_type *type) -{ - ir_to_mesa_src_reg src_reg; - int swizzle[4]; - int i; - - src_reg.file = PROGRAM_TEMPORARY; - src_reg.index = next_temp; - src_reg.reladdr = NULL; - next_temp += type_size(type); - - if (type->is_array() || type->is_record()) { - src_reg.swizzle = SWIZZLE_NOOP; - } else { - for (i = 0; i < type->vector_elements; i++) - swizzle[i] = i; - for (; i < 4; i++) - swizzle[i] = type->vector_elements - 1; - src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], - swizzle[2], swizzle[3]); - } - src_reg.negate = 0; - - return src_reg; -} - -variable_storage * -ir_to_mesa_visitor::find_variable_storage(ir_variable *var) -{ - - variable_storage *entry; - - foreach_iter(exec_list_iterator, iter, this->variables) { - entry = (variable_storage *)iter.get(); - - if (entry->var == var) - return entry; - } - - return NULL; -} - -void -ir_to_mesa_visitor::visit(ir_variable *ir) -{ - if (strcmp(ir->name, "gl_FragCoord") == 0) { - struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; - - fp->OriginUpperLeft = ir->origin_upper_left; - fp->PixelCenterInteger = ir->pixel_center_integer; - - } else if (strcmp(ir->name, "gl_FragDepth") == 0) { - struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; - switch (ir->depth_layout) { - case ir_depth_layout_none: - fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE; - break; - case ir_depth_layout_any: - fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY; - break; - case ir_depth_layout_greater: - fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER; - break; - case ir_depth_layout_less: - fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS; - break; - case ir_depth_layout_unchanged: - fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED; - break; - default: - assert(0); - break; - } - } - - if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { - unsigned int i; - const struct gl_builtin_uniform_desc *statevar; - - for (i = 0; _mesa_builtin_uniform_desc[i].name; i++) { - if (strcmp(ir->name, _mesa_builtin_uniform_desc[i].name) == 0) - break; - } - - if (!_mesa_builtin_uniform_desc[i].name) { - fail_link(this->shader_program, - "Failed to find builtin uniform `%s'\n", ir->name); - return; - } - - statevar = &_mesa_builtin_uniform_desc[i]; - - int array_count; - if (ir->type->is_array()) { - array_count = ir->type->length; - } else { - array_count = 1; - } - - /* Check if this statevar's setup in the STATE file exactly - * matches how we'll want to reference it as a - * struct/array/whatever. If not, then we need to move it into - * temporary storage and hope that it'll get copy-propagated - * out. - */ - for (i = 0; i < statevar->num_elements; i++) { - if (statevar->elements[i].swizzle != SWIZZLE_XYZW) { - break; - } - } - - struct variable_storage *storage; - ir_to_mesa_dst_reg dst; - if (i == statevar->num_elements) { - /* We'll set the index later. */ - storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); - this->variables.push_tail(storage); - - dst = ir_to_mesa_undef_dst; - } else { - storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, - this->next_temp); - this->variables.push_tail(storage); - this->next_temp += type_size(ir->type); - - dst = ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg(PROGRAM_TEMPORARY, - storage->index, - NULL)); - } - - - for (int a = 0; a < array_count; a++) { - for (unsigned int i = 0; i < statevar->num_elements; i++) { - struct gl_builtin_uniform_element *element = &statevar->elements[i]; - int tokens[STATE_LENGTH]; - - memcpy(tokens, element->tokens, sizeof(element->tokens)); - if (ir->type->is_array()) { - tokens[1] = a; - } - - int index = _mesa_add_state_reference(this->prog->Parameters, - (gl_state_index *)tokens); - - if (storage->file == PROGRAM_STATE_VAR) { - if (storage->index == -1) { - storage->index = index; - } else { - assert(index == - (int)(storage->index + a * statevar->num_elements + i)); - } - } else { - ir_to_mesa_src_reg src(PROGRAM_STATE_VAR, index, NULL); - src.swizzle = element->swizzle; - ir_to_mesa_emit_op1(ir, OPCODE_MOV, dst, src); - /* even a float takes up a whole vec4 reg in a struct/array. */ - dst.index++; - } - } - } - if (storage->file == PROGRAM_TEMPORARY && - dst.index != storage->index + type_size(ir->type)) { - fail_link(this->shader_program, - "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", - ir->name, dst.index - storage->index, - type_size(ir->type)); - } - } -} - -void -ir_to_mesa_visitor::visit(ir_loop *ir) -{ - ir_dereference_variable *counter = NULL; - - if (ir->counter != NULL) - counter = new(ir) ir_dereference_variable(ir->counter); - - if (ir->from != NULL) { - assert(ir->counter != NULL); - - ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); - - a->accept(this); - delete a; - } - - ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP); - - if (ir->to) { - ir_expression *e = - new(ir) ir_expression(ir->cmp, glsl_type::bool_type, - counter, ir->to); - ir_if *if_stmt = new(ir) ir_if(e); - - ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); - - if_stmt->then_instructions.push_tail(brk); - - if_stmt->accept(this); - - delete if_stmt; - delete e; - delete brk; - } - - visit_exec_list(&ir->body_instructions, this); - - if (ir->increment) { - ir_expression *e = - new(ir) ir_expression(ir_binop_add, counter->type, - counter, ir->increment); - - ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); - - a->accept(this); - delete a; - delete e; - } - - ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP); -} - -void -ir_to_mesa_visitor::visit(ir_loop_jump *ir) -{ - switch (ir->mode) { - case ir_loop_jump::jump_break: - ir_to_mesa_emit_op0(NULL, OPCODE_BRK); - break; - case ir_loop_jump::jump_continue: - ir_to_mesa_emit_op0(NULL, OPCODE_CONT); - break; - } -} - - -void -ir_to_mesa_visitor::visit(ir_function_signature *ir) -{ - assert(0); - (void)ir; -} - -void -ir_to_mesa_visitor::visit(ir_function *ir) -{ - /* Ignore function bodies other than main() -- we shouldn't see calls to - * them since they should all be inlined before we get to ir_to_mesa. - */ - if (strcmp(ir->name, "main") == 0) { - const ir_function_signature *sig; - exec_list empty; - - sig = ir->matching_signature(&empty); - - assert(sig); - - foreach_iter(exec_list_iterator, iter, sig->body) { - ir_instruction *ir = (ir_instruction *)iter.get(); - - ir->accept(this); - } - } -} - -GLboolean -ir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) -{ - int nonmul_operand = 1 - mul_operand; - ir_to_mesa_src_reg a, b, c; - - ir_expression *expr = ir->operands[mul_operand]->as_expression(); - if (!expr || expr->operation != ir_binop_mul) - return false; - - expr->operands[0]->accept(this); - a = this->result; - expr->operands[1]->accept(this); - b = this->result; - ir->operands[nonmul_operand]->accept(this); - c = this->result; - - this->result = get_temp(ir->type); - ir_to_mesa_emit_op3(ir, OPCODE_MAD, - ir_to_mesa_dst_reg_from_src(this->result), a, b, c); - - return true; -} - -GLboolean -ir_to_mesa_visitor::try_emit_sat(ir_expression *ir) -{ - /* Saturates were only introduced to vertex programs in - * NV_vertex_program3, so don't give them to drivers in the VP. - */ - if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) - return false; - - ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); - if (!sat_src) - return false; - - sat_src->accept(this); - ir_to_mesa_src_reg src = this->result; - - this->result = get_temp(ir->type); - ir_to_mesa_instruction *inst; - inst = ir_to_mesa_emit_op1(ir, OPCODE_MOV, - ir_to_mesa_dst_reg_from_src(this->result), - src); - inst->saturate = true; - - return true; -} - -void -ir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, - ir_to_mesa_src_reg *reg, int *num_reladdr) -{ - if (!reg->reladdr) - return; - - ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr); - - if (*num_reladdr != 1) { - ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); - - ir_to_mesa_emit_op1(ir, OPCODE_MOV, - ir_to_mesa_dst_reg_from_src(temp), *reg); - *reg = temp; - } - - (*num_reladdr)--; -} - -void -ir_to_mesa_visitor::emit_swz(ir_expression *ir) -{ - /* Assume that the vector operator is in a form compatible with OPCODE_SWZ. - * This means that each of the operands is either an immediate value of -1, - * 0, or 1, or is a component from one source register (possibly with - * negation). - */ - uint8_t components[4] = { 0 }; - bool negate[4] = { false }; - ir_variable *var = NULL; - - for (unsigned i = 0; i < ir->type->vector_elements; i++) { - ir_rvalue *op = ir->operands[i]; - - assert(op->type->is_scalar()); - - while (op != NULL) { - switch (op->ir_type) { - case ir_type_constant: { - - assert(op->type->is_scalar()); - - const ir_constant *const c = op->as_constant(); - if (c->is_one()) { - components[i] = SWIZZLE_ONE; - } else if (c->is_zero()) { - components[i] = SWIZZLE_ZERO; - } else if (c->is_negative_one()) { - components[i] = SWIZZLE_ONE; - negate[i] = true; - } else { - assert(!"SWZ constant must be 0.0 or 1.0."); - } - - op = NULL; - break; - } - - case ir_type_dereference_variable: { - ir_dereference_variable *const deref = - (ir_dereference_variable *) op; - - assert((var == NULL) || (deref->var == var)); - components[i] = SWIZZLE_X; - var = deref->var; - op = NULL; - break; - } - - case ir_type_expression: { - ir_expression *const expr = (ir_expression *) op; - - assert(expr->operation == ir_unop_neg); - negate[i] = true; - - op = expr->operands[0]; - break; - } - - case ir_type_swizzle: { - ir_swizzle *const swiz = (ir_swizzle *) op; - - components[i] = swiz->mask.x; - op = swiz->val; - break; - } - - default: - assert(!"Should not get here."); - return; - } - } - } - - assert(var != NULL); - - ir_dereference_variable *const deref = - new(mem_ctx) ir_dereference_variable(var); - - this->result.file = PROGRAM_UNDEFINED; - deref->accept(this); - if (this->result.file == PROGRAM_UNDEFINED) { - ir_print_visitor v; - printf("Failed to get tree for expression operand:\n"); - deref->accept(&v); - exit(1); - } - - ir_to_mesa_src_reg src; - - src = this->result; - src.swizzle = MAKE_SWIZZLE4(components[0], - components[1], - components[2], - components[3]); - src.negate = ((unsigned(negate[0]) << 0) - | (unsigned(negate[1]) << 1) - | (unsigned(negate[2]) << 2) - | (unsigned(negate[3]) << 3)); - - /* Storage for our result. Ideally for an assignment we'd be using the - * actual storage for the result here, instead. - */ - const ir_to_mesa_src_reg result_src = get_temp(ir->type); - ir_to_mesa_dst_reg result_dst = ir_to_mesa_dst_reg_from_src(result_src); - - /* Limit writes to the channels that will be used by result_src later. - * This does limit this temp's use as a temporary for multi-instruction - * sequences. - */ - result_dst.writemask = (1 << ir->type->vector_elements) - 1; - - ir_to_mesa_emit_op1(ir, OPCODE_SWZ, result_dst, src); - this->result = result_src; -} - -void -ir_to_mesa_visitor::visit(ir_expression *ir) -{ - unsigned int operand; - struct ir_to_mesa_src_reg op[Elements(ir->operands)]; - struct ir_to_mesa_src_reg result_src; - struct ir_to_mesa_dst_reg result_dst; - - /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) - */ - if (ir->operation == ir_binop_add) { - if (try_emit_mad(ir, 1)) - return; - if (try_emit_mad(ir, 0)) - return; - } - if (try_emit_sat(ir)) - return; - - if (ir->operation == ir_quadop_vector) { - this->emit_swz(ir); - return; - } - - for (operand = 0; operand < ir->get_num_operands(); operand++) { - this->result.file = PROGRAM_UNDEFINED; - ir->operands[operand]->accept(this); - if (this->result.file == PROGRAM_UNDEFINED) { - ir_print_visitor v; - printf("Failed to get tree for expression operand:\n"); - ir->operands[operand]->accept(&v); - exit(1); - } - op[operand] = this->result; - - /* Matrix expression operands should have been broken down to vector - * operations already. - */ - assert(!ir->operands[operand]->type->is_matrix()); - } - - int vector_elements = ir->operands[0]->type->vector_elements; - if (ir->operands[1]) { - vector_elements = MAX2(vector_elements, - ir->operands[1]->type->vector_elements); - } - - this->result.file = PROGRAM_UNDEFINED; - - /* Storage for our result. Ideally for an assignment we'd be using - * the actual storage for the result here, instead. - */ - result_src = get_temp(ir->type); - /* convenience for the emit functions below. */ - result_dst = ir_to_mesa_dst_reg_from_src(result_src); - /* Limit writes to the channels that will be used by result_src later. - * This does limit this temp's use as a temporary for multi-instruction - * sequences. - */ - result_dst.writemask = (1 << ir->type->vector_elements) - 1; - - switch (ir->operation) { - case ir_unop_logic_not: - ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, - op[0], src_reg_for_float(0.0)); - break; - case ir_unop_neg: - op[0].negate = ~op[0].negate; - result_src = op[0]; - break; - case ir_unop_abs: - ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]); - break; - case ir_unop_sign: - ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]); - break; - case ir_unop_rcp: - ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]); - break; - - case ir_unop_exp2: - ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]); - break; - case ir_unop_exp: - case ir_unop_log: - assert(!"not reached: should be handled by ir_explog_to_explog2"); - break; - case ir_unop_log2: - ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]); - break; - case ir_unop_sin: - ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]); - break; - case ir_unop_cos: - ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]); - break; - case ir_unop_sin_reduced: - emit_scs(ir, OPCODE_SIN, result_dst, op[0]); - break; - case ir_unop_cos_reduced: - emit_scs(ir, OPCODE_COS, result_dst, op[0]); - break; - - case ir_unop_dFdx: - ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]); - break; - case ir_unop_dFdy: - ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]); - break; - - case ir_unop_noise: { - const enum prog_opcode opcode = - prog_opcode(OPCODE_NOISE1 - + (ir->operands[0]->type->vector_elements) - 1); - assert((opcode >= OPCODE_NOISE1) && (opcode <= OPCODE_NOISE4)); - - ir_to_mesa_emit_op1(ir, opcode, result_dst, op[0]); - break; - } - - case ir_binop_add: - ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]); - break; - case ir_binop_sub: - ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]); - break; - - case ir_binop_mul: - ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]); - break; - case ir_binop_div: - assert(!"not reached: should be handled by ir_div_to_mul_rcp"); - case ir_binop_mod: - assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); - break; - - case ir_binop_less: - ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]); - break; - case ir_binop_greater: - ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]); - break; - case ir_binop_lequal: - ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]); - break; - case ir_binop_gequal: - ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]); - break; - case ir_binop_equal: - ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); - break; - case ir_binop_nequal: - ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); - break; - case ir_binop_all_equal: - /* "==" operator producing a scalar boolean. */ - if (ir->operands[0]->type->is_vector() || - ir->operands[1]->type->is_vector()) { - ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); - ir_to_mesa_emit_op2(ir, OPCODE_SNE, - ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]); - ir_to_mesa_emit_dp(ir, result_dst, temp, temp, vector_elements); - ir_to_mesa_emit_op2(ir, OPCODE_SEQ, - result_dst, result_src, src_reg_for_float(0.0)); - } else { - ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); - } - break; - case ir_binop_any_nequal: - /* "!=" operator producing a scalar boolean. */ - if (ir->operands[0]->type->is_vector() || - ir->operands[1]->type->is_vector()) { - ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); - ir_to_mesa_emit_op2(ir, OPCODE_SNE, - ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]); - ir_to_mesa_emit_dp(ir, result_dst, temp, temp, vector_elements); - ir_to_mesa_emit_op2(ir, OPCODE_SNE, - result_dst, result_src, src_reg_for_float(0.0)); - } else { - ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); - } - break; - - case ir_unop_any: - assert(ir->operands[0]->type->is_vector()); - ir_to_mesa_emit_dp(ir, result_dst, op[0], op[0], - ir->operands[0]->type->vector_elements); - ir_to_mesa_emit_op2(ir, OPCODE_SNE, - result_dst, result_src, src_reg_for_float(0.0)); - break; - - case ir_binop_logic_xor: - ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); - break; - - case ir_binop_logic_or: - /* This could be a saturated add and skip the SNE. */ - ir_to_mesa_emit_op2(ir, OPCODE_ADD, - result_dst, - op[0], op[1]); - - ir_to_mesa_emit_op2(ir, OPCODE_SNE, - result_dst, - result_src, src_reg_for_float(0.0)); - break; - - case ir_binop_logic_and: - /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ - ir_to_mesa_emit_op2(ir, OPCODE_MUL, - result_dst, - op[0], op[1]); - break; - - case ir_binop_dot: - assert(ir->operands[0]->type->is_vector()); - assert(ir->operands[0]->type == ir->operands[1]->type); - ir_to_mesa_emit_dp(ir, result_dst, op[0], op[1], - ir->operands[0]->type->vector_elements); - break; - - case ir_unop_sqrt: - /* sqrt(x) = x * rsq(x). */ - ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); - ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, result_src, op[0]); - /* For incoming channels <= 0, set the result to 0. */ - op[0].negate = ~op[0].negate; - ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst, - op[0], result_src, src_reg_for_float(0.0)); - break; - case ir_unop_rsq: - ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); - break; - case ir_unop_i2f: - case ir_unop_b2f: - case ir_unop_b2i: - /* Mesa IR lacks types, ints are stored as truncated floats. */ - result_src = op[0]; - break; - case ir_unop_f2i: - ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); - break; - case ir_unop_f2b: - case ir_unop_i2b: - ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, - op[0], src_reg_for_float(0.0)); - break; - case ir_unop_trunc: - ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); - break; - case ir_unop_ceil: - op[0].negate = ~op[0].negate; - ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); - result_src.negate = ~result_src.negate; - break; - case ir_unop_floor: - ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); - break; - case ir_unop_fract: - ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]); - break; - - case ir_binop_min: - ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]); - break; - case ir_binop_max: - ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]); - break; - case ir_binop_pow: - ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]); - break; - - case ir_unop_bit_not: - case ir_unop_u2f: - case ir_binop_lshift: - case ir_binop_rshift: - case ir_binop_bit_and: - case ir_binop_bit_xor: - case ir_binop_bit_or: - case ir_unop_round_even: - assert(!"GLSL 1.30 features unsupported"); - break; - - case ir_quadop_vector: - /* This operation should have already been handled. - */ - assert(!"Should not get here."); - break; - } - - this->result = result_src; -} - - -void -ir_to_mesa_visitor::visit(ir_swizzle *ir) -{ - ir_to_mesa_src_reg src_reg; - int i; - int swizzle[4]; - - /* Note that this is only swizzles in expressions, not those on the left - * hand side of an assignment, which do write masking. See ir_assignment - * for that. - */ - - ir->val->accept(this); - src_reg = this->result; - assert(src_reg.file != PROGRAM_UNDEFINED); - - for (i = 0; i < 4; i++) { - if (i < ir->type->vector_elements) { - switch (i) { - case 0: - swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x); - break; - case 1: - swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y); - break; - case 2: - swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z); - break; - case 3: - swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w); - break; - } - } else { - /* If the type is smaller than a vec4, replicate the last - * channel out. - */ - swizzle[i] = swizzle[ir->type->vector_elements - 1]; - } - } - - src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], - swizzle[1], - swizzle[2], - swizzle[3]); - - this->result = src_reg; -} - -void -ir_to_mesa_visitor::visit(ir_dereference_variable *ir) -{ - variable_storage *entry = find_variable_storage(ir->var); - ir_variable *var = ir->var; - - if (!entry) { - switch (var->mode) { - case ir_var_uniform: - entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, - var->location); - this->variables.push_tail(entry); - break; - case ir_var_in: - case ir_var_inout: - /* The linker assigns locations for varyings and attributes, - * including deprecated builtins (like gl_Color), user-assign - * generic attributes (glBindVertexLocation), and - * user-defined varyings. - * - * FINISHME: We would hit this path for function arguments. Fix! - */ - assert(var->location != -1); - entry = new(mem_ctx) variable_storage(var, - PROGRAM_INPUT, - var->location); - if (this->prog->Target == GL_VERTEX_PROGRAM_ARB && - var->location >= VERT_ATTRIB_GENERIC0) { - _mesa_add_attribute(this->prog->Attributes, - var->name, - _mesa_sizeof_glsl_type(var->type->gl_type), - var->type->gl_type, - var->location - VERT_ATTRIB_GENERIC0); - } - break; - case ir_var_out: - assert(var->location != -1); - entry = new(mem_ctx) variable_storage(var, - PROGRAM_OUTPUT, - var->location); - break; - case ir_var_system_value: - entry = new(mem_ctx) variable_storage(var, - PROGRAM_SYSTEM_VALUE, - var->location); - break; - case ir_var_auto: - case ir_var_temporary: - entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, - this->next_temp); - this->variables.push_tail(entry); - - next_temp += type_size(var->type); - break; - } - - if (!entry) { - printf("Failed to make storage for %s\n", var->name); - exit(1); - } - } - - this->result = ir_to_mesa_src_reg(entry->file, entry->index, var->type); -} - -void -ir_to_mesa_visitor::visit(ir_dereference_array *ir) -{ - ir_constant *index; - ir_to_mesa_src_reg src_reg; - int element_size = type_size(ir->type); - - index = ir->array_index->constant_expression_value(); - - ir->array->accept(this); - src_reg = this->result; - - if (index) { - src_reg.index += index->value.i[0] * element_size; - } else { - ir_to_mesa_src_reg array_base = this->result; - /* Variable index array dereference. It eats the "vec4" of the - * base of the array and an index that offsets the Mesa register - * index. - */ - ir->array_index->accept(this); - - ir_to_mesa_src_reg index_reg; - - if (element_size == 1) { - index_reg = this->result; - } else { - index_reg = get_temp(glsl_type::float_type); - - ir_to_mesa_emit_op2(ir, OPCODE_MUL, - ir_to_mesa_dst_reg_from_src(index_reg), - this->result, src_reg_for_float(element_size)); - } - - src_reg.reladdr = ralloc(mem_ctx, ir_to_mesa_src_reg); - memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); - } - - /* If the type is smaller than a vec4, replicate the last channel out. */ - if (ir->type->is_scalar() || ir->type->is_vector()) - src_reg.swizzle = swizzle_for_size(ir->type->vector_elements); - else - src_reg.swizzle = SWIZZLE_NOOP; - - this->result = src_reg; -} - -void -ir_to_mesa_visitor::visit(ir_dereference_record *ir) -{ - unsigned int i; - const glsl_type *struct_type = ir->record->type; - int offset = 0; - - ir->record->accept(this); - - for (i = 0; i < struct_type->length; i++) { - if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) - break; - offset += type_size(struct_type->fields.structure[i].type); - } - - /* If the type is smaller than a vec4, replicate the last channel out. */ - if (ir->type->is_scalar() || ir->type->is_vector()) - this->result.swizzle = swizzle_for_size(ir->type->vector_elements); - else - this->result.swizzle = SWIZZLE_NOOP; - - this->result.index += offset; -} - -/** - * We want to be careful in assignment setup to hit the actual storage - * instead of potentially using a temporary like we might with the - * ir_dereference handler. - */ -static struct ir_to_mesa_dst_reg -get_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v) -{ - /* The LHS must be a dereference. If the LHS is a variable indexed array - * access of a vector, it must be separated into a series conditional moves - * before reaching this point (see ir_vec_index_to_cond_assign). - */ - assert(ir->as_dereference()); - ir_dereference_array *deref_array = ir->as_dereference_array(); - if (deref_array) { - assert(!deref_array->array->type->is_vector()); - } - - /* Use the rvalue deref handler for the most part. We'll ignore - * swizzles in it and write swizzles using writemask, though. - */ - ir->accept(v); - return ir_to_mesa_dst_reg_from_src(v->result); -} - -/** - * Process the condition of a conditional assignment - * - * Examines the condition of a conditional assignment to generate the optimal - * first operand of a \c CMP instruction. If the condition is a relational - * operator with 0 (e.g., \c ir_binop_less), the value being compared will be - * used as the source for the \c CMP instruction. Otherwise the comparison - * is processed to a boolean result, and the boolean result is used as the - * operand to the CMP instruction. - */ -bool -ir_to_mesa_visitor::process_move_condition(ir_rvalue *ir) -{ - ir_rvalue *src_ir = ir; - bool negate = true; - bool switch_order = false; - - ir_expression *const expr = ir->as_expression(); - if ((expr != NULL) && (expr->get_num_operands() == 2)) { - bool zero_on_left = false; - - if (expr->operands[0]->is_zero()) { - src_ir = expr->operands[1]; - zero_on_left = true; - } else if (expr->operands[1]->is_zero()) { - src_ir = expr->operands[0]; - zero_on_left = false; - } - - /* a is - 0 + - 0 + - * (a < 0) T F F ( a < 0) T F F - * (0 < a) F F T (-a < 0) F F T - * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) - * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) - * (a > 0) F F T (-a < 0) F F T - * (0 > a) T F F ( a < 0) T F F - * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) - * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) - * - * Note that exchanging the order of 0 and 'a' in the comparison simply - * means that the value of 'a' should be negated. - */ - if (src_ir != ir) { - switch (expr->operation) { - case ir_binop_less: - switch_order = false; - negate = zero_on_left; - break; - - case ir_binop_greater: - switch_order = false; - negate = !zero_on_left; - break; - - case ir_binop_lequal: - switch_order = true; - negate = !zero_on_left; - break; - - case ir_binop_gequal: - switch_order = true; - negate = zero_on_left; - break; - - default: - /* This isn't the right kind of comparison afterall, so make sure - * the whole condition is visited. - */ - src_ir = ir; - break; - } - } - } - - src_ir->accept(this); - - /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the - * condition we produced is 0.0 or 1.0. By flipping the sign, we can - * choose which value OPCODE_CMP produces without an extra instruction - * computing the condition. - */ - if (negate) - this->result.negate = ~this->result.negate; - - return switch_order; -} - -void -ir_to_mesa_visitor::visit(ir_assignment *ir) -{ - struct ir_to_mesa_dst_reg l; - struct ir_to_mesa_src_reg r; - int i; - - ir->rhs->accept(this); - r = this->result; - - l = get_assignment_lhs(ir->lhs, this); - - /* FINISHME: This should really set to the correct maximal writemask for each - * FINISHME: component written (in the loops below). This case can only - * FINISHME: occur for matrices, arrays, and structures. - */ - if (ir->write_mask == 0) { - assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); - l.writemask = WRITEMASK_XYZW; - } else if (ir->lhs->type->is_scalar()) { - /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the - * FINISHME: W component of fragment shader output zero, work correctly. - */ - l.writemask = WRITEMASK_XYZW; - } else { - int swizzles[4]; - int first_enabled_chan = 0; - int rhs_chan = 0; - - assert(ir->lhs->type->is_vector()); - l.writemask = ir->write_mask; - - for (int i = 0; i < 4; i++) { - if (l.writemask & (1 << i)) { - first_enabled_chan = GET_SWZ(r.swizzle, i); - break; - } - } - - /* Swizzle a small RHS vector into the channels being written. - * - * glsl ir treats write_mask as dictating how many channels are - * present on the RHS while Mesa IR treats write_mask as just - * showing which channels of the vec4 RHS get written. - */ - for (int i = 0; i < 4; i++) { - if (l.writemask & (1 << i)) - swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); - else - swizzles[i] = first_enabled_chan; - } - r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], - swizzles[2], swizzles[3]); - } - - assert(l.file != PROGRAM_UNDEFINED); - assert(r.file != PROGRAM_UNDEFINED); - - if (ir->condition) { - const bool switch_order = this->process_move_condition(ir->condition); - ir_to_mesa_src_reg condition = this->result; - - for (i = 0; i < type_size(ir->lhs->type); i++) { - if (switch_order) { - ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, - condition, ir_to_mesa_src_reg_from_dst(l), r); - } else { - ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, - condition, r, ir_to_mesa_src_reg_from_dst(l)); - } - - l.index++; - r.index++; - } - } else { - for (i = 0; i < type_size(ir->lhs->type); i++) { - ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); - l.index++; - r.index++; - } - } -} - - -void -ir_to_mesa_visitor::visit(ir_constant *ir) -{ - ir_to_mesa_src_reg src_reg; - GLfloat stack_vals[4] = { 0 }; - GLfloat *values = stack_vals; - unsigned int i; - - /* Unfortunately, 4 floats is all we can get into - * _mesa_add_unnamed_constant. So, make a temp to store an - * aggregate constant and move each constant value into it. If we - * get lucky, copy propagation will eliminate the extra moves. - */ - - if (ir->type->base_type == GLSL_TYPE_STRUCT) { - ir_to_mesa_src_reg temp_base = get_temp(ir->type); - ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); - - foreach_iter(exec_list_iterator, iter, ir->components) { - ir_constant *field_value = (ir_constant *)iter.get(); - int size = type_size(field_value->type); - - assert(size > 0); - - field_value->accept(this); - src_reg = this->result; - - for (i = 0; i < (unsigned int)size; i++) { - ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); - - src_reg.index++; - temp.index++; - } - } - this->result = temp_base; - return; - } - - if (ir->type->is_array()) { - ir_to_mesa_src_reg temp_base = get_temp(ir->type); - ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); - int size = type_size(ir->type->fields.array); - - assert(size > 0); - - for (i = 0; i < ir->type->length; i++) { - ir->array_elements[i]->accept(this); - src_reg = this->result; - for (int j = 0; j < size; j++) { - ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); - - src_reg.index++; - temp.index++; - } - } - this->result = temp_base; - return; - } - - if (ir->type->is_matrix()) { - ir_to_mesa_src_reg mat = get_temp(ir->type); - ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat); - - for (i = 0; i < ir->type->matrix_columns; i++) { - assert(ir->type->base_type == GLSL_TYPE_FLOAT); - values = &ir->value.f[i * ir->type->vector_elements]; - - src_reg = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, NULL); - src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, - values, - ir->type->vector_elements, - &src_reg.swizzle); - ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg); - - mat_column.index++; - } - - this->result = mat; - return; - } - - src_reg.file = PROGRAM_CONSTANT; - switch (ir->type->base_type) { - case GLSL_TYPE_FLOAT: - values = &ir->value.f[0]; - break; - case GLSL_TYPE_UINT: - for (i = 0; i < ir->type->vector_elements; i++) { - values[i] = ir->value.u[i]; - } - break; - case GLSL_TYPE_INT: - for (i = 0; i < ir->type->vector_elements; i++) { - values[i] = ir->value.i[i]; - } - break; - case GLSL_TYPE_BOOL: - for (i = 0; i < ir->type->vector_elements; i++) { - values[i] = ir->value.b[i]; - } - break; - default: - assert(!"Non-float/uint/int/bool constant"); - } - - this->result = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, ir->type); - this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters, - values, - ir->type->vector_elements, - &this->result.swizzle); -} - -function_entry * -ir_to_mesa_visitor::get_function_signature(ir_function_signature *sig) -{ - function_entry *entry; - - foreach_iter(exec_list_iterator, iter, this->function_signatures) { - entry = (function_entry *)iter.get(); - - if (entry->sig == sig) - return entry; - } - - entry = ralloc(mem_ctx, function_entry); - entry->sig = sig; - entry->sig_id = this->next_signature_id++; - entry->bgn_inst = NULL; - - /* Allocate storage for all the parameters. */ - foreach_iter(exec_list_iterator, iter, sig->parameters) { - ir_variable *param = (ir_variable *)iter.get(); - variable_storage *storage; - - storage = find_variable_storage(param); - assert(!storage); - - storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, - this->next_temp); - this->variables.push_tail(storage); - - this->next_temp += type_size(param->type); - } - - if (!sig->return_type->is_void()) { - entry->return_reg = get_temp(sig->return_type); - } else { - entry->return_reg = ir_to_mesa_undef; - } - - this->function_signatures.push_tail(entry); - return entry; -} - -void -ir_to_mesa_visitor::visit(ir_call *ir) -{ - ir_to_mesa_instruction *call_inst; - ir_function_signature *sig = ir->get_callee(); - function_entry *entry = get_function_signature(sig); - int i; - - /* Process in parameters. */ - exec_list_iterator sig_iter = sig->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *param = (ir_variable *)sig_iter.get(); - - if (param->mode == ir_var_in || - param->mode == ir_var_inout) { - variable_storage *storage = find_variable_storage(param); - assert(storage); - - param_rval->accept(this); - ir_to_mesa_src_reg r = this->result; - - ir_to_mesa_dst_reg l; - l.file = storage->file; - l.index = storage->index; - l.reladdr = NULL; - l.writemask = WRITEMASK_XYZW; - l.cond_mask = COND_TR; - - for (i = 0; i < type_size(param->type); i++) { - ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); - l.index++; - r.index++; - } - } - - sig_iter.next(); - } - assert(!sig_iter.has_next()); - - /* Emit call instruction */ - call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL, - ir_to_mesa_undef_dst, ir_to_mesa_undef); - call_inst->function = entry; - - /* Process out parameters. */ - sig_iter = sig->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *param = (ir_variable *)sig_iter.get(); - - if (param->mode == ir_var_out || - param->mode == ir_var_inout) { - variable_storage *storage = find_variable_storage(param); - assert(storage); - - ir_to_mesa_src_reg r; - r.file = storage->file; - r.index = storage->index; - r.reladdr = NULL; - r.swizzle = SWIZZLE_NOOP; - r.negate = 0; - - param_rval->accept(this); - ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result); - - for (i = 0; i < type_size(param->type); i++) { - ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); - l.index++; - r.index++; - } - } - - sig_iter.next(); - } - assert(!sig_iter.has_next()); - - /* Process return value. */ - this->result = entry->return_reg; -} - -void -ir_to_mesa_visitor::visit(ir_texture *ir) -{ - ir_to_mesa_src_reg result_src, coord, lod_info, projector; - ir_to_mesa_dst_reg result_dst, coord_dst; - ir_to_mesa_instruction *inst = NULL; - prog_opcode opcode = OPCODE_NOP; - - ir->coordinate->accept(this); - - /* Put our coords in a temp. We'll need to modify them for shadow, - * projection, or LOD, so the only case we'd use it as is is if - * we're doing plain old texturing. Mesa IR optimization should - * handle cleaning up our mess in that case. - */ - coord = get_temp(glsl_type::vec4_type); - coord_dst = ir_to_mesa_dst_reg_from_src(coord); - ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, - this->result); - - if (ir->projector) { - ir->projector->accept(this); - projector = this->result; - } - - /* Storage for our result. Ideally for an assignment we'd be using - * the actual storage for the result here, instead. - */ - result_src = get_temp(glsl_type::vec4_type); - result_dst = ir_to_mesa_dst_reg_from_src(result_src); - - switch (ir->op) { - case ir_tex: - opcode = OPCODE_TEX; - break; - case ir_txb: - opcode = OPCODE_TXB; - ir->lod_info.bias->accept(this); - lod_info = this->result; - break; - case ir_txl: - opcode = OPCODE_TXL; - ir->lod_info.lod->accept(this); - lod_info = this->result; - break; - case ir_txd: - case ir_txf: - assert(!"GLSL 1.30 features unsupported"); - break; - } - - if (ir->projector) { - if (opcode == OPCODE_TEX) { - /* Slot the projector in as the last component of the coord. */ - coord_dst.writemask = WRITEMASK_W; - ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector); - coord_dst.writemask = WRITEMASK_XYZW; - opcode = OPCODE_TXP; - } else { - ir_to_mesa_src_reg coord_w = coord; - coord_w.swizzle = SWIZZLE_WWWW; - - /* For the other TEX opcodes there's no projective version - * since the last slot is taken up by lod info. Do the - * projective divide now. - */ - coord_dst.writemask = WRITEMASK_W; - ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector); - - coord_dst.writemask = WRITEMASK_XYZ; - ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w); - - coord_dst.writemask = WRITEMASK_XYZW; - coord.swizzle = SWIZZLE_XYZW; - } - } - - if (ir->shadow_comparitor) { - /* Slot the shadow value in as the second to last component of the - * coord. - */ - ir->shadow_comparitor->accept(this); - coord_dst.writemask = WRITEMASK_Z; - ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result); - coord_dst.writemask = WRITEMASK_XYZW; - } - - if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { - /* Mesa IR stores lod or lod bias in the last channel of the coords. */ - coord_dst.writemask = WRITEMASK_W; - ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info); - coord_dst.writemask = WRITEMASK_XYZW; - } - - inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord); - - if (ir->shadow_comparitor) - inst->tex_shadow = GL_TRUE; - - inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, - this->shader_program, - this->prog); - - const glsl_type *sampler_type = ir->sampler->type; - - switch (sampler_type->sampler_dimensionality) { - case GLSL_SAMPLER_DIM_1D: - inst->tex_target = (sampler_type->sampler_array) - ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; - break; - case GLSL_SAMPLER_DIM_2D: - inst->tex_target = (sampler_type->sampler_array) - ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; - break; - case GLSL_SAMPLER_DIM_3D: - inst->tex_target = TEXTURE_3D_INDEX; - break; - case GLSL_SAMPLER_DIM_CUBE: - inst->tex_target = TEXTURE_CUBE_INDEX; - break; - case GLSL_SAMPLER_DIM_RECT: - inst->tex_target = TEXTURE_RECT_INDEX; - break; - case GLSL_SAMPLER_DIM_BUF: - assert(!"FINISHME: Implement ARB_texture_buffer_object"); - break; - default: - assert(!"Should not get here."); - } - - this->result = result_src; -} - -void -ir_to_mesa_visitor::visit(ir_return *ir) -{ - if (ir->get_value()) { - ir_to_mesa_dst_reg l; - int i; - - assert(current_function); - - ir->get_value()->accept(this); - ir_to_mesa_src_reg r = this->result; - - l = ir_to_mesa_dst_reg_from_src(current_function->return_reg); - - for (i = 0; i < type_size(current_function->sig->return_type); i++) { - ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); - l.index++; - r.index++; - } - } - - ir_to_mesa_emit_op0(ir, OPCODE_RET); -} - -void -ir_to_mesa_visitor::visit(ir_discard *ir) -{ - struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; - - if (ir->condition) { - ir->condition->accept(this); - this->result.negate = ~this->result.negate; - ir_to_mesa_emit_op1(ir, OPCODE_KIL, ir_to_mesa_undef_dst, this->result); - } else { - ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV); - } - - fp->UsesKill = GL_TRUE; -} - -void -ir_to_mesa_visitor::visit(ir_if *ir) -{ - ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL; - ir_to_mesa_instruction *prev_inst; - - prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); - - ir->condition->accept(this); - assert(this->result.file != PROGRAM_UNDEFINED); - - if (this->options->EmitCondCodes) { - cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); - - /* See if we actually generated any instruction for generating - * the condition. If not, then cook up a move to a temp so we - * have something to set cond_update on. - */ - if (cond_inst == prev_inst) { - ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type); - cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV, - ir_to_mesa_dst_reg_from_src(temp), - result); - } - cond_inst->cond_update = GL_TRUE; - - if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF); - if_inst->dst_reg.cond_mask = COND_NE; - } else { - if_inst = ir_to_mesa_emit_op1(ir->condition, - OPCODE_IF, ir_to_mesa_undef_dst, - this->result); - } - - this->instructions.push_tail(if_inst); - - visit_exec_list(&ir->then_instructions, this); - - if (!ir->else_instructions.is_empty()) { - else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE); - visit_exec_list(&ir->else_instructions, this); - } - - if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF, - ir_to_mesa_undef_dst, ir_to_mesa_undef); -} - -ir_to_mesa_visitor::ir_to_mesa_visitor() -{ - result.file = PROGRAM_UNDEFINED; - next_temp = 1; - next_signature_id = 1; - current_function = NULL; - mem_ctx = ralloc_context(NULL); -} - -ir_to_mesa_visitor::~ir_to_mesa_visitor() -{ - ralloc_free(mem_ctx); -} - -static struct prog_src_register -mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg) -{ - struct prog_src_register mesa_reg; - - mesa_reg.File = reg.file; - assert(reg.index < (1 << INST_INDEX_BITS)); - mesa_reg.Index = reg.index; - mesa_reg.Swizzle = reg.swizzle; - mesa_reg.RelAddr = reg.reladdr != NULL; - mesa_reg.Negate = reg.negate; - mesa_reg.Abs = 0; - mesa_reg.HasIndex2 = GL_FALSE; - mesa_reg.RelAddr2 = 0; - mesa_reg.Index2 = 0; - - return mesa_reg; -} - -static void -set_branchtargets(ir_to_mesa_visitor *v, - struct prog_instruction *mesa_instructions, - int num_instructions) -{ - int if_count = 0, loop_count = 0; - int *if_stack, *loop_stack; - int if_stack_pos = 0, loop_stack_pos = 0; - int i, j; - - for (i = 0; i < num_instructions; i++) { - switch (mesa_instructions[i].Opcode) { - case OPCODE_IF: - if_count++; - break; - case OPCODE_BGNLOOP: - loop_count++; - break; - case OPCODE_BRK: - case OPCODE_CONT: - mesa_instructions[i].BranchTarget = -1; - break; - default: - break; - } - } - - if_stack = rzalloc_array(v->mem_ctx, int, if_count); - loop_stack = rzalloc_array(v->mem_ctx, int, loop_count); - - for (i = 0; i < num_instructions; i++) { - switch (mesa_instructions[i].Opcode) { - case OPCODE_IF: - if_stack[if_stack_pos] = i; - if_stack_pos++; - break; - case OPCODE_ELSE: - mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; - if_stack[if_stack_pos - 1] = i; - break; - case OPCODE_ENDIF: - mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; - if_stack_pos--; - break; - case OPCODE_BGNLOOP: - loop_stack[loop_stack_pos] = i; - loop_stack_pos++; - break; - case OPCODE_ENDLOOP: - loop_stack_pos--; - /* Rewrite any breaks/conts at this nesting level (haven't - * already had a BranchTarget assigned) to point to the end - * of the loop. - */ - for (j = loop_stack[loop_stack_pos]; j < i; j++) { - if (mesa_instructions[j].Opcode == OPCODE_BRK || - mesa_instructions[j].Opcode == OPCODE_CONT) { - if (mesa_instructions[j].BranchTarget == -1) { - mesa_instructions[j].BranchTarget = i; - } - } - } - /* The loop ends point at each other. */ - mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; - mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; - break; - case OPCODE_CAL: - foreach_iter(exec_list_iterator, iter, v->function_signatures) { - function_entry *entry = (function_entry *)iter.get(); - - if (entry->sig_id == mesa_instructions[i].BranchTarget) { - mesa_instructions[i].BranchTarget = entry->inst; - break; - } - } - break; - default: - break; - } - } -} - -static void -print_program(struct prog_instruction *mesa_instructions, - ir_instruction **mesa_instruction_annotation, - int num_instructions) -{ - ir_instruction *last_ir = NULL; - int i; - int indent = 0; - - for (i = 0; i < num_instructions; i++) { - struct prog_instruction *mesa_inst = mesa_instructions + i; - ir_instruction *ir = mesa_instruction_annotation[i]; - - fprintf(stdout, "%3d: ", i); - - if (last_ir != ir && ir) { - int j; - - for (j = 0; j < indent; j++) { - fprintf(stdout, " "); - } - ir->print(); - printf("\n"); - last_ir = ir; - - fprintf(stdout, " "); /* line number spacing. */ - } - - indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, - PROG_PRINT_DEBUG, NULL); - } -} - -static void -count_resources(struct gl_program *prog) -{ - unsigned int i; - - prog->SamplersUsed = 0; - - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = &prog->Instructions[i]; - - if (_mesa_is_tex_instruction(inst->Opcode)) { - prog->SamplerTargets[inst->TexSrcUnit] = - (gl_texture_index)inst->TexSrcTarget; - prog->SamplersUsed |= 1 << inst->TexSrcUnit; - if (inst->TexShadow) { - prog->ShadowSamplers |= 1 << inst->TexSrcUnit; - } - } - } - - _mesa_update_shader_textures_used(prog); -} - -struct uniform_sort { - struct gl_uniform *u; - int pos; -}; - -/* The shader_program->Uniforms list is almost sorted in increasing - * uniform->{Frag,Vert}Pos locations, but not quite when there are - * uniforms shared between targets. We need to add parameters in - * increasing order for the targets. - */ -static int -sort_uniforms(const void *a, const void *b) -{ - struct uniform_sort *u1 = (struct uniform_sort *)a; - struct uniform_sort *u2 = (struct uniform_sort *)b; - - return u1->pos - u2->pos; -} - -/* Add the uniforms to the parameters. The linker chose locations - * in our parameters lists (which weren't created yet), which the - * uniforms code will use to poke values into our parameters list - * when uniforms are updated. - */ -static void -add_uniforms_to_parameters_list(struct gl_shader_program *shader_program, - struct gl_shader *shader, - struct gl_program *prog) -{ - unsigned int i; - unsigned int next_sampler = 0, num_uniforms = 0; - struct uniform_sort *sorted_uniforms; - - sorted_uniforms = ralloc_array(NULL, struct uniform_sort, - shader_program->Uniforms->NumUniforms); - - for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) { - struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i; - int parameter_index = -1; - - switch (shader->Type) { - case GL_VERTEX_SHADER: - parameter_index = uniform->VertPos; - break; - case GL_FRAGMENT_SHADER: - parameter_index = uniform->FragPos; - break; - case GL_GEOMETRY_SHADER: - parameter_index = uniform->GeomPos; - break; - } - - /* Only add uniforms used in our target. */ - if (parameter_index != -1) { - sorted_uniforms[num_uniforms].pos = parameter_index; - sorted_uniforms[num_uniforms].u = uniform; - num_uniforms++; - } - } - - qsort(sorted_uniforms, num_uniforms, sizeof(struct uniform_sort), - sort_uniforms); - - for (i = 0; i < num_uniforms; i++) { - struct gl_uniform *uniform = sorted_uniforms[i].u; - int parameter_index = sorted_uniforms[i].pos; - const glsl_type *type = uniform->Type; - unsigned int size; - - if (type->is_vector() || - type->is_scalar()) { - size = type->vector_elements; - } else { - size = type_size(type) * 4; - } - - gl_register_file file; - if (type->is_sampler() || - (type->is_array() && type->fields.array->is_sampler())) { - file = PROGRAM_SAMPLER; - } else { - file = PROGRAM_UNIFORM; - } - - GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1, - uniform->Name); - - if (index < 0) { - index = _mesa_add_parameter(prog->Parameters, file, - uniform->Name, size, type->gl_type, - NULL, NULL, 0x0); - - /* Sampler uniform values are stored in prog->SamplerUnits, - * and the entry in that array is selected by this index we - * store in ParameterValues[]. - */ - if (file == PROGRAM_SAMPLER) { - for (unsigned int j = 0; j < size / 4; j++) - prog->Parameters->ParameterValues[index + j][0] = next_sampler++; - } - - /* The location chosen in the Parameters list here (returned - * from _mesa_add_uniform) has to match what the linker chose. - */ - if (index != parameter_index) { - fail_link(shader_program, "Allocation of uniform `%s' to target " - "failed (%d vs %d)\n", - uniform->Name, index, parameter_index); - } - } - } - - ralloc_free(sorted_uniforms); -} - -static void -set_uniform_initializer(struct gl_context *ctx, void *mem_ctx, - struct gl_shader_program *shader_program, - const char *name, const glsl_type *type, - ir_constant *val) -{ - if (type->is_record()) { - ir_constant *field_constant; - - field_constant = (ir_constant *)val->components.get_head(); - - for (unsigned int i = 0; i < type->length; i++) { - const glsl_type *field_type = type->fields.structure[i].type; - const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name, - type->fields.structure[i].name); - set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, - field_type, field_constant); - field_constant = (ir_constant *)field_constant->next; - } - return; - } - - int loc = _mesa_get_uniform_location(ctx, shader_program, name); - - if (loc == -1) { - fail_link(shader_program, - "Couldn't find uniform for initializer %s\n", name); - return; - } - - for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { - ir_constant *element; - const glsl_type *element_type; - if (type->is_array()) { - element = val->array_elements[i]; - element_type = type->fields.array; - } else { - element = val; - element_type = type; - } - - void *values; - - if (element_type->base_type == GLSL_TYPE_BOOL) { - int *conv = ralloc_array(mem_ctx, int, element_type->components()); - for (unsigned int j = 0; j < element_type->components(); j++) { - conv[j] = element->value.b[j]; - } - values = (void *)conv; - element_type = glsl_type::get_instance(GLSL_TYPE_INT, - element_type->vector_elements, - 1); - } else { - values = &element->value; - } - - if (element_type->is_matrix()) { - _mesa_uniform_matrix(ctx, shader_program, - element_type->matrix_columns, - element_type->vector_elements, - loc, 1, GL_FALSE, (GLfloat *)values); - loc += element_type->matrix_columns; - } else { - _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, - values, element_type->gl_type); - loc += type_size(element_type); - } - } -} - -static void -set_uniform_initializers(struct gl_context *ctx, - struct gl_shader_program *shader_program) -{ - void *mem_ctx = NULL; - - for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { - struct gl_shader *shader = shader_program->_LinkedShaders[i]; - - if (shader == NULL) - continue; - - foreach_iter(exec_list_iterator, iter, *shader->ir) { - ir_instruction *ir = (ir_instruction *)iter.get(); - ir_variable *var = ir->as_variable(); - - if (!var || var->mode != ir_var_uniform || !var->constant_value) - continue; - - if (!mem_ctx) - mem_ctx = ralloc_context(NULL); - - set_uniform_initializer(ctx, mem_ctx, shader_program, var->name, - var->type, var->constant_value); - } - } - - ralloc_free(mem_ctx); -} - -/* - * On a basic block basis, tracks available PROGRAM_TEMPORARY register - * channels for copy propagation and updates following instructions to - * use the original versions. - * - * The ir_to_mesa_visitor lazily produces code assuming that this pass - * will occur. As an example, a TXP production before this pass: - * - * 0: MOV TEMP[1], INPUT[4].xyyy; - * 1: MOV TEMP[1].w, INPUT[4].wwww; - * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; - * - * and after: - * - * 0: MOV TEMP[1], INPUT[4].xyyy; - * 1: MOV TEMP[1].w, INPUT[4].wwww; - * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; - * - * which allows for dead code elimination on TEMP[1]'s writes. - */ -void -ir_to_mesa_visitor::copy_propagate(void) -{ - ir_to_mesa_instruction **acp = rzalloc_array(mem_ctx, - ir_to_mesa_instruction *, - this->next_temp * 4); - - foreach_iter(exec_list_iterator, iter, this->instructions) { - ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); - - assert(inst->dst_reg.file != PROGRAM_TEMPORARY - || inst->dst_reg.index < this->next_temp); - - /* First, do any copy propagation possible into the src regs. */ - for (int r = 0; r < 3; r++) { - ir_to_mesa_instruction *first = NULL; - bool good = true; - int acp_base = inst->src_reg[r].index * 4; - - if (inst->src_reg[r].file != PROGRAM_TEMPORARY || - inst->src_reg[r].reladdr) - continue; - - /* See if we can find entries in the ACP consisting of MOVs - * from the same src register for all the swizzled channels - * of this src register reference. - */ - for (int i = 0; i < 4; i++) { - int src_chan = GET_SWZ(inst->src_reg[r].swizzle, i); - ir_to_mesa_instruction *copy_chan = acp[acp_base + src_chan]; - - if (!copy_chan) { - good = false; - break; - } - - if (!first) { - first = copy_chan; - } else { - if (first->src_reg[0].file != copy_chan->src_reg[0].file || - first->src_reg[0].index != copy_chan->src_reg[0].index) { - good = false; - break; - } - } - } - - if (good) { - /* We've now validated that we can copy-propagate to - * replace this src register reference. Do it. - */ - inst->src_reg[r].file = first->src_reg[0].file; - inst->src_reg[r].index = first->src_reg[0].index; - - int swizzle = 0; - for (int i = 0; i < 4; i++) { - int src_chan = GET_SWZ(inst->src_reg[r].swizzle, i); - ir_to_mesa_instruction *copy_inst = acp[acp_base + src_chan]; - swizzle |= (GET_SWZ(copy_inst->src_reg[0].swizzle, src_chan) << - (3 * i)); - } - inst->src_reg[r].swizzle = swizzle; - } - } - - switch (inst->op) { - case OPCODE_BGNLOOP: - case OPCODE_ENDLOOP: - case OPCODE_ELSE: - case OPCODE_ENDIF: - /* End of a basic block, clear the ACP entirely. */ - memset(acp, 0, sizeof(*acp) * this->next_temp * 4); - break; - - default: - /* Continuing the block, clear any written channels from - * the ACP. - */ - if (inst->dst_reg.file == PROGRAM_TEMPORARY && inst->dst_reg.reladdr) { - /* Any temporary might be written, so no copy propagation - * across this instruction. - */ - memset(acp, 0, sizeof(*acp) * this->next_temp * 4); - } else if (inst->dst_reg.file == PROGRAM_OUTPUT && - inst->dst_reg.reladdr) { - /* Any output might be written, so no copy propagation - * from outputs across this instruction. - */ - for (int r = 0; r < this->next_temp; r++) { - for (int c = 0; c < 4; c++) { - if (acp[4 * r + c]->src_reg[0].file == PROGRAM_OUTPUT) - acp[4 * r + c] = NULL; - } - } - } else if (inst->dst_reg.file == PROGRAM_TEMPORARY || - inst->dst_reg.file == PROGRAM_OUTPUT) { - /* Clear where it's used as dst. */ - if (inst->dst_reg.file == PROGRAM_TEMPORARY) { - for (int c = 0; c < 4; c++) { - if (inst->dst_reg.writemask & (1 << c)) { - acp[4 * inst->dst_reg.index + c] = NULL; - } - } - } - - /* Clear where it's used as src. */ - for (int r = 0; r < this->next_temp; r++) { - for (int c = 0; c < 4; c++) { - if (!acp[4 * r + c]) - continue; - - int src_chan = GET_SWZ(acp[4 * r + c]->src_reg[0].swizzle, c); - - if (acp[4 * r + c]->src_reg[0].file == inst->dst_reg.file && - acp[4 * r + c]->src_reg[0].index == inst->dst_reg.index && - inst->dst_reg.writemask & (1 << src_chan)) - { - acp[4 * r + c] = NULL; - } - } - } - } - break; - } - - /* If this is a copy, add it to the ACP. */ - if (inst->op == OPCODE_MOV && - inst->dst_reg.file == PROGRAM_TEMPORARY && - !inst->dst_reg.reladdr && - !inst->saturate && - !inst->src_reg[0].reladdr && - !inst->src_reg[0].negate) { - for (int i = 0; i < 4; i++) { - if (inst->dst_reg.writemask & (1 << i)) { - acp[4 * inst->dst_reg.index + i] = inst; - } - } - } - } - - ralloc_free(acp); -} - - -/** - * Convert a shader's GLSL IR into a Mesa gl_program. - */ -static struct gl_program * -get_mesa_program(struct gl_context *ctx, - struct gl_shader_program *shader_program, - struct gl_shader *shader) -{ - ir_to_mesa_visitor v; - struct prog_instruction *mesa_instructions, *mesa_inst; - ir_instruction **mesa_instruction_annotation; - int i; - struct gl_program *prog; - GLenum target; - const char *target_string; - GLboolean progress; - struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; - - switch (shader->Type) { - case GL_VERTEX_SHADER: - target = GL_VERTEX_PROGRAM_ARB; - target_string = "vertex"; - break; - case GL_FRAGMENT_SHADER: - target = GL_FRAGMENT_PROGRAM_ARB; - target_string = "fragment"; - break; - case GL_GEOMETRY_SHADER: - target = GL_GEOMETRY_PROGRAM_NV; - target_string = "geometry"; - break; - default: - assert(!"should not be reached"); - return NULL; - } - - validate_ir_tree(shader->ir); - - prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); - if (!prog) - return NULL; - prog->Parameters = _mesa_new_parameter_list(); - prog->Varying = _mesa_new_parameter_list(); - prog->Attributes = _mesa_new_parameter_list(); - v.ctx = ctx; - v.prog = prog; - v.shader_program = shader_program; - v.options = options; - - add_uniforms_to_parameters_list(shader_program, shader, prog); - - /* Emit Mesa IR for main(). */ - visit_exec_list(shader->ir, &v); - v.ir_to_mesa_emit_op0(NULL, OPCODE_END); - - /* Now emit bodies for any functions that were used. */ - do { - progress = GL_FALSE; - - foreach_iter(exec_list_iterator, iter, v.function_signatures) { - function_entry *entry = (function_entry *)iter.get(); - - if (!entry->bgn_inst) { - v.current_function = entry; - - entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB); - entry->bgn_inst->function = entry; - - visit_exec_list(&entry->sig->body, &v); - - ir_to_mesa_instruction *last; - last = (ir_to_mesa_instruction *)v.instructions.get_tail(); - if (last->op != OPCODE_RET) - v.ir_to_mesa_emit_op0(NULL, OPCODE_RET); - - ir_to_mesa_instruction *end; - end = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB); - end->function = entry; - - progress = GL_TRUE; - } - } - } while (progress); - - prog->NumTemporaries = v.next_temp; - - int num_instructions = 0; - foreach_iter(exec_list_iterator, iter, v.instructions) { - num_instructions++; - } - - mesa_instructions = - (struct prog_instruction *)calloc(num_instructions, - sizeof(*mesa_instructions)); - mesa_instruction_annotation = ralloc_array(v.mem_ctx, ir_instruction *, - num_instructions); - - v.copy_propagate(); - - /* Convert ir_mesa_instructions into prog_instructions. - */ - mesa_inst = mesa_instructions; - i = 0; - foreach_iter(exec_list_iterator, iter, v.instructions) { - const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); - - mesa_inst->Opcode = inst->op; - mesa_inst->CondUpdate = inst->cond_update; - if (inst->saturate) - mesa_inst->SaturateMode = SATURATE_ZERO_ONE; - mesa_inst->DstReg.File = inst->dst_reg.file; - mesa_inst->DstReg.Index = inst->dst_reg.index; - mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask; - mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask; - mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL; - mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]); - mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]); - mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]); - mesa_inst->TexSrcUnit = inst->sampler; - mesa_inst->TexSrcTarget = inst->tex_target; - mesa_inst->TexShadow = inst->tex_shadow; - mesa_instruction_annotation[i] = inst->ir; - - /* Set IndirectRegisterFiles. */ - if (mesa_inst->DstReg.RelAddr) - prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File; - - /* Update program's bitmask of indirectly accessed register files */ - for (unsigned src = 0; src < 3; src++) - if (mesa_inst->SrcReg[src].RelAddr) - prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; - - if (options->EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) { - fail_link(shader_program, "Couldn't flatten if statement\n"); - } - - switch (mesa_inst->Opcode) { - case OPCODE_BGNSUB: - inst->function->inst = i; - mesa_inst->Comment = strdup(inst->function->sig->function_name()); - break; - case OPCODE_ENDSUB: - mesa_inst->Comment = strdup(inst->function->sig->function_name()); - break; - case OPCODE_CAL: - mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */ - break; - case OPCODE_ARL: - prog->NumAddressRegs = 1; - break; - default: - break; - } - - mesa_inst++; - i++; - - if (!shader_program->LinkStatus) - break; - } - - if (!shader_program->LinkStatus) { - free(mesa_instructions); - _mesa_reference_program(ctx, &shader->Program, NULL); - return NULL; - } - - set_branchtargets(&v, mesa_instructions, num_instructions); - - if (ctx->Shader.Flags & GLSL_DUMP) { - printf("\n"); - printf("GLSL IR for linked %s program %d:\n", target_string, - shader_program->Name); - _mesa_print_ir(shader->ir, NULL); - printf("\n"); - printf("\n"); - printf("Mesa IR for linked %s program %d:\n", target_string, - shader_program->Name); - print_program(mesa_instructions, mesa_instruction_annotation, - num_instructions); - } - - prog->Instructions = mesa_instructions; - prog->NumInstructions = num_instructions; - - do_set_program_inouts(shader->ir, prog); - count_resources(prog); - - _mesa_reference_program(ctx, &shader->Program, prog); - - if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { - _mesa_optimize_program(ctx, prog); - } - - return prog; -} - -extern "C" { - -/** - * Called via ctx->Driver.CompilerShader(). - * This is a no-op. - * XXX can we remove the ctx->Driver.CompileShader() hook? - */ -GLboolean -_mesa_ir_compile_shader(struct gl_context *ctx, struct gl_shader *shader) -{ - assert(shader->CompileStatus); - (void) ctx; - - return GL_TRUE; -} - - -/** - * Link a shader. - * Called via ctx->Driver.LinkShader() - * This actually involves converting GLSL IR into Mesa gl_programs with - * code lowering and other optimizations. - */ -GLboolean -_mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) -{ - assert(prog->LinkStatus); - - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { - if (prog->_LinkedShaders[i] == NULL) - continue; - - bool progress; - exec_list *ir = prog->_LinkedShaders[i]->ir; - const struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; - - do { - progress = false; - - /* Lowering */ - do_mat_op_to_vec(ir); - lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2 - | LOG_TO_LOG2 - | ((options->EmitNoPow) ? POW_TO_EXP2 : 0))); - - progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; - - progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress; - - progress = lower_quadop_vector(ir, true) || progress; - - if (options->EmitNoIfs) { - progress = lower_discard(ir) || progress; - progress = lower_if_to_cond_assign(ir) || progress; - } - - if (options->EmitNoNoise) - progress = lower_noise(ir) || progress; - - /* If there are forms of indirect addressing that the driver - * cannot handle, perform the lowering pass. - */ - if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput - || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) - progress = - lower_variable_index_to_cond_assign(ir, - options->EmitNoIndirectInput, - options->EmitNoIndirectOutput, - options->EmitNoIndirectTemp, - options->EmitNoIndirectUniform) - || progress; - - progress = do_vec_index_to_cond_assign(ir) || progress; - } while (progress); - - validate_ir_tree(ir); - } - - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { - struct gl_program *linked_prog; - - if (prog->_LinkedShaders[i] == NULL) - continue; - - linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); - - if (linked_prog) { - bool ok = true; - - switch (prog->_LinkedShaders[i]->Type) { - case GL_VERTEX_SHADER: - _mesa_reference_vertprog(ctx, &prog->VertexProgram, - (struct gl_vertex_program *)linked_prog); - ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, - linked_prog); - break; - case GL_FRAGMENT_SHADER: - _mesa_reference_fragprog(ctx, &prog->FragmentProgram, - (struct gl_fragment_program *)linked_prog); - ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, - linked_prog); - break; - case GL_GEOMETRY_SHADER: - _mesa_reference_geomprog(ctx, &prog->GeometryProgram, - (struct gl_geometry_program *)linked_prog); - ok = ctx->Driver.ProgramStringNotify(ctx, GL_GEOMETRY_PROGRAM_NV, - linked_prog); - break; - } - if (!ok) { - return GL_FALSE; - } - } - - _mesa_reference_program(ctx, &linked_prog, NULL); - } - - return GL_TRUE; -} - - -/** - * Compile a GLSL shader. Called via glCompileShader(). - */ -void -_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) -{ - struct _mesa_glsl_parse_state *state = - new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); - - const char *source = shader->Source; - /* Check if the user called glCompileShader without first calling - * glShaderSource. This should fail to compile, but not raise a GL_ERROR. - */ - if (source == NULL) { - shader->CompileStatus = GL_FALSE; - return; - } - - state->error = preprocess(state, &source, &state->info_log, - &ctx->Extensions, ctx->API); - - if (ctx->Shader.Flags & GLSL_DUMP) { - printf("GLSL source for shader %d:\n", shader->Name); - printf("%s\n", shader->Source); - } - - if (!state->error) { - _mesa_glsl_lexer_ctor(state, source); - _mesa_glsl_parse(state); - _mesa_glsl_lexer_dtor(state); - } - - ralloc_free(shader->ir); - shader->ir = new(shader) exec_list; - if (!state->error && !state->translation_unit.is_empty()) - _mesa_ast_to_hir(shader->ir, state); - - if (!state->error && !shader->ir->is_empty()) { - validate_ir_tree(shader->ir); - - /* Do some optimization at compile time to reduce shader IR size - * and reduce later work if the same shader is linked multiple times - */ - while (do_common_optimization(shader->ir, false, 32)) - ; - - validate_ir_tree(shader->ir); - } - - shader->symbols = state->symbols; - - shader->CompileStatus = !state->error; - shader->InfoLog = state->info_log; - shader->Version = state->language_version; - memcpy(shader->builtins_to_link, state->builtins_to_link, - sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); - shader->num_builtins_to_link = state->num_builtins_to_link; - - if (ctx->Shader.Flags & GLSL_LOG) { - _mesa_write_shader_to_file(shader); - } - - if (ctx->Shader.Flags & GLSL_DUMP) { - if (shader->CompileStatus) { - printf("GLSL IR for shader %d:\n", shader->Name); - _mesa_print_ir(shader->ir, NULL); - printf("\n\n"); - } else { - printf("GLSL shader %d failed to compile.\n", shader->Name); - } - if (shader->InfoLog && shader->InfoLog[0] != 0) { - printf("GLSL shader %d info log:\n", shader->Name); - printf("%s\n", shader->InfoLog); - } - } - - /* Retain any live IR, but trash the rest. */ - reparent_ir(shader->ir, shader->ir); - - ralloc_free(state); - - if (shader->CompileStatus) { - if (!ctx->Driver.CompileShader(ctx, shader)) - shader->CompileStatus = GL_FALSE; - } -} - - -/** - * Link a GLSL shader program. Called via glLinkProgram(). - */ -void -_mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) -{ - unsigned int i; - - _mesa_clear_shader_program_data(ctx, prog); - - prog->LinkStatus = GL_TRUE; - - for (i = 0; i < prog->NumShaders; i++) { - if (!prog->Shaders[i]->CompileStatus) { - fail_link(prog, "linking with uncompiled shader"); - prog->LinkStatus = GL_FALSE; - } - } - - prog->Varying = _mesa_new_parameter_list(); - _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); - _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); - _mesa_reference_geomprog(ctx, &prog->GeometryProgram, NULL); - - if (prog->LinkStatus) { - link_shaders(ctx, prog); - } - - if (prog->LinkStatus) { - if (!ctx->Driver.LinkShader(ctx, prog)) { - prog->LinkStatus = GL_FALSE; - } - } - - set_uniform_initializers(ctx, prog); - - if (ctx->Shader.Flags & GLSL_DUMP) { - if (!prog->LinkStatus) { - printf("GLSL shader program %d failed to link\n", prog->Name); - } - - if (prog->InfoLog && prog->InfoLog[0] != 0) { - printf("GLSL shader program %d info log:\n", prog->Name); - printf("%s\n", prog->InfoLog); - } - } -} - -} /* extern "C" */ +/* + * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. + * Copyright (C) 2008 VMware, Inc. All Rights Reserved. + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file ir_to_mesa.cpp + * + * Translate GLSL IR to Mesa's gl_program representation. + */ + +#include +#include "main/compiler.h" +#include "ir.h" +#include "ir_visitor.h" +#include "ir_print_visitor.h" +#include "ir_expression_flattening.h" +#include "glsl_types.h" +#include "glsl_parser_extras.h" +#include "../glsl/program.h" +#include "ir_optimization.h" +#include "ast.h" + +extern "C" { +#include "main/mtypes.h" +#include "main/shaderapi.h" +#include "main/shaderobj.h" +#include "main/uniforms.h" +#include "program/hash_table.h" +#include "program/prog_instruction.h" +#include "program/prog_optimize.h" +#include "program/prog_print.h" +#include "program/program.h" +#include "program/prog_uniform.h" +#include "program/prog_parameter.h" +#include "program/sampler.h" +} + +static int swizzle_for_size(int size); + +/** + * This struct is a corresponding struct to Mesa prog_src_register, with + * wider fields. + */ +typedef struct ir_to_mesa_src_reg { + ir_to_mesa_src_reg(int file, int index, const glsl_type *type) + { + this->file = (gl_register_file) file; + this->index = index; + if (type && (type->is_scalar() || type->is_vector() || type->is_matrix())) + this->swizzle = swizzle_for_size(type->vector_elements); + else + this->swizzle = SWIZZLE_XYZW; + this->negate = 0; + this->reladdr = NULL; + } + + ir_to_mesa_src_reg() + { + this->file = PROGRAM_UNDEFINED; + this->index = 0; + this->swizzle = 0; + this->negate = 0; + this->reladdr = NULL; + } + + gl_register_file file; /**< PROGRAM_* from Mesa */ + int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ + GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ + int negate; /**< NEGATE_XYZW mask from mesa */ + /** Register index should be offset by the integer in this reg. */ + ir_to_mesa_src_reg *reladdr; +} ir_to_mesa_src_reg; + +typedef struct ir_to_mesa_dst_reg { + int file; /**< PROGRAM_* from Mesa */ + int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ + int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ + GLuint cond_mask:4; + /** Register index should be offset by the integer in this reg. */ + ir_to_mesa_src_reg *reladdr; +} ir_to_mesa_dst_reg; + +extern ir_to_mesa_src_reg ir_to_mesa_undef; + +class ir_to_mesa_instruction : public exec_node { +public: + /* Callers of this ralloc-based new need not call delete. It's + * easier to just ralloc_free 'ctx' (or any of its ancestors). */ + static void* operator new(size_t size, void *ctx) + { + void *node; + + node = rzalloc_size(ctx, size); + assert(node != NULL); + + return node; + } + + enum prog_opcode op; + ir_to_mesa_dst_reg dst_reg; + ir_to_mesa_src_reg src_reg[3]; + /** Pointer to the ir source this tree came from for debugging */ + ir_instruction *ir; + GLboolean cond_update; + bool saturate; + int sampler; /**< sampler index */ + int tex_target; /**< One of TEXTURE_*_INDEX */ + GLboolean tex_shadow; + + class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */ +}; + +class variable_storage : public exec_node { +public: + variable_storage(ir_variable *var, gl_register_file file, int index) + : file(file), index(index), var(var) + { + /* empty */ + } + + gl_register_file file; + int index; + ir_variable *var; /* variable that maps to this, if any */ +}; + +class function_entry : public exec_node { +public: + ir_function_signature *sig; + + /** + * identifier of this function signature used by the program. + * + * At the point that Mesa instructions for function calls are + * generated, we don't know the address of the first instruction of + * the function body. So we make the BranchTarget that is called a + * small integer and rewrite them during set_branchtargets(). + */ + int sig_id; + + /** + * Pointer to first instruction of the function body. + * + * Set during function body emits after main() is processed. + */ + ir_to_mesa_instruction *bgn_inst; + + /** + * Index of the first instruction of the function body in actual + * Mesa IR. + * + * Set after convertion from ir_to_mesa_instruction to prog_instruction. + */ + int inst; + + /** Storage for the return value. */ + ir_to_mesa_src_reg return_reg; +}; + +class ir_to_mesa_visitor : public ir_visitor { +public: + ir_to_mesa_visitor(); + ~ir_to_mesa_visitor(); + + function_entry *current_function; + + struct gl_context *ctx; + struct gl_program *prog; + struct gl_shader_program *shader_program; + struct gl_shader_compiler_options *options; + + int next_temp; + + variable_storage *find_variable_storage(ir_variable *var); + + function_entry *get_function_signature(ir_function_signature *sig); + + ir_to_mesa_src_reg get_temp(const glsl_type *type); + void reladdr_to_temp(ir_instruction *ir, + ir_to_mesa_src_reg *reg, int *num_reladdr); + + struct ir_to_mesa_src_reg src_reg_for_float(float val); + + /** + * \name Visit methods + * + * As typical for the visitor pattern, there must be one \c visit method for + * each concrete subclass of \c ir_instruction. Virtual base classes within + * the hierarchy should not have \c visit methods. + */ + /*@{*/ + virtual void visit(ir_variable *); + virtual void visit(ir_loop *); + virtual void visit(ir_loop_jump *); + virtual void visit(ir_function_signature *); + virtual void visit(ir_function *); + virtual void visit(ir_expression *); + virtual void visit(ir_swizzle *); + virtual void visit(ir_dereference_variable *); + virtual void visit(ir_dereference_array *); + virtual void visit(ir_dereference_record *); + virtual void visit(ir_assignment *); + virtual void visit(ir_constant *); + virtual void visit(ir_call *); + virtual void visit(ir_return *); + virtual void visit(ir_discard *); + virtual void visit(ir_texture *); + virtual void visit(ir_if *); + /*@}*/ + + struct ir_to_mesa_src_reg result; + + /** List of variable_storage */ + exec_list variables; + + /** List of function_entry */ + exec_list function_signatures; + int next_signature_id; + + /** List of ir_to_mesa_instruction */ + exec_list instructions; + + ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir, + enum prog_opcode op); + + ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0); + + ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0, + ir_to_mesa_src_reg src1); + + ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0, + ir_to_mesa_src_reg src1, + ir_to_mesa_src_reg src2); + + /** + * Emit the correct dot-product instruction for the type of arguments + * + * \sa ir_to_mesa_emit_op2 + */ + void ir_to_mesa_emit_dp(ir_instruction *ir, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0, + ir_to_mesa_src_reg src1, + unsigned elements); + + void ir_to_mesa_emit_scalar_op1(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0); + + void ir_to_mesa_emit_scalar_op2(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0, + ir_to_mesa_src_reg src1); + + void emit_scs(ir_instruction *ir, enum prog_opcode op, + ir_to_mesa_dst_reg dst, + const ir_to_mesa_src_reg &src); + + GLboolean try_emit_mad(ir_expression *ir, + int mul_operand); + GLboolean try_emit_sat(ir_expression *ir); + + void emit_swz(ir_expression *ir); + + bool process_move_condition(ir_rvalue *ir); + + void copy_propagate(void); + + void *mem_ctx; +}; + +ir_to_mesa_src_reg ir_to_mesa_undef = ir_to_mesa_src_reg(PROGRAM_UNDEFINED, 0, NULL); + +ir_to_mesa_dst_reg ir_to_mesa_undef_dst = { + PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL, +}; + +ir_to_mesa_dst_reg ir_to_mesa_address_reg = { + PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL +}; + +static void +fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); + +static void +fail_link(struct gl_shader_program *prog, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + ralloc_vasprintf_append(&prog->InfoLog, fmt, args); + va_end(args); + + prog->LinkStatus = GL_FALSE; +} + +static int +swizzle_for_size(int size) +{ + int size_swizzles[4] = { + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), + }; + + assert((size >= 1) && (size <= 4)); + return size_swizzles[size - 1]; +} + +ir_to_mesa_instruction * +ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0, + ir_to_mesa_src_reg src1, + ir_to_mesa_src_reg src2) +{ + ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); + int num_reladdr = 0; + + /* If we have to do relative addressing, we want to load the ARL + * reg directly for one of the regs, and preload the other reladdr + * sources into temps. + */ + num_reladdr += dst.reladdr != NULL; + num_reladdr += src0.reladdr != NULL; + num_reladdr += src1.reladdr != NULL; + num_reladdr += src2.reladdr != NULL; + + reladdr_to_temp(ir, &src2, &num_reladdr); + reladdr_to_temp(ir, &src1, &num_reladdr); + reladdr_to_temp(ir, &src0, &num_reladdr); + + if (dst.reladdr) { + ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, + *dst.reladdr); + + num_reladdr--; + } + assert(num_reladdr == 0); + + inst->op = op; + inst->dst_reg = dst; + inst->src_reg[0] = src0; + inst->src_reg[1] = src1; + inst->src_reg[2] = src2; + inst->ir = ir; + + inst->function = NULL; + + this->instructions.push_tail(inst); + + return inst; +} + + +ir_to_mesa_instruction * +ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0, + ir_to_mesa_src_reg src1) +{ + return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef); +} + +ir_to_mesa_instruction * +ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0) +{ + assert(dst.writemask != 0); + return ir_to_mesa_emit_op3(ir, op, dst, + src0, ir_to_mesa_undef, ir_to_mesa_undef); +} + +ir_to_mesa_instruction * +ir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir, + enum prog_opcode op) +{ + return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst, + ir_to_mesa_undef, + ir_to_mesa_undef, + ir_to_mesa_undef); +} + +void +ir_to_mesa_visitor::ir_to_mesa_emit_dp(ir_instruction *ir, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0, + ir_to_mesa_src_reg src1, + unsigned elements) +{ + static const gl_inst_opcode dot_opcodes[] = { + OPCODE_DP2, OPCODE_DP3, OPCODE_DP4 + }; + + ir_to_mesa_emit_op3(ir, dot_opcodes[elements - 2], + dst, src0, src1, ir_to_mesa_undef); +} + +inline ir_to_mesa_dst_reg +ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg) +{ + ir_to_mesa_dst_reg dst_reg; + + dst_reg.file = reg.file; + dst_reg.index = reg.index; + dst_reg.writemask = WRITEMASK_XYZW; + dst_reg.cond_mask = COND_TR; + dst_reg.reladdr = reg.reladdr; + + return dst_reg; +} + +inline ir_to_mesa_src_reg +ir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg) +{ + return ir_to_mesa_src_reg(reg.file, reg.index, NULL); +} + +/** + * Emits Mesa scalar opcodes to produce unique answers across channels. + * + * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X + * channel determines the result across all channels. So to do a vec4 + * of this operation, we want to emit a scalar per source channel used + * to produce dest channels. + */ +void +ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg orig_src0, + ir_to_mesa_src_reg orig_src1) +{ + int i, j; + int done_mask = ~dst.writemask; + + /* Mesa RCP is a scalar operation splatting results to all channels, + * like ARB_fp/vp. So emit as many RCPs as necessary to cover our + * dst channels. + */ + for (i = 0; i < 4; i++) { + GLuint this_mask = (1 << i); + ir_to_mesa_instruction *inst; + ir_to_mesa_src_reg src0 = orig_src0; + ir_to_mesa_src_reg src1 = orig_src1; + + if (done_mask & this_mask) + continue; + + GLuint src0_swiz = GET_SWZ(src0.swizzle, i); + GLuint src1_swiz = GET_SWZ(src1.swizzle, i); + for (j = i + 1; j < 4; j++) { + /* If there is another enabled component in the destination that is + * derived from the same inputs, generate its value on this pass as + * well. + */ + if (!(done_mask & (1 << j)) && + GET_SWZ(src0.swizzle, j) == src0_swiz && + GET_SWZ(src1.swizzle, j) == src1_swiz) { + this_mask |= (1 << j); + } + } + src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, + src0_swiz, src0_swiz); + src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, + src1_swiz, src1_swiz); + + inst = ir_to_mesa_emit_op2(ir, op, + dst, + src0, + src1); + inst->dst_reg.writemask = this_mask; + done_mask |= this_mask; + } +} + +void +ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir, + enum prog_opcode op, + ir_to_mesa_dst_reg dst, + ir_to_mesa_src_reg src0) +{ + ir_to_mesa_src_reg undef = ir_to_mesa_undef; + + undef.swizzle = SWIZZLE_XXXX; + + ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef); +} + +/** + * Emit an OPCODE_SCS instruction + * + * The \c SCS opcode functions a bit differently than the other Mesa (or + * ARB_fragment_program) opcodes. Instead of splatting its result across all + * four components of the destination, it writes one value to the \c x + * component and another value to the \c y component. + * + * \param ir IR instruction being processed + * \param op Either \c OPCODE_SIN or \c OPCODE_COS depending on which + * value is desired. + * \param dst Destination register + * \param src Source register + */ +void +ir_to_mesa_visitor::emit_scs(ir_instruction *ir, enum prog_opcode op, + ir_to_mesa_dst_reg dst, + const ir_to_mesa_src_reg &src) +{ + /* Vertex programs cannot use the SCS opcode. + */ + if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { + ir_to_mesa_emit_scalar_op1(ir, op, dst, src); + return; + } + + const unsigned component = (op == OPCODE_SIN) ? 0 : 1; + const unsigned scs_mask = (1U << component); + int done_mask = ~dst.writemask; + ir_to_mesa_src_reg tmp; + + assert(op == OPCODE_SIN || op == OPCODE_COS); + + /* If there are compnents in the destination that differ from the component + * that will be written by the SCS instrution, we'll need a temporary. + */ + if (scs_mask != unsigned(dst.writemask)) { + tmp = get_temp(glsl_type::vec4_type); + } + + for (unsigned i = 0; i < 4; i++) { + unsigned this_mask = (1U << i); + ir_to_mesa_src_reg src0 = src; + + if ((done_mask & this_mask) != 0) + continue; + + /* The source swizzle specified which component of the source generates + * sine / cosine for the current component in the destination. The SCS + * instruction requires that this value be swizzle to the X component. + * Replace the current swizzle with a swizzle that puts the source in + * the X component. + */ + unsigned src0_swiz = GET_SWZ(src.swizzle, i); + + src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, + src0_swiz, src0_swiz); + for (unsigned j = i + 1; j < 4; j++) { + /* If there is another enabled component in the destination that is + * derived from the same inputs, generate its value on this pass as + * well. + */ + if (!(done_mask & (1 << j)) && + GET_SWZ(src0.swizzle, j) == src0_swiz) { + this_mask |= (1 << j); + } + } + + if (this_mask != scs_mask) { + ir_to_mesa_instruction *inst; + ir_to_mesa_dst_reg tmp_dst = ir_to_mesa_dst_reg_from_src(tmp); + + /* Emit the SCS instruction. + */ + inst = ir_to_mesa_emit_op1(ir, OPCODE_SCS, tmp_dst, src0); + inst->dst_reg.writemask = scs_mask; + + /* Move the result of the SCS instruction to the desired location in + * the destination. + */ + tmp.swizzle = MAKE_SWIZZLE4(component, component, + component, component); + inst = ir_to_mesa_emit_op1(ir, OPCODE_SCS, dst, tmp); + inst->dst_reg.writemask = this_mask; + } else { + /* Emit the SCS instruction to write directly to the destination. + */ + ir_to_mesa_instruction *inst = + ir_to_mesa_emit_op1(ir, OPCODE_SCS, dst, src0); + inst->dst_reg.writemask = scs_mask; + } + + done_mask |= this_mask; + } +} + +struct ir_to_mesa_src_reg +ir_to_mesa_visitor::src_reg_for_float(float val) +{ + ir_to_mesa_src_reg src_reg(PROGRAM_CONSTANT, -1, NULL); + + src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, + &val, 1, &src_reg.swizzle); + + return src_reg; +} + +static int +type_size(const struct glsl_type *type) +{ + unsigned int i; + int size; + + switch (type->base_type) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_BOOL: + if (type->is_matrix()) { + return type->matrix_columns; + } else { + /* Regardless of size of vector, it gets a vec4. This is bad + * packing for things like floats, but otherwise arrays become a + * mess. Hopefully a later pass over the code can pack scalars + * down if appropriate. + */ + return 1; + } + case GLSL_TYPE_ARRAY: + assert(type->length > 0); + return type_size(type->fields.array) * type->length; + case GLSL_TYPE_STRUCT: + size = 0; + for (i = 0; i < type->length; i++) { + size += type_size(type->fields.structure[i].type); + } + return size; + case GLSL_TYPE_SAMPLER: + /* Samplers take up one slot in UNIFORMS[], but they're baked in + * at link time. + */ + return 1; + default: + assert(0); + return 0; + } +} + +/** + * In the initial pass of codegen, we assign temporary numbers to + * intermediate results. (not SSA -- variable assignments will reuse + * storage). Actual register allocation for the Mesa VM occurs in a + * pass over the Mesa IR later. + */ +ir_to_mesa_src_reg +ir_to_mesa_visitor::get_temp(const glsl_type *type) +{ + ir_to_mesa_src_reg src_reg; + int swizzle[4]; + int i; + + src_reg.file = PROGRAM_TEMPORARY; + src_reg.index = next_temp; + src_reg.reladdr = NULL; + next_temp += type_size(type); + + if (type->is_array() || type->is_record()) { + src_reg.swizzle = SWIZZLE_NOOP; + } else { + for (i = 0; i < type->vector_elements; i++) + swizzle[i] = i; + for (; i < 4; i++) + swizzle[i] = type->vector_elements - 1; + src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], + swizzle[2], swizzle[3]); + } + src_reg.negate = 0; + + return src_reg; +} + +variable_storage * +ir_to_mesa_visitor::find_variable_storage(ir_variable *var) +{ + + variable_storage *entry; + + foreach_iter(exec_list_iterator, iter, this->variables) { + entry = (variable_storage *)iter.get(); + + if (entry->var == var) + return entry; + } + + return NULL; +} + +void +ir_to_mesa_visitor::visit(ir_variable *ir) +{ + if (strcmp(ir->name, "gl_FragCoord") == 0) { + struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; + + fp->OriginUpperLeft = ir->origin_upper_left; + fp->PixelCenterInteger = ir->pixel_center_integer; + + } else if (strcmp(ir->name, "gl_FragDepth") == 0) { + struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; + switch (ir->depth_layout) { + case ir_depth_layout_none: + fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE; + break; + case ir_depth_layout_any: + fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY; + break; + case ir_depth_layout_greater: + fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER; + break; + case ir_depth_layout_less: + fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS; + break; + case ir_depth_layout_unchanged: + fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED; + break; + default: + assert(0); + break; + } + } + + if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { + unsigned int i; + const struct gl_builtin_uniform_desc *statevar; + + for (i = 0; _mesa_builtin_uniform_desc[i].name; i++) { + if (strcmp(ir->name, _mesa_builtin_uniform_desc[i].name) == 0) + break; + } + + if (!_mesa_builtin_uniform_desc[i].name) { + fail_link(this->shader_program, + "Failed to find builtin uniform `%s'\n", ir->name); + return; + } + + statevar = &_mesa_builtin_uniform_desc[i]; + + int array_count; + if (ir->type->is_array()) { + array_count = ir->type->length; + } else { + array_count = 1; + } + + /* Check if this statevar's setup in the STATE file exactly + * matches how we'll want to reference it as a + * struct/array/whatever. If not, then we need to move it into + * temporary storage and hope that it'll get copy-propagated + * out. + */ + for (i = 0; i < statevar->num_elements; i++) { + if (statevar->elements[i].swizzle != SWIZZLE_XYZW) { + break; + } + } + + struct variable_storage *storage; + ir_to_mesa_dst_reg dst; + if (i == statevar->num_elements) { + /* We'll set the index later. */ + storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); + this->variables.push_tail(storage); + + dst = ir_to_mesa_undef_dst; + } else { + storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, + this->next_temp); + this->variables.push_tail(storage); + this->next_temp += type_size(ir->type); + + dst = ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg(PROGRAM_TEMPORARY, + storage->index, + NULL)); + } + + + for (int a = 0; a < array_count; a++) { + for (unsigned int i = 0; i < statevar->num_elements; i++) { + struct gl_builtin_uniform_element *element = &statevar->elements[i]; + int tokens[STATE_LENGTH]; + + memcpy(tokens, element->tokens, sizeof(element->tokens)); + if (ir->type->is_array()) { + tokens[1] = a; + } + + int index = _mesa_add_state_reference(this->prog->Parameters, + (gl_state_index *)tokens); + + if (storage->file == PROGRAM_STATE_VAR) { + if (storage->index == -1) { + storage->index = index; + } else { + assert(index == + (int)(storage->index + a * statevar->num_elements + i)); + } + } else { + ir_to_mesa_src_reg src(PROGRAM_STATE_VAR, index, NULL); + src.swizzle = element->swizzle; + ir_to_mesa_emit_op1(ir, OPCODE_MOV, dst, src); + /* even a float takes up a whole vec4 reg in a struct/array. */ + dst.index++; + } + } + } + if (storage->file == PROGRAM_TEMPORARY && + dst.index != storage->index + type_size(ir->type)) { + fail_link(this->shader_program, + "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", + ir->name, dst.index - storage->index, + type_size(ir->type)); + } + } +} + +void +ir_to_mesa_visitor::visit(ir_loop *ir) +{ + ir_dereference_variable *counter = NULL; + + if (ir->counter != NULL) + counter = new(ir) ir_dereference_variable(ir->counter); + + if (ir->from != NULL) { + assert(ir->counter != NULL); + + ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); + + a->accept(this); + delete a; + } + + ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP); + + if (ir->to) { + ir_expression *e = + new(ir) ir_expression(ir->cmp, glsl_type::bool_type, + counter, ir->to); + ir_if *if_stmt = new(ir) ir_if(e); + + ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); + + if_stmt->then_instructions.push_tail(brk); + + if_stmt->accept(this); + + delete if_stmt; + delete e; + delete brk; + } + + visit_exec_list(&ir->body_instructions, this); + + if (ir->increment) { + ir_expression *e = + new(ir) ir_expression(ir_binop_add, counter->type, + counter, ir->increment); + + ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); + + a->accept(this); + delete a; + delete e; + } + + ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP); +} + +void +ir_to_mesa_visitor::visit(ir_loop_jump *ir) +{ + switch (ir->mode) { + case ir_loop_jump::jump_break: + ir_to_mesa_emit_op0(NULL, OPCODE_BRK); + break; + case ir_loop_jump::jump_continue: + ir_to_mesa_emit_op0(NULL, OPCODE_CONT); + break; + } +} + + +void +ir_to_mesa_visitor::visit(ir_function_signature *ir) +{ + assert(0); + (void)ir; +} + +void +ir_to_mesa_visitor::visit(ir_function *ir) +{ + /* Ignore function bodies other than main() -- we shouldn't see calls to + * them since they should all be inlined before we get to ir_to_mesa. + */ + if (strcmp(ir->name, "main") == 0) { + const ir_function_signature *sig; + exec_list empty; + + sig = ir->matching_signature(&empty); + + assert(sig); + + foreach_iter(exec_list_iterator, iter, sig->body) { + ir_instruction *ir = (ir_instruction *)iter.get(); + + ir->accept(this); + } + } +} + +GLboolean +ir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) +{ + int nonmul_operand = 1 - mul_operand; + ir_to_mesa_src_reg a, b, c; + + ir_expression *expr = ir->operands[mul_operand]->as_expression(); + if (!expr || expr->operation != ir_binop_mul) + return false; + + expr->operands[0]->accept(this); + a = this->result; + expr->operands[1]->accept(this); + b = this->result; + ir->operands[nonmul_operand]->accept(this); + c = this->result; + + this->result = get_temp(ir->type); + ir_to_mesa_emit_op3(ir, OPCODE_MAD, + ir_to_mesa_dst_reg_from_src(this->result), a, b, c); + + return true; +} + +GLboolean +ir_to_mesa_visitor::try_emit_sat(ir_expression *ir) +{ + /* Saturates were only introduced to vertex programs in + * NV_vertex_program3, so don't give them to drivers in the VP. + */ + if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) + return false; + + ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); + if (!sat_src) + return false; + + sat_src->accept(this); + ir_to_mesa_src_reg src = this->result; + + this->result = get_temp(ir->type); + ir_to_mesa_instruction *inst; + inst = ir_to_mesa_emit_op1(ir, OPCODE_MOV, + ir_to_mesa_dst_reg_from_src(this->result), + src); + inst->saturate = true; + + return true; +} + +void +ir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, + ir_to_mesa_src_reg *reg, int *num_reladdr) +{ + if (!reg->reladdr) + return; + + ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr); + + if (*num_reladdr != 1) { + ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); + + ir_to_mesa_emit_op1(ir, OPCODE_MOV, + ir_to_mesa_dst_reg_from_src(temp), *reg); + *reg = temp; + } + + (*num_reladdr)--; +} + +void +ir_to_mesa_visitor::emit_swz(ir_expression *ir) +{ + /* Assume that the vector operator is in a form compatible with OPCODE_SWZ. + * This means that each of the operands is either an immediate value of -1, + * 0, or 1, or is a component from one source register (possibly with + * negation). + */ + uint8_t components[4] = { 0 }; + bool negate[4] = { false }; + ir_variable *var = NULL; + + for (unsigned i = 0; i < ir->type->vector_elements; i++) { + ir_rvalue *op = ir->operands[i]; + + assert(op->type->is_scalar()); + + while (op != NULL) { + switch (op->ir_type) { + case ir_type_constant: { + + assert(op->type->is_scalar()); + + const ir_constant *const c = op->as_constant(); + if (c->is_one()) { + components[i] = SWIZZLE_ONE; + } else if (c->is_zero()) { + components[i] = SWIZZLE_ZERO; + } else if (c->is_negative_one()) { + components[i] = SWIZZLE_ONE; + negate[i] = true; + } else { + assert(!"SWZ constant must be 0.0 or 1.0."); + } + + op = NULL; + break; + } + + case ir_type_dereference_variable: { + ir_dereference_variable *const deref = + (ir_dereference_variable *) op; + + assert((var == NULL) || (deref->var == var)); + components[i] = SWIZZLE_X; + var = deref->var; + op = NULL; + break; + } + + case ir_type_expression: { + ir_expression *const expr = (ir_expression *) op; + + assert(expr->operation == ir_unop_neg); + negate[i] = true; + + op = expr->operands[0]; + break; + } + + case ir_type_swizzle: { + ir_swizzle *const swiz = (ir_swizzle *) op; + + components[i] = swiz->mask.x; + op = swiz->val; + break; + } + + default: + assert(!"Should not get here."); + return; + } + } + } + + assert(var != NULL); + + ir_dereference_variable *const deref = + new(mem_ctx) ir_dereference_variable(var); + + this->result.file = PROGRAM_UNDEFINED; + deref->accept(this); + if (this->result.file == PROGRAM_UNDEFINED) { + ir_print_visitor v; + printf("Failed to get tree for expression operand:\n"); + deref->accept(&v); + exit(1); + } + + ir_to_mesa_src_reg src; + + src = this->result; + src.swizzle = MAKE_SWIZZLE4(components[0], + components[1], + components[2], + components[3]); + src.negate = ((unsigned(negate[0]) << 0) + | (unsigned(negate[1]) << 1) + | (unsigned(negate[2]) << 2) + | (unsigned(negate[3]) << 3)); + + /* Storage for our result. Ideally for an assignment we'd be using the + * actual storage for the result here, instead. + */ + const ir_to_mesa_src_reg result_src = get_temp(ir->type); + ir_to_mesa_dst_reg result_dst = ir_to_mesa_dst_reg_from_src(result_src); + + /* Limit writes to the channels that will be used by result_src later. + * This does limit this temp's use as a temporary for multi-instruction + * sequences. + */ + result_dst.writemask = (1 << ir->type->vector_elements) - 1; + + ir_to_mesa_emit_op1(ir, OPCODE_SWZ, result_dst, src); + this->result = result_src; +} + +void +ir_to_mesa_visitor::visit(ir_expression *ir) +{ + unsigned int operand; + struct ir_to_mesa_src_reg op[Elements(ir->operands)]; + struct ir_to_mesa_src_reg result_src; + struct ir_to_mesa_dst_reg result_dst; + + /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) + */ + if (ir->operation == ir_binop_add) { + if (try_emit_mad(ir, 1)) + return; + if (try_emit_mad(ir, 0)) + return; + } + if (try_emit_sat(ir)) + return; + + if (ir->operation == ir_quadop_vector) { + this->emit_swz(ir); + return; + } + + for (operand = 0; operand < ir->get_num_operands(); operand++) { + this->result.file = PROGRAM_UNDEFINED; + ir->operands[operand]->accept(this); + if (this->result.file == PROGRAM_UNDEFINED) { + ir_print_visitor v; + printf("Failed to get tree for expression operand:\n"); + ir->operands[operand]->accept(&v); + exit(1); + } + op[operand] = this->result; + + /* Matrix expression operands should have been broken down to vector + * operations already. + */ + assert(!ir->operands[operand]->type->is_matrix()); + } + + int vector_elements = ir->operands[0]->type->vector_elements; + if (ir->operands[1]) { + vector_elements = MAX2(vector_elements, + ir->operands[1]->type->vector_elements); + } + + this->result.file = PROGRAM_UNDEFINED; + + /* Storage for our result. Ideally for an assignment we'd be using + * the actual storage for the result here, instead. + */ + result_src = get_temp(ir->type); + /* convenience for the emit functions below. */ + result_dst = ir_to_mesa_dst_reg_from_src(result_src); + /* Limit writes to the channels that will be used by result_src later. + * This does limit this temp's use as a temporary for multi-instruction + * sequences. + */ + result_dst.writemask = (1 << ir->type->vector_elements) - 1; + + switch (ir->operation) { + case ir_unop_logic_not: + ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, + op[0], src_reg_for_float(0.0)); + break; + case ir_unop_neg: + op[0].negate = ~op[0].negate; + result_src = op[0]; + break; + case ir_unop_abs: + ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]); + break; + case ir_unop_sign: + ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]); + break; + case ir_unop_rcp: + ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]); + break; + + case ir_unop_exp2: + ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]); + break; + case ir_unop_exp: + case ir_unop_log: + assert(!"not reached: should be handled by ir_explog_to_explog2"); + break; + case ir_unop_log2: + ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]); + break; + case ir_unop_sin: + ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]); + break; + case ir_unop_cos: + ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]); + break; + case ir_unop_sin_reduced: + emit_scs(ir, OPCODE_SIN, result_dst, op[0]); + break; + case ir_unop_cos_reduced: + emit_scs(ir, OPCODE_COS, result_dst, op[0]); + break; + + case ir_unop_dFdx: + ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]); + break; + case ir_unop_dFdy: + ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]); + break; + + case ir_unop_noise: { + const enum prog_opcode opcode = + prog_opcode(OPCODE_NOISE1 + + (ir->operands[0]->type->vector_elements) - 1); + assert((opcode >= OPCODE_NOISE1) && (opcode <= OPCODE_NOISE4)); + + ir_to_mesa_emit_op1(ir, opcode, result_dst, op[0]); + break; + } + + case ir_binop_add: + ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]); + break; + case ir_binop_sub: + ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]); + break; + + case ir_binop_mul: + ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]); + break; + case ir_binop_div: + assert(!"not reached: should be handled by ir_div_to_mul_rcp"); + case ir_binop_mod: + assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); + break; + + case ir_binop_less: + ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]); + break; + case ir_binop_greater: + ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]); + break; + case ir_binop_lequal: + ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]); + break; + case ir_binop_gequal: + ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]); + break; + case ir_binop_equal: + ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); + break; + case ir_binop_nequal: + ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); + break; + case ir_binop_all_equal: + /* "==" operator producing a scalar boolean. */ + if (ir->operands[0]->type->is_vector() || + ir->operands[1]->type->is_vector()) { + ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); + ir_to_mesa_emit_op2(ir, OPCODE_SNE, + ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]); + ir_to_mesa_emit_dp(ir, result_dst, temp, temp, vector_elements); + ir_to_mesa_emit_op2(ir, OPCODE_SEQ, + result_dst, result_src, src_reg_for_float(0.0)); + } else { + ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); + } + break; + case ir_binop_any_nequal: + /* "!=" operator producing a scalar boolean. */ + if (ir->operands[0]->type->is_vector() || + ir->operands[1]->type->is_vector()) { + ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); + ir_to_mesa_emit_op2(ir, OPCODE_SNE, + ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]); + ir_to_mesa_emit_dp(ir, result_dst, temp, temp, vector_elements); + ir_to_mesa_emit_op2(ir, OPCODE_SNE, + result_dst, result_src, src_reg_for_float(0.0)); + } else { + ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); + } + break; + + case ir_unop_any: + assert(ir->operands[0]->type->is_vector()); + ir_to_mesa_emit_dp(ir, result_dst, op[0], op[0], + ir->operands[0]->type->vector_elements); + ir_to_mesa_emit_op2(ir, OPCODE_SNE, + result_dst, result_src, src_reg_for_float(0.0)); + break; + + case ir_binop_logic_xor: + ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); + break; + + case ir_binop_logic_or: + /* This could be a saturated add and skip the SNE. */ + ir_to_mesa_emit_op2(ir, OPCODE_ADD, + result_dst, + op[0], op[1]); + + ir_to_mesa_emit_op2(ir, OPCODE_SNE, + result_dst, + result_src, src_reg_for_float(0.0)); + break; + + case ir_binop_logic_and: + /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ + ir_to_mesa_emit_op2(ir, OPCODE_MUL, + result_dst, + op[0], op[1]); + break; + + case ir_binop_dot: + assert(ir->operands[0]->type->is_vector()); + assert(ir->operands[0]->type == ir->operands[1]->type); + ir_to_mesa_emit_dp(ir, result_dst, op[0], op[1], + ir->operands[0]->type->vector_elements); + break; + + case ir_unop_sqrt: + /* sqrt(x) = x * rsq(x). */ + ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); + ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, result_src, op[0]); + /* For incoming channels <= 0, set the result to 0. */ + op[0].negate = ~op[0].negate; + ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst, + op[0], result_src, src_reg_for_float(0.0)); + break; + case ir_unop_rsq: + ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); + break; + case ir_unop_i2f: + case ir_unop_b2f: + case ir_unop_b2i: + /* Mesa IR lacks types, ints are stored as truncated floats. */ + result_src = op[0]; + break; + case ir_unop_f2i: + ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); + break; + case ir_unop_f2b: + case ir_unop_i2b: + ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, + op[0], src_reg_for_float(0.0)); + break; + case ir_unop_trunc: + ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); + break; + case ir_unop_ceil: + op[0].negate = ~op[0].negate; + ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); + result_src.negate = ~result_src.negate; + break; + case ir_unop_floor: + ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); + break; + case ir_unop_fract: + ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]); + break; + + case ir_binop_min: + ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]); + break; + case ir_binop_max: + ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]); + break; + case ir_binop_pow: + ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]); + break; + + case ir_unop_bit_not: + case ir_unop_u2f: + case ir_binop_lshift: + case ir_binop_rshift: + case ir_binop_bit_and: + case ir_binop_bit_xor: + case ir_binop_bit_or: + case ir_unop_round_even: + assert(!"GLSL 1.30 features unsupported"); + break; + + case ir_quadop_vector: + /* This operation should have already been handled. + */ + assert(!"Should not get here."); + break; + } + + this->result = result_src; +} + + +void +ir_to_mesa_visitor::visit(ir_swizzle *ir) +{ + ir_to_mesa_src_reg src_reg; + int i; + int swizzle[4]; + + /* Note that this is only swizzles in expressions, not those on the left + * hand side of an assignment, which do write masking. See ir_assignment + * for that. + */ + + ir->val->accept(this); + src_reg = this->result; + assert(src_reg.file != PROGRAM_UNDEFINED); + + for (i = 0; i < 4; i++) { + if (i < ir->type->vector_elements) { + switch (i) { + case 0: + swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x); + break; + case 1: + swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y); + break; + case 2: + swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z); + break; + case 3: + swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w); + break; + } + } else { + /* If the type is smaller than a vec4, replicate the last + * channel out. + */ + swizzle[i] = swizzle[ir->type->vector_elements - 1]; + } + } + + src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], + swizzle[1], + swizzle[2], + swizzle[3]); + + this->result = src_reg; +} + +void +ir_to_mesa_visitor::visit(ir_dereference_variable *ir) +{ + variable_storage *entry = find_variable_storage(ir->var); + ir_variable *var = ir->var; + + if (!entry) { + switch (var->mode) { + case ir_var_uniform: + entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, + var->location); + this->variables.push_tail(entry); + break; + case ir_var_in: + case ir_var_inout: + /* The linker assigns locations for varyings and attributes, + * including deprecated builtins (like gl_Color), user-assign + * generic attributes (glBindVertexLocation), and + * user-defined varyings. + * + * FINISHME: We would hit this path for function arguments. Fix! + */ + assert(var->location != -1); + entry = new(mem_ctx) variable_storage(var, + PROGRAM_INPUT, + var->location); + if (this->prog->Target == GL_VERTEX_PROGRAM_ARB && + var->location >= VERT_ATTRIB_GENERIC0) { + _mesa_add_attribute(this->prog->Attributes, + var->name, + _mesa_sizeof_glsl_type(var->type->gl_type), + var->type->gl_type, + var->location - VERT_ATTRIB_GENERIC0); + } + break; + case ir_var_out: + assert(var->location != -1); + entry = new(mem_ctx) variable_storage(var, + PROGRAM_OUTPUT, + var->location); + break; + case ir_var_system_value: + entry = new(mem_ctx) variable_storage(var, + PROGRAM_SYSTEM_VALUE, + var->location); + break; + case ir_var_auto: + case ir_var_temporary: + entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, + this->next_temp); + this->variables.push_tail(entry); + + next_temp += type_size(var->type); + break; + } + + if (!entry) { + printf("Failed to make storage for %s\n", var->name); + exit(1); + } + } + + this->result = ir_to_mesa_src_reg(entry->file, entry->index, var->type); +} + +void +ir_to_mesa_visitor::visit(ir_dereference_array *ir) +{ + ir_constant *index; + ir_to_mesa_src_reg src_reg; + int element_size = type_size(ir->type); + + index = ir->array_index->constant_expression_value(); + + ir->array->accept(this); + src_reg = this->result; + + if (index) { + src_reg.index += index->value.i[0] * element_size; + } else { + ir_to_mesa_src_reg array_base = this->result; + /* Variable index array dereference. It eats the "vec4" of the + * base of the array and an index that offsets the Mesa register + * index. + */ + ir->array_index->accept(this); + + ir_to_mesa_src_reg index_reg; + + if (element_size == 1) { + index_reg = this->result; + } else { + index_reg = get_temp(glsl_type::float_type); + + ir_to_mesa_emit_op2(ir, OPCODE_MUL, + ir_to_mesa_dst_reg_from_src(index_reg), + this->result, src_reg_for_float(element_size)); + } + + src_reg.reladdr = ralloc(mem_ctx, ir_to_mesa_src_reg); + memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); + } + + /* If the type is smaller than a vec4, replicate the last channel out. */ + if (ir->type->is_scalar() || ir->type->is_vector()) + src_reg.swizzle = swizzle_for_size(ir->type->vector_elements); + else + src_reg.swizzle = SWIZZLE_NOOP; + + this->result = src_reg; +} + +void +ir_to_mesa_visitor::visit(ir_dereference_record *ir) +{ + unsigned int i; + const glsl_type *struct_type = ir->record->type; + int offset = 0; + + ir->record->accept(this); + + for (i = 0; i < struct_type->length; i++) { + if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) + break; + offset += type_size(struct_type->fields.structure[i].type); + } + + /* If the type is smaller than a vec4, replicate the last channel out. */ + if (ir->type->is_scalar() || ir->type->is_vector()) + this->result.swizzle = swizzle_for_size(ir->type->vector_elements); + else + this->result.swizzle = SWIZZLE_NOOP; + + this->result.index += offset; +} + +/** + * We want to be careful in assignment setup to hit the actual storage + * instead of potentially using a temporary like we might with the + * ir_dereference handler. + */ +static struct ir_to_mesa_dst_reg +get_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v) +{ + /* The LHS must be a dereference. If the LHS is a variable indexed array + * access of a vector, it must be separated into a series conditional moves + * before reaching this point (see ir_vec_index_to_cond_assign). + */ + assert(ir->as_dereference()); + ir_dereference_array *deref_array = ir->as_dereference_array(); + if (deref_array) { + assert(!deref_array->array->type->is_vector()); + } + + /* Use the rvalue deref handler for the most part. We'll ignore + * swizzles in it and write swizzles using writemask, though. + */ + ir->accept(v); + return ir_to_mesa_dst_reg_from_src(v->result); +} + +/** + * Process the condition of a conditional assignment + * + * Examines the condition of a conditional assignment to generate the optimal + * first operand of a \c CMP instruction. If the condition is a relational + * operator with 0 (e.g., \c ir_binop_less), the value being compared will be + * used as the source for the \c CMP instruction. Otherwise the comparison + * is processed to a boolean result, and the boolean result is used as the + * operand to the CMP instruction. + */ +bool +ir_to_mesa_visitor::process_move_condition(ir_rvalue *ir) +{ + ir_rvalue *src_ir = ir; + bool negate = true; + bool switch_order = false; + + ir_expression *const expr = ir->as_expression(); + if ((expr != NULL) && (expr->get_num_operands() == 2)) { + bool zero_on_left = false; + + if (expr->operands[0]->is_zero()) { + src_ir = expr->operands[1]; + zero_on_left = true; + } else if (expr->operands[1]->is_zero()) { + src_ir = expr->operands[0]; + zero_on_left = false; + } + + /* a is - 0 + - 0 + + * (a < 0) T F F ( a < 0) T F F + * (0 < a) F F T (-a < 0) F F T + * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) + * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) + * (a > 0) F F T (-a < 0) F F T + * (0 > a) T F F ( a < 0) T F F + * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) + * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) + * + * Note that exchanging the order of 0 and 'a' in the comparison simply + * means that the value of 'a' should be negated. + */ + if (src_ir != ir) { + switch (expr->operation) { + case ir_binop_less: + switch_order = false; + negate = zero_on_left; + break; + + case ir_binop_greater: + switch_order = false; + negate = !zero_on_left; + break; + + case ir_binop_lequal: + switch_order = true; + negate = !zero_on_left; + break; + + case ir_binop_gequal: + switch_order = true; + negate = zero_on_left; + break; + + default: + /* This isn't the right kind of comparison afterall, so make sure + * the whole condition is visited. + */ + src_ir = ir; + break; + } + } + } + + src_ir->accept(this); + + /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the + * condition we produced is 0.0 or 1.0. By flipping the sign, we can + * choose which value OPCODE_CMP produces without an extra instruction + * computing the condition. + */ + if (negate) + this->result.negate = ~this->result.negate; + + return switch_order; +} + +void +ir_to_mesa_visitor::visit(ir_assignment *ir) +{ + struct ir_to_mesa_dst_reg l; + struct ir_to_mesa_src_reg r; + int i; + + ir->rhs->accept(this); + r = this->result; + + l = get_assignment_lhs(ir->lhs, this); + + /* FINISHME: This should really set to the correct maximal writemask for each + * FINISHME: component written (in the loops below). This case can only + * FINISHME: occur for matrices, arrays, and structures. + */ + if (ir->write_mask == 0) { + assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); + l.writemask = WRITEMASK_XYZW; + } else if (ir->lhs->type->is_scalar()) { + /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the + * FINISHME: W component of fragment shader output zero, work correctly. + */ + l.writemask = WRITEMASK_XYZW; + } else { + int swizzles[4]; + int first_enabled_chan = 0; + int rhs_chan = 0; + + assert(ir->lhs->type->is_vector()); + l.writemask = ir->write_mask; + + for (int i = 0; i < 4; i++) { + if (l.writemask & (1 << i)) { + first_enabled_chan = GET_SWZ(r.swizzle, i); + break; + } + } + + /* Swizzle a small RHS vector into the channels being written. + * + * glsl ir treats write_mask as dictating how many channels are + * present on the RHS while Mesa IR treats write_mask as just + * showing which channels of the vec4 RHS get written. + */ + for (int i = 0; i < 4; i++) { + if (l.writemask & (1 << i)) + swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); + else + swizzles[i] = first_enabled_chan; + } + r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], + swizzles[2], swizzles[3]); + } + + assert(l.file != PROGRAM_UNDEFINED); + assert(r.file != PROGRAM_UNDEFINED); + + if (ir->condition) { + const bool switch_order = this->process_move_condition(ir->condition); + ir_to_mesa_src_reg condition = this->result; + + for (i = 0; i < type_size(ir->lhs->type); i++) { + if (switch_order) { + ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, + condition, ir_to_mesa_src_reg_from_dst(l), r); + } else { + ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, + condition, r, ir_to_mesa_src_reg_from_dst(l)); + } + + l.index++; + r.index++; + } + } else { + for (i = 0; i < type_size(ir->lhs->type); i++) { + ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); + l.index++; + r.index++; + } + } +} + + +void +ir_to_mesa_visitor::visit(ir_constant *ir) +{ + ir_to_mesa_src_reg src_reg; + GLfloat stack_vals[4] = { 0 }; + GLfloat *values = stack_vals; + unsigned int i; + + /* Unfortunately, 4 floats is all we can get into + * _mesa_add_unnamed_constant. So, make a temp to store an + * aggregate constant and move each constant value into it. If we + * get lucky, copy propagation will eliminate the extra moves. + */ + + if (ir->type->base_type == GLSL_TYPE_STRUCT) { + ir_to_mesa_src_reg temp_base = get_temp(ir->type); + ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); + + foreach_iter(exec_list_iterator, iter, ir->components) { + ir_constant *field_value = (ir_constant *)iter.get(); + int size = type_size(field_value->type); + + assert(size > 0); + + field_value->accept(this); + src_reg = this->result; + + for (i = 0; i < (unsigned int)size; i++) { + ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); + + src_reg.index++; + temp.index++; + } + } + this->result = temp_base; + return; + } + + if (ir->type->is_array()) { + ir_to_mesa_src_reg temp_base = get_temp(ir->type); + ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); + int size = type_size(ir->type->fields.array); + + assert(size > 0); + + for (i = 0; i < ir->type->length; i++) { + ir->array_elements[i]->accept(this); + src_reg = this->result; + for (int j = 0; j < size; j++) { + ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); + + src_reg.index++; + temp.index++; + } + } + this->result = temp_base; + return; + } + + if (ir->type->is_matrix()) { + ir_to_mesa_src_reg mat = get_temp(ir->type); + ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat); + + for (i = 0; i < ir->type->matrix_columns; i++) { + assert(ir->type->base_type == GLSL_TYPE_FLOAT); + values = &ir->value.f[i * ir->type->vector_elements]; + + src_reg = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, NULL); + src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, + values, + ir->type->vector_elements, + &src_reg.swizzle); + ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg); + + mat_column.index++; + } + + this->result = mat; + return; + } + + src_reg.file = PROGRAM_CONSTANT; + switch (ir->type->base_type) { + case GLSL_TYPE_FLOAT: + values = &ir->value.f[0]; + break; + case GLSL_TYPE_UINT: + for (i = 0; i < ir->type->vector_elements; i++) { + values[i] = ir->value.u[i]; + } + break; + case GLSL_TYPE_INT: + for (i = 0; i < ir->type->vector_elements; i++) { + values[i] = ir->value.i[i]; + } + break; + case GLSL_TYPE_BOOL: + for (i = 0; i < ir->type->vector_elements; i++) { + values[i] = ir->value.b[i]; + } + break; + default: + assert(!"Non-float/uint/int/bool constant"); + } + + this->result = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, ir->type); + this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters, + values, + ir->type->vector_elements, + &this->result.swizzle); +} + +function_entry * +ir_to_mesa_visitor::get_function_signature(ir_function_signature *sig) +{ + function_entry *entry; + + foreach_iter(exec_list_iterator, iter, this->function_signatures) { + entry = (function_entry *)iter.get(); + + if (entry->sig == sig) + return entry; + } + + entry = ralloc(mem_ctx, function_entry); + entry->sig = sig; + entry->sig_id = this->next_signature_id++; + entry->bgn_inst = NULL; + + /* Allocate storage for all the parameters. */ + foreach_iter(exec_list_iterator, iter, sig->parameters) { + ir_variable *param = (ir_variable *)iter.get(); + variable_storage *storage; + + storage = find_variable_storage(param); + assert(!storage); + + storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, + this->next_temp); + this->variables.push_tail(storage); + + this->next_temp += type_size(param->type); + } + + if (!sig->return_type->is_void()) { + entry->return_reg = get_temp(sig->return_type); + } else { + entry->return_reg = ir_to_mesa_undef; + } + + this->function_signatures.push_tail(entry); + return entry; +} + +void +ir_to_mesa_visitor::visit(ir_call *ir) +{ + ir_to_mesa_instruction *call_inst; + ir_function_signature *sig = ir->get_callee(); + function_entry *entry = get_function_signature(sig); + int i; + + /* Process in parameters. */ + exec_list_iterator sig_iter = sig->parameters.iterator(); + foreach_iter(exec_list_iterator, iter, *ir) { + ir_rvalue *param_rval = (ir_rvalue *)iter.get(); + ir_variable *param = (ir_variable *)sig_iter.get(); + + if (param->mode == ir_var_in || + param->mode == ir_var_inout) { + variable_storage *storage = find_variable_storage(param); + assert(storage); + + param_rval->accept(this); + ir_to_mesa_src_reg r = this->result; + + ir_to_mesa_dst_reg l; + l.file = storage->file; + l.index = storage->index; + l.reladdr = NULL; + l.writemask = WRITEMASK_XYZW; + l.cond_mask = COND_TR; + + for (i = 0; i < type_size(param->type); i++) { + ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); + l.index++; + r.index++; + } + } + + sig_iter.next(); + } + assert(!sig_iter.has_next()); + + /* Emit call instruction */ + call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL, + ir_to_mesa_undef_dst, ir_to_mesa_undef); + call_inst->function = entry; + + /* Process out parameters. */ + sig_iter = sig->parameters.iterator(); + foreach_iter(exec_list_iterator, iter, *ir) { + ir_rvalue *param_rval = (ir_rvalue *)iter.get(); + ir_variable *param = (ir_variable *)sig_iter.get(); + + if (param->mode == ir_var_out || + param->mode == ir_var_inout) { + variable_storage *storage = find_variable_storage(param); + assert(storage); + + ir_to_mesa_src_reg r; + r.file = storage->file; + r.index = storage->index; + r.reladdr = NULL; + r.swizzle = SWIZZLE_NOOP; + r.negate = 0; + + param_rval->accept(this); + ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result); + + for (i = 0; i < type_size(param->type); i++) { + ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); + l.index++; + r.index++; + } + } + + sig_iter.next(); + } + assert(!sig_iter.has_next()); + + /* Process return value. */ + this->result = entry->return_reg; +} + +void +ir_to_mesa_visitor::visit(ir_texture *ir) +{ + ir_to_mesa_src_reg result_src, coord, lod_info, projector; + ir_to_mesa_dst_reg result_dst, coord_dst; + ir_to_mesa_instruction *inst = NULL; + prog_opcode opcode = OPCODE_NOP; + + ir->coordinate->accept(this); + + /* Put our coords in a temp. We'll need to modify them for shadow, + * projection, or LOD, so the only case we'd use it as is is if + * we're doing plain old texturing. Mesa IR optimization should + * handle cleaning up our mess in that case. + */ + coord = get_temp(glsl_type::vec4_type); + coord_dst = ir_to_mesa_dst_reg_from_src(coord); + ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, + this->result); + + if (ir->projector) { + ir->projector->accept(this); + projector = this->result; + } + + /* Storage for our result. Ideally for an assignment we'd be using + * the actual storage for the result here, instead. + */ + result_src = get_temp(glsl_type::vec4_type); + result_dst = ir_to_mesa_dst_reg_from_src(result_src); + + switch (ir->op) { + case ir_tex: + opcode = OPCODE_TEX; + break; + case ir_txb: + opcode = OPCODE_TXB; + ir->lod_info.bias->accept(this); + lod_info = this->result; + break; + case ir_txl: + opcode = OPCODE_TXL; + ir->lod_info.lod->accept(this); + lod_info = this->result; + break; + case ir_txd: + case ir_txf: + assert(!"GLSL 1.30 features unsupported"); + break; + } + + if (ir->projector) { + if (opcode == OPCODE_TEX) { + /* Slot the projector in as the last component of the coord. */ + coord_dst.writemask = WRITEMASK_W; + ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector); + coord_dst.writemask = WRITEMASK_XYZW; + opcode = OPCODE_TXP; + } else { + ir_to_mesa_src_reg coord_w = coord; + coord_w.swizzle = SWIZZLE_WWWW; + + /* For the other TEX opcodes there's no projective version + * since the last slot is taken up by lod info. Do the + * projective divide now. + */ + coord_dst.writemask = WRITEMASK_W; + ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector); + + coord_dst.writemask = WRITEMASK_XYZ; + ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w); + + coord_dst.writemask = WRITEMASK_XYZW; + coord.swizzle = SWIZZLE_XYZW; + } + } + + if (ir->shadow_comparitor) { + /* Slot the shadow value in as the second to last component of the + * coord. + */ + ir->shadow_comparitor->accept(this); + coord_dst.writemask = WRITEMASK_Z; + ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result); + coord_dst.writemask = WRITEMASK_XYZW; + } + + if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { + /* Mesa IR stores lod or lod bias in the last channel of the coords. */ + coord_dst.writemask = WRITEMASK_W; + ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info); + coord_dst.writemask = WRITEMASK_XYZW; + } + + inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord); + + if (ir->shadow_comparitor) + inst->tex_shadow = GL_TRUE; + + inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, + this->shader_program, + this->prog); + + const glsl_type *sampler_type = ir->sampler->type; + + switch (sampler_type->sampler_dimensionality) { + case GLSL_SAMPLER_DIM_1D: + inst->tex_target = (sampler_type->sampler_array) + ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; + break; + case GLSL_SAMPLER_DIM_2D: + inst->tex_target = (sampler_type->sampler_array) + ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; + break; + case GLSL_SAMPLER_DIM_3D: + inst->tex_target = TEXTURE_3D_INDEX; + break; + case GLSL_SAMPLER_DIM_CUBE: + inst->tex_target = TEXTURE_CUBE_INDEX; + break; + case GLSL_SAMPLER_DIM_RECT: + inst->tex_target = TEXTURE_RECT_INDEX; + break; + case GLSL_SAMPLER_DIM_BUF: + assert(!"FINISHME: Implement ARB_texture_buffer_object"); + break; + default: + assert(!"Should not get here."); + } + + this->result = result_src; +} + +void +ir_to_mesa_visitor::visit(ir_return *ir) +{ + if (ir->get_value()) { + ir_to_mesa_dst_reg l; + int i; + + assert(current_function); + + ir->get_value()->accept(this); + ir_to_mesa_src_reg r = this->result; + + l = ir_to_mesa_dst_reg_from_src(current_function->return_reg); + + for (i = 0; i < type_size(current_function->sig->return_type); i++) { + ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); + l.index++; + r.index++; + } + } + + ir_to_mesa_emit_op0(ir, OPCODE_RET); +} + +void +ir_to_mesa_visitor::visit(ir_discard *ir) +{ + struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; + + if (ir->condition) { + ir->condition->accept(this); + this->result.negate = ~this->result.negate; + ir_to_mesa_emit_op1(ir, OPCODE_KIL, ir_to_mesa_undef_dst, this->result); + } else { + ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV); + } + + fp->UsesKill = GL_TRUE; +} + +void +ir_to_mesa_visitor::visit(ir_if *ir) +{ + ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL; + ir_to_mesa_instruction *prev_inst; + + prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); + + ir->condition->accept(this); + assert(this->result.file != PROGRAM_UNDEFINED); + + if (this->options->EmitCondCodes) { + cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); + + /* See if we actually generated any instruction for generating + * the condition. If not, then cook up a move to a temp so we + * have something to set cond_update on. + */ + if (cond_inst == prev_inst) { + ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type); + cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV, + ir_to_mesa_dst_reg_from_src(temp), + result); + } + cond_inst->cond_update = GL_TRUE; + + if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF); + if_inst->dst_reg.cond_mask = COND_NE; + } else { + if_inst = ir_to_mesa_emit_op1(ir->condition, + OPCODE_IF, ir_to_mesa_undef_dst, + this->result); + } + + this->instructions.push_tail(if_inst); + + visit_exec_list(&ir->then_instructions, this); + + if (!ir->else_instructions.is_empty()) { + else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE); + visit_exec_list(&ir->else_instructions, this); + } + + if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF, + ir_to_mesa_undef_dst, ir_to_mesa_undef); +} + +ir_to_mesa_visitor::ir_to_mesa_visitor() +{ + result.file = PROGRAM_UNDEFINED; + next_temp = 1; + next_signature_id = 1; + current_function = NULL; + mem_ctx = ralloc_context(NULL); +} + +ir_to_mesa_visitor::~ir_to_mesa_visitor() +{ + ralloc_free(mem_ctx); +} + +static struct prog_src_register +mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg) +{ + struct prog_src_register mesa_reg; + + mesa_reg.File = reg.file; + assert(reg.index < (1 << INST_INDEX_BITS)); + mesa_reg.Index = reg.index; + mesa_reg.Swizzle = reg.swizzle; + mesa_reg.RelAddr = reg.reladdr != NULL; + mesa_reg.Negate = reg.negate; + mesa_reg.Abs = 0; + mesa_reg.HasIndex2 = GL_FALSE; + mesa_reg.RelAddr2 = 0; + mesa_reg.Index2 = 0; + + return mesa_reg; +} + +static void +set_branchtargets(ir_to_mesa_visitor *v, + struct prog_instruction *mesa_instructions, + int num_instructions) +{ + int if_count = 0, loop_count = 0; + int *if_stack, *loop_stack; + int if_stack_pos = 0, loop_stack_pos = 0; + int i, j; + + for (i = 0; i < num_instructions; i++) { + switch (mesa_instructions[i].Opcode) { + case OPCODE_IF: + if_count++; + break; + case OPCODE_BGNLOOP: + loop_count++; + break; + case OPCODE_BRK: + case OPCODE_CONT: + mesa_instructions[i].BranchTarget = -1; + break; + default: + break; + } + } + + if_stack = rzalloc_array(v->mem_ctx, int, if_count); + loop_stack = rzalloc_array(v->mem_ctx, int, loop_count); + + for (i = 0; i < num_instructions; i++) { + switch (mesa_instructions[i].Opcode) { + case OPCODE_IF: + if_stack[if_stack_pos] = i; + if_stack_pos++; + break; + case OPCODE_ELSE: + mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; + if_stack[if_stack_pos - 1] = i; + break; + case OPCODE_ENDIF: + mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; + if_stack_pos--; + break; + case OPCODE_BGNLOOP: + loop_stack[loop_stack_pos] = i; + loop_stack_pos++; + break; + case OPCODE_ENDLOOP: + loop_stack_pos--; + /* Rewrite any breaks/conts at this nesting level (haven't + * already had a BranchTarget assigned) to point to the end + * of the loop. + */ + for (j = loop_stack[loop_stack_pos]; j < i; j++) { + if (mesa_instructions[j].Opcode == OPCODE_BRK || + mesa_instructions[j].Opcode == OPCODE_CONT) { + if (mesa_instructions[j].BranchTarget == -1) { + mesa_instructions[j].BranchTarget = i; + } + } + } + /* The loop ends point at each other. */ + mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; + mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; + break; + case OPCODE_CAL: + foreach_iter(exec_list_iterator, iter, v->function_signatures) { + function_entry *entry = (function_entry *)iter.get(); + + if (entry->sig_id == mesa_instructions[i].BranchTarget) { + mesa_instructions[i].BranchTarget = entry->inst; + break; + } + } + break; + default: + break; + } + } +} + +static void +print_program(struct prog_instruction *mesa_instructions, + ir_instruction **mesa_instruction_annotation, + int num_instructions) +{ + ir_instruction *last_ir = NULL; + int i; + int indent = 0; + + for (i = 0; i < num_instructions; i++) { + struct prog_instruction *mesa_inst = mesa_instructions + i; + ir_instruction *ir = mesa_instruction_annotation[i]; + + fprintf(stdout, "%3d: ", i); + + if (last_ir != ir && ir) { + int j; + + for (j = 0; j < indent; j++) { + fprintf(stdout, " "); + } + ir->print(); + printf("\n"); + last_ir = ir; + + fprintf(stdout, " "); /* line number spacing. */ + } + + indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, + PROG_PRINT_DEBUG, NULL); + } +} + +static void +count_resources(struct gl_program *prog) +{ + unsigned int i; + + prog->SamplersUsed = 0; + + for (i = 0; i < prog->NumInstructions; i++) { + struct prog_instruction *inst = &prog->Instructions[i]; + + if (_mesa_is_tex_instruction(inst->Opcode)) { + prog->SamplerTargets[inst->TexSrcUnit] = + (gl_texture_index)inst->TexSrcTarget; + prog->SamplersUsed |= 1 << inst->TexSrcUnit; + if (inst->TexShadow) { + prog->ShadowSamplers |= 1 << inst->TexSrcUnit; + } + } + } + + _mesa_update_shader_textures_used(prog); +} + +struct uniform_sort { + struct gl_uniform *u; + int pos; +}; + +/* The shader_program->Uniforms list is almost sorted in increasing + * uniform->{Frag,Vert}Pos locations, but not quite when there are + * uniforms shared between targets. We need to add parameters in + * increasing order for the targets. + */ +static int +sort_uniforms(const void *a, const void *b) +{ + struct uniform_sort *u1 = (struct uniform_sort *)a; + struct uniform_sort *u2 = (struct uniform_sort *)b; + + return u1->pos - u2->pos; +} + +/* Add the uniforms to the parameters. The linker chose locations + * in our parameters lists (which weren't created yet), which the + * uniforms code will use to poke values into our parameters list + * when uniforms are updated. + */ +static void +add_uniforms_to_parameters_list(struct gl_shader_program *shader_program, + struct gl_shader *shader, + struct gl_program *prog) +{ + unsigned int i; + unsigned int next_sampler = 0, num_uniforms = 0; + struct uniform_sort *sorted_uniforms; + + sorted_uniforms = ralloc_array(NULL, struct uniform_sort, + shader_program->Uniforms->NumUniforms); + + for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) { + struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i; + int parameter_index = -1; + + switch (shader->Type) { + case GL_VERTEX_SHADER: + parameter_index = uniform->VertPos; + break; + case GL_FRAGMENT_SHADER: + parameter_index = uniform->FragPos; + break; + case GL_GEOMETRY_SHADER: + parameter_index = uniform->GeomPos; + break; + } + + /* Only add uniforms used in our target. */ + if (parameter_index != -1) { + sorted_uniforms[num_uniforms].pos = parameter_index; + sorted_uniforms[num_uniforms].u = uniform; + num_uniforms++; + } + } + + qsort(sorted_uniforms, num_uniforms, sizeof(struct uniform_sort), + sort_uniforms); + + for (i = 0; i < num_uniforms; i++) { + struct gl_uniform *uniform = sorted_uniforms[i].u; + int parameter_index = sorted_uniforms[i].pos; + const glsl_type *type = uniform->Type; + unsigned int size; + + if (type->is_vector() || + type->is_scalar()) { + size = type->vector_elements; + } else { + size = type_size(type) * 4; + } + + gl_register_file file; + if (type->is_sampler() || + (type->is_array() && type->fields.array->is_sampler())) { + file = PROGRAM_SAMPLER; + } else { + file = PROGRAM_UNIFORM; + } + + GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1, + uniform->Name); + + if (index < 0) { + index = _mesa_add_parameter(prog->Parameters, file, + uniform->Name, size, type->gl_type, + NULL, NULL, 0x0); + + /* Sampler uniform values are stored in prog->SamplerUnits, + * and the entry in that array is selected by this index we + * store in ParameterValues[]. + */ + if (file == PROGRAM_SAMPLER) { + for (unsigned int j = 0; j < size / 4; j++) + prog->Parameters->ParameterValues[index + j][0] = next_sampler++; + } + + /* The location chosen in the Parameters list here (returned + * from _mesa_add_uniform) has to match what the linker chose. + */ + if (index != parameter_index) { + fail_link(shader_program, "Allocation of uniform `%s' to target " + "failed (%d vs %d)\n", + uniform->Name, index, parameter_index); + } + } + } + + ralloc_free(sorted_uniforms); +} + +static void +set_uniform_initializer(struct gl_context *ctx, void *mem_ctx, + struct gl_shader_program *shader_program, + const char *name, const glsl_type *type, + ir_constant *val) +{ + if (type->is_record()) { + ir_constant *field_constant; + + field_constant = (ir_constant *)val->components.get_head(); + + for (unsigned int i = 0; i < type->length; i++) { + const glsl_type *field_type = type->fields.structure[i].type; + const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name, + type->fields.structure[i].name); + set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, + field_type, field_constant); + field_constant = (ir_constant *)field_constant->next; + } + return; + } + + int loc = _mesa_get_uniform_location(ctx, shader_program, name); + + if (loc == -1) { + fail_link(shader_program, + "Couldn't find uniform for initializer %s\n", name); + return; + } + + for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { + ir_constant *element; + const glsl_type *element_type; + if (type->is_array()) { + element = val->array_elements[i]; + element_type = type->fields.array; + } else { + element = val; + element_type = type; + } + + void *values; + + if (element_type->base_type == GLSL_TYPE_BOOL) { + int *conv = ralloc_array(mem_ctx, int, element_type->components()); + for (unsigned int j = 0; j < element_type->components(); j++) { + conv[j] = element->value.b[j]; + } + values = (void *)conv; + element_type = glsl_type::get_instance(GLSL_TYPE_INT, + element_type->vector_elements, + 1); + } else { + values = &element->value; + } + + if (element_type->is_matrix()) { + _mesa_uniform_matrix(ctx, shader_program, + element_type->matrix_columns, + element_type->vector_elements, + loc, 1, GL_FALSE, (GLfloat *)values); + loc += element_type->matrix_columns; + } else { + _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, + values, element_type->gl_type); + loc += type_size(element_type); + } + } +} + +static void +set_uniform_initializers(struct gl_context *ctx, + struct gl_shader_program *shader_program) +{ + void *mem_ctx = NULL; + + for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { + struct gl_shader *shader = shader_program->_LinkedShaders[i]; + + if (shader == NULL) + continue; + + foreach_iter(exec_list_iterator, iter, *shader->ir) { + ir_instruction *ir = (ir_instruction *)iter.get(); + ir_variable *var = ir->as_variable(); + + if (!var || var->mode != ir_var_uniform || !var->constant_value) + continue; + + if (!mem_ctx) + mem_ctx = ralloc_context(NULL); + + set_uniform_initializer(ctx, mem_ctx, shader_program, var->name, + var->type, var->constant_value); + } + } + + ralloc_free(mem_ctx); +} + +/* + * On a basic block basis, tracks available PROGRAM_TEMPORARY register + * channels for copy propagation and updates following instructions to + * use the original versions. + * + * The ir_to_mesa_visitor lazily produces code assuming that this pass + * will occur. As an example, a TXP production before this pass: + * + * 0: MOV TEMP[1], INPUT[4].xyyy; + * 1: MOV TEMP[1].w, INPUT[4].wwww; + * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; + * + * and after: + * + * 0: MOV TEMP[1], INPUT[4].xyyy; + * 1: MOV TEMP[1].w, INPUT[4].wwww; + * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; + * + * which allows for dead code elimination on TEMP[1]'s writes. + */ +void +ir_to_mesa_visitor::copy_propagate(void) +{ + ir_to_mesa_instruction **acp = rzalloc_array(mem_ctx, + ir_to_mesa_instruction *, + this->next_temp * 4); + + foreach_iter(exec_list_iterator, iter, this->instructions) { + ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); + + assert(inst->dst_reg.file != PROGRAM_TEMPORARY + || inst->dst_reg.index < this->next_temp); + + /* First, do any copy propagation possible into the src regs. */ + for (int r = 0; r < 3; r++) { + ir_to_mesa_instruction *first = NULL; + bool good = true; + int acp_base = inst->src_reg[r].index * 4; + + if (inst->src_reg[r].file != PROGRAM_TEMPORARY || + inst->src_reg[r].reladdr) + continue; + + /* See if we can find entries in the ACP consisting of MOVs + * from the same src register for all the swizzled channels + * of this src register reference. + */ + for (int i = 0; i < 4; i++) { + int src_chan = GET_SWZ(inst->src_reg[r].swizzle, i); + ir_to_mesa_instruction *copy_chan = acp[acp_base + src_chan]; + + if (!copy_chan) { + good = false; + break; + } + + if (!first) { + first = copy_chan; + } else { + if (first->src_reg[0].file != copy_chan->src_reg[0].file || + first->src_reg[0].index != copy_chan->src_reg[0].index) { + good = false; + break; + } + } + } + + if (good) { + /* We've now validated that we can copy-propagate to + * replace this src register reference. Do it. + */ + inst->src_reg[r].file = first->src_reg[0].file; + inst->src_reg[r].index = first->src_reg[0].index; + + int swizzle = 0; + for (int i = 0; i < 4; i++) { + int src_chan = GET_SWZ(inst->src_reg[r].swizzle, i); + ir_to_mesa_instruction *copy_inst = acp[acp_base + src_chan]; + swizzle |= (GET_SWZ(copy_inst->src_reg[0].swizzle, src_chan) << + (3 * i)); + } + inst->src_reg[r].swizzle = swizzle; + } + } + + switch (inst->op) { + case OPCODE_BGNLOOP: + case OPCODE_ENDLOOP: + case OPCODE_ELSE: + case OPCODE_ENDIF: + /* End of a basic block, clear the ACP entirely. */ + memset(acp, 0, sizeof(*acp) * this->next_temp * 4); + break; + + default: + /* Continuing the block, clear any written channels from + * the ACP. + */ + if (inst->dst_reg.file == PROGRAM_TEMPORARY && inst->dst_reg.reladdr) { + /* Any temporary might be written, so no copy propagation + * across this instruction. + */ + memset(acp, 0, sizeof(*acp) * this->next_temp * 4); + } else if (inst->dst_reg.file == PROGRAM_OUTPUT && + inst->dst_reg.reladdr) { + /* Any output might be written, so no copy propagation + * from outputs across this instruction. + */ + for (int r = 0; r < this->next_temp; r++) { + for (int c = 0; c < 4; c++) { + if (!acp[4 * r + c]) + continue; + + if (acp[4 * r + c]->src_reg[0].file == PROGRAM_OUTPUT) + acp[4 * r + c] = NULL; + } + } + } else if (inst->dst_reg.file == PROGRAM_TEMPORARY || + inst->dst_reg.file == PROGRAM_OUTPUT) { + /* Clear where it's used as dst. */ + if (inst->dst_reg.file == PROGRAM_TEMPORARY) { + for (int c = 0; c < 4; c++) { + if (inst->dst_reg.writemask & (1 << c)) { + acp[4 * inst->dst_reg.index + c] = NULL; + } + } + } + + /* Clear where it's used as src. */ + for (int r = 0; r < this->next_temp; r++) { + for (int c = 0; c < 4; c++) { + if (!acp[4 * r + c]) + continue; + + int src_chan = GET_SWZ(acp[4 * r + c]->src_reg[0].swizzle, c); + + if (acp[4 * r + c]->src_reg[0].file == inst->dst_reg.file && + acp[4 * r + c]->src_reg[0].index == inst->dst_reg.index && + inst->dst_reg.writemask & (1 << src_chan)) + { + acp[4 * r + c] = NULL; + } + } + } + } + break; + } + + /* If this is a copy, add it to the ACP. */ + if (inst->op == OPCODE_MOV && + inst->dst_reg.file == PROGRAM_TEMPORARY && + !inst->dst_reg.reladdr && + !inst->saturate && + !inst->src_reg[0].reladdr && + !inst->src_reg[0].negate) { + for (int i = 0; i < 4; i++) { + if (inst->dst_reg.writemask & (1 << i)) { + acp[4 * inst->dst_reg.index + i] = inst; + } + } + } + } + + ralloc_free(acp); +} + + +/** + * Convert a shader's GLSL IR into a Mesa gl_program. + */ +static struct gl_program * +get_mesa_program(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_shader *shader) +{ + ir_to_mesa_visitor v; + struct prog_instruction *mesa_instructions, *mesa_inst; + ir_instruction **mesa_instruction_annotation; + int i; + struct gl_program *prog; + GLenum target; + const char *target_string; + GLboolean progress; + struct gl_shader_compiler_options *options = + &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; + + switch (shader->Type) { + case GL_VERTEX_SHADER: + target = GL_VERTEX_PROGRAM_ARB; + target_string = "vertex"; + break; + case GL_FRAGMENT_SHADER: + target = GL_FRAGMENT_PROGRAM_ARB; + target_string = "fragment"; + break; + case GL_GEOMETRY_SHADER: + target = GL_GEOMETRY_PROGRAM_NV; + target_string = "geometry"; + break; + default: + assert(!"should not be reached"); + return NULL; + } + + validate_ir_tree(shader->ir); + + prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); + if (!prog) + return NULL; + prog->Parameters = _mesa_new_parameter_list(); + prog->Varying = _mesa_new_parameter_list(); + prog->Attributes = _mesa_new_parameter_list(); + v.ctx = ctx; + v.prog = prog; + v.shader_program = shader_program; + v.options = options; + + add_uniforms_to_parameters_list(shader_program, shader, prog); + + /* Emit Mesa IR for main(). */ + visit_exec_list(shader->ir, &v); + v.ir_to_mesa_emit_op0(NULL, OPCODE_END); + + /* Now emit bodies for any functions that were used. */ + do { + progress = GL_FALSE; + + foreach_iter(exec_list_iterator, iter, v.function_signatures) { + function_entry *entry = (function_entry *)iter.get(); + + if (!entry->bgn_inst) { + v.current_function = entry; + + entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB); + entry->bgn_inst->function = entry; + + visit_exec_list(&entry->sig->body, &v); + + ir_to_mesa_instruction *last; + last = (ir_to_mesa_instruction *)v.instructions.get_tail(); + if (last->op != OPCODE_RET) + v.ir_to_mesa_emit_op0(NULL, OPCODE_RET); + + ir_to_mesa_instruction *end; + end = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB); + end->function = entry; + + progress = GL_TRUE; + } + } + } while (progress); + + prog->NumTemporaries = v.next_temp; + + int num_instructions = 0; + foreach_iter(exec_list_iterator, iter, v.instructions) { + num_instructions++; + } + + mesa_instructions = + (struct prog_instruction *)calloc(num_instructions, + sizeof(*mesa_instructions)); + mesa_instruction_annotation = ralloc_array(v.mem_ctx, ir_instruction *, + num_instructions); + + v.copy_propagate(); + + /* Convert ir_mesa_instructions into prog_instructions. + */ + mesa_inst = mesa_instructions; + i = 0; + foreach_iter(exec_list_iterator, iter, v.instructions) { + const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); + + mesa_inst->Opcode = inst->op; + mesa_inst->CondUpdate = inst->cond_update; + if (inst->saturate) + mesa_inst->SaturateMode = SATURATE_ZERO_ONE; + mesa_inst->DstReg.File = inst->dst_reg.file; + mesa_inst->DstReg.Index = inst->dst_reg.index; + mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask; + mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask; + mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL; + mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]); + mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]); + mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]); + mesa_inst->TexSrcUnit = inst->sampler; + mesa_inst->TexSrcTarget = inst->tex_target; + mesa_inst->TexShadow = inst->tex_shadow; + mesa_instruction_annotation[i] = inst->ir; + + /* Set IndirectRegisterFiles. */ + if (mesa_inst->DstReg.RelAddr) + prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File; + + /* Update program's bitmask of indirectly accessed register files */ + for (unsigned src = 0; src < 3; src++) + if (mesa_inst->SrcReg[src].RelAddr) + prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; + + if (options->EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) { + fail_link(shader_program, "Couldn't flatten if statement\n"); + } + + switch (mesa_inst->Opcode) { + case OPCODE_BGNSUB: + inst->function->inst = i; + mesa_inst->Comment = strdup(inst->function->sig->function_name()); + break; + case OPCODE_ENDSUB: + mesa_inst->Comment = strdup(inst->function->sig->function_name()); + break; + case OPCODE_CAL: + mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */ + break; + case OPCODE_ARL: + prog->NumAddressRegs = 1; + break; + default: + break; + } + + mesa_inst++; + i++; + + if (!shader_program->LinkStatus) + break; + } + + if (!shader_program->LinkStatus) { + free(mesa_instructions); + _mesa_reference_program(ctx, &shader->Program, NULL); + return NULL; + } + + set_branchtargets(&v, mesa_instructions, num_instructions); + + if (ctx->Shader.Flags & GLSL_DUMP) { + printf("\n"); + printf("GLSL IR for linked %s program %d:\n", target_string, + shader_program->Name); + _mesa_print_ir(shader->ir, NULL); + printf("\n"); + printf("\n"); + printf("Mesa IR for linked %s program %d:\n", target_string, + shader_program->Name); + print_program(mesa_instructions, mesa_instruction_annotation, + num_instructions); + } + + prog->Instructions = mesa_instructions; + prog->NumInstructions = num_instructions; + + do_set_program_inouts(shader->ir, prog); + count_resources(prog); + + _mesa_reference_program(ctx, &shader->Program, prog); + + if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { + _mesa_optimize_program(ctx, prog); + } + + return prog; +} + +extern "C" { + +/** + * Called via ctx->Driver.CompilerShader(). + * This is a no-op. + * XXX can we remove the ctx->Driver.CompileShader() hook? + */ +GLboolean +_mesa_ir_compile_shader(struct gl_context *ctx, struct gl_shader *shader) +{ + assert(shader->CompileStatus); + (void) ctx; + + return GL_TRUE; +} + + +/** + * Link a shader. + * Called via ctx->Driver.LinkShader() + * This actually involves converting GLSL IR into Mesa gl_programs with + * code lowering and other optimizations. + */ +GLboolean +_mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) +{ + assert(prog->LinkStatus); + + for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; + + bool progress; + exec_list *ir = prog->_LinkedShaders[i]->ir; + const struct gl_shader_compiler_options *options = + &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; + + do { + progress = false; + + /* Lowering */ + do_mat_op_to_vec(ir); + lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2 + | LOG_TO_LOG2 + | ((options->EmitNoPow) ? POW_TO_EXP2 : 0))); + + progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; + + progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress; + + progress = lower_quadop_vector(ir, true) || progress; + + if (options->EmitNoIfs) { + progress = lower_discard(ir) || progress; + progress = lower_if_to_cond_assign(ir) || progress; + } + + if (options->EmitNoNoise) + progress = lower_noise(ir) || progress; + + /* If there are forms of indirect addressing that the driver + * cannot handle, perform the lowering pass. + */ + if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput + || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) + progress = + lower_variable_index_to_cond_assign(ir, + options->EmitNoIndirectInput, + options->EmitNoIndirectOutput, + options->EmitNoIndirectTemp, + options->EmitNoIndirectUniform) + || progress; + + progress = do_vec_index_to_cond_assign(ir) || progress; + } while (progress); + + validate_ir_tree(ir); + } + + for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + struct gl_program *linked_prog; + + if (prog->_LinkedShaders[i] == NULL) + continue; + + linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); + + if (linked_prog) { + bool ok = true; + + switch (prog->_LinkedShaders[i]->Type) { + case GL_VERTEX_SHADER: + _mesa_reference_vertprog(ctx, &prog->VertexProgram, + (struct gl_vertex_program *)linked_prog); + ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, + linked_prog); + break; + case GL_FRAGMENT_SHADER: + _mesa_reference_fragprog(ctx, &prog->FragmentProgram, + (struct gl_fragment_program *)linked_prog); + ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, + linked_prog); + break; + case GL_GEOMETRY_SHADER: + _mesa_reference_geomprog(ctx, &prog->GeometryProgram, + (struct gl_geometry_program *)linked_prog); + ok = ctx->Driver.ProgramStringNotify(ctx, GL_GEOMETRY_PROGRAM_NV, + linked_prog); + break; + } + if (!ok) { + return GL_FALSE; + } + } + + _mesa_reference_program(ctx, &linked_prog, NULL); + } + + return GL_TRUE; +} + + +/** + * Compile a GLSL shader. Called via glCompileShader(). + */ +void +_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) +{ + struct _mesa_glsl_parse_state *state = + new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); + + const char *source = shader->Source; + /* Check if the user called glCompileShader without first calling + * glShaderSource. This should fail to compile, but not raise a GL_ERROR. + */ + if (source == NULL) { + shader->CompileStatus = GL_FALSE; + return; + } + + state->error = preprocess(state, &source, &state->info_log, + &ctx->Extensions, ctx->API); + + if (ctx->Shader.Flags & GLSL_DUMP) { + printf("GLSL source for shader %d:\n", shader->Name); + printf("%s\n", shader->Source); + } + + if (!state->error) { + _mesa_glsl_lexer_ctor(state, source); + _mesa_glsl_parse(state); + _mesa_glsl_lexer_dtor(state); + } + + ralloc_free(shader->ir); + shader->ir = new(shader) exec_list; + if (!state->error && !state->translation_unit.is_empty()) + _mesa_ast_to_hir(shader->ir, state); + + if (!state->error && !shader->ir->is_empty()) { + validate_ir_tree(shader->ir); + + /* Do some optimization at compile time to reduce shader IR size + * and reduce later work if the same shader is linked multiple times + */ + while (do_common_optimization(shader->ir, false, 32)) + ; + + validate_ir_tree(shader->ir); + } + + shader->symbols = state->symbols; + + shader->CompileStatus = !state->error; + shader->InfoLog = state->info_log; + shader->Version = state->language_version; + memcpy(shader->builtins_to_link, state->builtins_to_link, + sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); + shader->num_builtins_to_link = state->num_builtins_to_link; + + if (ctx->Shader.Flags & GLSL_LOG) { + _mesa_write_shader_to_file(shader); + } + + if (ctx->Shader.Flags & GLSL_DUMP) { + if (shader->CompileStatus) { + printf("GLSL IR for shader %d:\n", shader->Name); + _mesa_print_ir(shader->ir, NULL); + printf("\n\n"); + } else { + printf("GLSL shader %d failed to compile.\n", shader->Name); + } + if (shader->InfoLog && shader->InfoLog[0] != 0) { + printf("GLSL shader %d info log:\n", shader->Name); + printf("%s\n", shader->InfoLog); + } + } + + /* Retain any live IR, but trash the rest. */ + reparent_ir(shader->ir, shader->ir); + + ralloc_free(state); + + if (shader->CompileStatus) { + if (!ctx->Driver.CompileShader(ctx, shader)) + shader->CompileStatus = GL_FALSE; + } +} + + +/** + * Link a GLSL shader program. Called via glLinkProgram(). + */ +void +_mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) +{ + unsigned int i; + + _mesa_clear_shader_program_data(ctx, prog); + + prog->LinkStatus = GL_TRUE; + + for (i = 0; i < prog->NumShaders; i++) { + if (!prog->Shaders[i]->CompileStatus) { + fail_link(prog, "linking with uncompiled shader"); + prog->LinkStatus = GL_FALSE; + } + } + + prog->Varying = _mesa_new_parameter_list(); + _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); + _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); + _mesa_reference_geomprog(ctx, &prog->GeometryProgram, NULL); + + if (prog->LinkStatus) { + link_shaders(ctx, prog); + } + + if (prog->LinkStatus) { + if (!ctx->Driver.LinkShader(ctx, prog)) { + prog->LinkStatus = GL_FALSE; + } + } + + set_uniform_initializers(ctx, prog); + + if (ctx->Shader.Flags & GLSL_DUMP) { + if (!prog->LinkStatus) { + printf("GLSL shader program %d failed to link\n", prog->Name); + } + + if (prog->InfoLog && prog->InfoLog[0] != 0) { + printf("GLSL shader program %d info log:\n", prog->Name); + printf("%s\n", prog->InfoLog); + } + } +} + +} /* extern "C" */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c index 398e32a34..2934f9ffb 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c @@ -1,620 +1,639 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Framebuffer/renderbuffer functions. - * - * \author Brian Paul - */ - - -#include "main/imports.h" -#include "main/context.h" -#include "main/fbobject.h" -#include "main/framebuffer.h" -#include "main/macros.h" -#include "main/mfeatures.h" -#include "main/renderbuffer.h" - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_screen.h" -#include "st_context.h" -#include "st_cb_fbo.h" -#include "st_cb_flush.h" -#include "st_format.h" -#include "st_texture.h" -#include "st_manager.h" - -#include "util/u_format.h" -#include "util/u_inlines.h" -#include "util/u_surface.h" - - -/** - * gl_renderbuffer::AllocStorage() - * This is called to allocate the original drawing surface, and - * during window resize. - */ -static GLboolean -st_renderbuffer_alloc_storage(struct gl_context * ctx, - struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height) -{ - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; - struct pipe_screen *screen = st->pipe->screen; - struct st_renderbuffer *strb = st_renderbuffer(rb); - enum pipe_format format; - struct pipe_surface surf_tmpl; - - if (strb->format != PIPE_FORMAT_NONE) - format = strb->format; - else - format = st_choose_renderbuffer_format(screen, internalFormat, - rb->NumSamples); - - /* init renderbuffer fields */ - strb->Base.Width = width; - strb->Base.Height = height; - strb->Base.Format = st_pipe_format_to_mesa_format(format); - strb->Base.DataType = st_format_datatype(format); - - strb->defined = GL_FALSE; /* undefined contents now */ - - if (strb->software) { - size_t size; - - free(strb->data); - - assert(strb->format != PIPE_FORMAT_NONE); - - strb->stride = util_format_get_stride(strb->format, width); - size = util_format_get_2d_size(strb->format, strb->stride, height); - - strb->data = malloc(size); - - return strb->data != NULL; - } - else { - struct pipe_resource template; - - /* Free the old surface and texture - */ - pipe_surface_reference( &strb->surface, NULL ); - pipe_resource_reference( &strb->texture, NULL ); - pipe_sampler_view_reference(&strb->sampler_view, NULL); - - /* Setup new texture template. - */ - memset(&template, 0, sizeof(template)); - template.target = st->internal_target; - template.format = format; - template.width0 = width; - template.height0 = height; - template.depth0 = 1; - template.array_size = 1; - template.last_level = 0; - template.nr_samples = rb->NumSamples; - if (util_format_is_depth_or_stencil(format)) { - template.bind = PIPE_BIND_DEPTH_STENCIL; - } - else { - template.bind = (PIPE_BIND_DISPLAY_TARGET | - PIPE_BIND_RENDER_TARGET); - } - - strb->texture = screen->resource_create(screen, &template); - - if (!strb->texture) - return FALSE; - - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); - u_surface_default_template(&surf_tmpl, strb->texture, template.bind); - strb->surface = pipe->create_surface(pipe, - strb->texture, - &surf_tmpl); - if (strb->surface) { - assert(strb->surface->texture); - assert(strb->surface->format); - assert(strb->surface->width == width); - assert(strb->surface->height == height); - } - - return strb->surface != NULL; - } -} - - -/** - * gl_renderbuffer::Delete() - */ -static void -st_renderbuffer_delete(struct gl_renderbuffer *rb) -{ - struct st_renderbuffer *strb = st_renderbuffer(rb); - ASSERT(strb); - pipe_surface_reference(&strb->surface, NULL); - pipe_resource_reference(&strb->texture, NULL); - pipe_sampler_view_reference(&strb->sampler_view, NULL); - free(strb->data); - free(strb); -} - - -/** - * gl_renderbuffer::GetPointer() - */ -static void * -null_get_pointer(struct gl_context * ctx, struct gl_renderbuffer *rb, - GLint x, GLint y) -{ - /* By returning NULL we force all software rendering to go through - * the span routines. - */ -#if 0 - assert(0); /* Should never get called with softpipe */ -#endif - return NULL; -} - - -/** - * Called via ctx->Driver.NewFramebuffer() - */ -static struct gl_framebuffer * -st_new_framebuffer(struct gl_context *ctx, GLuint name) -{ - /* XXX not sure we need to subclass gl_framebuffer for pipe */ - return _mesa_new_framebuffer(ctx, name); -} - - -/** - * Called via ctx->Driver.NewRenderbuffer() - */ -static struct gl_renderbuffer * -st_new_renderbuffer(struct gl_context *ctx, GLuint name) -{ - struct st_renderbuffer *strb = ST_CALLOC_STRUCT(st_renderbuffer); - if (strb) { - _mesa_init_renderbuffer(&strb->Base, name); - strb->Base.Delete = st_renderbuffer_delete; - strb->Base.AllocStorage = st_renderbuffer_alloc_storage; - strb->Base.GetPointer = null_get_pointer; - strb->format = PIPE_FORMAT_NONE; - return &strb->Base; - } - return NULL; -} - - -/** - * Allocate a renderbuffer for a an on-screen window (not a user-created - * renderbuffer). The window system code determines the format. - */ -struct gl_renderbuffer * -st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw) -{ - struct st_renderbuffer *strb; - - strb = ST_CALLOC_STRUCT(st_renderbuffer); - if (!strb) { - _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer"); - return NULL; - } - - _mesa_init_renderbuffer(&strb->Base, 0); - strb->Base.ClassID = 0x4242; /* just a unique value */ - strb->Base.NumSamples = samples; - strb->Base.Format = st_pipe_format_to_mesa_format(format); - strb->Base.DataType = st_format_datatype(format); - strb->format = format; - strb->software = sw; - - switch (format) { - case PIPE_FORMAT_R8G8B8A8_UNORM: - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_B5G5R5A1_UNORM: - case PIPE_FORMAT_B4G4R4A4_UNORM: - case PIPE_FORMAT_B5G6R5_UNORM: - strb->Base.InternalFormat = GL_RGBA; - break; - case PIPE_FORMAT_Z16_UNORM: - strb->Base.InternalFormat = GL_DEPTH_COMPONENT16; - break; - case PIPE_FORMAT_Z32_UNORM: - strb->Base.InternalFormat = GL_DEPTH_COMPONENT32; - break; - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT; - break; - case PIPE_FORMAT_S8_USCALED: - strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT; - break; - case PIPE_FORMAT_R16G16B16A16_SNORM: - strb->Base.InternalFormat = GL_RGBA16; - break; - case PIPE_FORMAT_R8_UNORM: - strb->Base.InternalFormat = GL_R8; - break; - case PIPE_FORMAT_R8G8_UNORM: - strb->Base.InternalFormat = GL_RG8; - break; - case PIPE_FORMAT_R16_UNORM: - strb->Base.InternalFormat = GL_R16; - break; - case PIPE_FORMAT_R16G16_UNORM: - strb->Base.InternalFormat = GL_RG16; - break; - default: - _mesa_problem(NULL, - "Unexpected format in st_new_renderbuffer_fb"); - free(strb); - return NULL; - } - - /* st-specific methods */ - strb->Base.Delete = st_renderbuffer_delete; - strb->Base.AllocStorage = st_renderbuffer_alloc_storage; - strb->Base.GetPointer = null_get_pointer; - - /* surface is allocated in st_renderbuffer_alloc_storage() */ - strb->surface = NULL; - - return &strb->Base; -} - - - - -/** - * Called via ctx->Driver.BindFramebufferEXT(). - */ -static void -st_bind_framebuffer(struct gl_context *ctx, GLenum target, - struct gl_framebuffer *fb, struct gl_framebuffer *fbread) -{ - -} - -/** - * Called by ctx->Driver.FramebufferRenderbuffer - */ -static void -st_framebuffer_renderbuffer(struct gl_context *ctx, - struct gl_framebuffer *fb, - GLenum attachment, - struct gl_renderbuffer *rb) -{ - /* XXX no need for derivation? */ - _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); -} - - -/** - * Called by ctx->Driver.RenderTexture - */ -static void -st_render_texture(struct gl_context *ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att) -{ - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; - struct st_renderbuffer *strb; - struct gl_renderbuffer *rb; - struct pipe_resource *pt = st_get_texobj_resource(att->Texture); - struct st_texture_object *stObj; - const struct gl_texture_image *texImage; - struct pipe_surface surf_tmpl; - - /* When would this fail? Perhaps assert? */ - if (!pt) - return; - - /* get pointer to texture image we're rendeing to */ - texImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; - - /* create new renderbuffer which wraps the texture image */ - rb = st_new_renderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()"); - return; - } - - _mesa_reference_renderbuffer(&att->Renderbuffer, rb); - assert(rb->RefCount == 1); - rb->AllocStorage = NULL; /* should not get called */ - strb = st_renderbuffer(rb); - - assert(strb->Base.RefCount > 0); - - /* get the texture for the texture object */ - stObj = st_texture_object(att->Texture); - - /* point renderbuffer at texobject */ - strb->rtt = stObj; - strb->rtt_level = att->TextureLevel; - strb->rtt_face = att->CubeMapFace; - strb->rtt_slice = att->Zoffset; - - rb->Width = texImage->Width2; - rb->Height = texImage->Height2; - rb->_BaseFormat = texImage->_BaseFormat; - /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/ - - /*printf("***** pipe texture %d x %d\n", pt->width0, pt->height0);*/ - - pipe_resource_reference( &strb->texture, pt ); - - pipe_surface_reference(&strb->surface, NULL); - - pipe_sampler_view_reference(&strb->sampler_view, - st_get_texture_sampler_view(stObj, pipe)); - - assert(strb->rtt_level <= strb->texture->last_level); - - /* new surface for rendering into the texture */ - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); - surf_tmpl.format = ctx->Color.sRGBEnabled ? strb->texture->format : util_format_linear(strb->texture->format); - surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; - surf_tmpl.u.tex.level = strb->rtt_level; - surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice; - surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice; - strb->surface = pipe->create_surface(pipe, - strb->texture, - &surf_tmpl); - - strb->format = pt->format; - - strb->Base.Format = st_pipe_format_to_mesa_format(pt->format); - strb->Base.DataType = st_format_datatype(pt->format); - - /* - printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p %d x %d\n", - att->Texture, pt, strb->surface, rb->Width, rb->Height); - */ - - /* Invalidate buffer state so that the pipe's framebuffer state - * gets updated. - * That's where the new renderbuffer (which we just created) gets - * passed to the pipe as a (color/depth) render target. - */ - st_invalidate_state(ctx, _NEW_BUFFERS); -} - - -/** - * Called via ctx->Driver.FinishRenderTexture. - */ -static void -st_finish_render_texture(struct gl_context *ctx, - struct gl_renderbuffer_attachment *att) -{ - struct st_context *st = st_context(ctx); - struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer); - - if (!strb) - return; - - st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); - - strb->rtt = NULL; - - /* - printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface); - */ - - /* restore previous framebuffer state */ - st_invalidate_state(ctx, _NEW_BUFFERS); -} - - -/** - * Validate a renderbuffer attachment for a particular set of bindings. - */ -static GLboolean -st_validate_attachment(struct pipe_screen *screen, - const struct gl_renderbuffer_attachment *att, - unsigned bindings) -{ - const struct st_texture_object *stObj = st_texture_object(att->Texture); - - /* Only validate texture attachments for now, since - * st_renderbuffer_alloc_storage makes sure that - * the format is supported. - */ - if (att->Type != GL_TEXTURE) - return GL_TRUE; - - if (!stObj) - return GL_FALSE; - - return screen->is_format_supported(screen, stObj->pt->format, - PIPE_TEXTURE_2D, - stObj->pt->nr_samples, bindings, 0); -} - - -/** - * Check if two renderbuffer attachments name a combined depth/stencil - * renderbuffer. - */ -GLboolean -st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth, - const struct gl_renderbuffer_attachment *stencil) -{ - assert(depth && stencil); - - if (depth->Type == stencil->Type) { - if (depth->Type == GL_RENDERBUFFER_EXT && - depth->Renderbuffer == stencil->Renderbuffer) - return GL_TRUE; - - if (depth->Type == GL_TEXTURE && - depth->Texture == stencil->Texture) - return GL_TRUE; - } - - return GL_FALSE; -} - - -/** - * Check that the framebuffer configuration is valid in terms of what - * the driver can support. - * - * For Gallium we only supports combined Z+stencil, not separate buffers. - */ -static void -st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) -{ - struct st_context *st = st_context(ctx); - struct pipe_screen *screen = st->pipe->screen; - const struct gl_renderbuffer_attachment *depth = - &fb->Attachment[BUFFER_DEPTH]; - const struct gl_renderbuffer_attachment *stencil = - &fb->Attachment[BUFFER_STENCIL]; - GLuint i; - - if (depth->Type && stencil->Type && depth->Type != stencil->Type) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - return; - } - if (depth->Type == GL_RENDERBUFFER_EXT && - stencil->Type == GL_RENDERBUFFER_EXT && - depth->Renderbuffer != stencil->Renderbuffer) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - return; - } - if (depth->Type == GL_TEXTURE && - stencil->Type == GL_TEXTURE && - depth->Texture != stencil->Texture) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - return; - } - - if (!st_validate_attachment(screen, - depth, - PIPE_BIND_DEPTH_STENCIL)) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - return; - } - if (!st_validate_attachment(screen, - stencil, - PIPE_BIND_DEPTH_STENCIL)) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - return; - } - for (i = 0; i < ctx->Const.MaxColorAttachments; i++) { - if (!st_validate_attachment(screen, - &fb->Attachment[BUFFER_COLOR0 + i], - PIPE_BIND_RENDER_TARGET)) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - return; - } - } -} - - -/** - * Called via glDrawBuffer. - */ -static void -st_DrawBuffers(struct gl_context *ctx, GLsizei count, const GLenum *buffers) -{ - struct st_context *st = st_context(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - GLuint i; - - (void) count; - (void) buffers; - - /* add the renderbuffers on demand */ - for (i = 0; i < fb->_NumColorDrawBuffers; i++) { - gl_buffer_index idx = fb->_ColorDrawBufferIndexes[i]; - st_manager_add_color_renderbuffer(st, fb, idx); - } -} - - -/** - * Called via glReadBuffer. - */ -static void -st_ReadBuffer(struct gl_context *ctx, GLenum buffer) -{ - struct st_context *st = st_context(ctx); - struct gl_framebuffer *fb = ctx->ReadBuffer; - - (void) buffer; - - /* add the renderbuffer on demand */ - st_manager_add_color_renderbuffer(st, fb, fb->_ColorReadBufferIndex); -} - - -void st_init_fbo_functions(struct dd_function_table *functions) -{ -#if FEATURE_EXT_framebuffer_object - functions->NewFramebuffer = st_new_framebuffer; - functions->NewRenderbuffer = st_new_renderbuffer; - functions->BindFramebuffer = st_bind_framebuffer; - functions->FramebufferRenderbuffer = st_framebuffer_renderbuffer; - functions->RenderTexture = st_render_texture; - functions->FinishRenderTexture = st_finish_render_texture; - functions->ValidateFramebuffer = st_validate_framebuffer; -#endif - /* no longer needed by core Mesa, drivers handle resizes... - functions->ResizeBuffers = st_resize_buffers; - */ - - functions->DrawBuffers = st_DrawBuffers; - functions->ReadBuffer = st_ReadBuffer; -} - -/* XXX unused ? */ -struct pipe_sampler_view * -st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb, - struct pipe_context *pipe) -{ - if (!rb->sampler_view) { - rb->sampler_view = st_create_texture_sampler_view(pipe, rb->texture); - } - - return rb->sampler_view; -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Framebuffer/renderbuffer functions. + * + * \author Brian Paul + */ + + +#include "main/imports.h" +#include "main/context.h" +#include "main/fbobject.h" +#include "main/framebuffer.h" +#include "main/macros.h" +#include "main/mfeatures.h" +#include "main/renderbuffer.h" + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" +#include "st_context.h" +#include "st_cb_fbo.h" +#include "st_cb_flush.h" +#include "st_format.h" +#include "st_texture.h" +#include "st_manager.h" + +#include "util/u_format.h" +#include "util/u_inlines.h" +#include "util/u_surface.h" + + +/** + * gl_renderbuffer::AllocStorage() + * This is called to allocate the original drawing surface, and + * during window resize. + */ +static GLboolean +st_renderbuffer_alloc_storage(struct gl_context * ctx, + struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = st->pipe->screen; + struct st_renderbuffer *strb = st_renderbuffer(rb); + enum pipe_format format; + struct pipe_surface surf_tmpl; + + if (strb->format != PIPE_FORMAT_NONE) + format = strb->format; + else + format = st_choose_renderbuffer_format(screen, internalFormat, + rb->NumSamples); + + /* init renderbuffer fields */ + strb->Base.Width = width; + strb->Base.Height = height; + strb->Base.Format = st_pipe_format_to_mesa_format(format); + strb->Base.DataType = st_format_datatype(format); + + strb->defined = GL_FALSE; /* undefined contents now */ + + if (strb->software) { + size_t size; + + free(strb->data); + + assert(strb->format != PIPE_FORMAT_NONE); + + strb->stride = util_format_get_stride(strb->format, width); + size = util_format_get_2d_size(strb->format, strb->stride, height); + + strb->data = malloc(size); + + return strb->data != NULL; + } + else { + struct pipe_resource template; + + /* Free the old surface and texture + */ + pipe_surface_reference( &strb->surface, NULL ); + pipe_resource_reference( &strb->texture, NULL ); + pipe_sampler_view_reference(&strb->sampler_view, NULL); + + /* Setup new texture template. + */ + memset(&template, 0, sizeof(template)); + template.target = st->internal_target; + template.format = format; + template.width0 = width; + template.height0 = height; + template.depth0 = 1; + template.array_size = 1; + template.last_level = 0; + template.nr_samples = rb->NumSamples; + if (util_format_is_depth_or_stencil(format)) { + template.bind = PIPE_BIND_DEPTH_STENCIL; + } + else { + template.bind = (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_RENDER_TARGET); + } + + strb->texture = screen->resource_create(screen, &template); + + if (!strb->texture) + return FALSE; + + memset(&surf_tmpl, 0, sizeof(surf_tmpl)); + u_surface_default_template(&surf_tmpl, strb->texture, template.bind); + strb->surface = pipe->create_surface(pipe, + strb->texture, + &surf_tmpl); + if (strb->surface) { + assert(strb->surface->texture); + assert(strb->surface->format); + assert(strb->surface->width == width); + assert(strb->surface->height == height); + } + + return strb->surface != NULL; + } +} + + +/** + * gl_renderbuffer::Delete() + */ +static void +st_renderbuffer_delete(struct gl_renderbuffer *rb) +{ + struct st_renderbuffer *strb = st_renderbuffer(rb); + ASSERT(strb); + pipe_surface_reference(&strb->surface, NULL); + pipe_resource_reference(&strb->texture, NULL); + pipe_sampler_view_reference(&strb->sampler_view, NULL); + free(strb->data); + free(strb); +} + + +/** + * gl_renderbuffer::GetPointer() + */ +static void * +null_get_pointer(struct gl_context * ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + /* By returning NULL we force all software rendering to go through + * the span routines. + */ +#if 0 + assert(0); /* Should never get called with softpipe */ +#endif + return NULL; +} + + +/** + * Called via ctx->Driver.NewFramebuffer() + */ +static struct gl_framebuffer * +st_new_framebuffer(struct gl_context *ctx, GLuint name) +{ + /* XXX not sure we need to subclass gl_framebuffer for pipe */ + return _mesa_new_framebuffer(ctx, name); +} + + +/** + * Called via ctx->Driver.NewRenderbuffer() + */ +static struct gl_renderbuffer * +st_new_renderbuffer(struct gl_context *ctx, GLuint name) +{ + struct st_renderbuffer *strb = ST_CALLOC_STRUCT(st_renderbuffer); + if (strb) { + _mesa_init_renderbuffer(&strb->Base, name); + strb->Base.Delete = st_renderbuffer_delete; + strb->Base.AllocStorage = st_renderbuffer_alloc_storage; + strb->Base.GetPointer = null_get_pointer; + strb->format = PIPE_FORMAT_NONE; + return &strb->Base; + } + return NULL; +} + + +/** + * Allocate a renderbuffer for a an on-screen window (not a user-created + * renderbuffer). The window system code determines the format. + */ +struct gl_renderbuffer * +st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw) +{ + struct st_renderbuffer *strb; + + strb = ST_CALLOC_STRUCT(st_renderbuffer); + if (!strb) { + _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer"); + return NULL; + } + + _mesa_init_renderbuffer(&strb->Base, 0); + strb->Base.ClassID = 0x4242; /* just a unique value */ + strb->Base.NumSamples = samples; + strb->Base.Format = st_pipe_format_to_mesa_format(format); + strb->Base.DataType = st_format_datatype(format); + strb->format = format; + strb->software = sw; + + switch (format) { + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R8G8B8X8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B4G4R4A4_UNORM: + case PIPE_FORMAT_B5G6R5_UNORM: + strb->Base.InternalFormat = GL_RGBA; + break; + case PIPE_FORMAT_Z16_UNORM: + strb->Base.InternalFormat = GL_DEPTH_COMPONENT16; + break; + case PIPE_FORMAT_Z32_UNORM: + strb->Base.InternalFormat = GL_DEPTH_COMPONENT32; + break; + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT; + break; + case PIPE_FORMAT_S8_USCALED: + strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT; + break; + case PIPE_FORMAT_R16G16B16A16_SNORM: + strb->Base.InternalFormat = GL_RGBA16; + break; + case PIPE_FORMAT_R8_UNORM: + strb->Base.InternalFormat = GL_R8; + break; + case PIPE_FORMAT_R8G8_UNORM: + strb->Base.InternalFormat = GL_RG8; + break; + case PIPE_FORMAT_R16_UNORM: + strb->Base.InternalFormat = GL_R16; + break; + case PIPE_FORMAT_R16G16_UNORM: + strb->Base.InternalFormat = GL_RG16; + break; + default: + _mesa_problem(NULL, + "Unexpected format in st_new_renderbuffer_fb"); + free(strb); + return NULL; + } + + /* st-specific methods */ + strb->Base.Delete = st_renderbuffer_delete; + strb->Base.AllocStorage = st_renderbuffer_alloc_storage; + strb->Base.GetPointer = null_get_pointer; + + /* surface is allocated in st_renderbuffer_alloc_storage() */ + strb->surface = NULL; + + return &strb->Base; +} + + + + +/** + * Called via ctx->Driver.BindFramebufferEXT(). + */ +static void +st_bind_framebuffer(struct gl_context *ctx, GLenum target, + struct gl_framebuffer *fb, struct gl_framebuffer *fbread) +{ + +} + +/** + * Called by ctx->Driver.FramebufferRenderbuffer + */ +static void +st_framebuffer_renderbuffer(struct gl_context *ctx, + struct gl_framebuffer *fb, + GLenum attachment, + struct gl_renderbuffer *rb) +{ + /* XXX no need for derivation? */ + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); +} + + +/** + * Called by ctx->Driver.RenderTexture + */ +static void +st_render_texture(struct gl_context *ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = st->pipe; + struct st_renderbuffer *strb; + struct gl_renderbuffer *rb; + struct pipe_resource *pt = st_get_texobj_resource(att->Texture); + struct st_texture_object *stObj; + const struct gl_texture_image *texImage; + struct pipe_surface surf_tmpl; + + /* When would this fail? Perhaps assert? */ + if (!pt) + return; + + /* get pointer to texture image we're rendeing to */ + texImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + + /* create new renderbuffer which wraps the texture image */ + rb = st_new_renderbuffer(ctx, 0); + if (!rb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()"); + return; + } + + _mesa_reference_renderbuffer(&att->Renderbuffer, rb); + assert(rb->RefCount == 1); + rb->AllocStorage = NULL; /* should not get called */ + strb = st_renderbuffer(rb); + + assert(strb->Base.RefCount > 0); + + /* get the texture for the texture object */ + stObj = st_texture_object(att->Texture); + + /* point renderbuffer at texobject */ + strb->rtt = stObj; + strb->rtt_level = att->TextureLevel; + strb->rtt_face = att->CubeMapFace; + strb->rtt_slice = att->Zoffset; + + rb->Width = texImage->Width2; + rb->Height = texImage->Height2; + rb->_BaseFormat = texImage->_BaseFormat; + /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/ + + /*printf("***** pipe texture %d x %d\n", pt->width0, pt->height0);*/ + + pipe_resource_reference( &strb->texture, pt ); + + pipe_surface_reference(&strb->surface, NULL); + + pipe_sampler_view_reference(&strb->sampler_view, + st_get_texture_sampler_view(stObj, pipe)); + + assert(strb->rtt_level <= strb->texture->last_level); + + /* new surface for rendering into the texture */ + memset(&surf_tmpl, 0, sizeof(surf_tmpl)); + surf_tmpl.format = ctx->Color.sRGBEnabled ? strb->texture->format : util_format_linear(strb->texture->format); + surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; + surf_tmpl.u.tex.level = strb->rtt_level; + surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice; + surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice; + strb->surface = pipe->create_surface(pipe, + strb->texture, + &surf_tmpl); + + strb->format = pt->format; + + strb->Base.Format = st_pipe_format_to_mesa_format(pt->format); + strb->Base.DataType = st_format_datatype(pt->format); + + /* + printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p %d x %d\n", + att->Texture, pt, strb->surface, rb->Width, rb->Height); + */ + + /* Invalidate buffer state so that the pipe's framebuffer state + * gets updated. + * That's where the new renderbuffer (which we just created) gets + * passed to the pipe as a (color/depth) render target. + */ + st_invalidate_state(ctx, _NEW_BUFFERS); +} + + +/** + * Called via ctx->Driver.FinishRenderTexture. + */ +static void +st_finish_render_texture(struct gl_context *ctx, + struct gl_renderbuffer_attachment *att) +{ + struct st_context *st = st_context(ctx); + struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer); + + if (!strb) + return; + + st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); + + strb->rtt = NULL; + + /* + printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface); + */ + + /* restore previous framebuffer state */ + st_invalidate_state(ctx, _NEW_BUFFERS); +} + + +/** + * Validate a renderbuffer attachment for a particular set of bindings. + */ +static GLboolean +st_validate_attachment(struct gl_context *ctx, + struct pipe_screen *screen, + const struct gl_renderbuffer_attachment *att, + unsigned bindings) +{ + const struct st_texture_object *stObj = st_texture_object(att->Texture); + enum pipe_format format; + gl_format texFormat; + + /* Only validate texture attachments for now, since + * st_renderbuffer_alloc_storage makes sure that + * the format is supported. + */ + if (att->Type != GL_TEXTURE) + return GL_TRUE; + + if (!stObj) + return GL_FALSE; + + format = stObj->pt->format; + texFormat = + stObj->base.Image[att->CubeMapFace][att->TextureLevel]->TexFormat; + + /* If the encoding is sRGB and sRGB rendering cannot be enabled, + * check for linear format support instead. + * Later when we create a surface, we change the format to a linear one. */ + if (!ctx->Const.sRGBCapable && + _mesa_get_format_color_encoding(texFormat) == GL_SRGB) { + const gl_format linearFormat = _mesa_get_srgb_format_linear(texFormat); + format = st_mesa_format_to_pipe_format(linearFormat); + } + + return screen->is_format_supported(screen, format, + PIPE_TEXTURE_2D, + stObj->pt->nr_samples, bindings, 0); +} + + +/** + * Check if two renderbuffer attachments name a combined depth/stencil + * renderbuffer. + */ +GLboolean +st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth, + const struct gl_renderbuffer_attachment *stencil) +{ + assert(depth && stencil); + + if (depth->Type == stencil->Type) { + if (depth->Type == GL_RENDERBUFFER_EXT && + depth->Renderbuffer == stencil->Renderbuffer) + return GL_TRUE; + + if (depth->Type == GL_TEXTURE && + depth->Texture == stencil->Texture) + return GL_TRUE; + } + + return GL_FALSE; +} + + +/** + * Check that the framebuffer configuration is valid in terms of what + * the driver can support. + * + * For Gallium we only supports combined Z+stencil, not separate buffers. + */ +static void +st_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) +{ + struct st_context *st = st_context(ctx); + struct pipe_screen *screen = st->pipe->screen; + const struct gl_renderbuffer_attachment *depth = + &fb->Attachment[BUFFER_DEPTH]; + const struct gl_renderbuffer_attachment *stencil = + &fb->Attachment[BUFFER_STENCIL]; + GLuint i; + + if (depth->Type && stencil->Type && depth->Type != stencil->Type) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; + } + if (depth->Type == GL_RENDERBUFFER_EXT && + stencil->Type == GL_RENDERBUFFER_EXT && + depth->Renderbuffer != stencil->Renderbuffer) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; + } + if (depth->Type == GL_TEXTURE && + stencil->Type == GL_TEXTURE && + depth->Texture != stencil->Texture) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; + } + + if (!st_validate_attachment(ctx, + screen, + depth, + PIPE_BIND_DEPTH_STENCIL)) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; + } + if (!st_validate_attachment(ctx, + screen, + stencil, + PIPE_BIND_DEPTH_STENCIL)) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; + } + for (i = 0; i < ctx->Const.MaxColorAttachments; i++) { + if (!st_validate_attachment(ctx, + screen, + &fb->Attachment[BUFFER_COLOR0 + i], + PIPE_BIND_RENDER_TARGET)) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; + } + } +} + + +/** + * Called via glDrawBuffer. + */ +static void +st_DrawBuffers(struct gl_context *ctx, GLsizei count, const GLenum *buffers) +{ + struct st_context *st = st_context(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + GLuint i; + + (void) count; + (void) buffers; + + /* add the renderbuffers on demand */ + for (i = 0; i < fb->_NumColorDrawBuffers; i++) { + gl_buffer_index idx = fb->_ColorDrawBufferIndexes[i]; + st_manager_add_color_renderbuffer(st, fb, idx); + } +} + + +/** + * Called via glReadBuffer. + */ +static void +st_ReadBuffer(struct gl_context *ctx, GLenum buffer) +{ + struct st_context *st = st_context(ctx); + struct gl_framebuffer *fb = ctx->ReadBuffer; + + (void) buffer; + + /* add the renderbuffer on demand */ + st_manager_add_color_renderbuffer(st, fb, fb->_ColorReadBufferIndex); +} + + +void st_init_fbo_functions(struct dd_function_table *functions) +{ +#if FEATURE_EXT_framebuffer_object + functions->NewFramebuffer = st_new_framebuffer; + functions->NewRenderbuffer = st_new_renderbuffer; + functions->BindFramebuffer = st_bind_framebuffer; + functions->FramebufferRenderbuffer = st_framebuffer_renderbuffer; + functions->RenderTexture = st_render_texture; + functions->FinishRenderTexture = st_finish_render_texture; + functions->ValidateFramebuffer = st_validate_framebuffer; +#endif + /* no longer needed by core Mesa, drivers handle resizes... + functions->ResizeBuffers = st_resize_buffers; + */ + + functions->DrawBuffers = st_DrawBuffers; + functions->ReadBuffer = st_ReadBuffer; +} + +/* XXX unused ? */ +struct pipe_sampler_view * +st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb, + struct pipe_context *pipe) +{ + if (!rb->sampler_view) { + rb->sampler_view = st_create_texture_sampler_view(pipe, rb->texture); + } + + return rb->sampler_view; +} diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index 3b54eb7b8..5684e9768 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -426,19 +426,13 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi) struct gl_config mode; gl_buffer_index idx; + if (!stfbi) + return NULL; + stfb = CALLOC_STRUCT(st_framebuffer); if (!stfb) return NULL; - /* for FBO-only context */ - if (!stfbi) { - struct gl_framebuffer *base = _mesa_get_incomplete_framebuffer(); - - stfb->Base = *base; - - return stfb; - } - st_visual_to_context_mode(stfbi->visual, &mode); _mesa_initialize_window_framebuffer(&stfb->Base, &mode); @@ -764,7 +758,8 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, ret = _mesa_make_current(st->ctx, &stdraw->Base, &stread->Base); } else { - ret = FALSE; + struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer(); + ret = _mesa_make_current(st->ctx, incomplete, incomplete); } st_framebuffer_reference(&stdraw, NULL); diff --git a/mesalib/src/mesa/swrast/s_trispan.h b/mesalib/src/mesa/swrast/s_trispan.h deleted file mode 100644 index 15207e863..000000000 --- a/mesalib/src/mesa/swrast/s_trispan.h +++ /dev/null @@ -1,31 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef S_TRISPAN_H -#define S_TRISPAN_H - - -#endif /* S_TRISPAN_H */ diff --git a/mesalib/src/mesa/x86/read_rgba_span_x86.S b/mesalib/src/mesa/x86/read_rgba_span_x86.S index 817729973..04571afb7 100644 --- a/mesalib/src/mesa/x86/read_rgba_span_x86.S +++ b/mesalib/src/mesa/x86/read_rgba_span_x86.S @@ -1,678 +1,686 @@ -/* - * (C) Copyright IBM Corporation 2004 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file read_rgba_span_x86.S - * Optimized routines to transfer pixel data from the framebuffer to a - * buffer in main memory. - * - * \author Ian Romanick - */ - - .file "read_rgba_span_x86.S" -#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__) /* this one cries for assyntax.h */ -/* Kevin F. Quinn 2nd July 2006 - * Replaced data segment constants with text-segment instructions. - */ -#define LOAD_MASK(mvins,m1,m2) \ - pushl $0xff00ff00 ;\ - pushl $0xff00ff00 ;\ - pushl $0xff00ff00 ;\ - pushl $0xff00ff00 ;\ - mvins (%esp), m1 ;\ - pushl $0x00ff0000 ;\ - pushl $0x00ff0000 ;\ - pushl $0x00ff0000 ;\ - pushl $0x00ff0000 ;\ - mvins (%esp), m2 ;\ - addl $32, %esp - -/* I implemented these as macros because they appear in several places, - * and I've tweaked them a number of times. I got tired of changing every - * place they appear. :) - */ - -#define DO_ONE_PIXEL() \ - movl (%ebx), %eax ; \ - addl $4, %ebx ; \ - bswap %eax /* ARGB -> BGRA */ ; \ - rorl $8, %eax /* BGRA -> ABGR */ ; \ - movl %eax, (%ecx) /* ABGR -> R, G, B, A */ ; \ - addl $4, %ecx - -#define DO_ONE_LAST_PIXEL() \ - movl (%ebx), %eax ; \ - bswap %eax /* ARGB -> BGRA */ ; \ - rorl $8, %eax /* BGRA -> ABGR */ ; \ - movl %eax, (%ecx) /* ABGR -> R, G, B, A */ ; \ - - -/** - * MMX optimized version of the BGRA8888_REV to RGBA copy routine. - * - * \warning - * This function assumes that the caller will issue the EMMS instruction - * at the correct places. - */ - -.globl _generic_read_RGBA_span_BGRA8888_REV_MMX -.hidden _generic_read_RGBA_span_BGRA8888_REV_MMX - .type _generic_read_RGBA_span_BGRA8888_REV_MMX, @function -_generic_read_RGBA_span_BGRA8888_REV_MMX: - pushl %ebx - -#ifdef USE_INNER_EMMS - emms -#endif - LOAD_MASK(movq,%mm1,%mm2) - - movl 8(%esp), %ebx /* source pointer */ - movl 16(%esp), %edx /* number of pixels to copy */ - movl 12(%esp), %ecx /* destination pointer */ - - testl %edx, %edx - jle .L20 /* Bail if there's nothing to do. */ - - movl %ebx, %eax - - negl %eax - sarl $2, %eax - andl $1, %eax - je .L17 - - subl %eax, %edx - DO_ONE_PIXEL() -.L17: - - /* Would it be faster to unroll this loop once and process 4 pixels - * per pass, instead of just two? - */ - - movl %edx, %eax - shrl %eax - jmp .L18 -.L19: - movq (%ebx), %mm0 - addl $8, %ebx - - /* These 9 instructions do what PSHUFB (if there were such an - * instruction) could do in 1. :( - */ - - movq %mm0, %mm3 - movq %mm0, %mm4 - - pand %mm2, %mm3 - psllq $16, %mm4 - psrlq $16, %mm3 - pand %mm2, %mm4 - - pand %mm1, %mm0 - por %mm4, %mm3 - por %mm3, %mm0 - - movq %mm0, (%ecx) - addl $8, %ecx - subl $1, %eax -.L18: - jne .L19 - -#ifdef USE_INNER_EMMS - emms -#endif - - /* At this point there are either 1 or 0 pixels remaining to be - * converted. Convert the last pixel, if needed. - */ - - testl $1, %edx - je .L20 - - DO_ONE_LAST_PIXEL() - -.L20: - popl %ebx - ret - .size _generic_read_RGBA_span_BGRA8888_REV_MMX, .-_generic_read_RGBA_span_BGRA8888_REV_MMX - - -/** - * SSE optimized version of the BGRA8888_REV to RGBA copy routine. SSE - * instructions are only actually used to read data from the framebuffer. - * In practice, the speed-up is pretty small. - * - * \todo - * Do some more testing and determine if there's any reason to have this - * function in addition to the MMX version. - * - * \warning - * This function assumes that the caller will issue the EMMS instruction - * at the correct places. - */ - -.globl _generic_read_RGBA_span_BGRA8888_REV_SSE -.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE - .type _generic_read_RGBA_span_BGRA8888_REV_SSE, @function -_generic_read_RGBA_span_BGRA8888_REV_SSE: - pushl %esi - pushl %ebx - pushl %ebp - -#ifdef USE_INNER_EMMS - emms -#endif - - LOAD_MASK(movq,%mm1,%mm2) - - movl 16(%esp), %ebx /* source pointer */ - movl 24(%esp), %edx /* number of pixels to copy */ - movl 20(%esp), %ecx /* destination pointer */ - - testl %edx, %edx - jle .L35 /* Bail if there's nothing to do. */ - - movl %esp, %ebp - subl $16, %esp - andl $0xfffffff0, %esp - - movl %ebx, %eax - movl %edx, %esi - - negl %eax - andl $15, %eax - sarl $2, %eax - cmpl %edx, %eax - cmovle %eax, %esi - - subl %esi, %edx - - testl $1, %esi - je .L32 - - DO_ONE_PIXEL() -.L32: - - testl $2, %esi - je .L31 - - movq (%ebx), %mm0 - addl $8, %ebx - - movq %mm0, %mm3 - movq %mm0, %mm4 - - pand %mm2, %mm3 - psllq $16, %mm4 - psrlq $16, %mm3 - pand %mm2, %mm4 - - pand %mm1, %mm0 - por %mm4, %mm3 - por %mm3, %mm0 - - movq %mm0, (%ecx) - addl $8, %ecx -.L31: - - movl %edx, %eax - shrl $2, %eax - jmp .L33 -.L34: - movaps (%ebx), %xmm0 - addl $16, %ebx - - /* This would be so much better if we could just move directly from - * an SSE register to an MMX register. Unfortunately, that - * functionality wasn't introduced until SSE2 with the MOVDQ2Q - * instruction. - */ - - movaps %xmm0, (%esp) - movq (%esp), %mm0 - movq 8(%esp), %mm5 - - movq %mm0, %mm3 - movq %mm0, %mm4 - movq %mm5, %mm6 - movq %mm5, %mm7 - - pand %mm2, %mm3 - pand %mm2, %mm6 - - psllq $16, %mm4 - psllq $16, %mm7 - - psrlq $16, %mm3 - psrlq $16, %mm6 - - pand %mm2, %mm4 - pand %mm2, %mm7 - - pand %mm1, %mm0 - pand %mm1, %mm5 - - por %mm4, %mm3 - por %mm7, %mm6 - - por %mm3, %mm0 - por %mm6, %mm5 - - movq %mm0, (%ecx) - movq %mm5, 8(%ecx) - addl $16, %ecx - - subl $1, %eax -.L33: - jne .L34 - -#ifdef USE_INNER_EMMS - emms -#endif - movl %ebp, %esp - - /* At this point there are either [0, 3] pixels remaining to be - * converted. - */ - - testl $2, %edx - je .L36 - - movq (%ebx), %mm0 - addl $8, %ebx - - movq %mm0, %mm3 - movq %mm0, %mm4 - - pand %mm2, %mm3 - psllq $16, %mm4 - psrlq $16, %mm3 - pand %mm2, %mm4 - - pand %mm1, %mm0 - por %mm4, %mm3 - por %mm3, %mm0 - - movq %mm0, (%ecx) - addl $8, %ecx -.L36: - - testl $1, %edx - je .L35 - - DO_ONE_LAST_PIXEL() -.L35: - popl %ebp - popl %ebx - popl %esi - ret - .size _generic_read_RGBA_span_BGRA8888_REV_SSE, .-_generic_read_RGBA_span_BGRA8888_REV_SSE - - -/** - * SSE2 optimized version of the BGRA8888_REV to RGBA copy routine. - */ - - .text -.globl _generic_read_RGBA_span_BGRA8888_REV_SSE2 -.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE2 - .type _generic_read_RGBA_span_BGRA8888_REV_SSE2, @function -_generic_read_RGBA_span_BGRA8888_REV_SSE2: - pushl %esi - pushl %ebx - - LOAD_MASK(movdqu,%xmm1,%xmm2) - - movl 12(%esp), %ebx /* source pointer */ - movl 20(%esp), %edx /* number of pixels to copy */ - movl 16(%esp), %ecx /* destination pointer */ - - movl %ebx, %eax - movl %edx, %esi - - testl %edx, %edx - jle .L46 /* Bail if there's nothing to do. */ - - /* If the source pointer isn't a multiple of 16 we have to process - * a few pixels the "slow" way to get the address aligned for - * the SSE fetch intsructions. - */ - - negl %eax - andl $15, %eax - sarl $2, %eax - - cmpl %edx, %eax - cmovbe %eax, %esi - subl %esi, %edx - - testl $1, %esi - je .L41 - - DO_ONE_PIXEL() -.L41: - testl $2, %esi - je .L40 - - movq (%ebx), %xmm0 - addl $8, %ebx - - movdqa %xmm0, %xmm3 - movdqa %xmm0, %xmm4 - andps %xmm1, %xmm0 - - andps %xmm2, %xmm3 - pslldq $2, %xmm4 - psrldq $2, %xmm3 - andps %xmm2, %xmm4 - - orps %xmm4, %xmm3 - orps %xmm3, %xmm0 - - movq %xmm0, (%ecx) - addl $8, %ecx -.L40: - - /* Would it be worth having a specialized version of this loop for - * the case where the destination is 16-byte aligned? That version - * would be identical except that it could use movedqa instead of - * movdqu. - */ - - movl %edx, %eax - shrl $2, %eax - jmp .L42 -.L43: - movdqa (%ebx), %xmm0 - addl $16, %ebx - - movdqa %xmm0, %xmm3 - movdqa %xmm0, %xmm4 - andps %xmm1, %xmm0 - - andps %xmm2, %xmm3 - pslldq $2, %xmm4 - psrldq $2, %xmm3 - andps %xmm2, %xmm4 - - orps %xmm4, %xmm3 - orps %xmm3, %xmm0 - - movdqu %xmm0, (%ecx) - addl $16, %ecx - subl $1, %eax -.L42: - jne .L43 - - - /* There may be upto 3 pixels remaining to be copied. Take care - * of them now. We do the 2 pixel case first because the data - * will be aligned. - */ - - testl $2, %edx - je .L47 - - movq (%ebx), %xmm0 - addl $8, %ebx - - movdqa %xmm0, %xmm3 - movdqa %xmm0, %xmm4 - andps %xmm1, %xmm0 - - andps %xmm2, %xmm3 - pslldq $2, %xmm4 - psrldq $2, %xmm3 - andps %xmm2, %xmm4 - - orps %xmm4, %xmm3 - orps %xmm3, %xmm0 - - movq %xmm0, (%ecx) - addl $8, %ecx -.L47: - - testl $1, %edx - je .L46 - - DO_ONE_LAST_PIXEL() -.L46: - - popl %ebx - popl %esi - ret - .size _generic_read_RGBA_span_BGRA8888_REV_SSE2, .-_generic_read_RGBA_span_BGRA8888_REV_SSE2 - - - -#define MASK_565_L 0x07e0f800 -#define MASK_565_H 0x0000001f -/* Setting SCALE_ADJUST to 5 gives a perfect match with the - * classic C implementation in Mesa. Setting SCALE_ADJUST - * to 0 is slightly faster but at a small cost to accuracy. - */ -#define SCALE_ADJUST 5 -#if SCALE_ADJUST == 5 -#define PRESCALE_L 0x00100001 -#define PRESCALE_H 0x00000200 -#define SCALE_L 0x40C620E8 -#define SCALE_H 0x0000839d -#elif SCALE_ADJUST == 0 -#define PRESCALE_L 0x00200001 -#define PRESCALE_H 0x00000800 -#define SCALE_L 0x01040108 -#define SCALE_H 0x00000108 -#else -#error SCALE_ADJUST must either be 5 or 0. -#endif -#define ALPHA_L 0x00000000 -#define ALPHA_H 0x00ff0000 - -/** - * MMX optimized version of the RGB565 to RGBA copy routine. - */ - - .text - .globl _generic_read_RGBA_span_RGB565_MMX - .hidden _generic_read_RGBA_span_RGB565_MMX - .type _generic_read_RGBA_span_RGB565_MMX, @function - -_generic_read_RGBA_span_RGB565_MMX: - -#ifdef USE_INNER_EMMS - emms -#endif - - movl 4(%esp), %eax /* source pointer */ - movl 8(%esp), %edx /* destination pointer */ - movl 12(%esp), %ecx /* number of pixels to copy */ - - pushl $MASK_565_H - pushl $MASK_565_L - movq (%esp), %mm5 - pushl $PRESCALE_H - pushl $PRESCALE_L - movq (%esp), %mm6 - pushl $SCALE_H - pushl $SCALE_L - movq (%esp), %mm7 - pushl $ALPHA_H - pushl $ALPHA_L - movq (%esp), %mm3 - addl $32,%esp - - sarl $2, %ecx - jl .L01 /* Bail early if the count is negative. */ - jmp .L02 - -.L03: - /* Fetch 4 RGB565 pixels into %mm4. Distribute the first and - * second pixels into the four words of %mm0 and %mm2. - */ - - movq (%eax), %mm4 - addl $8, %eax - - pshufw $0x00, %mm4, %mm0 - pshufw $0x55, %mm4, %mm2 - - - /* Mask the pixels so that each word of each register contains only - * one color component. - */ - - pand %mm5, %mm0 - pand %mm5, %mm2 - - - /* Adjust the component values so that they are as small as possible, - * but large enough so that we can multiply them by an unsigned 16-bit - * number and get a value as large as 0x00ff0000. - */ - - pmullw %mm6, %mm0 - pmullw %mm6, %mm2 -#if SCALE_ADJUST > 0 - psrlw $SCALE_ADJUST, %mm0 - psrlw $SCALE_ADJUST, %mm2 -#endif - - /* Scale the input component values to be on the range - * [0, 0x00ff0000]. This it the real magic of the whole routine. - */ - - pmulhuw %mm7, %mm0 - pmulhuw %mm7, %mm2 - - - /* Always set the alpha value to 0xff. - */ - - por %mm3, %mm0 - por %mm3, %mm2 - - - /* Pack the 16-bit values to 8-bit values and store the converted - * pixel data. - */ - - packuswb %mm2, %mm0 - movq %mm0, (%edx) - addl $8, %edx - - pshufw $0xaa, %mm4, %mm0 - pshufw $0xff, %mm4, %mm2 - - pand %mm5, %mm0 - pand %mm5, %mm2 - pmullw %mm6, %mm0 - pmullw %mm6, %mm2 -#if SCALE_ADJUST > 0 - psrlw $SCALE_ADJUST, %mm0 - psrlw $SCALE_ADJUST, %mm2 -#endif - pmulhuw %mm7, %mm0 - pmulhuw %mm7, %mm2 - - por %mm3, %mm0 - por %mm3, %mm2 - - packuswb %mm2, %mm0 - - movq %mm0, (%edx) - addl $8, %edx - - subl $1, %ecx -.L02: - jne .L03 - - - /* At this point there can be at most 3 pixels left to process. If - * there is either 2 or 3 left, process 2. - */ - - movl 12(%esp), %ecx - testl $0x02, %ecx - je .L04 - - movd (%eax), %mm4 - addl $4, %eax - - pshufw $0x00, %mm4, %mm0 - pshufw $0x55, %mm4, %mm2 - - pand %mm5, %mm0 - pand %mm5, %mm2 - pmullw %mm6, %mm0 - pmullw %mm6, %mm2 -#if SCALE_ADJUST > 0 - psrlw $SCALE_ADJUST, %mm0 - psrlw $SCALE_ADJUST, %mm2 -#endif - pmulhuw %mm7, %mm0 - pmulhuw %mm7, %mm2 - - por %mm3, %mm0 - por %mm3, %mm2 - - packuswb %mm2, %mm0 - - movq %mm0, (%edx) - addl $8, %edx - -.L04: - /* At this point there can be at most 1 pixel left to process. - * Process it if needed. - */ - - testl $0x01, %ecx - je .L01 - - movzwl (%eax), %ecx - movd %ecx, %mm4 - - pshufw $0x00, %mm4, %mm0 - - pand %mm5, %mm0 - pmullw %mm6, %mm0 -#if SCALE_ADJUST > 0 - psrlw $SCALE_ADJUST, %mm0 -#endif - pmulhuw %mm7, %mm0 - - por %mm3, %mm0 - - packuswb %mm0, %mm0 - - movd %mm0, (%edx) - -.L01: -#ifdef USE_INNER_EMMS - emms -#endif - ret -#endif /* !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__) */ - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif +/* + * (C) Copyright IBM Corporation 2004 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file read_rgba_span_x86.S + * Optimized routines to transfer pixel data from the framebuffer to a + * buffer in main memory. + * + * \author Ian Romanick + */ + + .file "read_rgba_span_x86.S" +#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__) /* this one cries for assyntax.h */ +/* Kevin F. Quinn 2nd July 2006 + * Replaced data segment constants with text-segment instructions. + */ +#define LOAD_MASK(mvins,m1,m2) \ + pushl $0xff00ff00 ;\ + pushl $0xff00ff00 ;\ + pushl $0xff00ff00 ;\ + pushl $0xff00ff00 ;\ + mvins (%esp), m1 ;\ + pushl $0x00ff0000 ;\ + pushl $0x00ff0000 ;\ + pushl $0x00ff0000 ;\ + pushl $0x00ff0000 ;\ + mvins (%esp), m2 ;\ + addl $32, %esp + +/* I implemented these as macros because they appear in several places, + * and I've tweaked them a number of times. I got tired of changing every + * place they appear. :) + */ + +#define DO_ONE_PIXEL() \ + movl (%ebx), %eax ; \ + addl $4, %ebx ; \ + bswap %eax /* ARGB -> BGRA */ ; \ + rorl $8, %eax /* BGRA -> ABGR */ ; \ + movl %eax, (%ecx) /* ABGR -> R, G, B, A */ ; \ + addl $4, %ecx + +#define DO_ONE_LAST_PIXEL() \ + movl (%ebx), %eax ; \ + bswap %eax /* ARGB -> BGRA */ ; \ + rorl $8, %eax /* BGRA -> ABGR */ ; \ + movl %eax, (%ecx) /* ABGR -> R, G, B, A */ ; \ + + +/** + * MMX optimized version of the BGRA8888_REV to RGBA copy routine. + * + * \warning + * This function assumes that the caller will issue the EMMS instruction + * at the correct places. + */ + +.globl _generic_read_RGBA_span_BGRA8888_REV_MMX +#ifndef USE_DRICORE +.hidden _generic_read_RGBA_span_BGRA8888_REV_MMX +#endif + .type _generic_read_RGBA_span_BGRA8888_REV_MMX, @function +_generic_read_RGBA_span_BGRA8888_REV_MMX: + pushl %ebx + +#ifdef USE_INNER_EMMS + emms +#endif + LOAD_MASK(movq,%mm1,%mm2) + + movl 8(%esp), %ebx /* source pointer */ + movl 16(%esp), %edx /* number of pixels to copy */ + movl 12(%esp), %ecx /* destination pointer */ + + testl %edx, %edx + jle .L20 /* Bail if there's nothing to do. */ + + movl %ebx, %eax + + negl %eax + sarl $2, %eax + andl $1, %eax + je .L17 + + subl %eax, %edx + DO_ONE_PIXEL() +.L17: + + /* Would it be faster to unroll this loop once and process 4 pixels + * per pass, instead of just two? + */ + + movl %edx, %eax + shrl %eax + jmp .L18 +.L19: + movq (%ebx), %mm0 + addl $8, %ebx + + /* These 9 instructions do what PSHUFB (if there were such an + * instruction) could do in 1. :( + */ + + movq %mm0, %mm3 + movq %mm0, %mm4 + + pand %mm2, %mm3 + psllq $16, %mm4 + psrlq $16, %mm3 + pand %mm2, %mm4 + + pand %mm1, %mm0 + por %mm4, %mm3 + por %mm3, %mm0 + + movq %mm0, (%ecx) + addl $8, %ecx + subl $1, %eax +.L18: + jne .L19 + +#ifdef USE_INNER_EMMS + emms +#endif + + /* At this point there are either 1 or 0 pixels remaining to be + * converted. Convert the last pixel, if needed. + */ + + testl $1, %edx + je .L20 + + DO_ONE_LAST_PIXEL() + +.L20: + popl %ebx + ret + .size _generic_read_RGBA_span_BGRA8888_REV_MMX, .-_generic_read_RGBA_span_BGRA8888_REV_MMX + + +/** + * SSE optimized version of the BGRA8888_REV to RGBA copy routine. SSE + * instructions are only actually used to read data from the framebuffer. + * In practice, the speed-up is pretty small. + * + * \todo + * Do some more testing and determine if there's any reason to have this + * function in addition to the MMX version. + * + * \warning + * This function assumes that the caller will issue the EMMS instruction + * at the correct places. + */ + +.globl _generic_read_RGBA_span_BGRA8888_REV_SSE +#ifndef USE_DRICORE +.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE +#endif + .type _generic_read_RGBA_span_BGRA8888_REV_SSE, @function +_generic_read_RGBA_span_BGRA8888_REV_SSE: + pushl %esi + pushl %ebx + pushl %ebp + +#ifdef USE_INNER_EMMS + emms +#endif + + LOAD_MASK(movq,%mm1,%mm2) + + movl 16(%esp), %ebx /* source pointer */ + movl 24(%esp), %edx /* number of pixels to copy */ + movl 20(%esp), %ecx /* destination pointer */ + + testl %edx, %edx + jle .L35 /* Bail if there's nothing to do. */ + + movl %esp, %ebp + subl $16, %esp + andl $0xfffffff0, %esp + + movl %ebx, %eax + movl %edx, %esi + + negl %eax + andl $15, %eax + sarl $2, %eax + cmpl %edx, %eax + cmovle %eax, %esi + + subl %esi, %edx + + testl $1, %esi + je .L32 + + DO_ONE_PIXEL() +.L32: + + testl $2, %esi + je .L31 + + movq (%ebx), %mm0 + addl $8, %ebx + + movq %mm0, %mm3 + movq %mm0, %mm4 + + pand %mm2, %mm3 + psllq $16, %mm4 + psrlq $16, %mm3 + pand %mm2, %mm4 + + pand %mm1, %mm0 + por %mm4, %mm3 + por %mm3, %mm0 + + movq %mm0, (%ecx) + addl $8, %ecx +.L31: + + movl %edx, %eax + shrl $2, %eax + jmp .L33 +.L34: + movaps (%ebx), %xmm0 + addl $16, %ebx + + /* This would be so much better if we could just move directly from + * an SSE register to an MMX register. Unfortunately, that + * functionality wasn't introduced until SSE2 with the MOVDQ2Q + * instruction. + */ + + movaps %xmm0, (%esp) + movq (%esp), %mm0 + movq 8(%esp), %mm5 + + movq %mm0, %mm3 + movq %mm0, %mm4 + movq %mm5, %mm6 + movq %mm5, %mm7 + + pand %mm2, %mm3 + pand %mm2, %mm6 + + psllq $16, %mm4 + psllq $16, %mm7 + + psrlq $16, %mm3 + psrlq $16, %mm6 + + pand %mm2, %mm4 + pand %mm2, %mm7 + + pand %mm1, %mm0 + pand %mm1, %mm5 + + por %mm4, %mm3 + por %mm7, %mm6 + + por %mm3, %mm0 + por %mm6, %mm5 + + movq %mm0, (%ecx) + movq %mm5, 8(%ecx) + addl $16, %ecx + + subl $1, %eax +.L33: + jne .L34 + +#ifdef USE_INNER_EMMS + emms +#endif + movl %ebp, %esp + + /* At this point there are either [0, 3] pixels remaining to be + * converted. + */ + + testl $2, %edx + je .L36 + + movq (%ebx), %mm0 + addl $8, %ebx + + movq %mm0, %mm3 + movq %mm0, %mm4 + + pand %mm2, %mm3 + psllq $16, %mm4 + psrlq $16, %mm3 + pand %mm2, %mm4 + + pand %mm1, %mm0 + por %mm4, %mm3 + por %mm3, %mm0 + + movq %mm0, (%ecx) + addl $8, %ecx +.L36: + + testl $1, %edx + je .L35 + + DO_ONE_LAST_PIXEL() +.L35: + popl %ebp + popl %ebx + popl %esi + ret + .size _generic_read_RGBA_span_BGRA8888_REV_SSE, .-_generic_read_RGBA_span_BGRA8888_REV_SSE + + +/** + * SSE2 optimized version of the BGRA8888_REV to RGBA copy routine. + */ + + .text +.globl _generic_read_RGBA_span_BGRA8888_REV_SSE2 +#ifndef USE_DRICORE +.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE2 +#endif + .type _generic_read_RGBA_span_BGRA8888_REV_SSE2, @function +_generic_read_RGBA_span_BGRA8888_REV_SSE2: + pushl %esi + pushl %ebx + + LOAD_MASK(movdqu,%xmm1,%xmm2) + + movl 12(%esp), %ebx /* source pointer */ + movl 20(%esp), %edx /* number of pixels to copy */ + movl 16(%esp), %ecx /* destination pointer */ + + movl %ebx, %eax + movl %edx, %esi + + testl %edx, %edx + jle .L46 /* Bail if there's nothing to do. */ + + /* If the source pointer isn't a multiple of 16 we have to process + * a few pixels the "slow" way to get the address aligned for + * the SSE fetch intsructions. + */ + + negl %eax + andl $15, %eax + sarl $2, %eax + + cmpl %edx, %eax + cmovbe %eax, %esi + subl %esi, %edx + + testl $1, %esi + je .L41 + + DO_ONE_PIXEL() +.L41: + testl $2, %esi + je .L40 + + movq (%ebx), %xmm0 + addl $8, %ebx + + movdqa %xmm0, %xmm3 + movdqa %xmm0, %xmm4 + andps %xmm1, %xmm0 + + andps %xmm2, %xmm3 + pslldq $2, %xmm4 + psrldq $2, %xmm3 + andps %xmm2, %xmm4 + + orps %xmm4, %xmm3 + orps %xmm3, %xmm0 + + movq %xmm0, (%ecx) + addl $8, %ecx +.L40: + + /* Would it be worth having a specialized version of this loop for + * the case where the destination is 16-byte aligned? That version + * would be identical except that it could use movedqa instead of + * movdqu. + */ + + movl %edx, %eax + shrl $2, %eax + jmp .L42 +.L43: + movdqa (%ebx), %xmm0 + addl $16, %ebx + + movdqa %xmm0, %xmm3 + movdqa %xmm0, %xmm4 + andps %xmm1, %xmm0 + + andps %xmm2, %xmm3 + pslldq $2, %xmm4 + psrldq $2, %xmm3 + andps %xmm2, %xmm4 + + orps %xmm4, %xmm3 + orps %xmm3, %xmm0 + + movdqu %xmm0, (%ecx) + addl $16, %ecx + subl $1, %eax +.L42: + jne .L43 + + + /* There may be upto 3 pixels remaining to be copied. Take care + * of them now. We do the 2 pixel case first because the data + * will be aligned. + */ + + testl $2, %edx + je .L47 + + movq (%ebx), %xmm0 + addl $8, %ebx + + movdqa %xmm0, %xmm3 + movdqa %xmm0, %xmm4 + andps %xmm1, %xmm0 + + andps %xmm2, %xmm3 + pslldq $2, %xmm4 + psrldq $2, %xmm3 + andps %xmm2, %xmm4 + + orps %xmm4, %xmm3 + orps %xmm3, %xmm0 + + movq %xmm0, (%ecx) + addl $8, %ecx +.L47: + + testl $1, %edx + je .L46 + + DO_ONE_LAST_PIXEL() +.L46: + + popl %ebx + popl %esi + ret + .size _generic_read_RGBA_span_BGRA8888_REV_SSE2, .-_generic_read_RGBA_span_BGRA8888_REV_SSE2 + + + +#define MASK_565_L 0x07e0f800 +#define MASK_565_H 0x0000001f +/* Setting SCALE_ADJUST to 5 gives a perfect match with the + * classic C implementation in Mesa. Setting SCALE_ADJUST + * to 0 is slightly faster but at a small cost to accuracy. + */ +#define SCALE_ADJUST 5 +#if SCALE_ADJUST == 5 +#define PRESCALE_L 0x00100001 +#define PRESCALE_H 0x00000200 +#define SCALE_L 0x40C620E8 +#define SCALE_H 0x0000839d +#elif SCALE_ADJUST == 0 +#define PRESCALE_L 0x00200001 +#define PRESCALE_H 0x00000800 +#define SCALE_L 0x01040108 +#define SCALE_H 0x00000108 +#else +#error SCALE_ADJUST must either be 5 or 0. +#endif +#define ALPHA_L 0x00000000 +#define ALPHA_H 0x00ff0000 + +/** + * MMX optimized version of the RGB565 to RGBA copy routine. + */ + + .text + .globl _generic_read_RGBA_span_RGB565_MMX +#ifndef USE_DRICORE + .hidden _generic_read_RGBA_span_RGB565_MMX +#endif + .type _generic_read_RGBA_span_RGB565_MMX, @function + +_generic_read_RGBA_span_RGB565_MMX: + +#ifdef USE_INNER_EMMS + emms +#endif + + movl 4(%esp), %eax /* source pointer */ + movl 8(%esp), %edx /* destination pointer */ + movl 12(%esp), %ecx /* number of pixels to copy */ + + pushl $MASK_565_H + pushl $MASK_565_L + movq (%esp), %mm5 + pushl $PRESCALE_H + pushl $PRESCALE_L + movq (%esp), %mm6 + pushl $SCALE_H + pushl $SCALE_L + movq (%esp), %mm7 + pushl $ALPHA_H + pushl $ALPHA_L + movq (%esp), %mm3 + addl $32,%esp + + sarl $2, %ecx + jl .L01 /* Bail early if the count is negative. */ + jmp .L02 + +.L03: + /* Fetch 4 RGB565 pixels into %mm4. Distribute the first and + * second pixels into the four words of %mm0 and %mm2. + */ + + movq (%eax), %mm4 + addl $8, %eax + + pshufw $0x00, %mm4, %mm0 + pshufw $0x55, %mm4, %mm2 + + + /* Mask the pixels so that each word of each register contains only + * one color component. + */ + + pand %mm5, %mm0 + pand %mm5, %mm2 + + + /* Adjust the component values so that they are as small as possible, + * but large enough so that we can multiply them by an unsigned 16-bit + * number and get a value as large as 0x00ff0000. + */ + + pmullw %mm6, %mm0 + pmullw %mm6, %mm2 +#if SCALE_ADJUST > 0 + psrlw $SCALE_ADJUST, %mm0 + psrlw $SCALE_ADJUST, %mm2 +#endif + + /* Scale the input component values to be on the range + * [0, 0x00ff0000]. This it the real magic of the whole routine. + */ + + pmulhuw %mm7, %mm0 + pmulhuw %mm7, %mm2 + + + /* Always set the alpha value to 0xff. + */ + + por %mm3, %mm0 + por %mm3, %mm2 + + + /* Pack the 16-bit values to 8-bit values and store the converted + * pixel data. + */ + + packuswb %mm2, %mm0 + movq %mm0, (%edx) + addl $8, %edx + + pshufw $0xaa, %mm4, %mm0 + pshufw $0xff, %mm4, %mm2 + + pand %mm5, %mm0 + pand %mm5, %mm2 + pmullw %mm6, %mm0 + pmullw %mm6, %mm2 +#if SCALE_ADJUST > 0 + psrlw $SCALE_ADJUST, %mm0 + psrlw $SCALE_ADJUST, %mm2 +#endif + pmulhuw %mm7, %mm0 + pmulhuw %mm7, %mm2 + + por %mm3, %mm0 + por %mm3, %mm2 + + packuswb %mm2, %mm0 + + movq %mm0, (%edx) + addl $8, %edx + + subl $1, %ecx +.L02: + jne .L03 + + + /* At this point there can be at most 3 pixels left to process. If + * there is either 2 or 3 left, process 2. + */ + + movl 12(%esp), %ecx + testl $0x02, %ecx + je .L04 + + movd (%eax), %mm4 + addl $4, %eax + + pshufw $0x00, %mm4, %mm0 + pshufw $0x55, %mm4, %mm2 + + pand %mm5, %mm0 + pand %mm5, %mm2 + pmullw %mm6, %mm0 + pmullw %mm6, %mm2 +#if SCALE_ADJUST > 0 + psrlw $SCALE_ADJUST, %mm0 + psrlw $SCALE_ADJUST, %mm2 +#endif + pmulhuw %mm7, %mm0 + pmulhuw %mm7, %mm2 + + por %mm3, %mm0 + por %mm3, %mm2 + + packuswb %mm2, %mm0 + + movq %mm0, (%edx) + addl $8, %edx + +.L04: + /* At this point there can be at most 1 pixel left to process. + * Process it if needed. + */ + + testl $0x01, %ecx + je .L01 + + movzwl (%eax), %ecx + movd %ecx, %mm4 + + pshufw $0x00, %mm4, %mm0 + + pand %mm5, %mm0 + pmullw %mm6, %mm0 +#if SCALE_ADJUST > 0 + psrlw $SCALE_ADJUST, %mm0 +#endif + pmulhuw %mm7, %mm0 + + por %mm3, %mm0 + + packuswb %mm0, %mm0 + + movd %mm0, (%edx) + +.L01: +#ifdef USE_INNER_EMMS + emms +#endif + ret +#endif /* !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__) */ + +#if defined (__ELF__) && defined (__linux__) + .section .note.GNU-stack,"",%progbits +#endif -- cgit v1.2.3