2 * neatcc - a small and simple C compiler
4 * Copyright (C) 2010-2011 Ali Gholami Rudi
6 * This program is released under GNU GPL version 2.
14 #include <sys/types.h>
19 static int nogen
; /* don't generate code */
21 #define o_bop(op) {if (!nogen) o_bop(op);}
22 #define o_uop(op) {if (!nogen) o_uop(op);}
23 #define o_cast(bt) {if (!nogen) o_cast(bt);}
24 #define o_memcpy() {if (!nogen) o_memcpy();}
25 #define o_memset() {if (!nogen) o_memset();}
26 #define o_call(argc, ret) {if (!nogen) o_call(argc, ret);}
27 #define o_ret(ret) {if (!nogen) o_ret(ret);}
28 #define o_assign(bt) {if (!nogen) o_assign(bt);}
29 #define o_deref(bt) {if (!nogen) o_deref(bt);}
30 #define o_load() {if (!nogen) o_load();}
31 #define o_popnum(c) (nogen ? 0 : o_popnum(c))
32 #define o_num(n) {if (!nogen) o_num(n);}
33 #define o_local(addr) {if (!nogen) o_local(addr);}
34 #define o_sym(sym) {if (!nogen) o_sym(sym);}
35 #define o_tmpdrop(n) {if (!nogen) o_tmpdrop(n);}
36 #define o_tmpswap() {if (!nogen) o_tmpswap();}
37 #define o_tmpcopy() {if (!nogen) o_tmpcopy();}
38 #define o_mklabel() (nogen ? 0 : o_mklabel())
39 #define o_jz(addr) (nogen ? 0 : o_jz(addr))
40 #define o_jnz(addr) (nogen ? 0 : o_jnz(addr))
41 #define o_jmp(addr) (nogen ? 0 : o_jmp(addr))
42 #define o_filljmp(addr) {if (!nogen) o_filljmp(addr);}
43 #define o_filljmp2(addr, dst) {if (!nogen) o_filljmp2(addr, dst);}
44 #define o_fork() {if (!nogen) o_fork();}
45 #define o_forkpush() {if (!nogen) o_forkpush();}
46 #define o_forkjoin() {if (!nogen) o_forkjoin();}
48 #define MAXLOCALS (1 << 10)
49 #define MAXGLOBALS (1 << 10)
50 #define MAXARGS (1 << 5)
52 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
53 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
67 int id
; /* for structs, functions and arrays */
68 int addr
; /* the address is passed to gen.c; deref for value */
72 static struct type ts
[MAXTMP
];
75 static void ts_push_bt(unsigned bt
)
83 static void ts_push(struct type
*t
)
85 struct type
*d
= &ts
[nts
++];
86 memcpy(d
, t
, sizeof(*t
));
89 static void ts_push_addr(struct type
*t
)
95 static void ts_pop(struct type
*type
)
104 die("%s: %s", cpp_loc(tok_addr()), msg
);
109 char elfname
[NAMELEN
]; /* local elf name for static variables in function */
111 long addr
; /* local stack offset, global data addr, struct offset */
114 static struct name locals
[MAXLOCALS
];
116 static struct name globals
[MAXGLOBALS
];
119 static void local_add(struct name
*name
)
121 if (nlocals
>= MAXLOCALS
)
122 err("nomem: MAXLOCALS reached!\n");
123 memcpy(&locals
[nlocals
++], name
, sizeof(*name
));
126 static int local_find(char *name
)
129 for (i
= nlocals
- 1; i
>= 0; --i
)
130 if (!strcmp(locals
[i
].name
, name
))
135 static int global_find(char *name
)
138 for (i
= nglobals
- 1; i
>= 0; i
--)
139 if (!strcmp(name
, globals
[i
].name
))
144 static void global_add(struct name
*name
)
146 if (nglobals
>= MAXGLOBALS
)
147 err("nomem: MAXGLOBALS reached!\n");
148 memcpy(&globals
[nglobals
++], name
, sizeof(*name
));
151 #define MAXENUMS (1 << 10)
153 static struct enumval
{
159 static void enum_add(char *name
, int val
)
161 struct enumval
*ev
= &enums
[nenums
++];
162 if (nenums
>= MAXENUMS
)
163 err("nomem: MAXENUMS reached!\n");
164 strcpy(ev
->name
, name
);
168 static int enum_find(int *val
, char *name
)
171 for (i
= nenums
- 1; i
>= 0; --i
)
172 if (!strcmp(name
, enums
[i
].name
)) {
179 #define MAXTYPEDEFS (1 << 10)
181 static struct typdefinfo
{
184 } typedefs
[MAXTYPEDEFS
];
185 static int ntypedefs
;
187 static void typedef_add(char *name
, struct type
*type
)
189 struct typdefinfo
*ti
= &typedefs
[ntypedefs
++];
190 if (ntypedefs
>= MAXTYPEDEFS
)
191 err("nomem: MAXTYPEDEFS reached!\n");
192 strcpy(ti
->name
, name
);
193 memcpy(&ti
->type
, type
, sizeof(*type
));
196 static int typedef_find(char *name
)
199 for (i
= ntypedefs
- 1; i
>= 0; --i
)
200 if (!strcmp(name
, typedefs
[i
].name
))
205 #define MAXARRAYS (1 << 10)
207 static struct array
{
213 static int array_add(struct type
*type
, int n
)
215 struct array
*a
= &arrays
[narrays
++];
216 if (narrays
>= MAXARRAYS
)
217 err("nomem: MAXARRAYS reached!\n");
218 memcpy(&a
->type
, type
, sizeof(*type
));
223 static void array2ptr(struct type
*t
)
225 if (t
->flags
& T_ARRAY
&& !t
->ptr
) {
226 memcpy(t
, &arrays
[t
->id
].type
, sizeof(*t
));
231 #define MAXSTRUCTS (1 << 10)
232 #define MAXFIELDS (1 << 7)
234 static struct structinfo
{
236 struct name fields
[MAXFIELDS
];
240 } structs
[MAXSTRUCTS
];
243 static int struct_find(char *name
, int isunion
)
246 for (i
= nstructs
- 1; i
>= 0; --i
)
247 if (*structs
[i
].name
&& !strcmp(name
, structs
[i
].name
) &&
248 structs
[i
].isunion
== isunion
)
251 if (nstructs
>= MAXSTRUCTS
)
252 err("nomem: MAXTYPES reached!\n");
253 memset(&structs
[i
], 0, sizeof(structs
[i
]));
254 strcpy(structs
[i
].name
, name
);
255 structs
[i
].isunion
= isunion
;
259 static struct name
*struct_field(int id
, char *name
)
261 struct structinfo
*si
= &structs
[id
];
263 for (i
= 0; i
< si
->nfields
; i
++)
264 if (!strcmp(name
, si
->fields
[i
].name
))
265 return &si
->fields
[i
];
266 err("field not found\n");
269 #define MAXBREAK (1 << 7)
271 static long breaks
[MAXBREAK
];
273 static long continues
[MAXBREAK
];
274 static int ncontinues
;
276 static void break_fill(long addr
, int till
)
279 for (i
= till
; i
< nbreaks
; i
++)
280 o_filljmp2(breaks
[i
], addr
);
284 static void continue_fill(long addr
, int till
)
287 for (i
= till
; i
< ncontinues
; i
++)
288 o_filljmp2(continues
[i
], addr
);
292 /* return t's size */
293 static int type_totsz(struct type
*t
)
297 if (t
->flags
& T_ARRAY
)
298 return arrays
[t
->id
].n
* type_totsz(&arrays
[t
->id
].type
);
299 return t
->flags
& T_STRUCT
? structs
[t
->id
].size
: BT_SZ(t
->bt
);
302 /* return t's dereferenced size */
303 static unsigned type_szde(struct type
*t
)
308 return type_totsz(&de
);
311 /* dereference stack top if t->addr (ie. address is pushed to gen.c) */
312 static void ts_de(int deref
)
314 struct type
*t
= &ts
[nts
- 1];
316 if (deref
&& t
->addr
&& (t
->ptr
|| !(t
->flags
& T_FUNC
)))
321 /* pop stack pop to *t and dereference if t->addr */
322 static void ts_pop_de(struct type
*t
)
328 /* pop the top 2 stack values and dereference them if t->addr */
329 static void ts_pop_de2(struct type
*t1
, struct type
*t2
)
337 static int tok_jmp(int tok
)
339 if (tok_see() != tok
)
345 static void tok_expect(int tok
)
347 if (tok_get() != tok
)
348 err("syntax error\n");
351 static unsigned bt_op(unsigned bt1
, unsigned bt2
)
353 unsigned s1
= BT_SZ(bt1
);
354 unsigned s2
= BT_SZ(bt2
);
355 return (bt1
| bt2
) & BT_SIGNED
| (s1
> s2
? s1
: s2
);
358 static void ts_binop(int op
)
362 ts_pop_de2(&t1
, &t2
);
363 if (op
== O_DIV
|| op
== O_MOD
)
366 bt
= bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
));
367 o_bop(op
| (bt
& BT_SIGNED
? O_SIGNED
: 0));
371 static void ts_addop(int op
)
374 ts_pop_de2(&t1
, &t2
);
375 if (!t1
.ptr
&& !t2
.ptr
) {
377 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
380 if (t1
.ptr
&& !t2
.ptr
)
382 if (!t1
.ptr
&& t2
.ptr
)
383 if (type_szde(&t2
) > 1) {
384 o_num(type_szde(&t2
));
387 if (t1
.ptr
&& !t2
.ptr
)
390 if (t1
.ptr
&& t2
.ptr
) {
391 int sz
= type_szde(&t1
);
396 ts_push_bt(4 | BT_SIGNED
);
398 ts_push(t1
.ptr
? &t1
: &t2
);
402 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
403 #define MIN(a, b) ((a) < (b) ? (a) : (b))
405 static int type_alignment(struct type
*t
)
407 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
408 return type_alignment(&arrays
[t
->id
].type
);
409 if (t
->flags
& T_STRUCT
&& !t
->ptr
)
410 return type_alignment(&structs
[t
->id
].fields
[0].type
);
411 return MIN(LONGSZ
, type_totsz(t
));
414 static void structdef(void *data
, struct name
*name
, unsigned flags
)
416 struct structinfo
*si
= data
;
419 if (si
->size
< type_totsz(&name
->type
))
420 si
->size
= type_totsz(&name
->type
);
422 struct type
*t
= &name
->type
;
423 int alignment
= type_alignment(t
);
424 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
425 alignment
= MIN(LONGSZ
, type_totsz(&arrays
[t
->id
].type
));
426 si
->size
= ALIGN(si
->size
, alignment
);
427 name
->addr
= si
->size
;
428 si
->size
+= type_totsz(&name
->type
);
430 memcpy(&si
->fields
[si
->nfields
++], name
, sizeof(*name
));
433 static int readdefs(void (*def
)(void *, struct name
*, unsigned f
), void *data
);
435 static int struct_create(char *name
, int isunion
)
437 int id
= struct_find(name
, isunion
);
438 struct structinfo
*si
= &structs
[id
];
440 while (tok_jmp('}')) {
441 readdefs(structdef
, si
);
447 static void readexpr(void);
449 static void enum_create(void)
453 while (tok_jmp('}')) {
455 tok_expect(TOK_NAME
);
456 strcpy(name
, tok_id());
461 err("const expr expected!\n");
468 static int basetype(struct type
*type
, unsigned *flags
)
475 char name
[NAMELEN
] = "";
513 isunion
= tok_get() == TOK_UNION
;
514 if (!tok_jmp(TOK_NAME
))
515 strcpy(name
, tok_id());
516 if (tok_see() == '{')
517 type
->id
= struct_create(name
, isunion
);
519 type
->id
= struct_find(name
, isunion
);
520 type
->flags
|= T_STRUCT
;
526 if (tok_see() == '{')
528 type
->bt
= 4 | BT_SIGNED
;
531 if (tok_see() == TOK_NAME
) {
532 int id
= typedef_find(tok_id());
535 memcpy(type
, &typedefs
[id
].type
,
548 type
->bt
= size
| (sign
? BT_SIGNED
: 0);
552 static int readname(struct type
*main
, char *name
,
553 struct type
*base
, unsigned flags
);
555 static int readtype(struct type
*type
)
557 return readname(type
, NULL
, NULL
, 0);
560 static void readptrs(struct type
*type
)
562 while (!tok_jmp('*')) {
569 /* used to differenciate labels from case and cond exprs */
573 static void readpre(void);
575 static char *tmp_str(char *buf
, int len
)
577 static char name
[NAMELEN
];
580 sprintf(name
, "__neatcc.s%d", id
++);
581 dat
= o_mkdat(name
, len
, 0);
582 memcpy(dat
, buf
, len
);
586 static void readprimary(void)
588 if (!tok_jmp(TOK_NUM
)) {
590 int bt
= tok_num(&n
);
595 if (!tok_jmp(TOK_STR
)) {
599 t
.bt
= 1 | BT_SIGNED
;
605 o_sym(tmp_str(buf
, len
));
608 if (!tok_jmp(TOK_NAME
)) {
609 struct name unkn
= {""};
610 char *name
= unkn
.name
;
612 strcpy(name
, tok_id());
613 /* don't search for labels here */
614 if (!ncexpr
&& !caseexpr
&& tok_see() == ':')
616 if ((n
= local_find(name
)) != -1) {
617 struct name
*l
= &locals
[n
];
619 ts_push_addr(&l
->type
);
622 if ((n
= global_find(name
)) != -1) {
623 struct name
*g
= &globals
[n
];
624 o_sym(*g
->elfname
? g
->elfname
: g
->name
);
625 ts_push_addr(&g
->type
);
628 if (!enum_find(&n
, name
)) {
629 ts_push_bt(4 | BT_SIGNED
);
633 if (tok_see() != '(')
634 err("unknown symbol\n");
648 if (!t
.ptr
|| !o
.ptr
)
652 while (tok_jmp(')')) {
663 static void arrayderef(void)
669 if (!(t
.flags
& T_ARRAY
) && t
.addr
) {
671 o_deref(TYPE_BT(&t
));
686 static void inc_post(int op
)
688 struct type t
= ts
[nts
- 1];
689 /* pushing the value before inc */
695 /* increment by 1 or pointer size */
699 o_num(t
.ptr
> 0 ? type_szde(&t
) : 1);
703 o_assign(TYPE_BT(&t
));
707 static void readfield(void)
711 tok_expect(TOK_NAME
);
714 field
= struct_field(t
.id
, tok_id());
719 ts_push_addr(&field
->type
);
722 #define MAXFUNCS (1 << 10)
724 static struct funcinfo
{
725 struct type args
[MAXFIELDS
];
732 static int func_create(struct type
*ret
, struct name
*args
, int nargs
)
734 struct funcinfo
*fi
= &funcs
[nfuncs
++];
736 if (nfuncs
>= MAXFUNCS
)
737 err("nomem: MAXFUNCS reached!\n");
738 memcpy(&fi
->ret
, ret
, sizeof(*ret
));
739 for (i
= 0; i
< nargs
; i
++)
740 memcpy(&fi
->args
[i
], &args
[i
].type
, sizeof(*ret
));
745 static void readcall(void)
751 if (t
.flags
& T_FUNC
&& t
.ptr
> 0)
753 fi
= t
.flags
& T_FUNC
? &funcs
[t
.id
] : NULL
;
754 if (tok_see() != ')') {
759 } while (!tok_jmp(','));
762 o_call(argc
, fi
? TYPE_BT(&fi
->ret
) : 4 | BT_SIGNED
);
764 if (TYPE_BT(&fi
->ret
))
765 o_cast(TYPE_BT(&fi
->ret
));
768 ts_push_bt(4 | BT_SIGNED
);
772 static void readpost(void)
786 if (!tok_jmp(TOK2("++"))) {
790 if (!tok_jmp(TOK2("--"))) {
798 if (!tok_jmp(TOK2("->"))) {
807 static void inc_pre(int op
)
811 /* copy the destination */
813 ts_push(&ts
[nts
- 1]);
814 /* increment by 1 or pointer size */
816 o_num(t
.ptr
> 0 ? type_szde(&t
) : 1);
818 /* assign the result */
819 o_assign(TYPE_BT(&t
));
823 static void readpre(void)
830 err("cannot use the address\n");
842 err("dereferencing non-pointer\n");
844 o_deref(TYPE_BT(&t
));
854 ts_push_bt(4 | BT_SIGNED
);
869 if (!tok_jmp(TOK2("++"))) {
873 if (!tok_jmp(TOK2("--"))) {
877 if (!tok_jmp(TOK_SIZEOF
)) {
879 int op
= !tok_jmp('(');
890 o_num(type_totsz(&t
));
898 static void readmul(void)
921 static void readadd(void)
939 static void shift(int op
)
943 ts_pop_de2(NULL
, &t
);
944 o_bop(op
| (BT_SIGNED
& TYPE_BT(&t
) ? O_SIGNED
: 0));
945 ts_push_bt(TYPE_BT(&t
));
948 static void readshift(void)
952 if (!tok_jmp(TOK2("<<"))) {
956 if (!tok_jmp(TOK2(">>"))) {
964 static void cmp(int op
)
969 ts_pop_de2(&t1
, &t2
);
970 bt
= bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
));
971 o_bop(op
| (bt
& BT_SIGNED
? O_SIGNED
: 0));
972 ts_push_bt(4 | BT_SIGNED
);
975 static void readcmp(void)
987 if (!tok_jmp(TOK2("<="))) {
991 if (!tok_jmp(TOK2(">="))) {
999 static void eq(int op
)
1002 ts_pop_de2(NULL
, NULL
);
1004 ts_push_bt(4 | BT_SIGNED
);
1007 static void readeq(void)
1011 if (!tok_jmp(TOK2("=="))) {
1015 if (!tok_jmp(TOK2("!="))) {
1023 static void readbitand(void)
1026 while (!tok_jmp('&')) {
1032 static void readxor(void)
1035 while (!tok_jmp('^')) {
1041 static void readbitor(void)
1044 while (!tok_jmp('|')) {
1050 #define MAXCOND (1 << 7)
1052 static void readand(void)
1054 long conds
[MAXCOND
];
1059 if (tok_see() != TOK2("&&"))
1063 conds
[nconds
++] = o_jz(0);
1064 while (!tok_jmp(TOK2("&&"))) {
1067 conds
[nconds
++] = o_jz(0);
1072 for (i
= 0; i
< nconds
; i
++)
1073 o_filljmp(conds
[i
]);
1078 ts_push_bt(4 | BT_SIGNED
);
1081 static void reador(void)
1083 long conds
[MAXCOND
];
1088 if (tok_see() != TOK2("||"))
1092 conds
[nconds
++] = o_jnz(0);
1093 while (!tok_jmp(TOK2("||"))) {
1096 conds
[nconds
++] = o_jnz(0);
1101 for (i
= 0; i
< nconds
; i
++)
1102 o_filljmp(conds
[i
]);
1107 ts_push_bt(4 | BT_SIGNED
);
1110 static void readcexpr(void);
1112 static int readcexpr_const(void)
1120 /* both branches yield the same type; so ignore the first */
1128 /* making sure t->addr == 0 on both branches */
1135 static void readcexpr(void)
1144 if (readcexpr_const()) {
1147 /* both branches yield the same type; so ignore the first */
1155 /* making sure t->addr == 0 on both branches */
1164 static void opassign(int op
, int ptrop
)
1166 struct type t
= ts
[nts
- 1];
1171 o_assign(TYPE_BT(&ts
[nts
- 2]));
1176 static void doassign(void)
1178 struct type t
= ts
[nts
- 1];
1179 if (!t
.ptr
&& t
.flags
& T_STRUCT
) {
1181 o_num(type_totsz(&t
));
1185 o_assign(TYPE_BT(&ts
[nts
- 1]));
1190 static void readexpr(void)
1193 if (!tok_jmp('=')) {
1198 if (!tok_jmp(TOK2("+="))) {
1202 if (!tok_jmp(TOK2("-="))) {
1206 if (!tok_jmp(TOK2("*="))) {
1210 if (!tok_jmp(TOK2("/="))) {
1214 if (!tok_jmp(TOK2("%="))) {
1218 if (!tok_jmp(TOK3("<<="))) {
1222 if (!tok_jmp(TOK3(">>="))) {
1226 if (!tok_jmp(TOK3("&="))) {
1230 if (!tok_jmp(TOK3("|="))) {
1234 if (!tok_jmp(TOK3("^="))) {
1240 static void readestmt(void)
1246 } while (!tok_jmp(','));
1249 static void o_localoff(long addr
, int off
)
1258 static struct type
*innertype(struct type
*t
)
1260 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
1261 return innertype(&arrays
[t
->id
].type
);
1265 static void initexpr(struct type
*t
, int off
, void *obj
,
1266 void (*set
)(void *obj
, int off
, struct type
*t
))
1272 if (!t
->ptr
&& t
->flags
& T_STRUCT
) {
1273 struct structinfo
*si
= &structs
[t
->id
];
1275 for (i
= 0; i
< si
->nfields
&& tok_see() != '}'; i
++) {
1276 struct name
*field
= &si
->fields
[i
];
1277 if (!tok_jmp('.')) {
1278 tok_expect(TOK_NAME
);
1279 field
= struct_field(t
->id
, tok_id());
1282 initexpr(&field
->type
, off
+ field
->addr
, obj
, set
);
1286 } else if (t
->flags
& T_ARRAY
) {
1287 struct type
*t_de
= &arrays
[t
->id
].type
;
1289 /* handling extra braces as in: char s[] = {"sth"} */
1290 if (TYPE_SZ(t_de
) == 1 && tok_see() == TOK_STR
) {
1295 for (i
= 0; tok_see() != '}'; i
++) {
1297 struct type
*it
= t_de
;
1298 if (!tok_jmp('[')) {
1305 if (tok_see() != '{' && (tok_see() != TOK_STR
||
1306 !(it
->flags
& T_ARRAY
)))
1307 it
= innertype(t_de
);
1308 initexpr(it
, off
+ type_totsz(it
) * idx
, obj
, set
);
1316 static void jumpbrace(void)
1319 while (tok_see() != '}' || depth
--)
1320 if (tok_get() == '{')
1325 static int initsize(void)
1327 long addr
= tok_addr();
1329 if (!tok_jmp(TOK_STR
)) {
1335 while (tok_jmp('}')) {
1337 if (!tok_jmp('[')) {
1346 while (tok_see() != '}' && tok_see() != ',')
1347 if (tok_get() == '{')
1355 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1357 static void globalinit(void *obj
, int off
, struct type
*t
)
1359 struct name
*name
= obj
;
1360 char *elfname
= *name
->elfname
? name
->elfname
: name
->name
;
1361 if (t
->flags
& T_ARRAY
&& tok_see() == TOK_STR
) {
1362 struct type
*t_de
= &arrays
[t
->id
].type
;
1363 if (!t_de
->ptr
&& !t_de
->flags
&& TYPE_SZ(t_de
) == 1) {
1366 tok_expect(TOK_STR
);
1368 memcpy((void *) name
->addr
+ off
, buf
, len
);
1373 o_datset(elfname
, off
, TYPE_BT(t
));
1377 static void globaldef(void *data
, struct name
*name
, unsigned flags
)
1379 struct type
*t
= &name
->type
;
1380 char *elfname
= *name
->elfname
? name
->elfname
: name
->name
;
1382 if (t
->flags
& T_ARRAY
&& !t
->ptr
&& !arrays
[t
->id
].n
)
1383 if (~flags
& F_EXTERN
)
1384 arrays
[t
->id
].n
= initsize();
1386 if (!(flags
& F_EXTERN
) && (!(t
->flags
& T_FUNC
) || t
->ptr
)) {
1388 name
->addr
= (long) o_mkdat(elfname
, sz
, F_GLOBAL(flags
));
1390 o_mkbss(elfname
, sz
, F_GLOBAL(flags
));
1394 initexpr(t
, 0, name
, globalinit
);
1397 static void localinit(void *obj
, int off
, struct type
*t
)
1399 long addr
= *(long *) obj
;
1400 if (t
->flags
& T_ARRAY
&& tok_see() == TOK_STR
) {
1401 struct type
*t_de
= &arrays
[t
->id
].type
;
1402 if (!t_de
->ptr
&& !t_de
->flags
&& TYPE_SZ(t_de
) == 1) {
1405 tok_expect(TOK_STR
);
1407 o_localoff(addr
, off
);
1408 o_sym(tmp_str(buf
, len
));
1415 o_localoff(addr
, off
);
1423 /* current function name */
1424 static char func_name
[NAMELEN
];
1426 static void localdef(void *data
, struct name
*name
, unsigned flags
)
1428 struct type
*t
= &name
->type
;
1429 if ((flags
& F_EXTERN
) || (t
->flags
& T_FUNC
) && !t
->ptr
) {
1433 if (flags
& F_STATIC
) {
1434 sprintf(name
->elfname
, "__neatcc.%s.%s", func_name
, name
->name
);
1435 globaldef(data
, name
, flags
);
1438 if (t
->flags
& T_ARRAY
&& !t
->ptr
&& !arrays
[t
->id
].n
)
1439 arrays
[t
->id
].n
= initsize();
1440 name
->addr
= o_mklocal(type_totsz(&name
->type
));
1442 if (flags
& F_INIT
) {
1443 if (t
->flags
& (T_ARRAY
| T_STRUCT
) && !t
->ptr
) {
1444 o_local(name
->addr
);
1446 o_num(type_totsz(t
));
1450 initexpr(t
, 0, &name
->addr
, localinit
);
1454 static void funcdef(char *name
, struct type
*type
, struct name
*args
,
1455 int nargs
, int varg
, unsigned flags
)
1457 struct name global
= {""};
1459 strcpy(global
.name
, name
);
1460 strcpy(func_name
, name
);
1461 memcpy(&global
.type
, type
, sizeof(*type
));
1462 o_func_beg(name
, nargs
, F_GLOBAL(flags
), varg
);
1463 global_add(&global
);
1464 for (i
= 0; i
< nargs
; i
++) {
1465 args
[i
].addr
= o_arg2loc(i
);
1466 local_add(&args
[i
]);
1470 static int readargs(struct name
*args
, int *varg
)
1475 while (tok_see() != ')') {
1476 if (!tok_jmp(TOK3("..."))) {
1480 readname(&args
[nargs
].type
, args
[nargs
].name
, NULL
, 0);
1481 array2ptr(&args
[nargs
].type
);
1487 if (nargs
== 1 && !TYPE_BT(&args
[0].type
))
1492 static int readname(struct type
*main
, char *name
,
1493 struct type
*base
, unsigned flags
)
1495 struct type tpool
[3];
1497 struct type
*type
= &tpool
[npool
++];
1498 struct type
*func
= NULL
;
1499 struct type
*ret
= NULL
;
1503 memset(tpool
, 0, sizeof(tpool
));
1507 if (basetype(type
, &flags
))
1510 memcpy(type
, base
, sizeof(*base
));
1513 if (!tok_jmp('(')) {
1515 type
= &tpool
[npool
++];
1519 if (!tok_jmp(TOK_NAME
) && name
)
1520 strcpy(name
, tok_id());
1521 while (!tok_jmp('[')) {
1527 err("const expr expected\n");
1532 for (i
= nar
- 1; i
>= 0; i
--) {
1533 type
->id
= array_add(type
, arsz
[i
]);
1534 if (func
&& i
== nar
- 1)
1535 func
= &arrays
[type
->id
].type
;
1536 type
->flags
= T_ARRAY
;
1542 if (tok_see() == '(') {
1543 struct name args
[MAXARGS
] = {{""}};
1545 int nargs
= readargs(args
, &varg
);
1549 type
= &tpool
[npool
++];
1552 func
->flags
= T_FUNC
;
1554 func
->id
= func_create(ret
, args
, nargs
);
1555 if (fdef
&& tok_see() == '{') {
1556 funcdef(name
, func
, args
, nargs
, varg
, flags
);
1560 memcpy(main
, type
, sizeof(*type
));
1564 static int readdefs(void (*def
)(void *data
, struct name
*name
, unsigned flags
),
1568 unsigned base_flags
;
1569 if (basetype(&base
, &base_flags
))
1571 while (tok_see() != ';' && tok_see() != '{') {
1572 struct name name
= {{""}};
1573 unsigned flags
= base_flags
;
1574 if (readname(&name
.type
, name
.name
, &base
, flags
))
1578 def(data
, &name
, flags
);
1584 static void typedefdef(void *data
, struct name
*name
, unsigned flags
)
1586 typedef_add(name
->name
, &name
->type
);
1589 static void readstmt(void);
1591 #define MAXCASES (1 << 7)
1593 static void readswitch(void)
1595 int break_beg
= nbreaks
;
1596 long val_addr
= o_mklocal(LONGSZ
);
1598 int ncases
= 0; /* number of case labels */
1599 long last_failed
= -1; /* address of last failed jmp */
1600 long last_matched
= -1; /* address of last walk through jmp */
1601 long default_addr
= -1; /* address of the default label */
1607 o_assign(TYPE_BT(&t
));
1612 while (tok_jmp('}')) {
1613 if (tok_see() != TOK_CASE
&& tok_see() != TOK_DEFAULT
) {
1618 last_matched
= o_jmp(0);
1619 if (tok_get() == TOK_CASE
) {
1620 if (last_failed
>= 0)
1621 o_filljmp(last_failed
);
1627 o_deref(TYPE_BT(&t
));
1629 last_failed
= o_jz(0);
1633 last_failed
= o_jmp(0);
1634 default_addr
= o_mklabel();
1637 if (last_matched
>= 0)
1638 o_filljmp(last_matched
);
1641 o_rmlocal(val_addr
, LONGSZ
);
1642 if (last_failed
>= 0)
1643 o_filljmp2(last_failed
,
1644 default_addr
>= 0 ? default_addr
: o_mklabel());
1645 break_fill(o_mklabel(), break_beg
);
1648 #define MAXGOTO (1 << 10)
1650 static struct gotoinfo
{
1656 static struct labelinfo
{
1662 static void goto_add(char *name
)
1664 strcpy(gotos
[ngotos
].name
, name
);
1665 gotos
[ngotos
++].addr
= o_jmp(0);
1668 static void label_add(char *name
)
1670 strcpy(labels
[nlabels
].name
, name
);
1671 labels
[nlabels
++].addr
= o_mklabel();
1674 static void goto_fill(void)
1677 for (i
= 0; i
< ngotos
; i
++)
1678 for (j
= 0; j
< nlabels
; j
++)
1679 if (!strcmp(gotos
[i
].name
, labels
[j
].name
)) {
1680 o_filljmp2(gotos
[i
].addr
, labels
[j
].addr
);
1685 static void readstmt(void)
1689 if (!tok_jmp('{')) {
1690 int _nlocals
= nlocals
;
1691 int _nglobals
= nglobals
;
1692 int _nenums
= nenums
;
1693 int _ntypedefs
= ntypedefs
;
1694 int _nstructs
= nstructs
;
1695 int _nfuncs
= nfuncs
;
1696 int _narrays
= narrays
;
1697 while (tok_jmp('}'))
1701 ntypedefs
= _ntypedefs
;
1702 nstructs
= _nstructs
;
1705 nglobals
= _nglobals
;
1708 if (!readdefs(localdef
, NULL
)) {
1712 if (!tok_jmp(TOK_TYPEDEF
)) {
1713 readdefs(typedefdef
, NULL
);
1717 if (!tok_jmp(TOK_IF
)) {
1725 if (!tok_jmp(TOK_ELSE
)) {
1735 if (!tok_jmp(TOK_WHILE
)) {
1737 int break_beg
= nbreaks
;
1738 int continue_beg
= ncontinues
;
1748 break_fill(o_mklabel(), break_beg
);
1749 continue_fill(l1
, continue_beg
);
1752 if (!tok_jmp(TOK_DO
)) {
1754 int break_beg
= nbreaks
;
1755 int continue_beg
= ncontinues
;
1758 tok_expect(TOK_WHILE
);
1765 break_fill(o_mklabel(), break_beg
);
1766 continue_fill(l2
, continue_beg
);
1770 if (!tok_jmp(TOK_FOR
)) {
1771 long l_check
, l_jump
, j_fail
, j_pass
;
1772 int break_beg
= nbreaks
;
1773 int continue_beg
= ncontinues
;
1776 if (tok_see() != ';')
1779 l_check
= o_mklabel();
1780 if (tok_see() != ';') {
1788 l_jump
= o_mklabel();
1789 if (tok_see() != ')')
1798 break_fill(o_mklabel(), break_beg
);
1799 continue_fill(l_jump
, continue_beg
);
1802 if (!tok_jmp(TOK_SWITCH
)) {
1806 if (!tok_jmp(TOK_RETURN
)) {
1807 int ret
= tok_see() != ';';
1816 if (!tok_jmp(TOK_BREAK
)) {
1818 breaks
[nbreaks
++] = o_jmp(0);
1821 if (!tok_jmp(TOK_CONTINUE
)) {
1823 continues
[ncontinues
++] = o_jmp(0);
1826 if (!tok_jmp(TOK_GOTO
)) {
1827 tok_expect(TOK_NAME
);
1834 if (!tok_jmp(':')) {
1835 label_add(tok_id());
1841 static void readdecl(void)
1843 if (!tok_jmp(TOK_TYPEDEF
)) {
1844 readdefs(typedefdef
, NULL
);
1848 readdefs(globaldef
, NULL
);
1849 if (tok_see() == '{') {
1853 func_name
[0] = '\0';
1862 static void parse(void)
1864 while (tok_see() != TOK_EOF
)
1868 static void compat_macros(void)
1870 cpp_define("__STDC__", "");
1871 cpp_define("__linux__", "");
1873 cpp_define("__arm__", "");
1875 cpp_define("__i386__", "");
1878 /* ignored keywords */
1879 cpp_define("const", "");
1880 cpp_define("register", "");
1881 cpp_define("volatile", "");
1882 cpp_define("inline", "");
1883 cpp_define("restrict", "");
1884 cpp_define("__inline__", "");
1885 cpp_define("__restrict__", "");
1886 cpp_define("__attribute__(x)", "");
1887 cpp_define("__builtin_va_list__", "long");
1890 int main(int argc
, char *argv
[])
1896 while (i
< argc
&& argv
[i
][0] == '-') {
1897 if (argv
[i
][1] == 'I')
1898 cpp_addpath(argv
[i
][2] ? argv
[i
] + 2 : argv
[++i
]);
1899 if (argv
[i
][1] == 'D') {
1900 char *name
= argv
[i
] + 2;
1902 char *eq
= strchr(name
, '=');
1907 cpp_define(name
, def
);
1909 if (argv
[i
][1] == 'o')
1910 strcpy(obj
, argv
[i
][2] ? argv
[i
] + 2 : argv
[++i
]);
1914 die("neatcc: no file given\n");
1915 if (cpp_init(argv
[i
]))
1916 die("neatcc: cannot open <%s>\n", argv
[i
]);
1919 strcpy(obj
, argv
[i
]);
1920 obj
[strlen(obj
) - 1] = 'o';
1922 ofd
= open(obj
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0600);