From 548fa293a37db8f01bd35d2dc878720e75886aa4 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 15 Mar 2010 13:04:13 -0700 Subject: [PATCH] Move ast_function_expression::hir to ast_function.cpp --- Makefile.am | 3 +- ast_function.cpp | 109 +++++++++++++++++++++++++++++++++++++++++++++++ ast_to_hir.cpp | 81 ----------------------------------- 3 files changed, 111 insertions(+), 82 deletions(-) create mode 100644 ast_function.cpp diff --git a/Makefile.am b/Makefile.am index ff4886a9e52..b2c49b018bb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,8 @@ AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = glsl glsl_SOURCES = symbol_table.c hash_table.c glsl_types.cpp \ glsl_parser.ypp glsl_lexer.lpp glsl_parser_extras.cpp \ - ast_expr.cpp ast_to_hir.cpp ir.cpp hir_field_selection.cpp \ + ast_expr.cpp ast_to_hir.cpp ast_function.cpp \ + ir.cpp hir_field_selection.cpp \ ir_print_visitor.cpp ir_variable.cpp ir_function.cpp BUILT_SOURCES = glsl_parser.h builtin_types.h diff --git a/ast_function.cpp b/ast_function.cpp new file mode 100644 index 00000000000..2e0cbe9e132 --- /dev/null +++ b/ast_function.cpp @@ -0,0 +1,109 @@ +/* + * 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 "symbol_table.h" +#include "ast.h" +#include "glsl_types.h" +#include "ir.h" + +ir_instruction * +ast_function_expression::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + /* There are three sorts of function calls. + * + * 1. contstructors - The first subexpression is an ast_type_specifier. + * 2. methods - Only the .length() method of array types. + * 3. functions - Calls to regular old functions. + * + * 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. + * + * Method calls are actually detected when the ast_field_selection + * expression is handled. + */ + if (is_constructor()) { + return ir_call::get_error_instruction(); + } else { + const ast_expression *id = subexpressions[0]; + + ir_function *f = (ir_function *) + _mesa_symbol_table_find_symbol(state->symbols, 0, + id->primary_expression.identifier); + + if (f == NULL) { + YYLTYPE loc = id->get_location(); + + _mesa_glsl_error(& loc, state, "function `%s' undeclared", + id->primary_expression.identifier); + return ir_call::get_error_instruction(); + } + + /* Once we've determined that the function being called might exist, + * process the parameters. + */ + exec_list actual_parameters; + simple_node *const first = subexpressions[1]; + if (first != NULL) { + simple_node *ptr = first; + do { + ir_instruction *const result = + ((ast_node *) ptr)->hir(instructions, state); + ptr = ptr->next; + + actual_parameters.push_tail(result); + } while (ptr != first); + } + + /* After processing the function's actual parameters, try to find an + * overload of the function that matches. + */ + const ir_function_signature *sig = + f->matching_signature(& actual_parameters); + if (sig != NULL) { + /* FINISHME: The list of actual parameters needs to be modified to + * FINISHME: include any necessary conversions. + */ + return new ir_call(sig, & actual_parameters); + } else { + YYLTYPE loc = id->get_location(); + + /* FINISHME: Log a better error message here. G++ will show the types + * FINISHME: of the actual parameters and the set of candidate + * FINISHME: functions. A different error should also be logged when + * FINISHME: multiple functions match. + */ + _mesa_glsl_error(& loc, state, "no matching function for call to `%s'", + id->primary_expression.identifier); + return ir_call::get_error_instruction(); + } + } + + return ir_call::get_error_instruction(); +} diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index d24dc159f21..1de64795ad6 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -710,87 +710,6 @@ ast_expression::hir(exec_list *instructions, } -ir_instruction * -ast_function_expression::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - /* There are three sorts of function calls. - * - * 1. contstructors - The first subexpression is an ast_type_specifier. - * 2. methods - Only the .length() method of array types. - * 3. functions - Calls to regular old functions. - * - * 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. - * - * Method calls are actually detected when the ast_field_selection - * expression is handled. - */ - if (is_constructor()) { - return ir_call::get_error_instruction(); - } else { - const ast_expression *id = subexpressions[0]; - - ir_function *f = (ir_function *) - _mesa_symbol_table_find_symbol(state->symbols, 0, - id->primary_expression.identifier); - - if (f == NULL) { - YYLTYPE loc = id->get_location(); - - _mesa_glsl_error(& loc, state, "function `%s' undeclared", - id->primary_expression.identifier); - return ir_call::get_error_instruction(); - } - - /* Once we've determined that the function being called might exist, - * process the parameters. - */ - exec_list actual_parameters; - simple_node *const first = subexpressions[1]; - if (first != NULL) { - simple_node *ptr = first; - do { - ir_instruction *const result = - ((ast_node *) ptr)->hir(instructions, state); - ptr = ptr->next; - - actual_parameters.push_tail(result); - } while (ptr != first); - } - - /* After processing the function's actual parameters, try to find an - * overload of the function that matches. - */ - const ir_function_signature *sig = - f->matching_signature(& actual_parameters); - if (sig != NULL) { - /* FINISHME: The list of actual parameters needs to be modified to - * FINISHME: include any necessary conversions. - */ - return new ir_call(sig, & actual_parameters); - } else { - YYLTYPE loc = id->get_location(); - - /* FINISHME: Log a better error message here. G++ will show the types - * FINISHME: of the actual parameters and the set of candidate - * FINISHME: functions. A different error should also be logged when - * FINISHME: multiple functions match. - */ - _mesa_glsl_error(& loc, state, "no matching function for call to `%s'", - id->primary_expression.identifier); - return ir_call::get_error_instruction(); - } - } - - return ir_call::get_error_instruction(); -} - ir_instruction * ast_expression_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) -- 2.30.2