Fix printing of necessary () in the AST-printer.
[cparser] / ast.c
diff --git a/ast.c b/ast.c
index 164c864..7a41eac 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -74,9 +74,9 @@ void print_indent(void)
 static int right_to_left(unsigned precedence)
 {
        switch (precedence) {
-               case 2*PREC_ASSIGNMENT:
-               case 2*PREC_CONDITIONAL:
-               case 2*PREC_UNARY:
+               case PREC_ASSIGNMENT:
+               case PREC_CONDITIONAL:
+               case PREC_UNARY:
                        return 1;
 
                default:
@@ -180,8 +180,7 @@ static unsigned get_expression_precedence(expression_kind_t kind)
        unsigned res = prec[kind];
 
        assert(res != PREC_BOTTOM);
-       /* we need the lowest bit for right-to-left precedence */
-       return 2 * res;
+       return res;
 }
 
 /**
@@ -406,7 +405,7 @@ static void print_call_expression(const call_expression_t *call)
                } else {
                        first = 0;
                }
-               print_expression_prec(argument->expression, 2 * PREC_ASSIGNMENT);
+               print_expression_prec(argument->expression, PREC_ASSIGNMENT);
 
                argument = argument->next;
        }
@@ -469,7 +468,7 @@ static void print_binary_expression(const binary_expression_t *binexpr)
        default: panic("invalid binexpression found");
        }
        fputs(op, out);
-       print_expression_prec(binexpr->right, prec - r2l);
+       print_expression_prec(binexpr->right, prec + 1 - r2l);
 }
 
 /**
@@ -508,7 +507,7 @@ static void print_unary_expression(const unary_expression_t *unexpr)
                break;
        case EXPR_UNARY_ASSUME:
                fputs("__assume(", out);
-               print_expression_prec(unexpr->value, 2 * PREC_ASSIGNMENT);
+               print_expression_prec(unexpr->value, PREC_ASSIGNMENT);
                fputc(')', out);
                return;
 
@@ -610,7 +609,7 @@ static void print_builtin_symbol(const builtin_symbol_expression_t *expression)
 static void print_builtin_constant(const builtin_constant_expression_t *expression)
 {
        fputs("__builtin_constant_p(", out);
-       print_expression_prec(expression->value, 2 * PREC_ASSIGNMENT);
+       print_expression_prec(expression->value, PREC_ASSIGNMENT);
        fputc(')', out);
 }
 
@@ -622,14 +621,14 @@ static void print_builtin_constant(const builtin_constant_expression_t *expressi
 static void print_builtin_prefetch(const builtin_prefetch_expression_t *expression)
 {
        fputs("__builtin_prefetch(", out);
-       print_expression_prec(expression->adr, 2 * PREC_ASSIGNMENT);
+       print_expression_prec(expression->adr, PREC_ASSIGNMENT);
        if (expression->rw) {
                fputc(',', out);
-               print_expression_prec(expression->rw, 2 * PREC_ASSIGNMENT);
+               print_expression_prec(expression->rw, PREC_ASSIGNMENT);
        }
        if (expression->locality) {
                fputc(',', out);
-               print_expression_prec(expression->locality, 2 * PREC_ASSIGNMENT);
+               print_expression_prec(expression->locality, PREC_ASSIGNMENT);
        }
        fputc(')', out);
 }
@@ -641,15 +640,15 @@ static void print_builtin_prefetch(const builtin_prefetch_expression_t *expressi
  */
 static void print_conditional(const conditional_expression_t *expression)
 {
-       print_expression_prec(expression->condition, 2 * PREC_LOGICAL_OR);
+       print_expression_prec(expression->condition, PREC_LOGICAL_OR);
        fputs(" ? ", out);
        if (expression->true_expression != NULL) {
-               print_expression_prec(expression->true_expression, 2 * PREC_EXPRESSION);
+               print_expression_prec(expression->true_expression, PREC_EXPRESSION);
                fputs(" : ", out);
        } else {
                fputs(": ", out);
        }
-       print_expression_prec(expression->false_expression, 2 * PREC_CONDITIONAL);
+       print_expression_prec(expression->false_expression, PREC_CONDITIONAL);
 }
 
 /**
@@ -660,7 +659,7 @@ static void print_conditional(const conditional_expression_t *expression)
 static void print_va_start(const va_start_expression_t *const expression)
 {
        fputs("__builtin_va_start(", out);
-       print_expression_prec(expression->ap, 2 * PREC_ASSIGNMENT);
+       print_expression_prec(expression->ap, PREC_ASSIGNMENT);
        fputs(", ", out);
        fputs(expression->parameter->base.base.symbol->string, out);
        fputc(')', out);
@@ -674,7 +673,7 @@ static void print_va_start(const va_start_expression_t *const expression)
 static void print_va_arg(const va_arg_expression_t *expression)
 {
        fputs("__builtin_va_arg(", out);
-       print_expression_prec(expression->ap, 2 * PREC_ASSIGNMENT);
+       print_expression_prec(expression->ap, PREC_ASSIGNMENT);
        fputs(", ", out);
        print_type(expression->base.type);
        fputc(')', out);
@@ -706,7 +705,7 @@ static void print_classify_type_expression(
        const classify_type_expression_t *const expr)
 {
        fputs("__builtin_classify_type(", out);
-       print_expression_prec(expr->type_expression, 2 * PREC_ASSIGNMENT);
+       print_expression_prec(expr->type_expression, PREC_ASSIGNMENT);
        fputc(')', out);
 }
 
@@ -1322,18 +1321,16 @@ void print_statement(const statement_t *statement)
  */
 static void print_storage_class(storage_class_tag_t storage_class)
 {
+       const char *text;
        switch (storage_class) {
-       case STORAGE_CLASS_NONE:
-               break;
-       case STORAGE_CLASS_TYPEDEF:       fputs("typedef ",        out); break;
-       case STORAGE_CLASS_EXTERN:        fputs("extern ",         out); break;
-       case STORAGE_CLASS_STATIC:        fputs("static ",         out); break;
-       case STORAGE_CLASS_AUTO:          fputs("auto ",           out); break;
-       case STORAGE_CLASS_REGISTER:      fputs("register ",       out); break;
-       case STORAGE_CLASS_THREAD:        fputs("__thread",        out); break;
-       case STORAGE_CLASS_THREAD_EXTERN: fputs("extern __thread", out); break;
-       case STORAGE_CLASS_THREAD_STATIC: fputs("static __thread", out); break;
+       case STORAGE_CLASS_NONE:     return;
+       case STORAGE_CLASS_TYPEDEF:  text = "typedef ";  break;
+       case STORAGE_CLASS_EXTERN:   text = "extern ";   break;
+       case STORAGE_CLASS_STATIC:   text = "static ";   break;
+       case STORAGE_CLASS_AUTO:     text = "auto ";     break;
+       case STORAGE_CLASS_REGISTER: text = "register "; break;
        }
+       fputs(text, out);
 }
 
 /**
@@ -1527,24 +1524,32 @@ void print_declaration(const entity_t *entity)
                }
        }
        print_ms_modifiers(declaration);
-       if (entity->kind == ENTITY_FUNCTION) {
-               print_type_ext(entity->declaration.type, entity->base.symbol,
-                              &entity->function.parameters);
+       switch (entity->kind) {
+               case ENTITY_FUNCTION:
+                       print_type_ext(entity->declaration.type, entity->base.symbol,
+                                       &entity->function.parameters);
+
+                       if (entity->function.statement != NULL) {
+                               fputc('\n', out);
+                               print_indent();
+                               print_statement(entity->function.statement);
+                               return;
+                       }
+                       break;
 
-               if (entity->function.statement != NULL) {
-                       fputs("\n", out);
-                       print_indent();
-                       print_statement(entity->function.statement);
-                       return;
-               }
-       } else {
-               print_type_ext(declaration->type, declaration->base.symbol, NULL);
+               case ENTITY_VARIABLE:
+                       if (entity->variable.thread_local)
+                               fputs("__thread ", out);
+                       print_type_ext(declaration->type, declaration->base.symbol, NULL);
+                       if (entity->variable.initializer != NULL) {
+                               fputs(" = ", out);
+                               print_initializer(entity->variable.initializer);
+                       }
+                       break;
 
-               if (entity->kind == ENTITY_VARIABLE
-                               && entity->variable.initializer != NULL) {
-                       fputs(" = ", out);
-                       print_initializer(entity->variable.initializer);
-               }
+               default:
+                       print_type_ext(declaration->type, declaration->base.symbol, NULL);
+                       break;
        }
        fputc(';', out);
 }
@@ -1556,7 +1561,7 @@ void print_declaration(const entity_t *entity)
  */
 void print_expression(const expression_t *expression)
 {
-       print_expression_prec(expression, 2 * PREC_BOTTOM);
+       print_expression_prec(expression, PREC_BOTTOM);
 }
 
 /**
@@ -1692,14 +1697,13 @@ static bool is_object_with_linker_constant_address(const expression_t *expressio
                        case STORAGE_CLASS_NONE:
                        case STORAGE_CLASS_EXTERN:
                        case STORAGE_CLASS_STATIC:
-                               return true;
+                               return
+                                       entity->kind != ENTITY_VARIABLE ||
+                                       !entity->variable.thread_local;
 
                        case STORAGE_CLASS_REGISTER:
                        case STORAGE_CLASS_TYPEDEF:
                        case STORAGE_CLASS_AUTO:
-                       case STORAGE_CLASS_THREAD:
-                       case STORAGE_CLASS_THREAD_EXTERN:
-                       case STORAGE_CLASS_THREAD_STATIC:
                                break;
                        }
                }