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 }