The kernel has recently started using the __cleanup__ attribute. Save a pointer to cleanup function. Signed-off-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx> --- v2: The first version of this patch had a bug handling a list of declarations. I had to add a .cleanup = NULL at the start of the loops iterations in declaration_list() and external_declaration(). parse.c | 26 +++++++++++++++++++++++++- symbol.h | 2 ++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/parse.c b/parse.c index 3d6fef7cb011..e5b5e6acc062 100644 --- a/parse.c +++ b/parse.c @@ -79,7 +79,8 @@ typedef struct token *attr_t(struct token *, struct symbol *, struct decl_state *); static attr_t - attribute_packed, attribute_aligned, attribute_modifier, + attribute_packed, attribute_aligned, attribute_cleanup, + attribute_modifier, attribute_function, attribute_bitwise, attribute_address_space, attribute_context, @@ -361,6 +362,10 @@ static struct symbol_op aligned_op = { .attribute = attribute_aligned, }; +static struct symbol_op cleanup_op = { + .attribute = attribute_cleanup, +}; + static struct symbol_op attr_mod_op = { .attribute = attribute_modifier, }; @@ -537,6 +542,7 @@ static struct init_keyword { /* Attributes */ D("packed", &packed_op), D("aligned", &aligned_op), + D("__cleanup__", &cleanup_op), D("nocast", &attr_mod_op, .mods = MOD_NOCAST), D("noderef", &attr_mod_op, .mods = MOD_NODEREF), D("safe", &attr_mod_op, .mods = MOD_SAFE), @@ -1114,6 +1120,18 @@ static struct token *attribute_aligned(struct token *token, struct symbol *attr, return token; } +static struct token *attribute_cleanup(struct token *token, struct symbol *attr, struct decl_state *ctx) +{ + struct expression *expr = NULL; + + if (match_op(token, '(')) { + token = parens_expression(token, &expr, "in attribute"); + if (expr && expr->type == EXPR_SYMBOL) + ctx->cleanup = expr; + } + return token; +} + static void apply_mod(struct position *pos, unsigned long *mods, unsigned long mod) { if (*mods & mod & ~MOD_DUP_OK) @@ -1899,6 +1917,7 @@ static struct token *declaration_list(struct token *token, struct symbol_list ** saved = ctx.ctype; for (;;) { struct symbol *decl = alloc_symbol(token->pos, SYM_NODE); + ctx.cleanup = NULL; ctx.ident = &decl->ident; token = declarator(token, &ctx); @@ -1910,6 +1929,7 @@ static struct token *declaration_list(struct token *token, struct symbol_list ** decl->ctype = ctx.ctype; decl->ctype.modifiers |= mod; + decl->cleanup = ctx.cleanup; decl->endpos = token->pos; add_symbol(list, decl); if (!match_op(token, ',')) @@ -1964,6 +1984,7 @@ struct token *typename(struct token *token, struct symbol **p, int *forced) token = declarator(token, &ctx); apply_modifiers(token->pos, &ctx); sym->ctype = ctx.ctype; + sym->cleanup = ctx.cleanup; sym->endpos = token->pos; class = ctx.storage_class; if (forced) @@ -2924,6 +2945,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis decl->ctype = ctx.ctype; decl->ctype.modifiers |= mod; + decl->cleanup = ctx.cleanup; decl->endpos = token->pos; /* Just a type declaration? */ @@ -3041,6 +3063,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis ident = NULL; decl = alloc_symbol(token->pos, SYM_NODE); ctx.ctype = saved; + ctx.cleanup = NULL; token = handle_attributes(token, &ctx); token = declarator(token, &ctx); token = handle_asm_name(token, &ctx); @@ -3048,6 +3071,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis apply_modifiers(token->pos, &ctx); decl->ctype = ctx.ctype; decl->ctype.modifiers |= mod; + decl->cleanup = ctx.cleanup; decl->endpos = token->pos; if (!ident) { sparse_error(token->pos, "expected identifier name in type definition"); diff --git a/symbol.h b/symbol.h index 5270fcd73a10..88130c15d4bd 100644 --- a/symbol.h +++ b/symbol.h @@ -107,6 +107,7 @@ struct decl_state { struct ctype ctype; struct ident **ident; struct symbol_op *mode; + struct expression *cleanup; unsigned long f_modifiers; // function attributes unsigned long storage_class; unsigned char prefer_abstract; @@ -204,6 +205,7 @@ struct symbol { struct statement *inline_stmt; struct symbol_list *inline_symbol_list; struct expression *initializer; + struct expression *cleanup; struct entrypoint *ep; struct symbol *definition; }; -- 2.42.0