glcpp: Add support for "redefined macro" error.
Carefully avoiding printing any error when the new definition matches the existing definition. This fixes the recently-added 088-redefine-macro-legitimate.c and 089-redefine-macro-error.c tests as well as glsparsertest/preprocess1 in piglit.
This commit is contained in:
parent
105e2137d6
commit
3882cf2169
|
@ -63,6 +63,9 @@ _string_list_contains (string_list_t *list, const char *member, int *index);
|
||||||
static int
|
static int
|
||||||
_string_list_length (string_list_t *list);
|
_string_list_length (string_list_t *list);
|
||||||
|
|
||||||
|
static int
|
||||||
|
_string_list_equal (string_list_t *a, string_list_t *b);
|
||||||
|
|
||||||
static argument_list_t *
|
static argument_list_t *
|
||||||
_argument_list_create (void *ctx);
|
_argument_list_create (void *ctx);
|
||||||
|
|
||||||
|
@ -95,6 +98,9 @@ _token_list_append (token_list_t *list, token_t *token);
|
||||||
static void
|
static void
|
||||||
_token_list_append_list (token_list_t *list, token_list_t *tail);
|
_token_list_append_list (token_list_t *list, token_list_t *tail);
|
||||||
|
|
||||||
|
static int
|
||||||
|
_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b);
|
||||||
|
|
||||||
static active_list_t *
|
static active_list_t *
|
||||||
_active_list_push (active_list_t *list,
|
_active_list_push (active_list_t *list,
|
||||||
const char *identifier,
|
const char *identifier,
|
||||||
|
@ -604,6 +610,31 @@ _string_list_length (string_list_t *list)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_string_list_equal (string_list_t *a, string_list_t *b)
|
||||||
|
{
|
||||||
|
string_node_t *node_a, *node_b;
|
||||||
|
|
||||||
|
if (a == NULL && b == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (a == NULL || b == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (node_a = a->head, node_b = b->head;
|
||||||
|
node_a && node_b;
|
||||||
|
node_a = node_a->next, node_b = node_b->next)
|
||||||
|
{
|
||||||
|
if (strcmp (node_a->str, node_b->str))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Catch the case of lists being different lengths, (which
|
||||||
|
* would cause the loop above to terminate after the shorter
|
||||||
|
* list). */
|
||||||
|
return node_a == node_b;
|
||||||
|
}
|
||||||
|
|
||||||
argument_list_t *
|
argument_list_t *
|
||||||
_argument_list_create (void *ctx)
|
_argument_list_create (void *ctx)
|
||||||
{
|
{
|
||||||
|
@ -781,6 +812,61 @@ _token_list_trim_trailing_space (token_list_t *list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b)
|
||||||
|
{
|
||||||
|
token_node_t *node_a, *node_b;
|
||||||
|
|
||||||
|
node_a = a->head;
|
||||||
|
node_b = b->head;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (node_a == NULL && node_b == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (node_a == NULL || node_b == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (node_a->token->type == SPACE) {
|
||||||
|
node_a = node_a->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node_b->token->type == SPACE) {
|
||||||
|
node_b = node_b->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node_a->token->type != node_b->token->type)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (node_a->token->type) {
|
||||||
|
case INTEGER:
|
||||||
|
if (node_a->token->value.ival !=
|
||||||
|
node_b->token->value.ival)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDENTIFIER:
|
||||||
|
case INTEGER_STRING:
|
||||||
|
case OTHER:
|
||||||
|
if (strcmp (node_a->token->value.str,
|
||||||
|
node_b->token->value.str))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_a = node_a->next;
|
||||||
|
node_b = node_b->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_token_print (char **out, token_t *token)
|
_token_print (char **out, token_t *token)
|
||||||
{
|
{
|
||||||
|
@ -1522,13 +1608,28 @@ _check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_macro_equal (macro_t *a, macro_t *b)
|
||||||
|
{
|
||||||
|
if (a->is_function != b->is_function)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (a->is_function) {
|
||||||
|
if (! _string_list_equal (a->parameters, b->parameters))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _token_list_equal_ignoring_space (a->replacements,
|
||||||
|
b->replacements);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_define_object_macro (glcpp_parser_t *parser,
|
_define_object_macro (glcpp_parser_t *parser,
|
||||||
YYLTYPE *loc,
|
YYLTYPE *loc,
|
||||||
const char *identifier,
|
const char *identifier,
|
||||||
token_list_t *replacements)
|
token_list_t *replacements)
|
||||||
{
|
{
|
||||||
macro_t *macro;
|
macro_t *macro, *previous;
|
||||||
|
|
||||||
if (loc != NULL)
|
if (loc != NULL)
|
||||||
_check_for_reserved_macro_name(parser, loc, identifier);
|
_check_for_reserved_macro_name(parser, loc, identifier);
|
||||||
|
@ -1540,6 +1641,16 @@ _define_object_macro (glcpp_parser_t *parser,
|
||||||
macro->identifier = talloc_strdup (macro, identifier);
|
macro->identifier = talloc_strdup (macro, identifier);
|
||||||
macro->replacements = talloc_steal (macro, replacements);
|
macro->replacements = talloc_steal (macro, replacements);
|
||||||
|
|
||||||
|
previous = hash_table_find (parser->defines, identifier);
|
||||||
|
if (previous) {
|
||||||
|
if (_macro_equal (macro, previous)) {
|
||||||
|
talloc_free (macro);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glcpp_error (loc, parser, "Redefinition of macro %s\n",
|
||||||
|
identifier);
|
||||||
|
}
|
||||||
|
|
||||||
hash_table_insert (parser->defines, macro, identifier);
|
hash_table_insert (parser->defines, macro, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1550,7 +1661,7 @@ _define_function_macro (glcpp_parser_t *parser,
|
||||||
string_list_t *parameters,
|
string_list_t *parameters,
|
||||||
token_list_t *replacements)
|
token_list_t *replacements)
|
||||||
{
|
{
|
||||||
macro_t *macro;
|
macro_t *macro, *previous;
|
||||||
|
|
||||||
_check_for_reserved_macro_name(parser, loc, identifier);
|
_check_for_reserved_macro_name(parser, loc, identifier);
|
||||||
|
|
||||||
|
@ -1561,6 +1672,16 @@ _define_function_macro (glcpp_parser_t *parser,
|
||||||
macro->identifier = talloc_strdup (macro, identifier);
|
macro->identifier = talloc_strdup (macro, identifier);
|
||||||
macro->replacements = talloc_steal (macro, replacements);
|
macro->replacements = talloc_steal (macro, replacements);
|
||||||
|
|
||||||
|
previous = hash_table_find (parser->defines, identifier);
|
||||||
|
if (previous) {
|
||||||
|
if (_macro_equal (macro, previous)) {
|
||||||
|
talloc_free (macro);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glcpp_error (loc, parser, "Redefinition of macro %s\n",
|
||||||
|
identifier);
|
||||||
|
}
|
||||||
|
|
||||||
hash_table_insert (parser->defines, macro, identifier);
|
hash_table_insert (parser->defines, macro, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue