*/
class ast_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;
- }
-
- /* If the user *does* call delete, that's OK, we will just
- * ralloc_free in that case. */
- static void operator delete(void *table)
- {
- ralloc_free(table);
- }
+ DECLARE_RALLOC_CXX_OPERATORS(ast_node);
/**
* Print an AST node in something approximating the original GLSL code
bool cons;
};
+class ast_array_specifier : public ast_node {
+public:
+ /** Unsized array specifier ([]) */
+ explicit ast_array_specifier(const struct YYLTYPE &locp)
+ : dimension_count(1), is_unsized_array(true)
+ {
+ set_location(locp);
+ }
+
+ /** Sized array specifier ([dim]) */
+ ast_array_specifier(const struct YYLTYPE &locp, ast_expression *dim)
+ : dimension_count(1), is_unsized_array(false)
+ {
+ set_location(locp);
+ array_dimensions.push_tail(&dim->link);
+ }
+
+ void add_dimension(ast_expression *dim)
+ {
+ array_dimensions.push_tail(&dim->link);
+ dimension_count++;
+ }
+
+ virtual void print(void) const;
+
+ /* Count including sized and unsized dimensions */
+ unsigned dimension_count;
+
+ /* If true, this means that the array has an unsized outermost dimension. */
+ bool is_unsized_array;
+
+ /* This list contains objects of type ast_node containing the
+ * sized dimensions only, in outermost-to-innermost order.
+ */
+ exec_list array_dimensions;
+};
+
/**
* C-style aggregate initialization class
*
/* empty */
}
- ast_type_specifier *constructor_type;
+ /**
+ * glsl_type of the aggregate, which is inferred from the LHS of whatever
+ * the aggregate is being used to initialize. This can't be inferred at
+ * parse time (since the parser deals with ast_type_specifiers, not
+ * glsl_types), so the parser leaves it NULL. However, the ast-to-hir
+ * conversion code makes sure to fill it in with the appropriate type
+ * before hir() is called.
+ */
+ const glsl_type *constructor_type;
+
virtual ir_rvalue *hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state);
};
class ast_declaration : public ast_node {
public:
- ast_declaration(const char *identifier, bool is_array, ast_expression *array_size,
- ast_expression *initializer);
+ ast_declaration(const char *identifier,
+ ast_array_specifier *array_specifier,
+ ast_expression *initializer);
virtual void print(void) const;
const char *identifier;
-
- bool is_array;
- ast_expression *array_size;
+
+ ast_array_specifier *array_specifier;
ast_expression *initializer;
};
};
struct ast_type_qualifier {
- /* 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;
- }
-
- /* If the user *does* call delete, that's OK, we will just
- * ralloc_free in that case. */
- static void operator delete(void *table)
- {
- ralloc_free(table);
- }
+ DECLARE_RALLOC_CXX_OPERATORS(ast_type_qualifier);
union {
struct {
unsigned in:1;
unsigned out:1;
unsigned centroid:1;
+ unsigned sample:1;
unsigned uniform:1;
unsigned smooth:1;
unsigned flat:1;
*/
unsigned explicit_binding:1;
+ /**
+ * Flag set if GL_ARB_shader_atomic counter "offset" layout
+ * qualifier is used.
+ */
+ unsigned explicit_offset:1;
+
/** \name Layout qualifiers for GL_AMD_conservative_depth */
/** \{ */
unsigned depth_any:1;
*/
int binding;
+ /**
+ * Offset specified via GL_ARB_shader_atomic_counter's "offset"
+ * keyword.
+ *
+ * \note
+ * This field is only valid if \c explicit_offset is set.
+ */
+ int offset;
+
/**
* Return true if and only if an interpolation qualifier is present.
*/
* Use only if the objects are allocated from the same context and will not
* be modified. Zeros the inherited ast_node's fields.
*/
- ast_type_specifier(const ast_type_specifier *that, bool is_array,
- ast_expression *array_size)
+ ast_type_specifier(const ast_type_specifier *that,
+ ast_array_specifier *array_specifier)
: ast_node(), type_name(that->type_name), structure(that->structure),
- is_array(is_array), array_size(array_size),
+ array_specifier(array_specifier),
default_precision(that->default_precision)
{
/* empty */
/** Construct a type specifier from a type name */
ast_type_specifier(const char *name)
- : type_name(name), structure(NULL),
- is_array(false), array_size(NULL),
+ : type_name(name), structure(NULL), array_specifier(NULL),
default_precision(ast_precision_none)
{
/* empty */
/** Construct a type specifier from a structure definition */
ast_type_specifier(ast_struct_specifier *s)
- : type_name(s->name), structure(s),
- is_array(false), array_size(NULL),
+ : type_name(s->name), structure(s), array_specifier(NULL),
default_precision(ast_precision_none)
{
/* empty */
const char *type_name;
ast_struct_specifier *structure;
- bool is_array;
- ast_expression *array_size;
+ ast_array_specifier *array_specifier;
/** For precision statements, this is the given precision; otherwise none. */
unsigned default_precision:2;
virtual void print(void) const;
bool has_qualifiers() const;
+ ast_fully_specified_type() : qualifier(), specifier(NULL)
+ {
+ }
+
+ const struct glsl_type *glsl_type(const char **name,
+ struct _mesa_glsl_parse_state *state)
+ const;
+
ast_type_qualifier qualifier;
ast_type_specifier *specifier;
};
* is used to note these cases when no type is specified.
*/
int invariant;
-
- /**
- * Flag indicating that these declarators are in a uniform block,
- * allowing UBO type qualifiers.
- */
- bool ubo_qualifiers_valid;
};
ast_parameter_declarator() :
type(NULL),
identifier(NULL),
- is_array(false),
- array_size(NULL),
+ array_specifier(NULL),
formal_parameter(false),
is_void(false)
{
ast_fully_specified_type *type;
const char *identifier;
- bool is_array;
- ast_expression *array_size;
+ ast_array_specifier *array_specifier;
static void parameters_to_hir(exec_list *ast_parameters,
bool formal, exec_list *ir_parameters,
class ast_function_definition : public ast_node {
public:
+ ast_function_definition() : prototype(NULL), body(NULL)
+ {
+ }
+
virtual void print(void) const;
virtual ir_rvalue *hir(exec_list *instructions,
class ast_interface_block : public ast_node {
public:
ast_interface_block(ast_type_qualifier layout,
- const char *instance_name,
- ast_expression *array_size)
+ const char *instance_name,
+ ast_array_specifier *array_specifier)
: layout(layout), block_name(NULL), instance_name(instance_name),
- array_size(array_size)
+ array_specifier(array_specifier)
{
- /* empty */
}
virtual ir_rvalue *hir(exec_list *instructions,
/**
* Declared array size of the block instance
*
- * If the block is not declared as an array, this field will be \c NULL.
- *
- * \note
- * A block can only be an array if it also has an instance name. If this
- * field is not \c NULL, ::instance_name must also not be \c NULL.
+ * If the block is not declared as an array or if the block instance array
+ * is unsized, this field will be \c NULL.
*/
- ast_expression *array_size;
+ ast_array_specifier *array_specifier;
};
YYLTYPE &loc, YYLTYPE &idx_loc);
extern void
-_mesa_ast_set_aggregate_type(const ast_type_specifier *type,
- ast_expression *expr,
- _mesa_glsl_parse_state *state);
+_mesa_ast_set_aggregate_type(const glsl_type *type,
+ ast_expression *expr);
void
emit_function(_mesa_glsl_parse_state *state, ir_function *f);