[hackers] [scc] Add compiler time conversions || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Wed, 29 Jul 2015 18:01:32 +0200 (CEST)

commit ad2d3ea7a4b95be09db3643e96b9e485e3296e81
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Wed Jul 29 09:35:00 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Wed Jul 29 09:35:00 2015 +0200

    Add compiler time conversions

diff --git a/cc1/expr.c b/cc1/expr.c
index 5a88352..0c2e53b 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -327,21 +327,71 @@ decay(Node *np)
         return node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL);
 }
 
+static Node *
+constconv(Node *np, Type *newtp)
+{
+ Type *oldtp = np->type;
+ Symbol aux, *sym, *osym = np->sym;
+
+ switch (newtp->op) {
+ case INT:
+ case ENUM:
+ switch (oldtp->op) {
+ case INT:
+ case ENUM:
+ if (newtp->sign == oldtp->sign)
+ aux.u = osym->u;
+ if (newtp->sign && !oldtp->sign)
+ aux.u.i = osym->u.u;
+ else if (!newtp->sign && oldtp->sign)
+ aux.u.u = osym->u.u;
+ break;
+ case FLOAT:
+ if (newtp->sign)
+ aux.u.i = osym->u.f;
+ else
+ aux.u.u = osym->u.f;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ case FLOAT:
+ aux.u.f = (oldtp->sign) ? sym->u.i : sym->u.u;
+ break;
+ default:
+ return NULL;
+ }
+
+ sym = newsym(NS_IDEN);
+ np->type = sym->type = newtp;
+ np->sym = sym;
+ sym->u = aux.u;
+
+ return np;
+}
+
 /*
  * Convert a Node to a type
  */
 Node *
-convert(Node *np, Type *tp, char iscast)
+convert(Node *np, Type *newtp, char iscast)
 {
- if (eqtype(np->type, tp))
+ Type *oldtp = np->type;
+ Node *p;
+
+ if (eqtype(newtp, oldtp))
                 return np;
- switch (BTYPE(np)) {
+ if (np->constant && (p = constconv(np, newtp)) != NULL)
+ return p;
+
+ switch (oldtp->op) {
         case ENUM:
         case INT:
         case FLOAT:
- switch (tp->op) {
+ switch (newtp->op) {
                 case PTR:
- if (!iscast || BTYPE(np) == FLOAT)
+ if (!iscast || oldtp->op == FLOAT)
                                 return NULL;
                         /* PASSTHROUGH */
                 case INT:
_AT_@ -354,7 +404,7 @@ convert(Node *np, Type *tp, char iscast)
                 }
                 break;
         case PTR:
- switch (tp->op) {
+ switch (newtp->op) {
                 case ENUM: /* TODO: allow p = 0 */
                 case INT:
                 case VOID:
_AT_@ -363,14 +413,14 @@ convert(Node *np, Type *tp, char iscast)
                         break;
                 case PTR:
                         if (iscast ||
- tp == pvoidtype ||
- np->type == pvoidtype) {
+ newtp == pvoidtype ||
+ oldtp == pvoidtype) {
                                 /* TODO:
                                  * we assume conversion between pointers
                                  * do not need any operation, but due to
                                  * alignment problems that may be false
                                  */
- np->type = tp;
+ np->type = newtp;
                                 return np;
                         }
                 default:
_AT_@ -379,7 +429,7 @@ convert(Node *np, Type *tp, char iscast)
         default:
                         return NULL;
         }
- return node(OCAST, tp, np, NULL);
+ return node(OCAST, newtp, np, NULL);
 }
 
 static Node *
Received on Wed Jul 29 2015 - 18:01:32 CEST

This archive was generated by hypermail 2.3.0 : Wed Jul 29 2015 - 18:12:11 CEST