summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2018-02-09 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2018-02-09 15:23:48 +0100
commitaebda1c0868dfadfa8ccb55f4edfb40b16e80635 (patch)
treeb59879024814b5f7a131ccb9c29aaed8964c0cb1
parent4f7a66a42c3897d986aff5d6d081d1ecb6af0ade (diff)
downloadgobject-introspection-aebda1c0868dfadfa8ccb55f4edfb40b16e80635.tar.gz
Fix parsing when type_specifier comes before type_qualifier.
If type_specifier comes after type_qualifier, then GISourceType representing type_specifier will be merely updated with qualifier flags. On the other hand, when this order is reversed the type qualifier used to be attached as a separate node through base_type (with CTYPE_INVALID), and interpreted incorrectly in transformer code. This commit changes this behaviour so that information about type qualifiers is stored directly in GISourceType corresponding to type specifier. It also fixes analogous issue with storage_class_specifier and function_specifier. From higher level viewpoint, it for example represents `const char*` and `char const*` in equivalent manner after parsing, and addresses issue #79.
-rw-r--r--giscanner/scannerparser.y27
-rw-r--r--tests/scanner/regress.c2
-rw-r--r--tests/scanner/regress.h2
3 files changed, 27 insertions, 4 deletions
diff --git a/giscanner/scannerparser.y b/giscanner/scannerparser.y
index d9490b00..2735f5f4 100644
--- a/giscanner/scannerparser.y
+++ b/giscanner/scannerparser.y
@@ -206,6 +206,29 @@ toggle_conditional (GISourceScanner *scanner)
}
}
+static void
+set_or_merge_base_type (GISourceType *type,
+ GISourceType *base)
+{
+ if (base->type == CTYPE_INVALID)
+ {
+ g_assert (base->base_type == NULL);
+
+ type->storage_class_specifier |= base->storage_class_specifier;
+ type->type_qualifier |= base->type_qualifier;
+ type->function_specifier |= base->function_specifier;
+ type->is_bitfield |= base->is_bitfield;
+
+ ctype_free (base);
+ }
+ else
+ {
+ g_assert (type->base_type == NULL);
+
+ type->base_type = base;
+ }
+}
+
%}
%error-verbose
@@ -786,7 +809,7 @@ declaration_specifiers
$$->name = name;
ctype_free ($2);
} else {
- $$->base_type = $2;
+ set_or_merge_base_type ($1, $2);
}
}
| type_specifier
@@ -983,7 +1006,7 @@ specifier_qualifier_list
: type_specifier specifier_qualifier_list
{
$$ = $1;
- $$->base_type = $2;
+ set_or_merge_base_type ($1, $2);
}
| type_specifier
| type_qualifier specifier_qualifier_list
diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c
index 92bf6c4e..85e00d9b 100644
--- a/tests/scanner/regress.c
+++ b/tests/scanner/regress.c
@@ -4294,7 +4294,7 @@ regress_test_versioning (void)
void
regress_like_xkl_config_item_set_name (RegressLikeXklConfigItem *self,
- const char *name)
+ char const *name)
{
strncpy (self->name, name, sizeof (self->name) - 1);
self->name[sizeof(self->name)-1] = '\0';
diff --git a/tests/scanner/regress.h b/tests/scanner/regress.h
index 7f315fdc..cf0059e4 100644
--- a/tests/scanner/regress.h
+++ b/tests/scanner/regress.h
@@ -1398,7 +1398,7 @@ typedef struct {
_GI_TEST_EXTERN
void regress_like_xkl_config_item_set_name (RegressLikeXklConfigItem *self,
- const char *name);
+ char const *name);
#define REGRESS_UTF8_CONSTANT "const \xe2\x99\xa5 utf8"