#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"
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 */
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");
}
/**
}
} 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)) {
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;
break;
}
+ case EXPR_CLASS_CONSTANT:
case EXPR_CLASS_VARIABLE:
array_type->array.is_vla = true;
break;
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;
}
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) {
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 {
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");
}
}
}
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");
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) {
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)
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");
}
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");
}