scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  1#include <stdio.h>
  2
  3#include <scc/scc.h>
  4#include "cc1.h"
  5
  6static Node *
  7builtin_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	np->flags |= NEFFECT;
 30	return np;
 31
 32error:
 33	return constnode(zero);
 34}
 35
 36static Node *
 37builtin_va_copy(Symbol *sym)
 38{
 39	Node *np, *src, *dst;
 40
 41	dst = simplify(assign());
 42	expect(',');
 43	src = simplify(assign());
 44
 45	if (!valid_va_list(dst->type) || !valid_va_list(src->type)) {
 46		errorp("incorrect parameters for va_copy");
 47		return constnode(zero);
 48	}
 49
 50	if (dst->type != va_type)
 51		dst = node(OPTR, dst->type->type, dst, NULL);
 52	if (src->type != va_type)
 53		src = node(OPTR, src->type->type, src, NULL);
 54	np = node(OASSIGN, dst->type, dst, src);
 55	np = node(OCAST, voidtype, np, NULL);
 56	np->flags |= NEFFECT;
 57
 58	return np;
 59}
 60
 61static Node *
 62builtin_va_start(Symbol *sym)
 63{
 64	Node *np, *ap, *last;
 65	Symbol **p;
 66	Type *tp;
 67
 68	ap = simplify(assign());
 69	expect(',');
 70	last = assign();
 71	if (last->op != OSYM)
 72		goto error;
 73
 74	if (!valid_va_list(ap->type) || !(last->sym->flags&SDECLARED))
 75		 goto error;
 76
 77	tp = curfun->type;
 78	for (p = curfun->u.pars; p && *p != last->sym; ++p)
 79		;
 80	if (!p || *p == NULL || p[1] != NULL ||
 81	    tp->p.pars[tp->n.elem-1] != ellipsistype) {
 82		warn("second parameter of 'va_start' not last named argument");
 83	}
 84
 85	tp = last->type;
 86	if (tp == booltype ||
 87	    tp == chartype || tp == uchartype || tp == schartype ||
 88	    tp == shorttype || tp == ushorttype) {
 89		warn("last parameter before '...' must not be bool, char or short");
 90	}
 91
 92	np = node(OBUILTIN, voidtype, ap, last);
 93	np->sym = sym;
 94	np->flags |= NEFFECT;
 95	return np;
 96
 97error:
 98	errorp("incorrect parameters for va_start");
 99	return constnode(zero);
100}
101
102static Node *
103builtin_va_end(Symbol *sym)
104{
105	Node *ap, *np;
106
107	ap = simplify(assign());
108
109	if (!valid_va_list(ap->type)) {
110		errorp("incorrect parameters for va_end");
111		return constnode(zero);
112	}
113
114	np = node(OBUILTIN, voidtype, ap, NULL);
115	np->sym = sym;
116	np->flags |= NEFFECT;
117	return np;
118}
119
120void
121ibuilts(void)
122{
123	struct builtin built[] = {
124		{"__builtin_va_arg", builtin_va_arg},
125		{"__builtin_va_copy", builtin_va_copy},
126		{"__builtin_va_start", builtin_va_start},
127		{"__builtin_va_end", builtin_va_end},
128		{NULL}
129	};
130	builtins(built);
131}