X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast.c;h=f02dc668a37122a5b76d3f71c3a7eae40cd6a025;hb=8f50e4997976bf4942a75b96ec8489edd4202203;hp=234a42d89a6a07750c8a9dccd6e79684dfaa8e17;hpb=892fda71da7cd9f59f4f3f9415eab0232dfc107e;p=cparser diff --git a/ast.c b/ast.c index 234a42d..f02dc66 100644 --- a/ast.c +++ b/ast.c @@ -208,7 +208,12 @@ static void print_const(const const_expression_t *cnst) fprintf(out, "%lld", cnst->v.int_value); } else if (is_type_float(type)) { long double const val = cnst->v.float_value; +#ifdef _WIN32 + /* ARG, no way to print long double */ + fprintf(out, "%.20g", (double)val); +#else fprintf(out, "%.20Lg", val); +#endif if (isfinite(val) && truncl(val) == val) fputs(".0", out); } else { @@ -385,7 +390,7 @@ static void print_compound_literal( { fputc('(', out); print_type(expression->type); - fputs(") ", out); + fputc(')', out); print_initializer(expression->initializer); } @@ -434,44 +439,42 @@ static void print_binary_expression(const binary_expression_t *binexpr) } print_expression_prec(binexpr->left, prec + r2l); - if (binexpr->base.kind != EXPR_BINARY_COMMA) { - fputc(' ', out); - } + char const* op; switch (binexpr->base.kind) { - case EXPR_BINARY_COMMA: fputs(",", out); break; - case EXPR_BINARY_ASSIGN: fputs("=", out); break; - case EXPR_BINARY_ADD: fputs("+", out); break; - case EXPR_BINARY_SUB: fputs("-", out); break; - case EXPR_BINARY_MUL: fputs("*", out); break; - case EXPR_BINARY_MOD: fputs("%", out); break; - case EXPR_BINARY_DIV: fputs("/", out); break; - case EXPR_BINARY_BITWISE_OR: fputs("|", out); break; - case EXPR_BINARY_BITWISE_AND: fputs("&", out); break; - case EXPR_BINARY_BITWISE_XOR: fputs("^", out); break; - case EXPR_BINARY_LOGICAL_OR: fputs("||", out); break; - case EXPR_BINARY_LOGICAL_AND: fputs("&&", out); break; - case EXPR_BINARY_NOTEQUAL: fputs("!=", out); break; - case EXPR_BINARY_EQUAL: fputs("==", out); break; - case EXPR_BINARY_LESS: fputs("<", out); break; - case EXPR_BINARY_LESSEQUAL: fputs("<=", out); break; - case EXPR_BINARY_GREATER: fputs(">", out); break; - case EXPR_BINARY_GREATEREQUAL: fputs(">=", out); break; - case EXPR_BINARY_SHIFTLEFT: fputs("<<", out); break; - case EXPR_BINARY_SHIFTRIGHT: fputs(">>", out); break; - - case EXPR_BINARY_ADD_ASSIGN: fputs("+=", out); break; - case EXPR_BINARY_SUB_ASSIGN: fputs("-=", out); break; - case EXPR_BINARY_MUL_ASSIGN: fputs("*=", out); break; - case EXPR_BINARY_MOD_ASSIGN: fputs("%=", out); break; - case EXPR_BINARY_DIV_ASSIGN: fputs("/=", out); break; - case EXPR_BINARY_BITWISE_OR_ASSIGN: fputs("|=", out); break; - case EXPR_BINARY_BITWISE_AND_ASSIGN: fputs("&=", out); break; - case EXPR_BINARY_BITWISE_XOR_ASSIGN: fputs("^=", out); break; - case EXPR_BINARY_SHIFTLEFT_ASSIGN: fputs("<<=", out); break; - case EXPR_BINARY_SHIFTRIGHT_ASSIGN: fputs(">>=", out); break; + case EXPR_BINARY_COMMA: op = ", "; break; + case EXPR_BINARY_ASSIGN: op = " = "; break; + case EXPR_BINARY_ADD: op = " + "; break; + case EXPR_BINARY_SUB: op = " - "; break; + case EXPR_BINARY_MUL: op = " * "; break; + case EXPR_BINARY_MOD: op = " % "; break; + case EXPR_BINARY_DIV: op = " / "; break; + case EXPR_BINARY_BITWISE_OR: op = " | "; break; + case EXPR_BINARY_BITWISE_AND: op = " & "; break; + case EXPR_BINARY_BITWISE_XOR: op = " ^ "; break; + case EXPR_BINARY_LOGICAL_OR: op = " || "; break; + case EXPR_BINARY_LOGICAL_AND: op = " && "; break; + case EXPR_BINARY_NOTEQUAL: op = " != "; break; + case EXPR_BINARY_EQUAL: op = " == "; break; + case EXPR_BINARY_LESS: op = " < "; break; + case EXPR_BINARY_LESSEQUAL: op = " <= "; break; + case EXPR_BINARY_GREATER: op = " > "; break; + case EXPR_BINARY_GREATEREQUAL: op = " >= "; break; + case EXPR_BINARY_SHIFTLEFT: op = " << "; break; + case EXPR_BINARY_SHIFTRIGHT: op = " >> "; break; + + case EXPR_BINARY_ADD_ASSIGN: op = " += "; break; + case EXPR_BINARY_SUB_ASSIGN: op = " -= "; break; + case EXPR_BINARY_MUL_ASSIGN: op = " *= "; break; + case EXPR_BINARY_MOD_ASSIGN: op = " %= "; break; + case EXPR_BINARY_DIV_ASSIGN: op = " /= "; break; + case EXPR_BINARY_BITWISE_OR_ASSIGN: op = " |= "; break; + case EXPR_BINARY_BITWISE_AND_ASSIGN: op = " &= "; break; + case EXPR_BINARY_BITWISE_XOR_ASSIGN: op = " ^= "; break; + case EXPR_BINARY_SHIFTLEFT_ASSIGN: op = " <<= "; break; + case EXPR_BINARY_SHIFTRIGHT_ASSIGN: op = " >>= "; break; default: panic("invalid binexpression found"); } - fputc(' ', out); + fputs(op, out); print_expression_prec(binexpr->right, prec - r2l); } @@ -655,7 +658,7 @@ static void print_va_start(const va_start_expression_t *const expression) print_expression_prec(expression->ap, PREC_COMMA + 1); fputs(", ", out); fputs(expression->parameter->symbol->string, out); - fputs(")", out); + fputc(')', out); } /** @@ -669,7 +672,7 @@ static void print_va_arg(const va_arg_expression_t *expression) print_expression_prec(expression->ap, PREC_COMMA + 1); fputs(", ", out); print_type(expression->base.type); - fputs(")", out); + fputc(')', out); } /** @@ -863,10 +866,11 @@ static void print_compound_statement(const compound_statement_t *block) ++indent; statement_t *statement = block->statements; - while(statement != NULL) { + while (statement != NULL) { if (statement->base.kind == STATEMENT_CASE_LABEL) --indent; - print_indent(); + if (statement->kind != STATEMENT_LABEL) + print_indent(); print_statement(statement); statement = statement->base.next; @@ -925,6 +929,7 @@ static void print_goto_statement(const goto_statement_t *statement) static void print_label_statement(const label_statement_t *statement) { fprintf(out, "%s:\n", statement->label->symbol->string); + print_indent(); print_statement(statement->statement); } @@ -997,21 +1002,38 @@ static void print_declaration_statement( const declaration_statement_t *statement) { bool first = true; - for (declaration_t *declaration = statement->declarations_begin; - declaration != statement->declarations_end->next; - declaration = declaration->next) { - if (declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY) - continue; - if (declaration->implicit) - continue; - - if (!first) { - print_indent(); - } else { - first = false; + declaration_t *declaration = statement->declarations_begin; + + if (declaration->namespc == NAMESPACE_LOCAL_LABEL) { + fputs("__label__ ", out); + for (; + declaration != statement->declarations_end->next; + declaration = declaration->next) { + if (!first) { + fputs(", ", out); + } else { + first = false; + } + fputs(declaration->symbol->string, out); + } + fputs(";\n", out); + } else { + for (; + declaration != statement->declarations_end->next; + declaration = declaration->next) { + if (declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY) + continue; + if (declaration->implicit) + continue; + + if (!first) { + print_indent(); + } else { + first = false; + } + print_declaration(declaration); + fputc('\n', out); } - print_declaration(declaration); - fputc('\n', out); } } @@ -1096,7 +1118,7 @@ static void print_asm_arguments(asm_argument_t *arguments) print_quoted_string(&argument->constraints, '"', 1); fputs(" (", out); print_expression(argument->expression); - fputs(")", out); + fputc(')', out); } } @@ -1127,20 +1149,21 @@ static void print_asm_statement(const asm_statement_t *statement) if(statement->is_volatile) { fputs("volatile ", out); } - fputs("(", out); + fputc('(', out); print_quoted_string(&statement->asm_text, '"', 1); - if(statement->inputs == NULL && statement->outputs == NULL - && statement->clobbers == NULL) + if (statement->outputs == NULL && + statement->inputs == NULL && + statement->clobbers == NULL) goto end_of_print_asm_statement; fputs(" : ", out); - print_asm_arguments(statement->inputs); - if(statement->outputs == NULL && statement->clobbers == NULL) + print_asm_arguments(statement->outputs); + if (statement->inputs == NULL && statement->clobbers == NULL) goto end_of_print_asm_statement; fputs(" : ", out); - print_asm_arguments(statement->outputs); - if(statement->clobbers == NULL) + print_asm_arguments(statement->inputs); + if (statement->clobbers == NULL) goto end_of_print_asm_statement; fputs(" : ", out); @@ -1188,7 +1211,7 @@ static void print_leave_statement(const leave_statement_t *statement) */ void print_statement(const statement_t *statement) { - switch(statement->kind) { + switch (statement->kind) { case STATEMENT_EMPTY: fputs(";\n", out); break; @@ -1244,7 +1267,7 @@ void print_statement(const statement_t *statement) print_leave_statement(&statement->leave); break; case STATEMENT_INVALID: - fputs("$invalid statement$", out); + fputs("$invalid statement$\n", out); break; } } @@ -1443,33 +1466,39 @@ void print_expression(const expression_t *expression) { */ void print_declaration(const declaration_t *declaration) { - if(declaration->namespc != NAMESPACE_NORMAL && - declaration->symbol == NULL) + if (declaration->namespc != NAMESPACE_NORMAL && + declaration->symbol == NULL) return; - switch(declaration->namespc) { + switch (declaration->namespc) { case NAMESPACE_NORMAL: print_normal_declaration(declaration); break; case NAMESPACE_STRUCT: fputs("struct ", out); fputs(declaration->symbol->string, out); - fputc(' ', out); - print_compound_definition(declaration); + if (declaration->init.complete) { + fputc(' ', out); + print_compound_definition(declaration); + } fputc(';', out); break; case NAMESPACE_UNION: fputs("union ", out); fputs(declaration->symbol->string, out); - fputc(' ', out); - print_compound_definition(declaration); + if (declaration->init.complete) { + fputc(' ', out); + print_compound_definition(declaration); + } fputc(';', out); break; case NAMESPACE_ENUM: fputs("enum ", out); fputs(declaration->symbol->string, out); - fputc(' ', out); - print_enum_definition(declaration); + if (declaration->init.complete) { + fputc(' ', out); + print_enum_definition(declaration); + } fputc(';', out); break; } @@ -1578,10 +1607,11 @@ bool is_address_constant(const expression_t *expression) case EXPR_UNARY_CAST: { type_t *dest = skip_typeref(expression->base.type); - if (!is_type_pointer(dest) && - ! (dest->kind == TYPE_ATOMIC - && (get_atomic_type_flags(dest->atomic.akind) & ATOMIC_TYPE_FLAG_INTEGER) - && (get_atomic_type_size(dest->atomic.akind) >= get_atomic_type_size(get_intptr_kind())))) + if (!is_type_pointer(dest) && ( + dest->kind != TYPE_ATOMIC || + !(get_atomic_type_flags(dest->atomic.akind) & ATOMIC_TYPE_FLAG_INTEGER) || + (get_atomic_type_size(dest->atomic.akind) < get_atomic_type_size(get_intptr_kind()) + ))) return false; return (is_constant_expression(expression->unary.value) @@ -1610,9 +1640,21 @@ bool is_address_constant(const expression_t *expression) if(is_type_array(type)) { return is_object_with_linker_constant_address(expression); } + /* Prevent stray errors */ + if (!is_type_valid(type)) + return true; return false; } + case EXPR_ARRAY_ACCESS: { + type_t *const type = + skip_typeref(revert_automatic_type_conversion(expression)); + return + is_type_array(type) && + is_constant_expression(expression->array_access.index) && + is_address_constant(expression->array_access.array_ref); + } + default: return false; } @@ -1644,8 +1686,6 @@ static bool is_constant_pointer(const expression_t *expression) return true; switch (expression->kind) { - case EXPR_SELECT: - return is_constant_pointer(expression->select.compound); case EXPR_UNARY_CAST: return is_constant_pointer(expression->unary.value); default: @@ -1666,9 +1706,17 @@ static bool is_object_with_constant_address(const expression_t *expression) return is_object_with_constant_address(compound); } } - case EXPR_ARRAY_ACCESS: - return is_constant_pointer(expression->array_access.array_ref) - && is_constant_expression(expression->array_access.index); + + case EXPR_ARRAY_ACCESS: { + array_access_expression_t const* const array_access = + &expression->array_access; + return + is_constant_expression(array_access->index) && ( + is_object_with_constant_address(array_access->array_ref) || + is_constant_pointer(array_access->array_ref) + ); + } + case EXPR_UNARY_DEREFERENCE: return is_constant_pointer(expression->unary.value); default: @@ -1728,6 +1776,7 @@ bool is_constant_expression(const expression_t *expression) case EXPR_BINARY_BITWISE_XOR_ASSIGN: case EXPR_BINARY_BITWISE_OR_ASSIGN: case EXPR_BINARY_COMMA: + case EXPR_ARRAY_ACCESS: return false; case EXPR_UNARY_TAKE_ADDRESS: @@ -1790,10 +1839,6 @@ bool is_constant_expression(const expression_t *expression) return is_constant_expression(expression->conditional.false_expression); } - case EXPR_ARRAY_ACCESS: - return is_constant_expression(expression->array_access.array_ref) - && is_constant_expression(expression->array_access.index); - case EXPR_REFERENCE: { declaration_t *declaration = expression->reference.declaration; if(declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY)