diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-06-04 17:06:00 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-06-04 17:06:00 +0000 |
commit | 7acb29a3d9e072c65c26e582d4f4204dcf232d4a (patch) | |
tree | d3d591092d6a64dfc049785317e9f17e96cf7276 /gcc/c-common.c | |
parent | 3fd62642d6a042a192f405ab559a0fef3c49f588 (diff) | |
download | gcc-7acb29a3d9e072c65c26e582d4f4204dcf232d4a.tar.gz |
* c-common.c (handle_cleanup_attribute): New.
(c_common_attributes): Add it.
* c-decl.c (finish_decl): Honor the cleanup attribute.
* doc/extend.texi (Variable Attributes): Document it.
* unwind-c.c: New file.
* Makefile.in (LIB2ADDEH): Add it.
* config/t-darwin, config/t-linux, config/t-linux-gnulibc1,
config/ia64/t-ia64: Likewise.
* gcc.dg/cleanup-1.c: New.
* gcc.dg/cleanup-2.c: New.
* gcc.dg/cleanup-3.c: New.
* gcc.dg/cleanup-4.c: New.
* gcc.dg/cleanup-5.c: New.
* gcc.dg/cleanup-6.c: New.
* gcc.dg/cleanup-7.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@67449 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index fe196b124bf..d194012e956 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -41,7 +41,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "target.h" #include "langhooks.h" #include "tree-inline.h" - +#include "c-tree.h" cpp_reader *parse_in; /* Declared in c-pragma.h. */ @@ -792,6 +792,8 @@ static tree handle_nonnull_attribute PARAMS ((tree *, tree, tree, int, bool *)); static tree handle_nothrow_attribute PARAMS ((tree *, tree, tree, int, bool *)); +static tree handle_cleanup_attribute PARAMS ((tree *, tree, tree, int, + bool *)); static tree vector_size_helper PARAMS ((tree, tree)); static void check_function_nonnull PARAMS ((tree, tree)); @@ -868,6 +870,8 @@ const struct attribute_spec c_common_attribute_table[] = { "nothrow", 0, 0, true, false, false, handle_nothrow_attribute }, { "may_alias", 0, 0, false, true, false, NULL }, + { "cleanup", 1, 1, true, false, false, + handle_cleanup_attribute }, { NULL, 0, 0, false, false, false, NULL } }; @@ -6093,6 +6097,55 @@ handle_nothrow_attribute (node, name, args, flags, no_add_attrs) return NULL_TREE; } + +/* Handle a "cleanup" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_cleanup_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; + tree args; + int flags ATTRIBUTE_UNUSED; + bool *no_add_attrs; +{ + tree decl = *node; + tree cleanup_id, cleanup_decl; + + /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do + for global destructors in C++. This requires infrastructure that + we don't have generically at the moment. It's also not a feature + we'd be missing too much, since we do have attribute constructor. */ + if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)) + { + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + return NULL_TREE; + } + + /* Verify that the argument is a function in scope. */ + /* ??? We could support pointers to functions here as well, if + that was considered desirable. */ + cleanup_id = TREE_VALUE (args); + if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE) + { + error ("cleanup arg not an identifier"); + *no_add_attrs = true; + return NULL_TREE; + } + cleanup_decl = lookup_name (cleanup_id); + if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL) + { + error ("cleanup arg not a function"); + *no_add_attrs = true; + return NULL_TREE; + } + + /* That the function has proper type is checked with the + eventual call to build_function_call. */ + + return NULL_TREE; +} /* Check for valid arguments being passed to a function. */ void |