Selaa lähdekoodia

working on new type system

Tobias Waldekranz.com 8 vuotta sitten
vanhempi
commit
0a62b4e3d5
9 muutettua tiedostoa jossa 581 lisäystä ja 387 poistoa
  1. 4 2
      Makefile
  2. 12 12
      arch-x86_64.c
  3. 1 13
      node.c
  4. 10 39
      node.h
  5. 58 58
      ply.c
  6. 20 27
      ply.h
  7. 383 175
      type.c
  8. 70 61
      type.h
  9. 23 0
      type_test.c

+ 4 - 2
Makefile

@@ -1,7 +1,7 @@
1 1
 CFLAGS ?= -Wall -Wextra -Werror -Wno-unused -O0 -g
2 2
 
3
-srcs := ply.c node.c
4
-hdrs := node.h ply.h
3
+srcs := ply.c node.c type.c
4
+hdrs := node.h ply.h type.h
5 5
 
6 6
 #srcs := $(wildcard *.c)
7 7
 #hdrs := $(wildcard *.h)
@@ -11,3 +11,5 @@ deps := $(srcs) $(hdrs)
11 11
 $(objs): $(deps)
12 12
 
13 13
 ply: $(objs)
14
+
15
+type_test: type_test.o type.o

+ 12 - 12
arch-x86_64.c

@@ -8,13 +8,13 @@
8 8
 		.t = { .tdef = { .name = #_a, .type = _t } },	\
9 9
 	}
10 10
 
11
-type_t t_s8 = arch_typedef(s8, &t_char);
12
-type_t t_u8 = arch_typedef(u8, &t_uchar);
13
-type_t t_s16 = arch_typedef(s16, &t_short);
11
+type_t t_s8  = arch_typedef(s8,  &t_schar);
12
+type_t t_u8  = arch_typedef(u8,  &t_uchar);
13
+type_t t_s16 = arch_typedef(s16, &t_sshort);
14 14
 type_t t_u16 = arch_typedef(u16, &t_ushort);
15
-type_t t_s32 = arch_typedef(s32, &t_int);
15
+type_t t_s32 = arch_typedef(s32, &t_sint);
16 16
 type_t t_u32 = arch_typedef(u32, &t_uint);
17
-type_t t_s64 = arch_typedef(s64, &t_long);
17
+type_t t_s64 = arch_typedef(s64, &t_slong);
18 18
 type_t t_u64 = arch_typedef(u64, &t_ulong);
19 19
 
20 20
 field_t f_pt_regs_fields[] = {
@@ -40,13 +40,13 @@ field_t f_pt_regs_fields[] = {
40 40
 	{ .name = "rsp",      .type = &t_ulong },
41 41
 	{ .name = "ss",       .type = &t_ulong },
42 42
 
43
-	{ .type = NULL }
43
+	{ .type = &t_void }
44 44
 };
45 45
 
46 46
 type_t t_pt_regs = {
47 47
 	.ttype = T_STRUCT,
48 48
 
49
-	.t.sou = {
49
+	.sou = {
50 50
 		.name = "pt_regs",
51 51
 		.fields = f_pt_regs_fields,
52 52
 	},
@@ -65,9 +65,9 @@ type_t *arch_types[] = {
65 65
 const char *arch_register_argument(int num)
66 66
 {
67 67
 	switch (num) {
68
-	case 0: return "di";
69
-	case 1: return "si";
70
-	case 2: return "dx";
68
+	case 0: return "rdi";
69
+	case 1: return "rsi";
70
+	case 2: return "rdx";
71 71
 	case 3: return "r10";
72 72
 	case 4: return "r8";
73 73
 	case 5: return "r9";
@@ -78,12 +78,12 @@ const char *arch_register_argument(int num)
78 78
 
79 79
 const char *arch_register_pc(void) 
80 80
 {
81
-	return "ip";
81
+	return "rip";
82 82
 }
83 83
 
84 84
 const char *arch_register_return(void)
85 85
 {
86
-	return "ax";
86
+	return "rax";
87 87
 }
88 88
 
89 89
 __attribute__((constructor))

+ 1 - 13
node.c

@@ -6,17 +6,7 @@
6 6
 #include <stdio.h>
7 7
 #include <stdlib.h>
8 8
 
9
-#include "ply.h"
10
-
11
-void __type_dump(type_t *t, FILE *fp)
12
-{
13
-	if (!t)
14
-		return;
15
-
16
-	fputs(" \e[2m<", fp);
17
-	/* type_dump(t, fp); */
18
-	fputs(">\e[0m", fp);
19
-}
9
+#include "node.h"
20 10
 
21 11
 void node_print(struct node *n, FILE *fp)
22 12
 {
@@ -37,8 +27,6 @@ void node_print(struct node *n, FILE *fp)
37 27
 	default:
38 28
 		fputs("<INVALID>", fp);
39 29
 	}
40
-
41
-	__type_dump(n->type, fp);
42 30
 }
43 31
 
44 32
 struct node_dump_info {

+ 10 - 39
node.h

@@ -4,12 +4,8 @@
4 4
 #include <stdint.h>
5 5
 #include <stdio.h>
6 6
 
7
-#include "ir.h"
8
-#include "sym.h"
9
-#include "type.h"
10
-
11
-/* REEEEEEEEEEEEEEMOVE */
12
-typedef struct node node_t;
7
+struct sym;
8
+/* symbol information is defined externally */
13 9
 
14 10
 enum ntype {
15 11
 	N_EXPR,
@@ -38,24 +34,18 @@ struct node {
38 34
 			char *data;
39 35
 		} string;
40 36
 	};
41
-
42
-
43
-	type_t *type;
44
-	sym_t *sym;
45
-	irstate_t irs;
46 37
 };
47 38
 
48 39
 /* debug */
49 40
 void node_print(struct node *n, FILE *fp);
50 41
 void node_dump (struct node *n, FILE *fp);
51 42
 
52
-typedef int (*walk_fn)(struct node *, void *);
53
-int node_walk(struct node *n, walk_fn pre, walk_fn post, void *ctx);
43
+
44
+typedef int (*nwalk_fn)(struct node *, void *);
45
+int node_walk(struct node *n, nwalk_fn pre, nwalk_fn post, void *ctx);
54 46
 
55 47
 int node_replace(struct node *n, struct node *new);
56 48
 
57
-#define node_expr_foreach(_expr, _arg) \
58
-	for ((_arg) = (_expr)->expr.args; (_arg); (_arg) = (_arg)->next)
59 49
 
60 50
 /* constructors */
61 51
 struct node *node_string(char *data);
@@ -64,6 +54,9 @@ struct node *node_ident (char *name);
64 54
 struct node *node_append(struct node *n, struct node *arg);
65 55
 struct node *node_expr  (char *func, ...);
66 56
 
57
+
58
+/* helpers */
59
+
67 60
 static inline int node_is_block(struct node *n)
68 61
 {
69 62
 	if (!n || (n->ntype != N_EXPR))
@@ -72,29 +65,7 @@ static inline int node_is_block(struct node *n)
72 65
 	return n->expr.func[0] == '\0';
73 66
 }
74 67
 
75
-/* static inline node_t *node_head(node_t *n) */
76
-/* { */
77
-/* 	if (!n) */
78
-/* 		return NULL; */
79
-
80
-/* 	for (; n->prev; n = n->prev); */
81
-
82
-/* 	return n; */
83
-/* } */
84
-
85
-/* static inline node_t *node_prev(node_t *n) */
86
-/* { */
87
-/* 	return n ? n->prev : NULL; */
88
-/* } */
89
-
90
-/* static inline node_t *node_next(node_t *n) */
91
-/* { */
92
-/* 	return n ? n->next : NULL; */
93
-/* } */
94
-
95
-/* static inline node_t *node_up(node_t *n) */
96
-/* { */
97
-/* 	return n ? n->up : NULL; */
98
-/* } */
68
+#define node_expr_foreach(_expr, _arg) \
69
+	for ((_arg) = (_expr)->expr.args; (_arg); (_arg) = (_arg)->next)
99 70
 
100 71
 #endif	/* _PLY_NODE_H */

+ 58 - 58
ply.c

@@ -5,62 +5,62 @@
5 5
 #include <string.h>
6 6
 
7 7
 #include "ply.h"
8
+#include "node.h"
8 9
 
9
-struct providers {
10
-	provider_t **prov;
11
-	size_t len;
12
-} providers;
10
+/* struct providers { */
11
+/* 	provider_t **prov; */
12
+/* 	size_t len; */
13
+/* } providers; */
13 14
 
14
-provider_t *provider_get(const char *name)
15
-{
16
-	size_t i;
15
+/* provider_t *provider_get(const char *name) */
16
+/* { */
17
+/* 	size_t i; */
17 18
 
18
-	for (i = 0; i < providers.len; i++) {
19
-		if (strstr(providers.prov[i]->name, name)
20
-		    == providers.prov[i]->name)
21
-			return providers.prov[i];
22
-	}
19
+/* 	for (i = 0; i < providers.len; i++) { */
20
+/* 		if (strstr(providers.prov[i]->name, name) */
21
+/* 		    == providers.prov[i]->name) */
22
+/* 			return providers.prov[i]; */
23
+/* 	} */
23 24
 
24
-	return NULL;
25
-}
25
+/* 	return NULL; */
26
+/* } */
26 27
 
27
-void provider_register(provider_t *prov)
28
-{
29
-	assert(prov);
30
-	assert(prov->probe);
31
-	assert(prov->resolve);
28
+/* void provider_register(provider_t *prov) */
29
+/* { */
30
+/* 	assert(prov); */
31
+/* 	assert(prov->probe); */
32
+/* 	assert(prov->resolve); */
32 33
 
33
-	providers.prov = realloc(providers.prov,
34
-				 ++providers.len * sizeof(*providers.prov));
34
+/* 	providers.prov = realloc(providers.prov, */
35
+/* 				 ++providers.len * sizeof(*providers.prov)); */
35 36
 
36
-	providers.prov[providers.len - 1] = prov;
37
-}
37
+/* 	providers.prov[providers.len - 1] = prov; */
38
+/* } */
38 39
 
39
-typedef struct pass pass_t;
40 40
 struct pass {
41
-	int (*run)(pass_t *, ctx_t *);
42
-	walk_fn pre;
43
-	walk_fn post;
41
+	int (*run)(struct pass *, struct ctx *);
42
+	nwalk_fn pre;
43
+	nwalk_fn post;
44 44
 };
45 45
 
46 46
 
47
-symtab_t globals = { .sym = NULL, .len = 0 };
48
-symtab_t locals = { .sym = NULL, .len = 0 };
47
+/* symtab_t globals = { .sym = NULL, .len = 0 }; */
48
+/* symtab_t locals = { .sym = NULL, .len = 0 }; */
49 49
 
50
-ctx_t *ctx_get(void)
50
+struct ctx *ctx_get(void)
51 51
 {
52
-	ctx_t *ctx;
53
-	prog_t *prog;
52
+	struct ctx *ctx;
53
+	struct prog *prog;
54 54
 
55 55
 	ctx = calloc(1, sizeof(*ctx));
56
-	ctx->globals = calloc(1, sizeof(*ctx->globals));
56
+	/* ctx->globals = calloc(1, sizeof(*ctx->globals)); */
57 57
 
58 58
 	ctx->progs = calloc(3, sizeof(*ctx->progs));
59 59
 
60 60
 	/* PROBE0 */
61 61
 	prog = calloc(1, sizeof(*prog));
62
-	prog->locals = calloc(1, sizeof(*prog->locals));
63
-	prog->globals = ctx->globals;
62
+	/* prog->locals = calloc(1, sizeof(*prog->locals)); */
63
+	/* prog->globals = ctx->globals; */
64 64
 
65 65
 	prog->probe = "k:SyS_read";
66 66
 	/* { @t[0] = time(); @reads[pid()] = quantize(arg2) } */
@@ -89,8 +89,8 @@ ctx_t *ctx_get(void)
89 89
 
90 90
 	/* PROBE1 */
91 91
 	prog = calloc(1, sizeof(*prog));
92
-	prog->locals = calloc(1, sizeof(*prog->locals));
93
-	prog->globals = ctx->globals;
92
+	/* prog->locals = calloc(1, sizeof(*prog->locals)); */
93
+	/* prog->globals = ctx->globals; */
94 94
 
95 95
 	/* TODO: k -> kret */
96 96
 	prog->probe = "k:SyS_read2"; 
@@ -120,7 +120,7 @@ ctx_t *ctx_get(void)
120 120
 
121 121
 /* int pass_resolve_symbols(node_t *n, void *_prog) */
122 122
 /* { */
123
-/* 	prog_t *prog = _prog; */
123
+/* 	struct prog *prog = _prog; */
124 124
 /* 	provider_t *global = provider_get(":"); */
125 125
 /* 	node_t *op; */
126 126
 /* 	int err; */
@@ -141,7 +141,7 @@ ctx_t *ctx_get(void)
141 141
 /* 	return sym_add(prog->globals, n->ident, NULL, &n->sym); */
142 142
 /* } */
143 143
 
144
-/* int infer_type_list(prog_t *prog, node_t *n) */
144
+/* int infer_type_list(struct prog *prog, node_t *n) */
145 145
 /* { */
146 146
 /* 	type_t *t; */
147 147
 
@@ -165,7 +165,7 @@ ctx_t *ctx_get(void)
165 165
 /* 	return 0; */
166 166
 /* } */
167 167
 
168
-/* int infer_type_keyword(prog_t *prog, node_t *n) */
168
+/* int infer_type_keyword(struct prog *prog, node_t *n) */
169 169
 /* { */
170 170
 /* 	node_t *dst, *src; */
171 171
 
@@ -211,7 +211,7 @@ ctx_t *ctx_get(void)
211 211
 /* 	return -ENOSYS; */
212 212
 /* } */
213 213
 
214
-/* int infer_type_sym(prog_t *prog, node_t *n) */
214
+/* int infer_type_sym(struct prog *prog, node_t *n) */
215 215
 /* { */
216 216
 /* 	node_t *parent, *key; */
217 217
 
@@ -244,7 +244,7 @@ ctx_t *ctx_get(void)
244 244
 
245 245
 /* int pass_infer_types(node_t *n, void *_prog) */
246 246
 /* { */
247
-/* 	prog_t *prog = _prog; */
247
+/* 	struct prog *prog = _prog; */
248 248
 
249 249
 /* 	if (n->type) */
250 250
 /* 		return 0; */
@@ -302,7 +302,7 @@ ctx_t *ctx_get(void)
302 302
 
303 303
 /* int pass_validate_types(node_t *n, void *_prog) */
304 304
 /* { */
305
-/* 	prog_t *prog = _prog; */
305
+/* 	struct prog *prog = _prog; */
306 306
 
307 307
 /* 	node_print(n, stdout); putchar('\n');  */
308 308
 /* 	if (!n->type) { */
@@ -321,14 +321,14 @@ ctx_t *ctx_get(void)
321 321
 /* 	return validate_func(n->list); */
322 322
 /* } */
323 323
 
324
-/* int validate_syms(prog_t *prog) */
324
+/* int validate_syms(struct prog *prog) */
325 325
 /* { */
326 326
 /* 	return 0; */
327 327
 /* } */
328 328
 
329
-/* int run_validate_types(pass_t *pass, ctx_t *ctx) */
329
+/* int run_validate_types(struct pass *pass, struct ctx *ctx) */
330 330
 /* { */
331
-/* 	prog_t **prog; */
331
+/* 	struct prog **prog; */
332 332
 /* 	int err; */
333 333
 
334 334
 /* 	for (prog = ctx->progs; *prog; prog++) { */
@@ -377,7 +377,7 @@ ctx_t *ctx_get(void)
377 377
 
378 378
 /* int pass_rewrite_ast(node_t *n, void *_prog) */
379 379
 /* { */
380
-/* 	prog_t *prog = _prog; */
380
+/* 	struct prog *prog = _prog; */
381 381
 /* 	provider_t *global = provider_get(":"); */
382 382
 /* 	int err; */
383 383
 
@@ -404,7 +404,7 @@ ctx_t *ctx_get(void)
404 404
 /* 	return 0; */
405 405
 /* } */
406 406
 
407
-/* int generate_ir_ident(prog_t *prog, node_t *n) */
407
+/* int generate_ir_ident(struct prog *prog, node_t *n) */
408 408
 /* { */
409 409
 
410 410
 /* 	switch (n->sym->type->ttype) { */
@@ -422,7 +422,7 @@ ctx_t *ctx_get(void)
422 422
 
423 423
 /* int pass_generate_ir(node_t *n, void *_prog) */
424 424
 /* { */
425
-/* 	prog_t *prog = _prog; */
425
+/* 	struct prog *prog = _prog; */
426 426
 
427 427
 /* 	switch (n->ntype) { */
428 428
 /* 	case N_LIST: */
@@ -436,13 +436,13 @@ ctx_t *ctx_get(void)
436 436
 /* 	return 0; */
437 437
 /* } */
438 438
 
439
-/* int run_generate_ir(pass_t *pass, ctx_t *ctx) */
439
+/* int run_generate_ir(struct pass *pass, struct ctx *ctx) */
440 440
 /* { */
441
-/* 	prog_t **progp; */
441
+/* 	struct prog **progp; */
442 442
 /* 	int err; */
443 443
 
444 444
 /* 	for (progp = ctx->progs; *progp; progp++) { */
445
-/* 		prog_t *prog = *progp; */
445
+/* 		struct prog *prog = *progp; */
446 446
 
447 447
 /* 		int return_label = ir_alloc_label(prog->ir); */
448 448
 
@@ -467,9 +467,9 @@ ctx_t *ctx_get(void)
467 467
 /* 	return 0; */
468 468
 /* } */
469 469
 
470
-int run_walk(pass_t *pass, ctx_t *ctx)
470
+int run_walk(struct pass *pass, struct ctx *ctx)
471 471
 {
472
-	prog_t **prog;
472
+	struct prog **prog;
473 473
 	int err;
474 474
 
475 475
 	for (prog = ctx->progs; *prog; prog++) {
@@ -481,7 +481,7 @@ int run_walk(pass_t *pass, ctx_t *ctx)
481 481
 	return 0;
482 482
 }
483 483
 
484
-pass_t passes[] = {
484
+struct pass passes[] = {
485 485
 	/* { .run = run_walk, .post = pass_resolve_symbols }, */
486 486
 	/* { .run = run_walk, .post = pass_infer_types }, */
487 487
 	/* { .run = run_walk, .post = pass_infer_types }, */
@@ -495,9 +495,9 @@ pass_t passes[] = {
495 495
 
496 496
 int main(void)
497 497
 {
498
-	ctx_t *ctx = ctx_get();
499
-	prog_t **prog;
500
-	pass_t *pass;
498
+	struct ctx *ctx = ctx_get();
499
+	struct prog **prog;
500
+	struct pass *pass;
501 501
 	int err = 0;
502 502
 
503 503
 	for (pass = passes; pass->run; pass++) {

+ 20 - 27
ply.h

@@ -1,44 +1,37 @@
1 1
 #ifndef _PLY_H
2 2
 #define _PLY_H
3 3
 
4
-#include "node.h"
5
-#include "sym.h"
6
-#include "type.h"
7
-#include "arch.h"
8
-#include "ir.h"
9
-
10
-typedef struct prog prog_t;
11
-typedef struct provider provider_t;
4
+struct node;
12 5
 
13 6
 struct prog {
14 7
 	const char *probe;
15
-	node_t *ast;
8
+	struct node *ast;
16 9
 
17
-	symtab_t *locals;
18
-	symtab_t *globals;
10
+	/* symtab_t *locals; */
11
+	/* symtab_t *globals; */
19 12
 
20
-	provider_t *provider;
21
-	void *provider_data;
13
+	/* provider_t *provider; */
14
+	/* void *provider_data; */
22 15
 
23
-	ir_t *ir;
16
+	/* ir_t *ir; */
24 17
 };
25 18
 
26
-typedef struct ctx {
27
-	prog_t **progs;
19
+struct ctx {
20
+	struct prog **progs;
28 21
 
29
-	symtab_t *globals;
30
-} ctx_t;
22
+	/* symtab_t *globals; */
23
+};
31 24
 
32
-struct provider {
33
-	const char *name;
25
+/* struct provider { */
26
+/* 	const char *name; */
34 27
 
35
-	int (*probe)(prog_t *);
36
-	int (*resolve)(prog_t *, node_t *);
37
-	int (*rewrite_node)(prog_t *, node_t *);
38
-	int (*ir_prologue)(prog_t *);
39
-	int (*ir_epilogue)(prog_t *);
40
-};
28
+/* 	int (*probe)(prog_t *); */
29
+/* 	int (*resolve)(prog_t *, node_t *); */
30
+/* 	int (*rewrite_node)(prog_t *, node_t *); */
31
+/* 	int (*ir_prologue)(prog_t *); */
32
+/* 	int (*ir_epilogue)(prog_t *); */
33
+/* }; */
41 34
 
42
-void provider_register(provider_t *prov);
35
+/* void provider_register(provider_t *prov); */
43 36
 
44 37
 #endif	/* _PLY_H */

+ 383 - 175
type.c

@@ -1,64 +1,25 @@
1 1
 #include <assert.h>
2
+#include <errno.h>
2 3
 #include <stdio.h>
3 4
 #include <stdlib.h>
4 5
 #include <string.h>
5 6
 
6 7
 #include "type.h"
7 8
 
8
-#define builtin_scalar(_t) {				\
9
-		.ttype = T_SCALAR,			\
10
-		.size = sizeof(_t),			\
11
-		.t = { .scalar = { .name = #_t } },	\
12
-	}
13
-
14
-type_t t_void = builtin_scalar(void);
15
-
16
-type_t t_char  = builtin_scalar(char);
17
-type_t t_uchar = builtin_scalar(unsigned char);
18
-
19
-type_t t_short  = builtin_scalar(short);
20
-type_t t_ushort = builtin_scalar(unsigned short);
21
-
22
-type_t t_int  = builtin_scalar(int);
23
-type_t t_uint = builtin_scalar(unsigned int);
24
-
25
-type_t t_long  = builtin_scalar(long);
26
-type_t t_ulong = builtin_scalar(unsigned long);
27
-
28
-type_t t_llong  = builtin_scalar(long long);
29
-type_t t_ullong = builtin_scalar(unsigned long long);
30
-
31
-type_t *builtin_types[] = {
32
-	&t_void,
33
-	&t_char,  &t_uchar,
34
-	&t_short, &t_ushort,
35
-	&t_int,   &t_uint,
36
-	&t_long,  &t_ulong,
37
-	&t_llong, &t_ullong,
38
-
39
-	NULL
40
-};
41
-
42
-struct type_list {
43
-	type_t **type;
44
-	size_t len;
45
-} types;
46
-
47
-
48
-void type_dump_func(type_t *t, FILE *fp)
9
+void type_dump_func(struct type *t, FILE *fp)
49 10
 {
50
-	field_t *arg;
11
+	struct tfield *arg;
51 12
 
52
-	type_dump(t->t.func.type, fp);
53
-	fprintf(fp, " (*%s)(", t->t.func.name ? : "");
13
+	type_dump(t->func.type, fp);
14
+	fputs(" (*)(", fp);
54 15
 
55
-	if (!t->t.func.args) {
16
+	if (!t->func.args) {
56 17
 		fputs("void)", fp);
57 18
 		return;
58 19
 	}
59 20
 
60
-	for (arg = t->t.func.args; arg->type; arg++) {
61
-		if (arg != t->t.func.args)
21
+	for (arg = t->func.args; arg->type != T_VOID; arg++) {
22
+		if (arg != t->func.args)
62 23
 			fputs(", ", fp);
63 24
 
64 25
 		type_dump(arg->type, fp);
@@ -67,7 +28,7 @@ void type_dump_func(type_t *t, FILE *fp)
67 28
 	fputc(')', fp);
68 29
 }
69 30
 
70
-void type_dump(type_t *t, FILE *fp)
31
+void type_dump(struct type *t, FILE *fp)
71 32
 {
72 33
 	if (!t) {
73 34
 		fputs("<NONE>", fp);
@@ -75,47 +36,50 @@ void type_dump(type_t *t, FILE *fp)
75 36
 	}
76 37
 
77 38
 	switch (t->ttype){
39
+	case T_VOID:
40
+		fputs("void", fp);
41
+		break;
78 42
 	case T_TYPEDEF:
79
-		fputs(t->t.tdef.name, fp);
43
+		fputs(t->tdef.name, fp);
80 44
 		break;
81 45
 	case T_SCALAR:
82
-		fputs(t->t.scalar.name, fp);
46
+		fputs(t->scalar.name, fp);
83 47
 		break;
84 48
 	case T_POINTER:
85
-		type_dump(t->t.pointer.type, fp);
49
+		type_dump(t->ptr.type, fp);
86 50
 		fputs(" *", fp);
87 51
 		break;
88 52
 	case T_ARRAY:
89
-		type_dump(t->t.array.type, fp);
90
-		fprintf(fp, "[%zu]", t->t.array.len);
53
+		type_dump(t->array.type, fp);
54
+		fprintf(fp, "[%zu]", t->array.len);
91 55
 		break;
92 56
 	case T_STRUCT:
93 57
 		fputs("struct ", fp);
94
-		fputs(t->t.sou.name, fp);
58
+		fputs(t->sou.name, fp);
95 59
 		break;
96 60
 	case T_UNION:
97 61
 		fputs("union ", fp);
98
-		fputs(t->t.sou.name, fp);
62
+		fputs(t->sou.name, fp);
99 63
 		break;
100 64
 	case T_FUNC:
101 65
 		type_dump_func(t, fp);
102 66
 		break;
103 67
 	case T_MAP:
104 68
 		fputs("map [", fp);
105
-		type_dump(t->t.map.ktype, fp);
69
+		type_dump(t->map.ktype, fp);
106 70
 		fputs("] ", fp);
107
-		type_dump(t->t.map.vtype, fp);
71
+		type_dump(t->map.vtype, fp);
108 72
 		break;
109 73
 	}
110 74
 }
111 75
 
112
-void type_dump_cdecl_sou(type_t *t, FILE *fp)
76
+void type_dump_cdecl_sou(struct type *t, FILE *fp)
113 77
 {
114
-	field_t *f;
78
+	struct tfield *f;
115 79
 
116 80
 	type_dump(t, fp);
117 81
 	fputs(" {\n", fp);
118
-	for (f = t->t.sou.fields; f->type; f++) {
82
+	for (f = t->sou.fields; f->type; f++) {
119 83
 		fputc('\t', fp);
120 84
 		type_dump(f->type, fp);
121 85
 		fprintf(fp, " %s;\n", f->name);
@@ -123,13 +87,13 @@ void type_dump_cdecl_sou(type_t *t, FILE *fp)
123 87
 	fputs("}", fp);
124 88
 }
125 89
 
126
-void type_dump_cdecl(type_t *t, FILE *fp)
90
+void type_dump_cdecl(struct type *t, FILE *fp)
127 91
 {
128 92
 	switch (t->ttype) {
129 93
 	case T_TYPEDEF:
130 94
 		fputs("typedef ", fp);
131
-		type_dump(t->t.tdef.type, fp);
132
-		fprintf(fp, " %s", t->t.tdef.name);
95
+		type_dump(t->tdef.type, fp);
96
+		fprintf(fp, " %s", t->tdef.name);
133 97
 		break;
134 98
 
135 99
 	case T_STRUCT:
@@ -137,6 +101,7 @@ void type_dump_cdecl(type_t *t, FILE *fp)
137 101
 		type_dump_cdecl_sou(t, fp);
138 102
 		break;
139 103
 
104
+	case T_VOID:
140 105
 	case T_SCALAR:
141 106
 	case T_POINTER:
142 107
 	case T_ARRAY:
@@ -147,73 +112,74 @@ void type_dump_cdecl(type_t *t, FILE *fp)
147 112
 	}
148 113
 }
149 114
 
150
-void types_dump_cdecl(FILE *fp)
151
-{
152
-	size_t i;
153
-
154
-	for (i = 0; i < types.len; i++) {
155
-		type_t *t = types.type[i];
156
-
157
-		type_dump_cdecl(t, stdout);
158
-		printf(" <sz:0x%zx>\n", t->size);
159
-	}
160
-}
161
-
162
-type_t *type_map_of(type_t *ktype, type_t *vtype)
163
-{
164
-	type_t *t;
165
-	size_t i;
166
-
167
-	for (i = 0; i < types.len; i++) {
168
-		t = types.type[i];
169
-		if ((t->ttype == T_MAP)
170
-		    && (t->t.map.ktype == ktype)
171
-		    && (t->t.map.vtype == vtype))
172
-			return t;
173
-	}
174
-
175
-	t = calloc(1, sizeof(*t));
176
-	t->ttype = T_MAP;
177
-	t->t.map.vtype = vtype;
178
-	t->t.map.ktype = ktype;
179
-	type_add(t);
180
-	return t;
181
-}
182
-
183
-type_t *type_ptr_of(type_t *type)
184
-{
185
-	type_t *t;
186
-	size_t i;
187
-
188
-	for (i = 0; i < types.len; i++) {
189
-		t = types.type[i];
190
-		if ((t->ttype == T_POINTER)
191
-		    && (t->t.pointer.type == type))
192
-			return t;
193
-	}
194
-
195
-	t = calloc(1, sizeof(*t));
196
-	t->ttype = T_POINTER;
197
-	t->t.pointer.type = type;
198
-	type_add(t);
199
-	return t;
200
-}
201
-
202
-type_t *type_normalize(type_t *t)
115
+/* void types_dump_cdecl(FILE *fp) */
116
+/* { */
117
+/* 	size_t i; */
118
+
119
+/* 	for (i = 0; i < types.len; i++) { */
120
+/* 		struct type *t = types.type[i]; */
121
+
122
+/* 		type_dump_cdecl(t, stdout); */
123
+/* 		printf(" <sz:0x%zx>\n", t->size); */
124
+/* 	} */
125
+/* } */
126
+
127
+/* struct type *type_map_of(struct type *ktype, struct type *vtype) */
128
+/* { */
129
+/* 	struct type *t; */
130
+/* 	size_t i; */
131
+
132
+/* 	for (i = 0; i < types.len; i++) { */
133
+/* 		t = types.type[i]; */
134
+/* 		if ((t->ttype == T_MAP) */
135
+/* 		    && (t->map.ktype == ktype) */
136
+/* 		    && (t->map.vtype == vtype)) */
137
+/* 			return t; */
138
+/* 	} */
139
+
140
+/* 	t = calloc(1, sizeof(*t)); */
141
+/* 	t->ttype = T_MAP; */
142
+/* 	t->map.vtype = vtype; */
143
+/* 	t->map.ktype = ktype; */
144
+/* 	type_add(t); */
145
+/* 	return t; */
146
+/* } */
147
+
148
+/* struct type *type_ptr_of(struct type *type) */
149
+/* { */
150
+/* 	struct type *t; */
151
+/* 	size_t i; */
152
+
153
+/* 	for (i = 0; i < types.len; i++) { */
154
+/* 		t = types.type[i]; */
155
+/* 		if ((t->ttype == T_POINTER) */
156
+/* 		    && (t->pointer.type == type)) */
157
+/* 			return t; */
158
+/* 	} */
159
+
160
+/* 	t = calloc(1, sizeof(*t)); */
161
+/* 	t->ttype = T_POINTER; */
162
+/* 	t->pointer.type = type; */
163
+/* 	type_add(t); */
164
+/* 	return t; */
165
+/* } */
166
+
167
+
168
+struct type *type_normalize(struct type *t)
203 169
 {
204 170
 	while (t->ttype == T_TYPEDEF)
205
-		t = t->t.tdef.type;
171
+		t = t->tdef.type;
206 172
 
207 173
 	return t;
208 174
 }
209 175
 
210
-int type_equal(type_t *a, type_t *b)
176
+int type_equal(struct type *a, struct type *b)
211 177
 {
212 178
 	/* TODO */
213 179
 	return a == b;
214 180
 }
215 181
 
216
-int type_compatible(type_t *a, type_t *b)
182
+int type_compatible(struct type *a, struct type *b)
217 183
 {
218 184
 
219 185
 	a = type_normalize(a);
@@ -223,22 +189,22 @@ int type_compatible(type_t *a, type_t *b)
223 189
 		return 0;
224 190
 
225 191
 	switch (a->ttype){
192
+	case T_VOID:
226 193
 	case T_SCALAR:
227
-		return 1;
228 194
 	case T_POINTER:
229 195
 		return 1;
230 196
 	case T_ARRAY:
231
-		if (a->t.array.len != b->t.array.len)
197
+		if (a->array.len != b->array.len)
232 198
 			return 0;
233 199
 
234
-		return type_compatible(a->t.array.type, b->t.array.type);
200
+		return type_compatible(a->array.type, b->array.type);
235 201
 	case T_STRUCT:
236 202
 	case T_UNION:
237
-		return !strcmp(a->t.sou.name, b->t.sou.name);
203
+		return !strcmp(a->sou.name, b->sou.name);
238 204
 	case T_FUNC:
239
-		return type_compatible(a->t.func.type, b->t.func.type);
205
+		return type_compatible(a->func.type, b->func.type);
240 206
 	case T_MAP:
241
-		return type_compatible(a->t.map.vtype, b->t.map.vtype);
207
+		return type_compatible(a->map.vtype, b->map.vtype);
242 208
 
243 209
 	case T_TYPEDEF:
244 210
 		assert(0);
@@ -248,91 +214,281 @@ int type_compatible(type_t *a, type_t *b)
248 214
 	return 0;
249 215
 }
250 216
 
251
-void type_size_set_sou(type_t *t)
217
+/* void type_size_set_sou(struct type *t) */
218
+/* { */
219
+/* 	struct tfield *f; */
220
+/* 	size_t size = 0; */
221
+
222
+/* 	if (!t->sou.fields) */
223
+/* 		return; */
224
+
225
+/* 	for (f = t->sou.fields; f->name; f++) { */
226
+/* 		/\* size of all members is now known yet, abort *\/ */
227
+/* 		if (!f->type->size) */
228
+/* 			return; */
229
+
230
+/* 		if (!t->sou.packed) */
231
+/* 			size += size % f->type->size; */
232
+
233
+/* 		size += f->type->size; */
234
+/* 		f->offset = size; */
235
+/* 	} */
236
+
237
+/* 	if (!t->sou.packed && size) { */
238
+/* 		/\* align complete struct to requirements of first */
239
+/* 		 * member, if struct keep going downwards *\/ */
240
+/* 		f = t->sou.fields; */
241
+/* 		while (f->type->ttype == T_STRUCT) */
242
+/* 			f = f->type->sou.fields; */
243
+
244
+/* 		size += size % f->type->size; */
245
+/* 	} */
246
+
247
+/* 	t->size = size; */
248
+/* } */
249
+
250
+/* void type_size_set(struct type *t) */
251
+/* { */
252
+/* 	switch (t->ttype) { */
253
+/* 	case T_TYPEDEF: */
254
+/* 		t->size = t->tdef.type->size; */
255
+/* 		break; */
256
+/* 	case T_STRUCT: */
257
+/* 	case T_UNION: */
258
+/* 		type_size_set_sou(t); */
259
+/* 		break; */
260
+/* 	case T_FUNC: */
261
+/* 		t->size = t->func.type->size; */
262
+/* 		assert(t->func.generate_ir); */
263
+/* 		break; */
264
+/* 	case T_SCALAR: */
265
+/* 		break; */
266
+/* 	case T_POINTER: */
267
+/* 		t->size = sizeof(void *); */
268
+/* 		break; */
269
+/* 	case T_ARRAY: */
270
+/* 		t->size = t->array.len * t->array.type->size; */
271
+/* 		break; */
272
+/* 	case T_MAP: */
273
+/* 		/\* map fds are s64:s *\/ */
274
+/* 		t->size = 8; */
275
+/* 		break; */
276
+/* 	} */
277
+/* } */
278
+
279
+static ssize_t type_alignof_union(struct type *t)
280
+{
281
+	ssize_t amax = -EINVAL;
282
+	struct tfield *f;
283
+
284
+	for (f = t->sou.fields; f->type != T_VOID; f++) {
285
+		ssize_t a;
286
+
287
+		a = type_alignof(f->type);
288
+		if (a < 0)
289
+			return a;
290
+
291
+		if (a > amax)
292
+			amax = a;
293
+	}
294
+
295
+	return amax;
296
+}
297
+
298
+ssize_t type_alignof(struct type *t)
299
+{
300
+	switch (t->ttype){
301
+	case T_VOID:
302
+	case T_SCALAR:
303
+	case T_POINTER:
304
+	case T_FUNC:
305
+	case T_MAP:
306
+		return type_sizeof(t);
307
+	case T_TYPEDEF:
308
+		return type_alignof(t->tdef.type);
309
+	case T_ARRAY:
310
+		return type_alignof(t->array.type);
311
+	case T_STRUCT:
312
+		if (!t->sou.fields)
313
+			return type_alignof(&t_void);
314
+		return type_alignof(t->sou.fields->type);
315
+	case T_UNION:
316
+		if (!t->sou.fields)
317
+			return type_alignof(&t_void);
318
+		return type_alignof_union(t);
319
+	}
320
+
321
+	return -EINVAL;
322
+}
323
+
324
+static ssize_t type_sizeof_struct(struct type *t)
252 325
 {
253
-	field_t *f;
326
+	struct tfield *f;
254 327
 	size_t size = 0;
328
+	ssize_t fsize;
255 329
 
256
-	if (!t->t.sou.fields)
257
-		return;
330
+	if (!t->sou.fields)
331
+		return 0;
258 332
 
259
-	for (f = t->t.sou.fields; f->name; f++) {
333
+	for (f = t->sou.fields; f->name; f++) {
260 334
 		/* size of all members is now known yet, abort */
261
-		if (!f->type->size)
262
-			return;
335
+		fsize = type_sizeof(f->type);
336
+		if (fsize < 0)
337
+			return fsize;
263 338
 
264
-		if (!t->t.sou.packed)
265
-			size += size % f->type->size;
339
+		size += fsize;
266 340
 
267
-		size += f->type->size;
268
-		f->offset = size;
341
+		if (!t->sou.packed)
342
+			size += size % type_alignof(f->type);
269 343
 	}
270 344
 
271
-	if (!t->t.sou.packed && size) {
272
-		/* align complete struct to requirements of first
273
-		 * member, if struct keep going downwards */
274
-		f = t->t.sou.fields;
275
-		while (f->type->ttype == T_STRUCT)
276
-			f = f->type->t.sou.fields;
345
+	if (!t->sou.packed && size)
346
+		size += size % type_alignof(t);
347
+
348
+	return size;
349
+}
350
+
351
+static ssize_t type_sizeof_union(struct type *t)
352
+{
353
+	struct tfield *f;
354
+	ssize_t size = 0;
355
+
356
+	if (!t->sou.fields)
357
+		return 0;
358
+
359
+	for (f = t->sou.fields; f->name; f++) {
360
+		ssize_t z, a;
361
+
362
+		z = type_sizeof(f->type);
363
+		a = t->sou.packed ? type_alignof(f->type) : 0;
364
+		if ((z < 0) || (a < 0))
365
+			return -EINVAL;
277 366
 
278
-		size += size % f->type->size;
367
+		z += z % a;
368
+		if (z > size)
369
+			size = z;
279 370
 	}
280 371
 
281
-	t->size = size;
372
+	return size;
282 373
 }
283 374
 
284
-void type_size_set(type_t *t)
375
+ssize_t type_sizeof(struct type *t)
285 376
 {
286
-	switch (t->ttype) {
287
-	case T_TYPEDEF:
288
-		t->size = t->t.tdef.type->size;
289
-		break;
290
-	case T_STRUCT:
291
-	case T_UNION:
292
-		type_size_set_sou(t);
293
-		break;
294
-	case T_FUNC:
295
-		t->size = t->t.func.type->size;
296
-		assert(t->t.func.generate_ir);
297
-		break;
377
+	switch (t->ttype){
378
+	case T_VOID:
379
+		return sizeof(void);
298 380
 	case T_SCALAR:
299
-		break;
381
+		return t->scalar.size;
382
+	case T_TYPEDEF:
383
+		return type_sizeof(t->tdef.type);
300 384
 	case T_POINTER:
301
-		t->size = sizeof(void *);
302
-		break;
385
+	case T_FUNC:
386
+		return sizeof(void *);
303 387
 	case T_ARRAY:
304
-		t->size = t->t.array.len * t->t.array.type->size;
305
-		break;
388
+		return t->array.len * type_sizeof(t->array.type);
389
+	case T_STRUCT:
390
+		return type_sizeof_struct(t);
391
+	case T_UNION:
392
+		return type_sizeof_union(t);
306 393
 	case T_MAP:
307
-		/* map fds are s64:s */
308
-		t->size = 8;
309
-		break;
394
+		return sizeof(int);
310 395
 	}
396
+
397
+	return -EINVAL;
311 398
 }
312 399
 
313
-int type_cmp(const void *_a, const void *_b)
400
+/* int type_walk_fields(struct tfield *f, twalk_fn pre, twalk_fn post, void *ctx) */
401
+/* { */
402
+/* 	if (!f) */
403
+/* 		return 0; */
404
+
405
+/* 	while (f->type != T_VOID) { */
406
+/* 		if (pre && (err = pre(f->type, ctx))) */
407
+/* 			return err; */
408
+
409
+/* 		err = type_walk(f->type, pre, post, ctx); */
410
+/* 		if (err) */
411
+/* 			return err; */
412
+
413
+/* 		if (post && (err = post(f->type, ctx))) */
414
+/* 			return err; */
415
+/* 	} */
416
+/* } */
417
+
418
+/* int type_walk(struct type *t, twalk_fn pre, twalk_fn post, void *ctx) */
419
+/* { */
420
+/* 	int err; */
421
+
422
+/* 	if (pre && (err = pre(t, ctx))) */
423
+/* 		return err; */
424
+		
425
+/* 	switch (t->ttype){ */
426
+/* 	case T_VOID: */
427
+/* 	case T_SCALAR: */
428
+/* 		break; */
429
+/* 	case T_TYPEDEF: */
430
+/* 		err = type_walk(t->tdef.type, pre, post, ctx); */
431
+/* 		break; */
432
+/* 	case T_POINTER: */
433
+/* 		err = type_walk(t->ptr.type, pre, post, ctx); */
434
+/* 		break; */
435
+/* 	case T_ARRAY: */
436
+/* 		err = type_walk(t->array.type, pre, post, ctx); */
437
+/* 		break; */
438
+/* 	case T_STRUCT: */
439
+/* 	case T_UNION: */
440
+/* 		err = type_walk_fields(t->sou.fields, pre, post, ctx); */
441
+/* 		break; */
442
+/* 	case T_FUNC: */
443
+/* 		err = type_walk_fields(t->func.args, pre, post, ctx); */
444
+/* 		break; */
445
+/* 	case T_MAP: */
446
+/* 		err = type_walk(t->map.ktype, pre, post, ctx); */
447
+/* 		if (err) */
448
+/* 			break; */
449
+
450
+/* 		err = type_walk(t->map.vtype, pre, post, ctx); */
451
+/* 		break; */
452
+/* 	} */
453
+
454
+/* 	if (err) */
455
+/* 		return err; */
456
+	
457
+/* 	if (post && (err = post(t, ctx))) */
458
+/* 		return err; */
459
+/* } */
460
+
461
+
462
+int all_types_cmp(const void *_a, const void *_b)
314 463
 {
315
-	const type_t *a = *((type_t **)_a);
316
-	const type_t *b = *((type_t **)_b);
464
+	const struct type *a = *((struct type **)_a);
465
+	const struct type *b = *((struct type **)_b);
317 466
 
318 467
 	return a - b;
319 468
 }
320 469
 
321
-int type_add(type_t *t)
470
+struct type_list {
471
+	struct type **types;
472
+	size_t len;
473
+} all_types;
474
+
475
+int type_add(struct type *t)
322 476
 {
323
-	if (bsearch(t, types.type, types.len, sizeof(*types.type), type_cmp))
477
+	if (bsearch(t, all_types.types, all_types.len,
478
+		    sizeof(*all_types.types), all_types_cmp))
324 479
 		return 0;
325 480
 
326
-	type_size_set(t);
481
+	/* type_size_set(t); */
327 482
 
328
-	types.type = realloc(types.type, ++types.len * sizeof(*types.type));
329
-	types.type[types.len - 1] = t;
330
-	qsort(types.type, types.len, sizeof(*types.type), type_cmp);
483
+	all_types.types = realloc(all_types.types,
484
+				  ++all_types.len * sizeof(*all_types.types));
485
+	all_types.types[all_types.len - 1] = t;
486
+	qsort(all_types.types, all_types.len, sizeof(*all_types.types), all_types_cmp);
331 487
 
332 488
 	return 0;
333 489
 }
334 490
 
335
-int type_add_list(type_t **ts)
491
+int type_add_list(struct type **ts)
336 492
 {
337 493
 	int err;
338 494
 
@@ -345,6 +501,58 @@ int type_add_list(type_t **ts)
345 501
 	return 0;
346 502
 }
347 503
 
504
+#define is_signed(_t) (((_t)(-1)) < 0)
505
+
506
+#define builtin_scalar(_t) {				\
507
+		.ttype = T_SCALAR,			\
508
+		.scalar = {				\
509
+			.name = #_t,			\
510
+			.size = sizeof(_t),		\
511
+			.is_signed = is_signed(_t),	\
512
+		},					\
513
+	}
514
+
515
+struct type t_void = { .ttype = T_VOID };
516
+
517
+#pragma GCC diagnostic ignored "-Wtype-limits"
518
+/* is_signed will generate a warning for unsigned types since the
519
+ * expression can never be true. this is exactly what we're interested
520
+ * in here though. it gets us out of having to specify scalar
521
+ * signedness per architecture. */
522
+
523
+struct type t_char  = builtin_scalar(char);
524
+struct type t_schar = builtin_scalar(signed char);
525
+struct type t_uchar = builtin_scalar(unsigned char);
526
+
527
+struct type t_short  = builtin_scalar(short);
528
+struct type t_sshort = builtin_scalar(signed short);
529
+struct type t_ushort = builtin_scalar(unsigned short);
530
+
531
+struct type t_int  = builtin_scalar(int);
532
+struct type t_sint = builtin_scalar(signed int);
533
+struct type t_uint = builtin_scalar(unsigned int);
534
+
535
+struct type t_long  = builtin_scalar(long);
536
+struct type t_slong = builtin_scalar(signed long);
537
+struct type t_ulong = builtin_scalar(unsigned long);
538
+
539
+struct type t_llong  = builtin_scalar(long long);
540
+struct type t_sllong = builtin_scalar(signed long long);
541
+struct type t_ullong = builtin_scalar(unsigned long long);
542
+
543
+#pragma GCC diagnostic pop
544
+
545
+struct type *builtin_types[] = {
546
+	&t_void,
547
+	&t_char,  &t_schar,  &t_uchar,
548
+	&t_short, &t_sshort, &t_ushort,
549
+	&t_int,   &t_sint,   &t_uint,
550
+	&t_long,  &t_slong,  &t_ulong,
551
+	&t_llong, &t_sllong, &t_ullong,
552
+
553
+	NULL
554
+};
555
+
348 556
 __attribute__((constructor))
349 557
 static void type_init(void)
350 558
 {

+ 70 - 61
type.h

@@ -4,61 +4,54 @@
4 4
 #include <stddef.h>
5 5
 #include <stdio.h>
6 6
 
7
-typedef struct prog prog_t;
8
-typedef struct node node_t;
9
-
10
-typedef struct type type_t;
11
-
12
-struct t_tdef {
7
+struct ttdef {
13 8
 	char *name;
14
-	type_t *type;
9
+	struct type *type;
15 10
 };
16 11
 
17
-struct t_scalar {
12
+struct tscalar {
13
+	size_t size;
14
+	int is_signed:1;
18 15
 	char *name;
19 16
 };
20 17
 
21
-struct t_pointer {
22
-	type_t *type;
18
+struct tptr {
19
+	struct type *type;
23 20
 };
24 21
 
25
-struct t_array {
26
-	type_t *type;
22
+struct tarray {
23
+	struct type *type;
27 24
 	size_t len;
28 25
 };
29 26
 
30
-struct t_map {
31
-	type_t *vtype;
32
-	type_t *ktype;
27
+struct tmap {
28
+	struct type *vtype;
29
+	struct type *ktype;
33 30
 	size_t len;
34 31
 };
35 32
 
36
-typedef struct field {
33
+struct tfield {
37 34
 	char *name;
38
-	type_t *type;
39
-	size_t offset;
35
+	struct type *type;
40 36
 
41 37
 	/* function arguments */
42 38
 	int optional:1;
43
-} field_t;
39
+};
44 40
 
45
-struct t_sou {
41
+struct tstruct {
46 42
 	char *name;
47 43
 
48 44
 	int packed:1;
49
-	field_t *fields;
45
+	struct tfield *fields;
50 46
 };
51 47
 
52
-struct t_func {
53
-	char *name;
54
-	type_t *type;
55
-
56
-	field_t *args;
57
-
58
-	int (*generate_ir)(prog_t *prog, node_t *n);
48
+struct tfunc {
49
+	struct type *type;
50
+	struct tfield *args;
59 51
 };
60 52
 
61
-typedef enum ttype {
53
+enum ttype {
54
+	T_VOID,
62 55
 	T_TYPEDEF,
63 56
 	T_SCALAR,
64 57
 	T_POINTER,
@@ -67,47 +60,63 @@ typedef enum ttype {
67 60
 	T_STRUCT,
68 61
 	T_UNION,
69 62
 	T_FUNC,
70
-} ttype_t;
63
+};
71 64
 
72 65
 struct type {
73
-	size_t size;
74
-
75
-	ttype_t ttype;
66
+	enum ttype ttype;
76 67
 	union {
77
-		struct t_tdef tdef;
78
-		struct t_scalar scalar;
79
-		struct t_pointer pointer;
80
-		struct t_array array;
81
-		struct t_map map;
82
-		struct t_sou sou;
83
-		struct t_func func;
84
-	} t;
68
+		struct ttdef tdef;
69
+		struct tscalar scalar;
70
+		struct tptr ptr;
71
+		struct tarray array;
72
+		struct tmap map;
73
+		struct tstruct sou;
74
+		struct tfunc func;
75
+	};
85 76
 };
86 77
 
87
-extern type_t t_void;
78
+/* struct type *type_map_of(struct type *ktype, struct type *vtype); */
79
+/* struct type *type_ptr_of(struct type *type); */
80
+
81
+int type_equal     (struct type *a, struct type *b);
82
+int type_compatible(struct type *a, struct type *b);
83
+
84
+void type_dump      (struct type *t, FILE *fp);
85
+void type_dump_cdecl(struct type *t, FILE *fp);
86
+
87
+ssize_t type_alignof(struct type *t);
88
+ssize_t type_sizeof(struct type *t);
89
+
90
+/* typedef int (*twalk_fn)(struct type *, void *); */
91
+/* int type_walk(struct type *t, twalk_fn pre, twalk_fn post, void *ctx); */
92
+
93
+
94
+int type_add(struct type *t);
95
+int type_add_list(struct type **ts);
96
+
97
+
98
+/* built-in types */
99
+
100
+extern struct type t_void;
88 101
 
89
-extern type_t t_char;
90
-extern type_t t_uchar;
91
-extern type_t t_short;
92
-extern type_t t_ushort;
93
-extern type_t t_int;
94
-extern type_t t_uint;
95
-extern type_t t_long;
96
-extern type_t t_ulong;
97
-extern type_t t_llong;
98
-extern type_t t_ullong;
102
+extern struct type t_char;
103
+extern struct type t_schar;
104
+extern struct type t_uchar;
99 105
 
100
-type_t *type_map_of(type_t *ktype, type_t *vtype);
101
-type_t *type_ptr_of(type_t *type);
106
+extern struct type t_short;
107
+extern struct type t_sshort;
108
+extern struct type t_ushort;
102 109
 
103
-int type_equal     (type_t *a, type_t *b);
104
-int type_compatible(type_t *a, type_t *b);
110
+extern struct type t_int;
111
+extern struct type t_sint;
112
+extern struct type t_uint;
105 113
 
106
-int type_add(type_t *t);
107
-int type_add_list(type_t **ts);
114
+extern struct type t_long;
115
+extern struct type t_slong;
116
+extern struct type t_ulong;
108 117
 
109
-void type_dump      (type_t *t, FILE *fp);
110
-void type_dump_cdecl(type_t *t, FILE *fp);
111
-void types_dump_cdecl(FILE *fp);
118
+extern struct type t_llong;
119
+extern struct type t_sllong;
120
+extern struct type t_ullong;
112 121
 
113 122
 #endif	/* _PLY_TYPE_H */

+ 23 - 0
type_test.c

@@ -0,0 +1,23 @@
1
+#include <assert.h>
2
+
3
+#include "type.h"
4
+
5
+typedef void (*unittest_fn)(void)
6
+#define unittest __attribute__((section("unittest"))) static void
7
+
8
+unittest test_sizeof_builtins(void)
9
+{
10
+	assert(type_sizeof(&t_void) == sizeof(int));
11
+}
12
+
13
+int main(void)
14
+{
15
+	unittest_fn test_fn;
16
+	int err;
17
+
18
+	for (test_fn = &__start_unittest; test_fn < &__stop_unittest; testfn++) {
19
+		test_fn();
20
+	}
21
+
22
+	return 0;
23
+}