gsksl: Error on redeclaration of variable

Also, emit shadow warnings whenever possible.
This commit is contained in:
Benjamin Otte
2017-10-25 05:53:56 +02:00
parent cb857e7231
commit 9f4da8c509
10 changed files with 101 additions and 20 deletions

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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,

View File

@@ -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;

View File

@@ -0,0 +1,10 @@
void
foo (int x, int x)
{
}
void
main ()
{
foo (4, 2);
}

View File

@@ -0,0 +1,11 @@
void
foo (int x)
{
int x;
}
void main()
{
foo (1);
}

View File

@@ -0,0 +1,5 @@
void main()
{
int x;
int x;
}

View File

@@ -0,0 +1,9 @@
int x;
uniform Block {
int x;
};
void
main ()
{
}

View File

@@ -0,0 +1,7 @@
int x;
int x;
void
main ()
{
}