builtin.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
builtin.c (2522B)
---
1 #include <stdio.h>
2
3 #include <scc/scc.h>
4 #include "cc1.h"
5
6 static Node *
7 builtin_va_arg(Symbol *sym)
8 {
9 Node *np, *ap;
10 Type *tp;
11
12 ap = simplify(assign());
13 expect(',');
14 tp = typename();
15
16 if (!valid_va_list(ap->type)) {
17 errorp("incorrect parameters for va_arg");
18 goto error;
19 }
20 if (tp == booltype ||
21 tp == chartype || tp == uchartype || tp == schartype ||
22 tp == shorttype || tp == ushorttype) {
23 warn("bool, char and short are promoted to int when passed through '...'");
24 tp = (tp->prop & TSIGNED) ? inttype : uinttype;
25 }
26
27 np = node(OBUILTIN, tp, ap, NULL);
28 np->sym = sym;
29 return np;
30
31 error:
32 return constnode(zero);
33 }
34
35 static Node *
36 builtin_va_copy(Symbol *sym)
37 {
38 Node *np, *src, *dst;
39
40 dst = simplify(assign());
41 expect(',');
42 src = simplify(assign());
43
44 if (!valid_va_list(dst->type) || !valid_va_list(src->type)) {
45 errorp("incorrect parameters for va_copy");
46 return constnode(zero);
47 }
48
49 if (dst->type != va_type)
50 dst = node(OPTR, dst->type->type, dst, NULL);
51 if (src->type != va_type)
52 src = node(OPTR, src->type->type, src, NULL);
53 np = node(OASSIGN, dst->type, dst, src);
54 np = node(OCAST, voidtype, np, NULL);
55
56 return np;
57 }
58
59 static Node *
60 builtin_va_start(Symbol *sym)
61 {
62 Node *np, *ap, *last;
63 Symbol **p;
64 Type *tp;
65
66 ap = simplify(assign());
67 expect(',');
68 last = assign();
69 if (last->op != OSYM)
70 goto error;
71
72 if (!valid_va_list(ap->type) || !(last->sym->flags&SDECLARED))
73 goto error;
74
75 for (p = curfun->u.pars; p && *p != last->sym; ++p)
76 ;
77 if (!p || *p == NULL || p[1] == NULL || p[1]->type != ellipsistype)
78 warn("second parameter of 'va_start' not last named argument");
79
80 tp = last->type;
81 if (tp == booltype ||
82 tp == chartype || tp == uchartype || tp == schartype ||
83 tp == shorttype || tp == ushorttype) {
84 warn("last parameter before '...' must not be bool, char or short");
85 }
86
87 np = node(OBUILTIN, voidtype, ap, last);
88 np->sym = sym;
89 return np;
90
91 error:
92 errorp("incorrect parameters for va_start");
93 return constnode(zero);
94 }
95
96 static Node *
97 builtin_va_end(Symbol *sym)
98 {
99 Node *ap, *np;
100
101 ap = simplify(assign());
102
103 if (!valid_va_list(ap->type)) {
104 errorp("incorrect parameters for va_end");
105 return constnode(zero);
106 }
107
108 np = node(OBUILTIN, voidtype, ap, NULL);
109 np->sym = sym;
110 return np;
111 }
112
113 void
114 ibuilts(void)
115 {
116 struct builtin built[] = {
117 {"__builtin_va_arg", builtin_va_arg},
118 {"__builtin_va_copy", builtin_va_copy},
119 {"__builtin_va_start", builtin_va_start},
120 {"__builtin_va_end", builtin_va_end},
121 {NULL}
122 };
123 builtins(built);
124 }