diff options
Diffstat (limited to 'src/glsl/ast.h')
| -rw-r--r-- | src/glsl/ast.h | 664 | 
1 files changed, 664 insertions, 0 deletions
| diff --git a/src/glsl/ast.h b/src/glsl/ast.h new file mode 100644 index 0000000000..44c31b6e62 --- /dev/null +++ b/src/glsl/ast.h @@ -0,0 +1,664 @@ +/* -*- c++ -*- */ +/* + * Copyright © 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. + */ + +#pragma once +#ifndef AST_H +#define AST_H + +#include "list.h" +#include "glsl_parser_extras.h" + +struct _mesa_glsl_parse_state; + +struct YYLTYPE; + +class ast_node { +public: +   /* Callers of this talloc-based new need not call delete. It's +    * easier to just talloc_free 'ctx' (or any of its ancestors). */ +   static void* operator new(size_t size, void *ctx) +   { +      void *node; + +      node = talloc_zero_size(ctx, size); +      assert(node != NULL); + +      return node; +   } + +   /* If the user *does* call delete, that's OK, we will just +    * talloc_free in that case. */ +   static void operator delete(void *table) +   { +      talloc_free(table); +   } + +   virtual void print(void) const; +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   /** +    * Retrieve the source location of an AST node +    * +    * This function is primarily used to get the source position of an AST node +    * into a form that can be passed to \c _mesa_glsl_error. +    * +    * \sa _mesa_glsl_error, ast_node::set_location +    */ +   struct YYLTYPE get_location(void) const +   { +      struct YYLTYPE locp; + +      locp.source = this->location.source; +      locp.first_line = this->location.line; +      locp.first_column = this->location.column; +      locp.last_line = locp.first_line; +      locp.last_column = locp.first_column; + +      return locp; +   } + +   /** +    * Set the source location of an AST node from a parser location +    * +    * \sa ast_node::get_location +    */ +   void set_location(const struct YYLTYPE &locp) +   { +      this->location.source = locp.source; +      this->location.line = locp.first_line; +      this->location.column = locp.first_column; +   } + +   struct { +      unsigned source; +      unsigned line; +      unsigned column; +   } location; + +   exec_node link; + +protected: +   ast_node(void); +}; + + +enum ast_operators { +   ast_assign, +   ast_plus,        /**< Unary + operator. */ +   ast_neg, +   ast_add, +   ast_sub, +   ast_mul, +   ast_div, +   ast_mod, +   ast_lshift, +   ast_rshift, +   ast_less, +   ast_greater, +   ast_lequal, +   ast_gequal, +   ast_equal, +   ast_nequal, +   ast_bit_and, +   ast_bit_xor, +   ast_bit_or, +   ast_bit_not, +   ast_logic_and, +   ast_logic_xor, +   ast_logic_or, +   ast_logic_not, + +   ast_mul_assign, +   ast_div_assign, +   ast_mod_assign, +   ast_add_assign, +   ast_sub_assign, +   ast_ls_assign, +   ast_rs_assign, +   ast_and_assign, +   ast_xor_assign, +   ast_or_assign, + +   ast_conditional, + +   ast_pre_inc, +   ast_pre_dec, +   ast_post_inc, +   ast_post_dec, +   ast_field_selection, +   ast_array_index, + +   ast_function_call, + +   ast_identifier, +   ast_int_constant, +   ast_uint_constant, +   ast_float_constant, +   ast_bool_constant, + +   ast_sequence +}; + +class ast_expression : public ast_node { +public: +   ast_expression(int oper, ast_expression *, +		  ast_expression *, ast_expression *); + +   ast_expression(const char *identifier) : +      oper(ast_identifier) +   { +      subexpressions[0] = NULL; +      subexpressions[1] = NULL; +      subexpressions[2] = NULL; +      primary_expression.identifier = (char *) identifier; +   } + +   static const char *operator_string(enum ast_operators op); + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   virtual void print(void) const; + +   enum ast_operators oper; + +   ast_expression *subexpressions[3]; + +   union { +      char *identifier; +      int int_constant; +      float float_constant; +      unsigned uint_constant; +      int bool_constant; +   } primary_expression; + + +   /** +    * List of expressions for an \c ast_sequence or parameters for an +    * \c ast_function_call +    */ +   exec_list expressions; +}; + +class ast_expression_bin : public ast_expression { +public: +   ast_expression_bin(int oper, ast_expression *, ast_expression *); + +   virtual void print(void) const; +}; + +/** + * Subclass of expressions for function calls + */ +class ast_function_expression : public ast_expression { +public: +   ast_function_expression(ast_expression *callee) +      : ast_expression(ast_function_call, callee, +		       NULL, NULL), +	cons(false) +   { +      /* empty */ +   } + +   ast_function_expression(class ast_type_specifier *type) +      : ast_expression(ast_function_call, (ast_expression *) type, +		       NULL, NULL), +	cons(true) +   { +      /* empty */ +   } + +   bool is_constructor() const +   { +      return cons; +   } + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +private: +   /** +    * Is this function call actually a constructor? +    */ +   bool cons; +}; + + +/** + * Number of possible operators for an ast_expression + * + * This is done as a define instead of as an additional value in the enum so + * that the compiler won't generate spurious messages like "warning: + * enumeration value ‘ast_num_operators’ not handled in switch" + */ +#define AST_NUM_OPERATORS (ast_sequence + 1) + + +class ast_compound_statement : public ast_node { +public: +   ast_compound_statement(int new_scope, ast_node *statements); +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   int new_scope; +   exec_list statements; +}; + +class ast_declaration : public ast_node { +public: +   ast_declaration(char *identifier, int is_array, ast_expression *array_size, +		   ast_expression *initializer); +   virtual void print(void) const; + +   char *identifier; +    +   int is_array; +   ast_expression *array_size; + +   ast_expression *initializer; +}; + + +enum { +   ast_precision_high = 0, /**< Default precision. */ +   ast_precision_medium, +   ast_precision_low +}; + +struct ast_type_qualifier { +   unsigned invariant:1; +   unsigned constant:1; +   unsigned attribute:1; +   unsigned varying:1; +   unsigned in:1; +   unsigned out:1; +   unsigned centroid:1; +   unsigned uniform:1; +   unsigned smooth:1; +   unsigned flat:1; +   unsigned noperspective:1; + +   /** \name Layout qualifiers for GL_ARB_fragment_coord_conventions */ +   /*@{*/ +   unsigned origin_upper_left:1; +   unsigned pixel_center_integer:1; +   /*@}*/ +}; + +class ast_struct_specifier : public ast_node { +public: +   ast_struct_specifier(char *identifier, ast_node *declarator_list); +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   char *name; +   exec_list declarations; +}; + + +enum ast_types { +   ast_void, +   ast_float, +   ast_int, +   ast_uint, +   ast_bool, +   ast_vec2, +   ast_vec3, +   ast_vec4, +   ast_bvec2, +   ast_bvec3, +   ast_bvec4, +   ast_ivec2, +   ast_ivec3, +   ast_ivec4, +   ast_uvec2, +   ast_uvec3, +   ast_uvec4, +   ast_mat2, +   ast_mat2x3, +   ast_mat2x4, +   ast_mat3x2, +   ast_mat3, +   ast_mat3x4, +   ast_mat4x2, +   ast_mat4x3, +   ast_mat4, +   ast_sampler1d, +   ast_sampler2d, +   ast_sampler2drect, +   ast_sampler3d, +   ast_samplercube, +   ast_sampler1dshadow, +   ast_sampler2dshadow, +   ast_sampler2drectshadow, +   ast_samplercubeshadow, +   ast_sampler1darray, +   ast_sampler2darray, +   ast_sampler1darrayshadow, +   ast_sampler2darrayshadow, +   ast_isampler1d, +   ast_isampler2d, +   ast_isampler3d, +   ast_isamplercube, +   ast_isampler1darray, +   ast_isampler2darray, +   ast_usampler1d, +   ast_usampler2d, +   ast_usampler3d, +   ast_usamplercube, +   ast_usampler1darray, +   ast_usampler2darray, + +   ast_struct, +   ast_type_name +}; + + +class ast_type_specifier : public ast_node { +public: +   ast_type_specifier(int specifier); + +   /** Construct a type specifier from a type name */ +   ast_type_specifier(const char *name)  +      : type_specifier(ast_type_name), type_name(name), structure(NULL), +	is_array(false), array_size(NULL), precision(ast_precision_high) +   { +      /* empty */ +   } + +   /** Construct a type specifier from a structure definition */ +   ast_type_specifier(ast_struct_specifier *s) +      : type_specifier(ast_struct), type_name(s->name), structure(s), +	is_array(false), array_size(NULL), precision(ast_precision_high) +   { +      /* empty */ +   } + +   const struct glsl_type *glsl_type(const char **name, +				     struct _mesa_glsl_parse_state *state) +      const; + +   virtual void print(void) const; + +   ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *); + +   enum ast_types type_specifier; + +   const char *type_name; +   ast_struct_specifier *structure; + +   int is_array; +   ast_expression *array_size; + +   unsigned precision:2; +}; + + +class ast_fully_specified_type : public ast_node { +public: +   virtual void print(void) const; +   bool has_qualifiers() const; + +   ast_type_qualifier qualifier; +   ast_type_specifier *specifier; +}; + + +class ast_declarator_list : public ast_node { +public: +   ast_declarator_list(ast_fully_specified_type *); +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   ast_fully_specified_type *type; +   exec_list declarations; + +   /** +    * Special flag for vertex shader "invariant" declarations. +    * +    * Vertex shaders can contain "invariant" variable redeclarations that do +    * not include a type.  For example, "invariant gl_Position;".  This flag +    * is used to note these cases when no type is specified. +    */ +   int invariant; +}; + + +class ast_parameter_declarator : public ast_node { +public: +   ast_parameter_declarator() +   { +      this->identifier = NULL; +      this->is_array = false; +      this->array_size = 0; +   } + +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   ast_fully_specified_type *type; +   char *identifier; +   int is_array; +   ast_expression *array_size; + +   static void parameters_to_hir(exec_list *ast_parameters, +				 bool formal, exec_list *ir_parameters, +				 struct _mesa_glsl_parse_state *state); + +private: +   /** Is this parameter declaration part of a formal parameter list? */ +   bool formal_parameter; + +   /** +    * Is this parameter 'void' type? +    * +    * This field is set by \c ::hir. +    */ +   bool is_void; +}; + + +class ast_function : public ast_node { +public: +   ast_function(void); + +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   ast_fully_specified_type *return_type; +   char *identifier; + +   exec_list parameters; + +private: +   /** +    * Is this prototype part of the function definition? +    * +    * Used by ast_function_definition::hir to process the parameters, etc. +    * of the function. +    * +    * \sa ::hir +    */ +   bool is_definition; + +   /** +    * Function signature corresponding to this function prototype instance +    * +    * Used by ast_function_definition::hir to process the parameters, etc. +    * of the function. +    * +    * \sa ::hir +    */ +   class ir_function_signature *signature; + +   friend class ast_function_definition; +}; + + +class ast_declaration_statement : public ast_node { +public: +   ast_declaration_statement(void); + +   enum { +      ast_function, +      ast_declaration, +      ast_precision +   } mode; + +   union { +      class ast_function *function; +      ast_declarator_list *declarator; +      ast_type_specifier *type; +      ast_node *node; +   } declaration; +}; + + +class ast_expression_statement : public ast_node { +public: +   ast_expression_statement(ast_expression *); +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   ast_expression *expression; +}; + + +class ast_case_label : public ast_node { +public: + +   /** +    * An expression of NULL means 'default'. +    */ +   ast_expression *expression; +}; + +class ast_selection_statement : public ast_node { +public: +   ast_selection_statement(ast_expression *condition, +			   ast_node *then_statement, +			   ast_node *else_statement); +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   ast_expression *condition; +   ast_node *then_statement; +   ast_node *else_statement; +}; + + +class ast_switch_statement : public ast_node { +public: +   ast_expression *expression; +   exec_list statements; +}; + +class ast_iteration_statement : public ast_node { +public: +   ast_iteration_statement(int mode, ast_node *init, ast_node *condition, +			   ast_expression *rest_expression, ast_node *body); + +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *); + +   enum ast_iteration_modes { +      ast_for, +      ast_while, +      ast_do_while +   } mode; +    + +   ast_node *init_statement; +   ast_node *condition; +   ast_expression *rest_expression; + +   ast_node *body; + +private: +   /** +    * Generate IR from the condition of a loop +    * +    * This is factored out of ::hir because some loops have the condition +    * test at the top (for and while), and others have it at the end (do-while). +    */ +   void condition_to_hir(class ir_loop *, struct _mesa_glsl_parse_state *); +}; + + +class ast_jump_statement : public ast_node { +public: +   ast_jump_statement(int mode, ast_expression *return_value); +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   enum ast_jump_modes { +      ast_continue, +      ast_break, +      ast_return, +      ast_discard +   } mode; + +   ast_expression *opt_return_value; +}; + + +class ast_function_definition : public ast_node { +public: +   virtual void print(void) const; + +   virtual ir_rvalue *hir(exec_list *instructions, +			  struct _mesa_glsl_parse_state *state); + +   ast_function *prototype; +   ast_compound_statement *body; +}; + + +extern void +_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); + +extern ir_rvalue * +_mesa_ast_field_selection_to_hir(const ast_expression *expr, +				 exec_list *instructions, +				 struct _mesa_glsl_parse_state *state); + +#endif /* AST_H */ | 
