aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-09-13 22:57:25 +0900
committernsfisis <nsfisis@gmail.com>2025-09-13 22:57:25 +0900
commit4ef1add4c20d4b44aa43d0f3a102ee173b7a5e5b (patch)
tree6f8801e122a1896f7a5df92f711acb6e0d77fe73 /src
parent5e1b01f35ca68a09de1bc3d5b577fe84342d773d (diff)
downloadducc-4ef1add4c20d4b44aa43d0f3a102ee173b7a5e5b.tar.gz
ducc-4ef1add4c20d4b44aa43d0f3a102ee173b7a5e5b.tar.zst
ducc-4ef1add4c20d4b44aa43d0f3a102ee173b7a5e5b.zip
feat: support pointer types with type qualifiers
Diffstat (limited to 'src')
-rw-r--r--src/parse.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/parse.c b/src/parse.c
index cc0648a..afbb282 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -873,13 +873,28 @@ static AstNode* parse_if_stmt(Parser* p) {
return stmt;
}
+// type-qualifier-list:
+// { type-qualifier }+
+static void parse_type_qualifier_list_opt(Parser* p) {
+ while (1) {
+ Token* tok = peek_token(p);
+ if (tok->kind == TokenKind_keyword_const || tok->kind == TokenKind_keyword_restrict ||
+ tok->kind == TokenKind_keyword_volatile || tok->kind == TokenKind_keyword__Atomic) {
+ // TODO: currently type qualifiers are just ignored.
+ next_token(p);
+ } else {
+ break;
+ }
+ }
+}
+
// pointer:
-// '*' TODO attribute-specifier-sequence? TODO type-qualifier-list?
-// '*' TODO attribute-specifier-sequence? TODO type-qualifier-list? pointer
+// { '*' TODO attribute-specifier-sequence? type-qualifier-list? }+
static Type* parse_pointer_opt(Parser* p, Type* ty) {
while (peek_token(p)->kind == TokenKind_star) {
next_token(p);
ty = type_new_ptr(ty);
+ parse_type_qualifier_list_opt(p);
}
return ty;
}
@@ -1744,7 +1759,7 @@ static Type* distinguish_type_from_type_specifiers(int type_specifiers) {
else if (type_specifiers == TypeSpecifierMask_typedef_name)
return NULL;
else if (type_specifiers == 0)
- fatal_error("no type specifiers");
+ return NULL;
else
unimplemented();
}
@@ -1828,8 +1843,9 @@ static Type* parse_declaration_specifiers(Parser* p) {
int type_specifiers = 0;
Type* ty = NULL;
+ Token* tok;
while (1) {
- Token* tok = peek_token(p);
+ tok = peek_token(p);
// storage-class-spciefier
if (tok->kind == TokenKind_keyword_auto) {
@@ -2010,6 +2026,9 @@ static Type* parse_declaration_specifiers(Parser* p) {
if (ty_) {
ty = ty_;
}
+ if (!ty) {
+ fatal_error("%s:%d: no type specifiers", tok->loc.filename, tok->loc.line);
+ }
ty->storage_class = storage_class;
return ty;