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