X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast.c;h=a191992127f95a720e06f0e8d8f2db1c457a7df4;hb=cf80e941ca33006ab52321c2c74c6c30a7a4d10a;hp=77be43e6d92e7a13fd16dbb0ab97bc983b24d12e;hpb=4ea6966017e1519a46f887b8db6cb4023d9628c4;p=cparser diff --git a/ast.c b/ast.c index 77be43e..a191992 100644 --- a/ast.c +++ b/ast.c @@ -636,7 +636,7 @@ static void print_select(const select_expression_t *expression) { unsigned prec = get_expression_precedence(expression->base.kind); print_expression_prec(expression->compound, prec); - if(is_type_pointer(expression->compound->base.type)) { + if(is_type_pointer(skip_typeref(expression->compound->base.type))) { fputs("->", out); } else { fputc('.', out); @@ -1020,23 +1020,23 @@ static void print_for_statement(const for_statement_t *statement) } /** - * Print assembler constraints. + * Print assembler arguments. * - * @param constraints the constraints + * @param arguments the arguments */ -static void print_asm_constraints(asm_constraint_t *constraints) +static void print_asm_arguments(asm_argument_t *arguments) { - asm_constraint_t *constraint = constraints; - for( ; constraint != NULL; constraint = constraint->next) { - if(constraint != constraints) + asm_argument_t *argument = arguments; + for( ; argument != NULL; argument = argument->next) { + if(argument != arguments) fputs(", ", out); - if(constraint->symbol) { - fprintf(out, "[%s] ", constraint->symbol->string); + if(argument->symbol) { + fprintf(out, "[%s] ", argument->symbol->string); } - print_quoted_string(&constraint->constraints, '"'); + print_quoted_string(&argument->constraints, '"'); fputs(" (", out); - print_expression(constraint->expression); + print_expression(argument->expression); fputs(")", out); } } @@ -1075,12 +1075,12 @@ static void print_asm_statement(const asm_statement_t *statement) goto end_of_print_asm_statement; fputs(" : ", out); - print_asm_constraints(statement->inputs); + print_asm_arguments(statement->inputs); if(statement->outputs == NULL && statement->clobbers == NULL) goto end_of_print_asm_statement; fputs(" : ", out); - print_asm_constraints(statement->outputs); + print_asm_arguments(statement->outputs); if(statement->clobbers == NULL) goto end_of_print_asm_statement; @@ -1268,7 +1268,7 @@ static void print_ms_modifiers(const declaration_t *declaration) { if((c_mode & _MS) == 0) return; - decl_modifiers_t modifiers = declaration->decl_modifiers; + decl_modifiers_t modifiers = declaration->modifiers; /* DM_FORCEINLINE handled outside. */ if((modifiers & ~DM_FORCEINLINE) != 0 || @@ -1342,10 +1342,10 @@ static void print_normal_declaration(const declaration_t *declaration) { print_storage_class((storage_class_tag_t) declaration->declared_storage_class); if(declaration->is_inline) { - if(declaration->decl_modifiers & DM_FORCEINLINE) + if(declaration->modifiers & DM_FORCEINLINE) fputs("__forceinline ", out); else { - if(declaration->decl_modifiers & DM_MICROSOFT_INLINE) + if(declaration->modifiers & DM_MICROSOFT_INLINE) fputs("__inline ", out); else fputs("inline ", out); @@ -1461,7 +1461,7 @@ bool is_constant_initializer(const initializer_t *initializer) panic("invalid initializer kind found"); } -static bool is_object_with_constant_address(const expression_t *expression) +static bool is_object_with_linker_constant_address(const expression_t *expression) { switch(expression->kind) { case EXPR_UNARY_DEREFERENCE: @@ -1472,7 +1472,7 @@ static bool is_object_with_constant_address(const expression_t *expression) /* it's a -> */ return is_address_constant(expression->select.compound); } else { - return is_object_with_constant_address(expression->select.compound); + return is_object_with_linker_constant_address(expression->select.compound); } } @@ -1501,14 +1501,17 @@ bool is_address_constant(const expression_t *expression) { switch(expression->kind) { case EXPR_UNARY_TAKE_ADDRESS: - return is_object_with_constant_address(expression->unary.value); + return is_object_with_linker_constant_address(expression->unary.value); case EXPR_UNARY_DEREFERENCE: { - type_t *real_type = revert_automatic_type_conversion(expression->unary.value); + type_t *real_type + = revert_automatic_type_conversion(expression->unary.value); /* dereferencing a function is a NOP */ if(is_type_function(real_type)) { return is_address_constant(expression->unary.value); } + + /* fallthrough */ } case EXPR_UNARY_CAST: @@ -1536,7 +1539,7 @@ bool is_address_constant(const expression_t *expression) if(is_type_function(type)) return true; if(is_type_array(type)) { - return is_object_with_constant_address(expression); + return is_object_with_linker_constant_address(expression); } return false; } @@ -1546,6 +1549,62 @@ bool is_address_constant(const expression_t *expression) } } +static bool is_builtin_const_call(const expression_t *expression) +{ + expression_t *function = expression->call.function; + if (function->kind != EXPR_BUILTIN_SYMBOL) { + return false; + } + + symbol_t *symbol = function->builtin_symbol.symbol; + + switch (symbol->ID) { + case T___builtin_huge_val: + case T___builtin_nan: + case T___builtin_nanf: + case T___builtin_nand: + return true; + } + + return false; +} + +static bool is_constant_pointer(const expression_t *expression) +{ + if (is_constant_expression(expression)) + return true; + + switch (expression->kind) { + case EXPR_UNARY_CAST: + return is_constant_pointer(expression->unary.value); + default: + return false; + } +} + +static bool is_object_with_constant_address(const expression_t *expression) +{ + switch(expression->kind) { + case EXPR_SELECT: { + expression_t *compound = expression->select.compound; + type_t *compound_type = compound->base.type; + compound_type = skip_typeref(compound_type); + if(is_type_pointer(compound_type)) { + return is_constant_pointer(compound); + } else { + 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_UNARY_DEREFERENCE: + return is_constant_pointer(expression->unary.value); + default: + return false; + } +} + bool is_constant_expression(const expression_t *expression) { switch(expression->kind) { @@ -1565,7 +1624,6 @@ bool is_constant_expression(const expression_t *expression) case EXPR_BUILTIN_SYMBOL: case EXPR_BUILTIN_PREFETCH: - case EXPR_CALL: case EXPR_SELECT: case EXPR_VA_START: case EXPR_VA_ARG: @@ -1575,7 +1633,6 @@ bool is_constant_expression(const expression_t *expression) case EXPR_UNARY_PREFIX_INCREMENT: case EXPR_UNARY_PREFIX_DECREMENT: case EXPR_UNARY_ASSUME: /* has VOID type */ - case EXPR_UNARY_TAKE_ADDRESS: case EXPR_UNARY_DEREFERENCE: case EXPR_BINARY_ASSIGN: case EXPR_BINARY_MUL_ASSIGN: @@ -1591,6 +1648,12 @@ bool is_constant_expression(const expression_t *expression) case EXPR_BINARY_COMMA: return false; + case EXPR_UNARY_TAKE_ADDRESS: + return is_object_with_constant_address(expression->unary.value); + + case EXPR_CALL: + return is_builtin_const_call(expression); + case EXPR_UNARY_NEGATE: case EXPR_UNARY_PLUS: case EXPR_UNARY_BITWISE_NEGATE: