scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

builtin.c (2294B)


      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 = 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 == shortype || tp == ushortype) {
     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 = assign();
     41 	expect(',');
     42 	src = 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 	np = node(OBUILTIN, voidtype, dst, src);
     50 	np->sym = sym;
     51 	return np;
     52 }
     53 
     54 static Node *
     55 builtin_va_start(Symbol *sym)
     56 {
     57 	Node *np, *ap, *last;
     58 	Symbol **p;
     59 	Type *tp;
     60 
     61 	ap = assign();
     62 	expect(',');
     63 	last = assign();
     64 	if (last->op != OSYM)
     65 		goto error;
     66 
     67 	if (!valid_va_list(ap->type) || !(last->sym->flags&SDECLARED))
     68 		 goto error;
     69 
     70 	for (p = curfun->u.pars; p && *p != last->sym; ++p)
     71 		;
     72 	if (!p || *p == NULL || p[1] == NULL || p[1]->type != ellipsistype)
     73 		warn("second parameter of 'va_start' not last named argument");
     74 
     75 	tp = last->type;
     76 	if (tp == booltype ||
     77 	    tp == chartype || tp == uchartype || tp == schartype ||
     78 	    tp == shortype || tp == ushortype) {
     79 		warn("last parameter before '...' must not be bool, char or short");
     80 	}
     81 
     82 	np = node(OBUILTIN, voidtype, ap, last);
     83 	np->sym = sym;
     84 	return np;
     85 
     86 error:
     87 	errorp("incorrect parameters for va_start");
     88 	return constnode(zero);
     89 }
     90 
     91 static Node *
     92 builtin_va_end(Symbol *sym)
     93 {
     94 	Node *ap, *np;
     95 
     96 	ap = assign();
     97 
     98 	if (!valid_va_list(ap->type)) {
     99 		errorp("incorrect parameters for va_end");
    100 		return constnode(zero);
    101 	}
    102 
    103 	np = node(OBUILTIN, voidtype, ap, NULL);
    104 	np->sym = sym;
    105 	return np;
    106 }
    107 
    108 void
    109 ibuilts(void)
    110 {
    111 	struct builtin built[] = {
    112 		{"__builtin_va_arg", builtin_va_arg},
    113 		{"__builtin_va_copy", builtin_va_copy},
    114 		{"__builtin_va_start", builtin_va_start},
    115 		{"__builtin_va_end", builtin_va_end},
    116 		{NULL}
    117 	};
    118 	builtins(built);
    119 }