Home
       builtin.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       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 }