[gtk+/wip/otte/shader: 56/150] gsksl: Add support for overloaded functions
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 56/150] gsksl: Add support for overloaded functions
- Date: Sat, 21 Oct 2017 02:30:53 +0000 (UTC)
commit 6261e13feffaed4844f38f19f7e1ec6ff9c26e37
Author: Benjamin Otte <otte redhat com>
Date: Sat Sep 30 01:41:01 2017 +0200
gsksl: Add support for overloaded functions
This changes GskSlScope to allow multiple functions of the same name.
It also introduces GskSlFunctionMatcher, which does overload matching in
a way that can be used while parsing function calls.
gsk/gskslcompiler.h | 1 +
gsk/gskslexpression.c | 105 +++++++++++++++++------
gsk/gskslexpressionprivate.h | 1 +
gsk/gskslfunction.c | 196 ++++++++++++++++++++++++++++++++++++------
gsk/gskslfunctionprivate.h | 25 +++++-
gsk/gskslnode.c | 12 +++-
gsk/gskslprogram.c | 9 ++-
gsk/gskslscope.c | 38 ++++++---
gsk/gskslscopeprivate.h | 3 +-
gsk/gsksltype.c | 17 +++-
gsk/gsksltypesprivate.h | 1 +
11 files changed, 331 insertions(+), 77 deletions(-)
---
diff --git a/gsk/gskslcompiler.h b/gsk/gskslcompiler.h
index a042260..c5103f2 100644
--- a/gsk/gskslcompiler.h
+++ b/gsk/gskslcompiler.h
@@ -36,6 +36,7 @@ typedef enum {
GSK_SL_COMPILER_ERROR_SYNTAX,
GSK_SL_COMPILER_ERROR_TOKENIZER,
GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
+ GSK_SL_COMPILER_ERROR_UNIQUENESS,
GSK_SL_COMPILER_ERROR_UNSUPPORTED,
} GskSlCompilerError;
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 973328a..9683182 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -1279,16 +1279,14 @@ gsk_sl_constructor_get_args_by_type (const GskSlType *type)
}
GskSlExpression *
-gsk_sl_expression_parse_function_call (GskSlScope *scope,
- GskSlPreprocessor *stream,
- GskSlFunction *function)
+gsk_sl_expression_parse_function_call (GskSlScope *scope,
+ GskSlPreprocessor *stream,
+ GskSlFunctionMatcher *matcher,
+ GskSlFunction *function)
{
GskSlExpressionFunctionCall *call;
const GskSlToken *token;
- GskSlType **types;
- GError *error = NULL;
gssize missing_args; /* only used for builtin constructors */
- guint i;
call = gsk_sl_expression_new (GskSlExpressionFunctionCall, &GSK_SL_EXPRESSION_FUNCTION_CALL);
@@ -1316,13 +1314,33 @@ gsk_sl_expression_parse_function_call (GskSlScope *scope,
{
GskSlExpression *expression = gsk_sl_expression_parse_assignment (scope, stream);
- g_ptr_array_add (arguments, expression);
-
- if (function == NULL)
+ if (function == NULL && matcher == NULL)
{
/* no checking necessary */
}
- if (missing_args == 0)
+ else if (matcher)
+ {
+ GskSlType *type = gsk_sl_expression_get_return_type (expression);
+
+ gsk_sl_function_matcher_match_argument (matcher, arguments->len, type);
+ if (!gsk_sl_function_matcher_has_matches (matcher))
+ {
+ if (function)
+ gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+ "Cannot convert argument %u from %s to %s.",
+ arguments->len + 1,
+ gsk_sl_type_get_name (type),
+ gsk_sl_type_get_name (gsk_sl_function_get_argument_type
(function, arguments->len)));
+ else
+ gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+ "No overloaded function available that matches the first %u
arguments",
+ arguments->len + 1);
+
+ matcher = NULL;
+ function = NULL;
+ }
+ }
+ else if (missing_args == 0)
{
gsk_sl_preprocessor_error (stream, ARGUMENT_COUNT,
"Too many arguments given to builtin constructor, only the first %u
are necessary.",
@@ -1347,6 +1365,8 @@ gsk_sl_expression_parse_function_call (GskSlScope *scope,
}
}
+ g_ptr_array_add (arguments, expression);
+
token = gsk_sl_preprocessor_get (stream);
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_COMMA))
break;
@@ -1365,14 +1385,29 @@ gsk_sl_expression_parse_function_call (GskSlScope *scope,
call->arguments = (GskSlExpression **) g_ptr_array_free (arguments, FALSE);
}
- types = g_newa (GskSlType *, call->n_arguments);
- for (i = 0; i < call->n_arguments; i++)
- types[i] = gsk_sl_expression_get_return_type (call->arguments[i]);
- if (function && missing_args < 0 && !gsk_sl_function_matches (function, types, call->n_arguments, &error))
+ if (matcher)
{
- gsk_sl_preprocessor_emit_error (stream, TRUE, gsk_sl_preprocessor_get_location (stream), error);
- g_clear_error (&error);
- function = NULL;
+ gsk_sl_function_matcher_match_n_arguments (matcher, call->n_arguments);
+ if (!gsk_sl_function_matcher_has_matches (matcher))
+ {
+ if (function)
+ gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+ "Function %s needs %"G_GSIZE_FORMAT" arguments, but %u given.",
+ gsk_sl_function_get_name (function),
+ gsk_sl_function_get_n_arguments (function),
+ call->n_arguments);
+ else
+ gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+ "No overloaded function available that matches this call");
+ function = NULL;
+ }
+ else
+ {
+ function = gsk_sl_function_matcher_get_match (matcher);
+ if (function == NULL)
+ gsk_sl_preprocessor_error (stream, UNIQUENESS,
+ "Cannot find unique match for overloaded function.");
+ }
}
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
@@ -1387,8 +1422,7 @@ gsk_sl_expression_parse_function_call (GskSlScope *scope,
gsk_sl_expression_unref ((GskSlExpression *) call);
return gsk_sl_expression_error_new ();
}
- else
-
+
call->function = gsk_sl_function_ref (function);
return (GskSlExpression *) call;
}
@@ -1407,10 +1441,24 @@ gsk_sl_expression_parse_primary (GskSlScope *scope,
{
GskSlExpression *expr;
GskSlVariable *variable;
+ GskSlType *type;
char *name;
- if (gsk_sl_scope_lookup_type (scope, token->str))
- goto its_a_type;
+ type = gsk_sl_scope_lookup_type (scope, token->str);
+ if (type)
+ {
+ GskSlFunctionMatcher matcher;
+ GskSlFunction *constructor;
+
+ constructor = gsk_sl_function_new_constructor (type);
+ gsk_sl_function_matcher_init (&matcher, g_list_prepend (NULL, constructor));
+ expr = gsk_sl_expression_parse_function_call (scope, stream, &matcher, constructor);
+ gsk_sl_function_matcher_finish (&matcher);
+ gsk_sl_function_unref (constructor);
+ gsk_sl_type_unref (type);
+
+ return expr;
+ }
name = g_strdup (token->str);
gsk_sl_preprocessor_consume (stream, NULL);
@@ -1418,12 +1466,18 @@ gsk_sl_expression_parse_primary (GskSlScope *scope,
token = gsk_sl_preprocessor_get (stream);
if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
{
- GskSlFunction *function = gsk_sl_scope_lookup_function (scope, name);
+ GskSlFunctionMatcher matcher;
- if (function == NULL)
+ gsk_sl_scope_match_function (scope, &matcher, name);
+
+ if (!gsk_sl_function_matcher_has_matches (&matcher))
gsk_sl_preprocessor_error (stream, DECLARATION, "No function named \"%s\".", name);
- expr = gsk_sl_expression_parse_function_call (scope, stream, function);
+ expr = gsk_sl_expression_parse_function_call (scope, stream,
+ &matcher,
+ gsk_sl_function_matcher_get_match (&matcher));
+
+ gsk_sl_function_matcher_finish (&matcher);
}
else
{
@@ -1549,10 +1603,9 @@ gsk_sl_expression_parse_primary (GskSlScope *scope,
GskSlExpression *expression;
GskSlType *type;
-its_a_type:
type = gsk_sl_type_new_parse (scope, stream);
constructor = gsk_sl_function_new_constructor (type);
- expression = gsk_sl_expression_parse_function_call (scope, stream, constructor);
+ expression = gsk_sl_expression_parse_function_call (scope, stream, NULL, constructor);
gsk_sl_function_unref (constructor);
gsk_sl_type_unref (type);
diff --git a/gsk/gskslexpressionprivate.h b/gsk/gskslexpressionprivate.h
index 3fb1811..02be57c 100644
--- a/gsk/gskslexpressionprivate.h
+++ b/gsk/gskslexpressionprivate.h
@@ -31,6 +31,7 @@ GskSlExpression * gsk_sl_expression_parse_constant (GskSlScope
GskSlPreprocessor *stream);
GskSlExpression * gsk_sl_expression_parse_function_call (GskSlScope *scope,
GskSlPreprocessor *stream,
+ GskSlFunctionMatcher *matcher,
GskSlFunction *function);
GskSlExpression * gsk_sl_expression_ref (GskSlExpression *expression);
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index 75d4f1b..09c2a06 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -568,46 +568,186 @@ gsk_sl_function_print (const GskSlFunction *function,
function->class->print (function, string);
}
+guint32
+gsk_sl_function_write_spv (const GskSlFunction *function,
+ GskSpvWriter *writer)
+{
+ return function->class->write_spv (function, writer);
+}
+
+void
+gsk_sl_function_matcher_init (GskSlFunctionMatcher *matcher,
+ GList *list)
+{
+ matcher->best_matches = list;
+ matcher->matches = NULL;
+}
+
+void
+gsk_sl_function_matcher_finish (GskSlFunctionMatcher *matcher)
+{
+ g_list_free (matcher->best_matches);
+ g_list_free (matcher->matches);
+}
+
gboolean
-gsk_sl_function_matches (const GskSlFunction *function,
- GskSlType **arguments,
- gsize n_arguments,
- GError **error)
+gsk_sl_function_matcher_has_matches (GskSlFunctionMatcher *matcher)
{
- guint i;
+ return matcher->best_matches || matcher->matches;
+}
- if (n_arguments != gsk_sl_function_get_n_arguments (function))
+GskSlFunction *
+gsk_sl_function_matcher_get_match (GskSlFunctionMatcher *matcher)
+{
+ if (matcher->best_matches == NULL)
+ return NULL;
+
+ if (matcher->best_matches->next != NULL)
+ return NULL;
+
+ return matcher->best_matches->data;
+}
+
+void
+gsk_sl_function_matcher_match_n_arguments (GskSlFunctionMatcher *matcher,
+ gsize n_arguments)
+{
+ GList *l;
+
+ for (l = matcher->best_matches; l; l = l->next)
{
- g_set_error (error,
- GSK_SL_COMPILER_ERROR, GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
- "Function %s needs %"G_GSIZE_FORMAT" arguments, but %"G_GSIZE_FORMAT" given.",
- gsk_sl_function_get_name (function),
- gsk_sl_function_get_n_arguments (function),
- n_arguments);
- return FALSE;
+ if (gsk_sl_function_get_n_arguments (l->data) != n_arguments)
+ matcher->best_matches = g_list_delete_link (matcher->best_matches, l);
}
+ for (l = matcher->matches; l; l = l->next)
+ {
+ if (gsk_sl_function_get_n_arguments (l->data) != n_arguments)
+ matcher->matches = g_list_delete_link (matcher->matches, l);
+ }
+}
+
+typedef enum {
+ MATCH_NONE,
+ MATCH_CONVERT_TO_DOUBLE,
+ MATCH_CONVERT,
+ MATCH_EXACT
+} GskSlFunctionMatch;
- for (i = 0; i < n_arguments; i++)
+static GskSlFunctionMatch
+gsk_sl_function_matcher_match_types (const GskSlType *function_type,
+ const GskSlType *argument_type)
+{
+ if (!gsk_sl_type_can_convert (function_type, argument_type))
+ return MATCH_NONE;
+
+ if (gsk_sl_type_equal (function_type, argument_type))
+ return MATCH_EXACT;
+
+ if (gsk_sl_type_get_scalar_type (function_type))
+ return MATCH_CONVERT_TO_DOUBLE;
+
+ return MATCH_CONVERT;
+}
+
+void
+gsk_sl_function_matcher_match_argument (GskSlFunctionMatcher *matcher,
+ gsize n,
+ const GskSlType *argument_type)
+{
+ GList *best_matches = NULL, *matches = NULL, *l;
+ GskSlFunctionMatch best = MATCH_NONE, function_match;
+
+ for (l = matcher->best_matches; l; l = l->next)
{
- if (!gsk_sl_type_can_convert (gsk_sl_function_get_argument_type (function, i), arguments[i]))
+ GskSlType *function_type;
+ GskSlFunctionMatch function_match;
+
+ if (gsk_sl_function_get_n_arguments (l->data) <= n)
+ continue;
+
+ function_type = gsk_sl_function_get_argument_type (l->data, n);
+ function_match = gsk_sl_function_matcher_match_types (function_type, argument_type);
+ if (function_match == MATCH_NONE)
+ continue;
+
+ if (function_match == best)
{
- g_set_error (error,
- GSK_SL_COMPILER_ERROR, GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
- "Cannot convert argument %u from %s to %s.",
- i + 1,
- gsk_sl_type_get_name (arguments[i]),
- gsk_sl_type_get_name (gsk_sl_function_get_argument_type (function, i)));
- return FALSE;
+ best_matches = g_list_prepend (best_matches, l->data);
+ best = function_match;
+ }
+ else if (function_match > best)
+ {
+ matches = g_list_concat (matches, best_matches);
+ best_matches = g_list_prepend (NULL, l->data);
+ best = function_match;
+ }
+ else
+ {
+ matches = g_list_prepend (matches, l->data);
}
}
- return TRUE;
+ for (l = matcher->matches; l; l = l->next)
+ {
+ GskSlType *function_type;
+
+ if (gsk_sl_function_get_n_arguments (l->data) <= n)
+ continue;
+
+ function_type = gsk_sl_function_get_argument_type (l->data, n);
+ function_match = gsk_sl_function_matcher_match_types (function_type, argument_type);
+ if (function_match == MATCH_NONE)
+ continue;
+
+ if (function_match > best)
+ {
+ matches = g_list_concat (matches, best_matches);
+ best_matches = NULL;
+ best = function_match;
+ }
+ matches = g_list_prepend (matches, l->data);
+ }
+
+ g_list_free (matcher->best_matches);
+ g_list_free (matcher->matches);
+ matcher->best_matches = best_matches;
+ matcher->matches = matches;
}
-guint32
-gsk_sl_function_write_spv (const GskSlFunction *function,
- GskSpvWriter *writer)
+void
+gsk_sl_function_matcher_match_function (GskSlFunctionMatcher *matcher,
+ const GskSlFunction *function)
{
- return function->class->write_spv (function, writer);
-}
+ GList *l;
+ gsize i, n;
+
+ n = gsk_sl_function_get_n_arguments (function);
+
+ for (l = matcher->best_matches; l; l = l->next)
+ {
+ GskSlFunction *f = l->data;
+
+ if (gsk_sl_function_get_n_arguments (f) != n)
+ continue;
+ for (i = 0; i < n; i++)
+ {
+ if (!gsk_sl_type_equal (gsk_sl_function_get_argument_type (f, i),
+ gsk_sl_function_get_argument_type (function, i)))
+ break;
+ }
+ if (i == n)
+ {
+ g_list_free (matcher->best_matches);
+ g_list_free (matcher->matches);
+ matcher->best_matches = g_list_prepend (NULL, f);
+ matcher->matches = NULL;
+ return;
+ }
+ }
+
+ g_list_free (matcher->best_matches);
+ g_list_free (matcher->matches);
+ matcher->best_matches = NULL;
+ matcher->matches = NULL;
+}
diff --git a/gsk/gskslfunctionprivate.h b/gsk/gskslfunctionprivate.h
index ce38b8e..92d11f7 100644
--- a/gsk/gskslfunctionprivate.h
+++ b/gsk/gskslfunctionprivate.h
@@ -67,13 +67,30 @@ GskSlType * gsk_sl_function_get_return_type (const GskSlFunc
gsize gsk_sl_function_get_n_arguments (const GskSlFunction *function);
GskSlType * gsk_sl_function_get_argument_type (const GskSlFunction *function,
gsize i);
-gboolean gsk_sl_function_matches (const GskSlFunction *function,
- GskSlType **arguments,
- gsize n_arguments,
- GError **error);
guint32 gsk_sl_function_write_spv (const GskSlFunction *function,
GskSpvWriter *writer);
+struct _GskSlFunctionMatcher
+{
+ GList *best_matches;
+ GList *matches;
+};
+
+void gsk_sl_function_matcher_init (GskSlFunctionMatcher *matcher,
+ GList *list);
+void gsk_sl_function_matcher_finish (GskSlFunctionMatcher *matcher);
+
+gboolean gsk_sl_function_matcher_has_matches (GskSlFunctionMatcher *matcher);
+GskSlFunction * gsk_sl_function_matcher_get_match (GskSlFunctionMatcher *matcher);
+
+void gsk_sl_function_matcher_match_n_arguments (GskSlFunctionMatcher *matcher,
+ gsize n_arguments);
+void gsk_sl_function_matcher_match_argument (GskSlFunctionMatcher *matcher,
+ gsize n,
+ const GskSlType *argument_type);
+void gsk_sl_function_matcher_match_function (GskSlFunctionMatcher *matcher,
+ const GskSlFunction *function);
+
G_END_DECLS
#endif /* __GSK_SL_FUNCTION_PRIVATE_H__ */
diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c
index 2f33f85..e8c9b2a 100644
--- a/gsk/gskslnode.c
+++ b/gsk/gskslnode.c
@@ -402,7 +402,17 @@ its_a_type:
constructor = gsk_sl_function_new_constructor (type);
node_expression = gsk_sl_node_new (GskSlNodeExpression, &GSK_SL_NODE_EXPRESSION);
- node_expression->expression = gsk_sl_expression_parse_function_call (scope, preproc,
constructor);
+ if (gsk_sl_function_is_builtin_constructor (constructor))
+ {
+ node_expression->expression = gsk_sl_expression_parse_function_call (scope, preproc, NULL,
constructor);
+ }
+ else
+ {
+ GskSlFunctionMatcher matcher;
+ gsk_sl_function_matcher_init (&matcher, g_list_prepend (NULL, constructor));
+ node_expression->expression = gsk_sl_expression_parse_function_call (scope, preproc,
&matcher, constructor);
+ gsk_sl_function_matcher_finish (&matcher);
+ }
node = (GskSlNode *) node_expression;
gsk_sl_function_unref (constructor);
}
diff --git a/gsk/gskslprogram.c b/gsk/gskslprogram.c
index 3d47dd6..d9a78c9 100644
--- a/gsk/gskslprogram.c
+++ b/gsk/gskslprogram.c
@@ -175,13 +175,20 @@ gsk_sl_program_parse_declaration (GskSlProgram *program,
if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
{
+ GskSlFunctionMatcher matcher;
GskSlFunction *function;
function = gsk_sl_function_new_parse (scope,
preproc,
type,
name);
- gsk_sl_scope_add_function (scope, function);
+ gsk_sl_scope_match_function (scope, &matcher, gsk_sl_function_get_name (function));
+ gsk_sl_function_matcher_match_function (&matcher, function);
+ if (gsk_sl_function_matcher_has_matches (&matcher))
+ gsk_sl_preprocessor_error (preproc, DECLARATION, "A function with the same prototype has already
been defined.");
+ else
+ gsk_sl_scope_add_function (scope, function);
+ gsk_sl_function_matcher_finish (&matcher);
program->functions = g_slist_append (program->functions, function);
}
else
diff --git a/gsk/gskslscope.c b/gsk/gskslscope.c
index 53027a1..1d06b01 100644
--- a/gsk/gskslscope.c
+++ b/gsk/gskslscope.c
@@ -20,8 +20,8 @@
#include "gskslscopeprivate.h"
-#include "gsksltypeprivate.h"
#include "gskslfunctionprivate.h"
+#include "gsksltypeprivate.h"
#include "gskslvariableprivate.h"
#include <string.h>
@@ -38,6 +38,12 @@ struct _GskSlScope
GHashTable *types;
};
+static void
+free_function_list (gpointer data)
+{
+ g_list_free_full (data, (GDestroyNotify) gsk_sl_function_unref);
+}
+
GskSlScope *
gsk_sl_scope_new (GskSlScope *parent,
GskSlType *return_type)
@@ -52,7 +58,7 @@ gsk_sl_scope_new (GskSlScope *parent,
if (return_type)
scope->return_type = gsk_sl_type_ref (return_type);
scope->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)
gsk_sl_variable_unref);
- scope->functions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)
gsk_sl_function_unref);
+ scope->functions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)
free_function_list);
scope->types = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) gsk_sl_type_unref);
return scope;
@@ -131,25 +137,35 @@ void
gsk_sl_scope_add_function (GskSlScope *scope,
GskSlFunction *function)
{
- g_hash_table_replace (scope->functions, (gpointer) gsk_sl_function_get_name (function),
gsk_sl_function_ref (function));
+ GList *functions;
+ const char *name;
+
+ name = gsk_sl_function_get_name (function);
+
+ functions = g_hash_table_lookup (scope->functions, name);
+ gsk_sl_function_ref (function);
+ if (functions)
+ functions = g_list_append (functions, function);
+ else
+ g_hash_table_insert (scope->functions, (gpointer) name, g_list_prepend (NULL, function));
}
-GskSlFunction *
-gsk_sl_scope_lookup_function (GskSlScope *scope,
- const char *name)
+void
+gsk_sl_scope_match_function (GskSlScope *scope,
+ GskSlFunctionMatcher *matcher,
+ const char *name)
{
- GskSlFunction *result;
+ GList *result = NULL, *lookup;
for (;
scope != NULL;
scope = scope->parent)
{
- result = g_hash_table_lookup (scope->functions, name);
- if (result)
- return result;
+ lookup = g_hash_table_lookup (scope->functions, name);
+ result = g_list_concat (result, g_list_copy (lookup));
}
- return NULL;
+ gsk_sl_function_matcher_init (matcher, result);
}
void
diff --git a/gsk/gskslscopeprivate.h b/gsk/gskslscopeprivate.h
index 50e6120..6c6e865 100644
--- a/gsk/gskslscopeprivate.h
+++ b/gsk/gskslscopeprivate.h
@@ -40,7 +40,8 @@ GskSlVariable * gsk_sl_scope_lookup_variable (GskSlScope
const char *name);
void gsk_sl_scope_add_function (GskSlScope *scope,
GskSlFunction *function);
-GskSlFunction * gsk_sl_scope_lookup_function (GskSlScope *scope,
+void gsk_sl_scope_match_function (GskSlScope *scope,
+ GskSlFunctionMatcher *matcher,
const char *name);
void gsk_sl_scope_add_type (GskSlScope *scope,
GskSlType *type);
diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c
index a1bcd9e..f4225d0 100644
--- a/gsk/gsksltype.c
+++ b/gsk/gsksltype.c
@@ -20,10 +20,10 @@
#include "gsksltypeprivate.h"
-#include "gsksltokenizerprivate.h"
-#include "gskslpreprocessorprivate.h"
+#include "gskslfunctionprivate.h"
#include "gskslpreprocessorprivate.h"
#include "gskslscopeprivate.h"
+#include "gsksltokenizerprivate.h"
#include "gskslvalueprivate.h"
#include "gskspvwriterprivate.h"
@@ -1183,10 +1183,17 @@ out:
{
if (gsk_sl_scope_lookup_type (scope, gsk_sl_type_get_name (type)))
gsk_sl_preprocessor_error (preproc, DECLARATION, "Redefinition of struct \"%s\".",
gsk_sl_type_get_name (type));
- else if (gsk_sl_scope_lookup_function (scope, gsk_sl_type_get_name (type)))
- gsk_sl_preprocessor_error (preproc, DECLARATION, "Constructor name \"%s\" would override function of
same name.", gsk_sl_type_get_name (type));
else
- gsk_sl_scope_add_type (scope, type);
+ {
+ GskSlFunctionMatcher matcher;
+
+ gsk_sl_scope_match_function (scope, &matcher, gsk_sl_type_get_name (type));
+ if (gsk_sl_function_matcher_has_matches (&matcher))
+ gsk_sl_preprocessor_error (preproc, DECLARATION, "Constructor name \"%s\" would override
function of same name.", gsk_sl_type_get_name (type));
+ else
+ gsk_sl_scope_add_type (scope, type);
+ gsk_sl_function_matcher_finish (&matcher);
+ }
}
return type;
}
diff --git a/gsk/gsksltypesprivate.h b/gsk/gsksltypesprivate.h
index cd15ae1..3a7125f 100644
--- a/gsk/gsksltypesprivate.h
+++ b/gsk/gsksltypesprivate.h
@@ -23,6 +23,7 @@
typedef struct _GskSlExpression GskSlExpression;
typedef struct _GskSlFunction GskSlFunction;
+typedef struct _GskSlFunctionMatcher GskSlFunctionMatcher;
typedef struct _GskSlNode GskSlNode;
typedef struct _GskSlPreprocessor GskSlPreprocessor;
typedef struct _GskSlPointerType GskSlPointerType;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]