summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Sotoudeh <matthew@masot.net>2023-07-30 18:18:25 -0700
committerMatthew Sotoudeh <matthew@masot.net>2023-07-30 18:18:25 -0700
commit44662c62f444fc50fe523d987199f6a10c9a693c (patch)
treeb52a68243ef283471c53d224fd3f0ae87f8c0d0f
parentf2297c20b69d942fd1e8fdcdd8f4d142c71de662 (diff)
add support for passing through sizeof & alignofs
-rw-r--r--README.txt26
-rw-r--r--chibicc.h5
-rw-r--r--codegen.c8
-rw-r--r--main.c5
-rw-r--r--parse.c16
-rw-r--r--tests/keeping_sizeof.c4
6 files changed, 51 insertions, 13 deletions
diff --git a/README.txt b/README.txt
index 2ffd02d..cdf7306 100644
--- a/README.txt
+++ b/README.txt
@@ -42,14 +42,24 @@ Selling points:
Known to be unsupported:
-- dietC is ... optimistic about identifier conflicts with its generated
- labels. It likely will not work if you run it on its own output. This is very
- fixable, will do soon.
-- chibicc does not have good support for long double; specifically, long
- doubles cannot be used in constant expressions. This is fixable, but requires
- non-trivial modifications to the chibicc side of the code.
-- chibicc does not parse const, volatile, etc. type qualifiers. it would not be
- too hard to support this if desired.
+ - dietC is ... optimistic about identifier conflicts with its generated
+ labels. It likely will not work if you run it on its own output. This is
+ very fixable, will do soon.
+ - chibicc does not have good support for long double; specifically, long
+ doubles cannot be used in constant expressions. This is fixable, but
+ requires non-trivial modifications to the chibicc side of the code.
+ - chibicc does not parse const, volatile, etc. type qualifiers. it would not
+ be too hard to support this if desired.
+
+Options:
+
+ - Passing "--line-numbers" enables (very WIP) support for outputting #line
+ directives. The dietcc wrapper will attempt to automatically strip those
+ before calling passes & then re-insert them, so that it all happens
+ "automagically." Of course, it doesn't really. You'll probably find that it
+ has roughly the right file, but totally wrong line.
+ - Passing "--type-builtins" will output "sizeof(Type_%d)" and
+ "alignof(Type_%d)" instead of pre-computing these operations.
Why not cilly?
diff --git a/chibicc.h b/chibicc.h
index 522c214..2782481 100644
--- a/chibicc.h
+++ b/chibicc.h
@@ -281,6 +281,10 @@ struct Node {
// Numeric literal
int64_t val;
long double fval;
+
+ // sizeof(...) or alignof(...)
+ Type *is_sizeof;
+ Type *is_alignof;
};
Node *new_cast(Node *expr, Type *ty);
@@ -465,6 +469,7 @@ void hashmap_test(void);
extern bool opt_fpic;
extern bool opt_fcommon;
extern bool opt_line_numbers;
+extern bool opt_type_builtins;
extern char *base_file;
//
diff --git a/codegen.c b/codegen.c
index 7acd2c9..b56a8b9 100644
--- a/codegen.c
+++ b/codegen.c
@@ -311,6 +311,14 @@ static void gen_addr(Node *node, int to_tmp) {
// Generate code for a given node.
static void gen_expr(Node *node, int to_tmp) {
emit_line(node->tok);
+ if (opt_type_builtins && (node->is_sizeof || node->is_alignof)) {
+ decltmp(node->ty, to_tmp);
+ if (node->is_sizeof) printnoln("\tt%d = sizeof ( ", to_tmp);
+ else printnoln("\tt%d = alignof ( ", to_tmp);
+ print_type(node->is_sizeof);
+ println(" ) ;");
+ return;
+ }
switch (node->kind) {
case ND_NULL_EXPR:
return;
diff --git a/main.c b/main.c
index 36c16e9..9e8bf70 100644
--- a/main.c
+++ b/main.c
@@ -10,6 +10,7 @@ StringArray include_paths;
bool opt_fcommon = false;
bool opt_fpic;
bool opt_line_numbers;
+bool opt_type_builtins;
static FILE *open_file(char *path) {
if (!path || strcmp(path, "-") == 0)
@@ -68,9 +69,11 @@ int main(int argc, char **argv) {
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--line-numbers")) {
opt_line_numbers = 1;
+ } else if (!strcmp(argv[i], "--type-builtins")) {
+ opt_type_builtins = 1;
} else {
assert(!base_file);
- base_file = argv[1];
+ base_file = argv[i];
}
}
cc1(base_file);
diff --git a/parse.c b/parse.c
index fe17515..0cbabc2 100644
--- a/parse.c
+++ b/parse.c
@@ -3020,7 +3020,9 @@ static Node *primary(Token **rest, Token *tok) {
return new_binary(ND_COMMA, lhs, rhs, tok);
}
- return new_ulong(ty->size, start);
+ Node *res = new_ulong(ty->size, start);
+ res->is_sizeof = ty;
+ return res;
}
if (equal(tok, "sizeof")) {
@@ -3028,19 +3030,25 @@ static Node *primary(Token **rest, Token *tok) {
add_type(node);
if (node->ty->kind == TY_VLA)
return new_var_node(node->ty->vla_size, tok);
- return new_ulong(node->ty->size, tok);
+ Node *res = new_ulong(node->ty->size, tok);
+ res->is_sizeof = node->ty;
+ return res;
}
if (equal(tok, "_Alignof") && equal(tok->next, "(") && is_typename(tok->next->next)) {
Type *ty = typename(&tok, tok->next->next);
*rest = skip(tok, ")");
- return new_ulong(ty->align, tok);
+ Node *res = new_ulong(ty->align, tok);
+ res->is_alignof = ty;
+ return res;
}
if (equal(tok, "_Alignof")) {
Node *node = unary(rest, tok->next);
add_type(node);
- return new_ulong(node->ty->align, tok);
+ Node *res = new_ulong(node->ty->align, tok);
+ res->is_alignof = node->ty;
+ return res;
}
if (equal(tok, "_Generic"))
diff --git a/tests/keeping_sizeof.c b/tests/keeping_sizeof.c
new file mode 100644
index 0000000..caa34e9
--- /dev/null
+++ b/tests/keeping_sizeof.c
@@ -0,0 +1,4 @@
+int main() {
+ int x = sizeof(struct { int a; char b; });
+ return 0;
+}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback