X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast.c;h=a191992127f95a720e06f0e8d8f2db1c457a7df4;hb=cf80e941ca33006ab52321c2c74c6c30a7a4d10a;hp=b7b0f9cd99ff2ebec0d8fc9ba8bb34f5ecaf36ef;hpb=7c3e9800278cd3f36d1a9de106808625fc29767e;p=cparser diff --git a/ast.c b/ast.c index b7b0f9c..a191992 100644 --- a/ast.c +++ b/ast.c @@ -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; } @@ -1566,6 +1569,42 @@ static bool is_builtin_const_call(const expression_t *expression) 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) { @@ -1594,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: @@ -1610,6 +1648,9 @@ 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);