[gtk+/wip/otte/shader] gsksl: Error on redeclaration of variable
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader] gsksl: Error on redeclaration of variable
- Date: Wed, 25 Oct 2017 03:54:49 +0000 (UTC)
commit a966940e05a15a27680605f267bf3e7923be3b07
Author: Benjamin Otte <otte redhat com>
Date: Wed Oct 25 05:53:56 2017 +0200
gsksl: Error on redeclaration of variable
Also, emit shadow warnings whenever possible.
gsk/gsksldeclaration.c | 6 +-
gsk/gskslfunction.c | 17 +------
gsk/gskslscope.c | 51 ++++++++++++++++++++
gsk/gskslscopeprivate.h | 3 +
gsk/gskslstatement.c | 2 +-
.../gsksl/errors/duplicate-function-parameter.glsl | 10 ++++
.../local-redeclaration-of-function-parameter.glsl | 11 ++++
.../local-redeclaration-of-local-variable.glsl | 5 ++
...tion-of-global-variable-in-anonymous-block.glsl | 9 ++++
.../errors/redeclaration-of-global-variable.glsl | 7 +++
10 files changed, 101 insertions(+), 20 deletions(-)
---
diff --git a/gsk/gsksldeclaration.c b/gsk/gsksldeclaration.c
index 5431093..539f178 100644
--- a/gsk/gsksldeclaration.c
+++ b/gsk/gsksldeclaration.c
@@ -316,7 +316,7 @@ gsk_sl_declaration_parse_block (GskSlScope *scope,
variable = gsk_sl_declaration_new (&GSK_SL_DECLARATION_VARIABLE);
variable->variable = gsk_sl_variable_new (name, type, qualifier, NULL);
- gsk_sl_scope_add_variable (scope, variable->variable);
+ gsk_sl_scope_try_add_variable (scope, preproc, variable->variable);
token = gsk_sl_preprocessor_get (preproc);
}
@@ -334,7 +334,7 @@ gsk_sl_declaration_parse_block (GskSlScope *scope,
GskSlVariable *sub;
sub = gsk_sl_variable_new_block_member (variable->variable, i);
- gsk_sl_scope_add_variable (scope, sub);
+ gsk_sl_scope_try_add_variable (scope, preproc, sub);
gsk_sl_variable_unref (sub);
}
}
@@ -413,7 +413,7 @@ gsk_sl_declaration_parse_variable (GskSlScope *scope,
variable = gsk_sl_declaration_new (&GSK_SL_DECLARATION_VARIABLE);
variable->variable = gsk_sl_variable_new (name, type, qualifier, initial_value);
variable->initial = initial;
- gsk_sl_scope_add_variable (scope, variable->variable);
+ gsk_sl_scope_try_add_variable (scope, preproc, variable->variable);
gsk_sl_type_unref (type);
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index a7c508b..33b1aa3 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -604,21 +604,6 @@ gsk_sl_function_new_parse (GskSlScope *scope,
if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
{
char *name;
- guint i;
-
- if (gsk_sl_scope_lookup_variable (function->scope, token->str))
- {
- for (i = 0; i < arguments->len; i++)
- {
- if (g_str_equal (gsk_sl_variable_get_name (g_ptr_array_index (arguments, i)),
token->str))
- {
- gsk_sl_preprocessor_error (preproc, DECLARATION, "Duplicate argument name
\"%s\".", token->str);
- break;
- }
- }
- if (i == arguments->len)
- gsk_sl_preprocessor_warn (preproc, SHADOW, "Function argument \"%s\" shadows global
variable of same name.", token->str);
- }
name = g_strdup (token->str);
gsk_sl_preprocessor_consume (preproc, (GskSlStatement *) function);
@@ -631,7 +616,7 @@ gsk_sl_function_new_parse (GskSlScope *scope,
type);
g_ptr_array_add (arguments, variable);
- gsk_sl_scope_add_variable (function->scope, variable);
+ gsk_sl_scope_try_add_variable (function->scope, preproc, variable);
g_free (name);
}
diff --git a/gsk/gskslscope.c b/gsk/gskslscope.c
index 07fddf7..f4b8f7d 100644
--- a/gsk/gskslscope.c
+++ b/gsk/gskslscope.c
@@ -21,6 +21,8 @@
#include "gskslscopeprivate.h"
#include "gskslfunctionprivate.h"
+#include "gskslpreprocessorprivate.h"
+#include "gskslqualifierprivate.h"
#include "gsksltypeprivate.h"
#include "gskslvariableprivate.h"
@@ -153,6 +155,55 @@ gsk_sl_scope_add_variable (GskSlScope *scope,
g_hash_table_replace (scope->variables, (gpointer) gsk_sl_variable_get_name (variable),
gsk_sl_variable_ref (variable));
}
+static const char *
+gsk_sl_scope_describe_variable (GskSlVariable *variable)
+{
+ switch (gsk_sl_qualifier_get_location (gsk_sl_variable_get_qualifier (variable)))
+ {
+ default:
+ g_assert_not_reached ();
+ case GSK_SL_QUALIFIER_GLOBAL:
+ return "global variable";
+ case GSK_SL_QUALIFIER_PARAMETER:
+ return "function parameter";
+ case GSK_SL_QUALIFIER_LOCAL:
+ return "local variable";
+ }
+}
+
+void
+gsk_sl_scope_try_add_variable (GskSlScope *scope,
+ GskSlPreprocessor *preproc,
+ GskSlVariable *variable)
+{
+ GskSlVariable *shadow;
+
+ /* only look in current scope for error */
+ shadow = g_hash_table_lookup (scope->variables, gsk_sl_variable_get_name (variable));
+ if (shadow)
+ {
+ gsk_sl_preprocessor_error (preproc, DECLARATION,
+ "Redefinition of %s \"%s\".",
+ gsk_sl_scope_describe_variable (shadow),
+ gsk_sl_variable_get_name (variable));
+ return;
+ }
+
+ if (scope->parent)
+ {
+ shadow = gsk_sl_scope_lookup_variable (scope->parent, gsk_sl_variable_get_name (variable));
+ if (shadow)
+ {
+ gsk_sl_preprocessor_warn (preproc, SHADOW,
+ "Name \"%s\" shadows %s of same name.",
+ gsk_sl_variable_get_name (variable),
+ gsk_sl_scope_describe_variable (shadow));
+ }
+ }
+
+ gsk_sl_scope_add_variable (scope, variable);
+}
+
GskSlVariable *
gsk_sl_scope_lookup_variable (GskSlScope *scope,
const char *name)
diff --git a/gsk/gskslscopeprivate.h b/gsk/gskslscopeprivate.h
index cb4bac8..4cd81b2 100644
--- a/gsk/gskslscopeprivate.h
+++ b/gsk/gskslscopeprivate.h
@@ -42,6 +42,9 @@ gboolean gsk_sl_scope_is_global (const GskSlScop
void gsk_sl_scope_add_variable (GskSlScope *scope,
GskSlVariable *variable);
+void gsk_sl_scope_try_add_variable (GskSlScope *scope,
+ GskSlPreprocessor *preproc,
+ GskSlVariable *variable);
GskSlVariable * gsk_sl_scope_lookup_variable (GskSlScope *scope,
const char *name);
void gsk_sl_scope_add_function (GskSlScope *scope,
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index 1b2547b..e1d26b4 100644
--- a/gsk/gskslstatement.c
+++ b/gsk/gskslstatement.c
@@ -743,7 +743,7 @@ gsk_sl_statement_parse_declaration (GskSlScope *scope,
declaration->variable = gsk_sl_variable_new (name, type, qualifier, initial_value);
g_free (name);
- gsk_sl_scope_add_variable (scope, declaration->variable);
+ gsk_sl_scope_try_add_variable (scope, stream, declaration->variable);
gsk_sl_type_unref (type);
return (GskSlStatement *) declaration;
diff --git a/testsuite/gsksl/errors/duplicate-function-parameter.glsl
b/testsuite/gsksl/errors/duplicate-function-parameter.glsl
new file mode 100644
index 0000000..8d1e19c
--- /dev/null
+++ b/testsuite/gsksl/errors/duplicate-function-parameter.glsl
@@ -0,0 +1,10 @@
+void
+foo (int x, int x)
+{
+}
+
+void
+main ()
+{
+ foo (4, 2);
+}
diff --git a/testsuite/gsksl/errors/local-redeclaration-of-function-parameter.glsl
b/testsuite/gsksl/errors/local-redeclaration-of-function-parameter.glsl
new file mode 100644
index 0000000..2c0d2c5
--- /dev/null
+++ b/testsuite/gsksl/errors/local-redeclaration-of-function-parameter.glsl
@@ -0,0 +1,11 @@
+
+void
+foo (int x)
+{
+ int x;
+}
+
+void main()
+{
+ foo (1);
+}
diff --git a/testsuite/gsksl/errors/local-redeclaration-of-local-variable.glsl
b/testsuite/gsksl/errors/local-redeclaration-of-local-variable.glsl
new file mode 100644
index 0000000..47503f7
--- /dev/null
+++ b/testsuite/gsksl/errors/local-redeclaration-of-local-variable.glsl
@@ -0,0 +1,5 @@
+void main()
+{
+ int x;
+ int x;
+}
diff --git a/testsuite/gsksl/errors/redeclaration-of-global-variable-in-anonymous-block.glsl
b/testsuite/gsksl/errors/redeclaration-of-global-variable-in-anonymous-block.glsl
new file mode 100644
index 0000000..61f0c3e
--- /dev/null
+++ b/testsuite/gsksl/errors/redeclaration-of-global-variable-in-anonymous-block.glsl
@@ -0,0 +1,9 @@
+int x;
+uniform Block {
+ int x;
+};
+
+void
+main ()
+{
+}
diff --git a/testsuite/gsksl/errors/redeclaration-of-global-variable.glsl
b/testsuite/gsksl/errors/redeclaration-of-global-variable.glsl
new file mode 100644
index 0000000..a9e2908
--- /dev/null
+++ b/testsuite/gsksl/errors/redeclaration-of-global-variable.glsl
@@ -0,0 +1,7 @@
+int x;
+int x;
+
+void
+main ()
+{
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]