diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2021-01-01 22:21:46 +0100 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2021-01-01 22:21:46 +0100 |
| commit | fe455dd6b9fb47743271f342691c4b68532f1260 (patch) | |
| tree | 44e21912adf82caa03e11214fc682bbe460e1b16 /parse.c | |
| parent | 10283ac0f48df99e02a5cb16a423972ae42de00d (diff) | |
| parent | 2cf493d1f63f075e6fe0cccbcb7463b1aa773a74 (diff) | |
| download | sparse-dev-fe455dd6b9fb47743271f342691c4b68532f1260.tar.gz | |
Merge branch 'packed'
* packed: add support for __packed struct
Diffstat (limited to 'parse.c')
| -rw-r--r-- | parse.c | 78 |
1 files changed, 41 insertions, 37 deletions
@@ -669,6 +669,8 @@ struct statement *alloc_statement(struct position pos, int type) static struct token *struct_declaration_list(struct token *token, struct symbol_list **list); +static void apply_ctype(struct position pos, struct ctype *dst, struct ctype *src); + static void apply_modifiers(struct position pos, struct decl_state *ctx) { struct symbol *ctype; @@ -717,10 +719,11 @@ static struct token *struct_union_enum_specifier(enum type type, struct token *token, struct decl_state *ctx, struct token *(*parse)(struct token *, struct symbol *)) { + struct decl_state attr = { }; struct symbol *sym; struct position *repos; - token = handle_attributes(token, ctx); + token = handle_attributes(token, &attr); if (token_type(token) == TOKEN_IDENT) { sym = lookup_symbol(token->ident, NS_STRUCT); if (!sym || @@ -736,35 +739,36 @@ static struct token *struct_union_enum_specifier(enum type type, ctx->ctype.base_type = sym; repos = &token->pos; token = token->next; - if (match_op(token, '{')) { - // The following test is actually wrong for empty - // structs, but (1) they are not C99, (2) gcc does - // the same thing, and (3) it's easier. - if (sym->symbol_list) - error_die(token->pos, "redefinition of %s", show_typename (sym)); - sym->pos = *repos; - token = parse(token->next, sym); - token = expect(token, '}', "at end of struct-union-enum-specifier"); - - // Mark the structure as needing re-examination - sym->examined = 0; - sym->endpos = token->pos; - } - return token; - } + if (!match_op(token, '{')) + return token; - // private struct/union/enum type - if (!match_op(token, '{')) { + // The following test is actually wrong for empty + // structs, but (1) they are not C99, (2) gcc does + // the same thing, and (3) it's easier. + if (sym->symbol_list) + error_die(token->pos, "redefinition of %s", show_typename (sym)); + sym->pos = *repos; + + // Mark the structure as needing re-examination + sym->examined = 0; + } else if (match_op(token, '{')) { + // private struct/union/enum type + sym = alloc_symbol(token->pos, type); + set_current_scope(sym); // used by dissect + ctx->ctype.base_type = sym; + } else { sparse_error(token->pos, "expected declaration"); ctx->ctype.base_type = &bad_ctype; return token; } - sym = alloc_symbol(token->pos, type); - set_current_scope(sym); // used by dissect token = parse(token->next, sym); - ctx->ctype.base_type = sym; - token = expect(token, '}', "at end of specifier"); + token = expect(token, '}', "at end of specifier"); + attr.ctype.base_type = sym; + token = handle_attributes(token, &attr); + apply_ctype(token->pos, &sym->ctype, &attr.ctype); + sym->packed = attr.packed; + sym->endpos = token->pos; return token; @@ -1043,8 +1047,6 @@ static struct token *enum_specifier(struct token *token, struct symbol *sym, str return ret; } -static void apply_ctype(struct position pos, struct ctype *thistype, struct ctype *ctype); - static struct token *typeof_specifier(struct token *token, struct symbol *sym, struct decl_state *ctx) { @@ -1056,7 +1058,7 @@ static struct token *typeof_specifier(struct token *token, struct symbol *sym, s struct symbol *sym; token = typename(token->next, &sym, NULL); ctx->ctype.base_type = sym->ctype.base_type; - apply_ctype(token->pos, &sym->ctype, &ctx->ctype); + apply_ctype(token->pos, &ctx->ctype, &sym->ctype); } else { struct symbol *typeof_sym = alloc_symbol(token->pos, SYM_TYPEOF); token = parse_expression(token->next, &typeof_sym->initializer); @@ -1088,8 +1090,10 @@ static struct token *ignore_attribute(struct token *token, struct symbol *attr, static struct token *attribute_packed(struct token *token, struct symbol *attr, struct decl_state *ctx) { - if (!ctx->ctype.alignment) + if (!ctx->ctype.alignment) { ctx->ctype.alignment = 1; + ctx->packed = 1; + } return token; } @@ -1427,24 +1431,24 @@ static struct token *generic_qualifier(struct token *next, struct symbol *sym, s return next; } -static void apply_ctype(struct position pos, struct ctype *thistype, struct ctype *ctype) +static void apply_ctype(struct position pos, struct ctype *dst, struct ctype *src) { - unsigned long mod = thistype->modifiers; + unsigned long mod = src->modifiers; if (mod) - apply_qualifier(&pos, ctype, mod); + apply_qualifier(&pos, dst, mod); /* Context */ - concat_ptr_list((struct ptr_list *)thistype->contexts, - (struct ptr_list **)&ctype->contexts); + concat_ptr_list((struct ptr_list *)src->contexts, + (struct ptr_list **)&dst->contexts); /* Alignment */ - if (thistype->alignment > ctype->alignment) - ctype->alignment = thistype->alignment; + if (src->alignment > dst->alignment) + dst->alignment = src->alignment; /* Address space */ - if (thistype->as) - ctype->as = thistype->as; + if (src->as) + dst->as = src->as; } static void specifier_conflict(struct position pos, int what, struct ident *new) @@ -1529,7 +1533,7 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta break; seen |= Set_S | Set_T; ctx->ctype.base_type = s->ctype.base_type; - apply_ctype(token->pos, &s->ctype, &ctx->ctype); + apply_ctype(token->pos, &ctx->ctype, &s->ctype); token = token->next; continue; } |
