parser: Remove the unused attribute alignment from struct declaration_specifiers_t.
[cparser] / parser.c
index 95a204f..b95b756 100644 (file)
--- a/parser.c
+++ b/parser.c
 #include <stdbool.h>
 
 #include "adt/strutil.h"
+#include "adt/util.h"
 #include "parser.h"
 #include "diagnostic.h"
 #include "format_check.h"
 #include "preprocessor.h"
 #include "symbol_t.h"
+#include "symbol_table.h"
 #include "token_t.h"
 #include "types.h"
 #include "type_t.h"
 #include "type_hash.h"
 #include "ast_t.h"
-#include "entity_t.h"
 #include "attribute_t.h"
 #include "lang_features.h"
 #include "walk.h"
 #include "warning.h"
 #include "printer.h"
 #include "ast2firm.h"
-#include "adt/bitfiddle.h"
 #include "adt/error.h"
 #include "adt/array.h"
 
@@ -44,7 +44,6 @@ typedef struct declaration_specifiers_t  declaration_specifiers_t;
 struct declaration_specifiers_t {
        position_t      pos;
        storage_class_t storage_class;
-       unsigned char   alignment;         /**< Alignment, 0 if not set. */
        bool            is_inline    : 1;
        bool            thread_local : 1;
        attribute_t    *attributes;        /**< list of attributes */
@@ -856,18 +855,17 @@ static bool is_null_pointer_constant(const expression_t *expression)
        /* skip void* cast */
        if (expression->kind == EXPR_UNARY_CAST) {
                type_t *const type = skip_typeref(expression->base.type);
-               if (types_compatible(type, type_void_ptr))
+               if (type == type_void_ptr)
                        expression = expression->unary.value;
        }
 
-       type_t *const type = skip_typeref(expression->base.type);
-       if (!is_type_integer(type))
-               return false;
        switch (is_constant_expression(expression)) {
-               case EXPR_CLASS_ERROR:    return true;
-               case EXPR_CLASS_CONSTANT: return !fold_constant_to_bool(expression);
-               default:                  return false;
+               case EXPR_CLASS_VARIABLE:         return false;
+               case EXPR_CLASS_ERROR:            return true;
+               case EXPR_CLASS_CONSTANT:         return false;
+               case EXPR_CLASS_INTEGER_CONSTANT: return !fold_constant_to_bool(expression);
        }
+       panic("invalid expression classification");
 }
 
 /**
@@ -1838,7 +1836,7 @@ static bool walk_designator(type_path_t *path, const designator_t *designator,
                        }
                } else {
                        expression_t *array_index = designator->array_index;
-                       if (is_constant_expression(array_index) != EXPR_CLASS_CONSTANT)
+                       if (is_constant_expression(array_index) < EXPR_CLASS_CONSTANT)
                                return true;
 
                        if (!is_type_array(type)) {
@@ -3558,7 +3556,7 @@ static type_t *construct_declarator_type(construct_type_t *construct_list,
 
                        if (size_expression != NULL) {
                                switch (is_constant_expression(size_expression)) {
-                               case EXPR_CLASS_CONSTANT: {
+                               case EXPR_CLASS_INTEGER_CONSTANT: {
                                        long const size = fold_constant_to_int(size_expression);
                                        array_type->array.size          = size;
                                        array_type->array.size_constant = true;
@@ -3574,6 +3572,7 @@ static type_t *construct_declarator_type(construct_type_t *construct_list,
                                        break;
                                }
 
+                               case EXPR_CLASS_CONSTANT:
                                case EXPR_CLASS_VARIABLE:
                                        array_type->array.is_vla = true;
                                        break;
@@ -4587,8 +4586,8 @@ static void check_declarations(void)
 static int determine_truth(expression_t const* const cond)
 {
        return
-               is_constant_expression(cond) != EXPR_CLASS_CONSTANT ? 0 :
-               fold_constant_to_bool(cond)                         ? 1 :
+               is_constant_expression(cond) < EXPR_CLASS_CONSTANT ? 0 :
+               fold_constant_to_bool(cond)                        ? 1 :
                -1;
 }
 
@@ -4796,7 +4795,7 @@ static void check_reachable(statement_t *const stmt)
                        if (!expression_returns(expr))
                                return;
 
-                       if (is_constant_expression(expr) == EXPR_CLASS_CONSTANT) {
+                       if (is_constant_expression(expr) >= EXPR_CLASS_CONSTANT) {
                                ir_tarval              *const val      = fold_constant_to_tarval(expr);
                                case_label_statement_t *      defaults = NULL;
                                for (case_label_statement_t *i = switchs->first_case; i != NULL; i = i->next) {
@@ -5463,7 +5462,7 @@ static void parse_bitfield_member(entity_t *entity)
                           type);
        }
 
-       if (is_constant_expression(size) != EXPR_CLASS_CONSTANT) {
+       if (is_constant_expression(size) < EXPR_CLASS_CONSTANT) {
                /* error already reported by parse_constant_expression */
                size_long = get_type_size(type) * 8;
        } else {
@@ -5498,65 +5497,43 @@ static void parse_compound_declarators(compound_t *compound,
        add_anchor_token(';');
        add_anchor_token(',');
        do {
-               entity_t *entity;
-               if (token.kind == ':') {
-                       /* anonymous bitfield */
-                       type_t *type = specifiers->type;
-                       entity = allocate_entity_zero(ENTITY_COMPOUND_MEMBER, NAMESPACE_NORMAL, NULL, HERE);
-                       entity->declaration.declared_storage_class = STORAGE_CLASS_NONE;
-                       entity->declaration.storage_class          = STORAGE_CLASS_NONE;
-                       entity->declaration.type                   = type;
-
-                       parse_bitfield_member(entity);
-
-                       attribute_t  *attributes = parse_attributes(NULL);
-                       attribute_t **anchor     = &attributes;
-                       while (*anchor != NULL)
-                               anchor = &(*anchor)->next;
-                       *anchor = specifiers->attributes;
-                       if (attributes != NULL) {
-                               handle_entity_attributes(attributes, entity);
-                       }
-                       entity->declaration.attributes = attributes;
-               } else {
-                       entity = parse_declarator(specifiers, DECL_MAY_BE_ABSTRACT | DECL_CREATE_COMPOUND_MEMBER);
-                       position_t const *const pos = &entity->base.pos;
-                       if (entity->kind == ENTITY_TYPEDEF) {
-                               errorf(pos, "typedef not allowed as compound member");
-                               continue;
-                       }
+               entity_t         *const entity = parse_declarator(specifiers, DECL_MAY_BE_ABSTRACT | DECL_CREATE_COMPOUND_MEMBER);
+               position_t const *const pos    = &entity->base.pos;
+               if (entity->kind == ENTITY_TYPEDEF) {
+                       errorf(pos, "typedef not allowed as compound member");
+                       continue;
+               }
 
-                       assert(entity->kind == ENTITY_COMPOUND_MEMBER);
+               assert(entity->kind == ENTITY_COMPOUND_MEMBER);
 
-                       /* make sure we don't define a symbol multiple times */
-                       symbol_t *symbol = entity->base.symbol;
-                       if (symbol != NULL) {
-                               entity_t *prev = find_compound_entry(compound, symbol);
-                               if (prev != NULL) {
-                                       position_t const *const ppos = &prev->base.pos;
-                                       errorf(pos, "multiple declarations of '%N' (declared %P)", entity, ppos);
-                               }
+               /* make sure we don't define a symbol multiple times */
+               symbol_t *symbol = entity->base.symbol;
+               if (symbol != NULL) {
+                       entity_t *prev = find_compound_entry(compound, symbol);
+                       if (prev != NULL) {
+                               position_t const *const ppos = &prev->base.pos;
+                               errorf(pos, "multiple declarations of '%N' (declared %P)", entity, ppos);
                        }
+               }
 
-                       if (token.kind == ':') {
-                               parse_bitfield_member(entity);
+               if (token.kind == ':') {
+                       parse_bitfield_member(entity);
 
-                               attribute_t *attributes = parse_attributes(NULL);
-                               handle_entity_attributes(attributes, entity);
-                       } else {
-                               type_t *orig_type = entity->declaration.type;
-                               type_t *type      = skip_typeref(orig_type);
-                               if (is_type_function(type)) {
-                                       errorf(pos, "'%N' must not have function type '%T'", entity, orig_type);
-                               } else if (is_type_incomplete(type)) {
-                                       /* §6.7.2.1:16 flexible array member */
-                                       if (!is_type_array(type)       ||
-                                                       token.kind          != ';' ||
-                                                       look_ahead(1)->kind != '}') {
-                                               errorf(pos, "'%N' has incomplete type '%T'", entity, orig_type);
-                                       } else if (compound->members.entities == NULL) {
-                                               errorf(pos, "flexible array member in otherwise empty struct");
-                                       }
+                       attribute_t *attributes = parse_attributes(NULL);
+                       handle_entity_attributes(attributes, entity);
+               } else {
+                       type_t *orig_type = entity->declaration.type;
+                       type_t *type      = skip_typeref(orig_type);
+                       if (is_type_function(type)) {
+                               errorf(pos, "'%N' must not have function type '%T'", entity, orig_type);
+                       } else if (is_type_incomplete(type)) {
+                               /* §6.7.2.1:16 flexible array member */
+                               if (!is_type_array(type)       ||
+                                               token.kind          != ';' ||
+                                               look_ahead(1)->kind != '}') {
+                                       errorf(pos, "'%N' has incomplete type '%T'", entity, orig_type);
+                               } else if (compound->members.entities == NULL) {
+                                       errorf(pos, "flexible array member in otherwise empty struct");
                                }
                        }
                }
@@ -7871,7 +7848,7 @@ static void warn_div_by_zero(binary_expression_t const *const expression)
        expression_t const *const right = expression->right;
        /* The type of the right operand can be different for /= */
        if (is_type_integer(skip_typeref(right->base.type))      &&
-           is_constant_expression(right) == EXPR_CLASS_CONSTANT &&
+           is_constant_expression(right) >= EXPR_CLASS_CONSTANT &&
            !fold_constant_to_bool(right)) {
                position_t const *const pos = &expression->base.pos;
                warningf(WARN_DIV_BY_ZERO, pos, "division by zero");
@@ -7931,7 +7908,7 @@ static bool semantic_shift(binary_expression_t *expression)
 
        type_left = promote_integer(type_left);
 
-       if (is_constant_expression(right) == EXPR_CLASS_CONSTANT) {
+       if (is_constant_expression(right) >= EXPR_CLASS_CONSTANT) {
                position_t const *const pos   = &right->base.pos;
                long              const count = fold_constant_to_int(right);
                if (count < 0) {
@@ -8057,10 +8034,12 @@ static void warn_string_literal_address(expression_t const* expr)
 static bool maybe_negative(expression_t const *const expr)
 {
        switch (is_constant_expression(expr)) {
-               case EXPR_CLASS_ERROR:    return false;
-               case EXPR_CLASS_CONSTANT: return constant_is_negative(expr);
-               default:                  return true;
+               case EXPR_CLASS_VARIABLE:         return true;
+               case EXPR_CLASS_ERROR:            return false;
+               case EXPR_CLASS_CONSTANT:
+               case EXPR_CLASS_INTEGER_CONSTANT: return constant_is_negative(expr);
        }
+       panic("invalid expression classification");
 }
 
 static void warn_comparison(position_t const *const pos, expression_t const *const expr, expression_t const *const other)
@@ -8944,7 +8923,7 @@ static statement_t *parse_case_statement(void)
 
        statement->case_label.expression = expression;
        expression_classification_t const expr_class = is_constant_expression(expression);
-       if (expr_class != EXPR_CLASS_CONSTANT) {
+       if (expr_class < EXPR_CLASS_CONSTANT) {
                if (expr_class != EXPR_CLASS_ERROR) {
                        errorf(pos, "case label does not reduce to an integer constant");
                }
@@ -8968,7 +8947,7 @@ static statement_t *parse_case_statement(void)
                        end_range = create_implicit_cast(end_range, type);
                        statement->case_label.end_range = end_range;
                        expression_classification_t const end_class = is_constant_expression(end_range);
-                       if (end_class != EXPR_CLASS_CONSTANT) {
+                       if (end_class < EXPR_CLASS_CONSTANT) {
                                if (end_class != EXPR_CLASS_ERROR) {
                                        errorf(pos, "case range does not reduce to an integer constant");
                                }