scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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 }