improve type printing
authorMatthias Braun <matze@braunis.de>
Sat, 8 Sep 2007 11:21:26 +0000 (11:21 +0000)
committerMatthias Braun <matze@braunis.de>
Sat, 8 Sep 2007 11:21:26 +0000 (11:21 +0000)
[r18342]

type.c
type.h

diff --git a/type.c b/type.c
index d892130..368ca39 100644 (file)
--- a/type.c
+++ b/type.c
@@ -5,6 +5,10 @@
 
 static struct obstack  _type_obst;
 struct obstack        *type_obst = &_type_obst;
+static FILE           *out;
+
+static void intern_print_type_pre(const type_t *type);
+static void intern_print_type_post(const type_t *type);
 
 void init_types()
 {
@@ -16,8 +20,13 @@ void exit_types()
        obstack_free(type_obst, NULL);
 }
 
+void type_set_output(FILE *stream)
+{
+       out = stream;
+}
+
 static
-void print_type_qualifiers(FILE *out, const type_t *type)
+void print_type_qualifiers(const type_t *type)
 {
        unsigned qualifiers = type->qualifiers;
        if(qualifiers & TYPE_QUALIFIER_CONST) {
@@ -35,9 +44,9 @@ void print_type_qualifiers(FILE *out, const type_t *type)
 }
 
 static
-void print_atomic_type(FILE *out, const atomic_type_t *type)
+void print_atomic_type(const atomic_type_t *type)
 {
-       print_type_qualifiers(out, & type->type);
+       print_type_qualifiers(& type->type);
 
        switch(type->atype) {
        case ATOMIC_TYPE_INVALID:     fputs("INVALIDATOMIC", out); return;
@@ -62,58 +71,80 @@ void print_atomic_type(FILE *out, const atomic_type_t *type)
 }
 
 static
-void print_method_type(FILE *out, const method_type_t *type)
+void print_method_type_pre(const method_type_t *type)
 {
-       print_type_qualifiers(out, & type->type);
+       print_type_qualifiers(& type->type);
 
-       fputs("<", out);
-       print_type(out, type->result_type);
-       fputs(" ", out);
+       intern_print_type_pre(type->result_type);
 
-       fputs("method(", out);
-       method_parameter_type_t *param_type = type->parameter_types;
-       int first = 1;
-       while(param_type != NULL) {
+       /* TODO: don't emit braces if we're the toplevel type... */
+       fputc('(', out);
+}
+
+static
+void print_method_type_post(const method_type_t *type)
+{
+       /* TODO: don't emit braces if we're the toplevel type... */
+       intern_print_type_post(type->result_type);
+       fputc(')', out);
+
+       fputc('(', out);
+
+       method_parameter_type_t *parameter = type->parameter_types;
+       int                      first     = 1;
+       for( ; parameter != NULL; parameter = parameter->next) {
                if(first) {
                        first = 0;
                } else {
                        fputs(", ", out);
                }
-               print_type(out, param_type->type);
-               param_type = param_type->next;
+               print_type(parameter->type, parameter->symbol);
        }
-       fputs(")>", out);
+       if(type->variadic) {
+               if(first) {
+                       first = 0;
+               } else {
+                       fputs(", ", out);
+               }
+               fputs("...", out);
+       }
+       if(first && !type->unspecified_parameters) {
+               fputs("void", out);
+       }
+       fputc(')', out);
 }
 
 static
-void print_pointer_type(FILE *out, const pointer_type_t *type)
+void print_pointer_type_pre(const pointer_type_t *type)
 {
-       print_type(out, type->points_to);
+       intern_print_type_pre(type->points_to);
        fputs("*", out);
-       print_type_qualifiers(out, &type->type);
+       print_type_qualifiers(&type->type);
 }
 
-void print_type(FILE *out, const type_t *type)
+static
+void print_pointer_type_post(const pointer_type_t *type)
 {
-       if(type == NULL) {
-               fputs("nil type", out);
-               return;
-       }
+       intern_print_type_post(type->points_to);
+}
 
+static
+void intern_print_type_pre(const type_t *type)
+{
        switch(type->type) {
        case TYPE_INVALID:
                fputs("invalid", out);
                return;
        case TYPE_ENUM:
-               print_type_qualifiers(out, type);
+               print_type_qualifiers(type);
                fputs("enum (TODO)", out);
                return;
        case TYPE_ATOMIC:
-               print_atomic_type(out, (const atomic_type_t*) type);
+               print_atomic_type((const atomic_type_t*) type);
                return;
        case TYPE_COMPOUND_STRUCT:
        case TYPE_COMPOUND_UNION:
-               print_type_qualifiers(out, type);
+               print_type_qualifiers(type);
                if(((const compound_type_t*) type)->symbol != NULL) {
                        fprintf(out, "%s", ((const compound_type_t*) type)->symbol->string);
                }
@@ -122,15 +153,50 @@ void print_type(FILE *out, const type_t *type)
                fputs(((builtin_type_t*) type)->symbol->string, out);
                return;
        case TYPE_METHOD:
-               print_method_type(out, (const method_type_t*) type);
+               print_method_type_pre((const method_type_t*) type);
                return;
        case TYPE_POINTER:
-               print_pointer_type(out, (const pointer_type_t*) type);
+               print_pointer_type_pre((const pointer_type_t*) type);
                return;
        }
        fputs("unknown", out);
 }
 
+static
+void intern_print_type_post(const type_t *type)
+{
+       switch(type->type) {
+       case TYPE_METHOD:
+               print_method_type_post((const method_type_t*) type);
+               return;
+       case TYPE_POINTER:
+               print_pointer_type_post((const pointer_type_t*) type);
+               return;
+       case TYPE_INVALID:
+       case TYPE_ATOMIC:
+       case TYPE_ENUM:
+       case TYPE_COMPOUND_STRUCT:
+       case TYPE_COMPOUND_UNION:
+       case TYPE_BUILTIN:
+               break;
+       }
+}
+
+void print_type(const type_t *type, const symbol_t *symbol)
+{
+       if(type == NULL) {
+               fputs("nil type", out);
+               return;
+       }
+
+       intern_print_type_pre(type);
+       if(symbol != NULL) {
+               fputc(' ', out);
+               fputs(symbol->string, out);
+       }
+       intern_print_type_post(type);
+}
+
 int type_valid(const type_t *type)
 {
        return type->type != TYPE_INVALID;
@@ -163,7 +229,10 @@ int is_type_int(const type_t *type)
 static __attribute__((unused))
 void dbg_type(const type_t *type)
 {
-       print_type(stdout,type);
+       FILE *old_out = out;
+       out = stderr;
+       print_type(type, NULL);
        puts("\n");
-       fflush(stdout);
+       fflush(stderr);
+       out = old_out;
 }
diff --git a/type.h b/type.h
index 80f03dc..276846e 100644 (file)
--- a/type.h
+++ b/type.h
@@ -2,6 +2,7 @@
 #define TYPE_H
 
 #include <stdio.h>
+#include "symbol.h"
 
 typedef struct type_t                   type_t;
 typedef struct atomic_type_t            atomic_type_t;
@@ -9,6 +10,7 @@ typedef struct pointer_type_t           pointer_type_t;
 typedef struct method_parameter_type_t  method_parameter_type_t;
 typedef struct method_type_t            method_type_t;
 typedef struct compound_type_t          compound_type_t;
+typedef struct enum_entry_t             enum_entry_t;
 typedef struct enum_type_t              enum_type_t;
 typedef struct builtin_type_t           builtin_type_t;
 
@@ -16,9 +18,15 @@ void init_types(void);
 void exit_types(void);
 
 /**
- * prints a human readable form of @p type to a stream
+ * prints a human readable form of @p type. prints an abstract typename
+ * if symbol is NULL
  */
-void print_type(FILE* out, const type_t *type);
+void print_type(const type_t *type, const symbol_t *symbol);
+
+/**
+ * set output stream for the type printer
+ */
+void type_set_output(FILE *out);
 
 /**
  * returns 1 if type contains integer numbers