summaryrefslogtreecommitdiff
path: root/gcc/config/arm
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2001-09-21 01:27:06 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2001-09-21 01:27:06 +0000
commite3c541f009be650d66aef14d6df32dae184e0f08 (patch)
treef30b39e86c1e124ae235fd7661bc83c06577bc32 /gcc/config/arm
parent476444cc89debd9fcf42ef56d9f9a413105fb6cf (diff)
downloadgcc-e3c541f009be650d66aef14d6df32dae184e0f08.tar.gz
Table-driven attributes.
* c-decl.c, config/alpha/alpha.c, config/arc/arc.c, config/arm/arm.c, config/arm/pe.c, config/avr/avr.c, config/avr/avr.h, config/d30v/d30v.h, config/fr30/fr30.h, config/h8300/h8300.c, config/i386/cygwin.h, config/i386/winnt.c, config/m32r/m32r.c, config/mcore/mcore.c, config/sh/sh.c, config/stormy16/stormy16.h, config/v850/v850.c, doc/c-tree.texi, doc/tm.texi, ggc-common.c, integrate.c, print-tree.c, tree.c, tree.h: Rename DECL_MACHINE_ATTRIBUTES to DECL_ATTRIBUTES. * tree.h (struct tree_decl): Change machine_attributes to attributes. * doc/c-tree.texi: Document that all attributes are now attached to decls and types. * c-common.c (add_attribute, attrtab, attrtab_idx, default_valid_lang_attribute, valid_lang_attribute): Remove. (attribute_tables, attributes_initialized, c_common_attribute_table, default_lang_attribute_table): New variables. (handle_packed_attribute, handle_nocommon_attribute, handle_common_attribute, handle_noreturn_attribute, handle_unused_attribute, handle_const_attribute, handle_transparent_union_attribute, handle_constructor_attribute, handle_destructor_attribute, handle_mode_attribute, handle_section_attribute, handle_aligned_attribute, handle_weak_attribute, handle_alias_attribute, handle_no_instrument_function_attribute, handle_no_check_memory_usage_attribute, handle_malloc_attribute, handle_no_limit_stack_attribute, handle_pure_attribute): New functions. (init_attributes, decl_attributes): Rewrite to implement table-driven attributes. * c-common.h (enum attribute_flags): Move to tree.h. * c-format.c (decl_handle_format_attribute, decl_handle_format_arg_attribute): Rename to handle_format_attribute and handle_format_arg_attribute. Update for table-driven attributes. * c-common.h (decl_handle_format_attribute, decl_handle_format_arg_attribute): Remove prototypes. (handle_format_attribute, handle_format_arg_attribute): Add prototypes. * c-decl.c (grokdeclarator): Handle attributes nested inside declarators. * c-parse.in (setattrs, maybe_setattrs): Remove. (maybe_type_quals_setattrs): Rename to maybe_type_quals_attrs. Update to handle nested attributes properly. (maybe_resetattrs, after_type_declarator, parm_declarator_nostarttypename, notype_declarator, absdcl1_noea, absdcl1_ea, direct_absdcl1): Update to handle nested attributes properly. (make_pointer_declarator): Update to handle nested attributes properly. * doc/extend.texi: Update documentation of limits of attributes syntax. Warn about problems with attribute semantics in C++. * target.h (struct target): Remove valid_decl_attribute and valid_type_attribute. Add attribute_table and function_attribute_inlinable_p. * target-def.h (TARGET_VALID_DECL_ATTRIBUTE, TARGET_VALID_TYPE_ATTRIBUTE): Remove. (TARGET_ATTRIBUTE_TABLE, TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P): Add. (TARGET_INITIALIZER): Update. * integrate.c (FUNCTION_ATTRIBUTE_INLINABLE_P): Remove default definition. (function_attribute_inlinable_p): New function. Check for the presence of any machine attributes before using targetm.function_attribute_inlinable_p. (function_cannot_inline_p): Update. * Makefile.in (integrate.o): Update dependencies. * doc/tm.texi: Update documentation of target attributes and example definition of TARGET_VALID_TYPE_ATTRIBUTE. * tree.c (default_valid_attribute_p, valid_machine_attribute): Remove. (default_target_attribute_table, default_function_attribute_inlinable_p): New. (lookup_attribute): Update comment to clarify handling of multiple attributes with the same name. (merge_attributes, attribute_list_contained): Allow multiple attributes with the same name but different arguments to appear in the same attribute list. * tree.h (default_valid_attribute_p): Remove prototype. (struct attribute_spec): New. (default_target_attribute_table): Declare. (enum attribute_flags): Move from c-common.h. Add ATTR_FLAG_TYPE_IN_PLACE. (default_function_attribute_inlinable_p): Declare. * config/alpha/alpha.c (vms_valid_decl_attribute_p): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (vms_attribute_table): New. * config/arc/arc.c (arc_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (arc_attribute_table, arc_handle_interrupt_attribute): New. * config/arm/arm.c (arm_valid_type_attribute_p, arm_valid_decl_attribute_p, arm_pe_valid_decl_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE, TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (arm_attribute_table, arm_handle_fndecl_attribute, arm_handle_isr_attribute): New. * config/avr/avr.c (avr_valid_type_attribute, avr_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE, TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (avr_attribute_table, avr_handle_progmem_attribute, avr_handle_fndecl_attribute): New. * config/c4x/c4x.c (c4x_valid_type_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (c4x_attribute_table, c4x_handle_fntype_attribute): New. * config/h8300/h8300.c (h8300_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (h8300_attribute_table, h8300_handle_fndecl_attribute, h8300_handle_eightbit_data_attribute, h8300_handle_tiny_data_attribute): New. * config/i386/i386-protos.h (ix86_valid_type_attribute_p, i386_pe_valid_decl_attribute_p, i386_pe_valid_type_attribute_p): Remove prototypes. (ix86_handle_dll_attribute, ix86_handle_shared_attribute): New declarations. * config/i386/i386.c (ix86_valid_type_attribute_p: Remove. (TARGET_VALID_TYPE_ATTRIBUTE, TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (ix86_attribute_table, ix86_handle_cdecl_attribute, ix86_handle_regparm_attribute): New. * config/i386/winnt.c (i386_pe_valid_decl_attribute_p, i386_pe_valid_type_attribute_p): Remove. (ix86_handle_dll_attribute, ix86_handle_shared_attribute): New. * config/ia64/ia64.c (ia64_valid_type_attribute): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (ia64_attribute_table): New. * config/m32r/m32r.c (m32r_valid_decl_attribute, interrupt_ident1, interrupt_ident2, model_ident1, model_ident2): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (init_idents): Update. (m32r_attribute_table, m32r_handle_model_attribute): New. * config/m68hc11/m68hc11.c (m68hc11_valid_type_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (m68hc11_attribute_table, m68hc11_handle_fntype_attribute): New. * config/mcore/mcore.c (mcore_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (mcore_attribute_table, mcore_handle_naked_attribute): New. * config/ns32k/ns32k.c (ns32k_valid_type_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (ns32k_attribute_table, ns32k_handle_fntype_attribute): New. * config/rs6000/rs6000.c (rs6000_valid_type_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (rs6000_attribute_table, rs6000_handle_longcall_attribute): New. * config/sh/sh.c (sh_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (sh_attribute_table, sh_handle_interrupt_handler_attribute, sh_handle_sp_switch_attribute, sh_handle_trap_exit_attribute): New. * config/stormy16/stormy16.c (stormy16_valid_type_attribute): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define (TARGET_ATTRIBUTE_TABLE): Define. (stormy16_attribute_table, stormy16_handle_interrupt_attribute): New. * config/v850/v850.c (v850_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (v850_attribute_table, v850_handle_interrupt_attribute, v850_handle_data_area_attribute): New. * config/v850/v850-c.c (mark_current_function_as_interrupt): Return void. Call decl_attributes instead of valid_machine_attribute. cp: Table-driven attributes. * decl.c: Rename DECL_MACHINE_ATTRIBUTES to DECL_ATTRIBUTES. * decl2.c (cplus_decl_attributes): Only take one attributes parameter. * cp-tree.c (cplus_decl_attributes): Update prototype. * class.c (finish_struct), decl.c (start_decl, start_function), decl2.c (grokfield), friend.c (do_friend), parse.y (parse_bitfield): Update calls to cplus_decl_attributes. * decl.c (grokdeclarator): Take a pointer to a single ordinary attribute list. * decl.h (grokdeclarator): Update prototype. * decl2.c (grokfield): Take a single ordinary attribute list. * friend.c (do_friend): Likewise. * decl.c (shadow_tag, groktypename, start_decl, start_handler_parms, grokdeclarator, grokparms, start_function, start_method), decl2.c (grokfield, grokbitfield, grokoptypename), parse.y (parse_field, parse_bitfield, component_decl_1), pt.c (process_template_parm, do_decl_instantiation): Pass single ordinary attribute lists around. * decl.c (grokdeclarator): Correct handling of nested attributes. Revert the patch 1998-10-18 Jason Merrill <jason@yorick.cygnus.com> * decl.c (grokdeclarator): Embedded attrs bind to the right, not the left. . * cp-tree.h (cp_valid_lang_attribute): Remove declaration (cp_attribute_table): Declare. * decl.c (valid_lang_attribute): Don't define. (lang_attribute_table): Define. (init_decl_processing): Initialize lang_attribute_table instead of valid_lang_attribute. * tree.c (cp_valid_lang_attribute): Remove. (handle_java_interface_attribute, handle_com_interface_attribute, handle_init_priority_attribute): New functions. (cp_attribute_table): New array. * decl2.c (import_export_class): Don't use targetm.valid_type_attribute. testsuite: Table-driven attributes. * g++.dg/ext/attrib1.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45718 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/arm')
-rw-r--r--gcc/config/arm/arm.c233
-rw-r--r--gcc/config/arm/pe.c6
2 files changed, 116 insertions, 123 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 1ad558e8b5b..fcd90ddf4bd 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -103,10 +103,9 @@ static int current_file_function_operand PARAMS ((rtx));
static Ulong arm_compute_save_reg_mask PARAMS ((void));
static Ulong arm_isr_value PARAMS ((tree));
static Ulong arm_compute_func_type PARAMS ((void));
-static int arm_valid_type_attribute_p PARAMS ((tree, tree,
- tree, tree));
-static int arm_valid_decl_attribute_p PARAMS ((tree, tree,
- tree, tree));
+static tree arm_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
+static tree arm_handle_isr_attribute PARAMS ((tree *, tree, tree, int, bool *));
+const struct attribute_spec arm_attribute_table[];
static void arm_output_function_epilogue PARAMS ((FILE *,
HOST_WIDE_INT));
static void arm_output_function_prologue PARAMS ((FILE *,
@@ -130,16 +129,8 @@ static int arm_adjust_cost PARAMS ((rtx, rtx, rtx, int));
#define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
#endif
-#undef TARGET_VALID_TYPE_ATTRIBUTE
-#define TARGET_VALID_TYPE_ATTRIBUTE arm_valid_type_attribute_p
-
-#undef TARGET_VALID_DECL_ATTRIBUTE
-#ifdef ARM_PE
- static int arm_pe_valid_decl_attribute_p PARAMS ((tree, tree, tree, tree));
-# define TARGET_VALID_DECL_ATTRIBUTE arm_pe_valid_decl_attribute_p
-#else
-# define TARGET_VALID_DECL_ATTRIBUTE arm_valid_decl_attribute_p
-#endif
+#undef TARGET_ATTRIBUTE_TABLE
+#define TARGET_ATTRIBUTE_TABLE arm_attribute_table
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE arm_output_function_prologue
@@ -845,7 +836,7 @@ arm_compute_func_type ()
if (current_function_needs_context)
type |= ARM_FT_NESTED;
- attr = DECL_MACHINE_ATTRIBUTES (current_function_decl);
+ attr = DECL_ATTRIBUTES (current_function_decl);
a = lookup_attribute ("naked", attr);
if (a != NULL_TREE)
@@ -1909,39 +1900,120 @@ arm_pr_long_calls_off (pfile)
}
-/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine
- specific attribute for TYPE. The attributes in ATTRIBUTES have
- previously been assigned to TYPE. */
-static int
-arm_valid_type_attribute_p (type, attributes, identifier, args)
- tree type;
- tree attributes ATTRIBUTE_UNUSED;
- tree identifier;
- tree args;
+/* Table of machine attributes. */
+const struct attribute_spec arm_attribute_table[] =
{
- if ( TREE_CODE (type) != FUNCTION_TYPE
- && TREE_CODE (type) != METHOD_TYPE
- && TREE_CODE (type) != FIELD_DECL
- && TREE_CODE (type) != TYPE_DECL)
- return 0;
-
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
/* Function calls made to this symbol must be done indirectly, because
it may lie outside of the 26 bit addressing range of a normal function
call. */
- if (is_attribute_p ("long_call", identifier))
- return (args == NULL_TREE);
-
+ { "long_call", 0, 0, false, true, true, NULL },
/* Whereas these functions are always known to reside within the 26 bit
addressing range. */
- if (is_attribute_p ("short_call", identifier))
- return (args == NULL_TREE);
-
+ { "short_call", 0, 0, false, true, true, NULL },
/* Interrupt Service Routines have special prologue and epilogue requirements. */
- if (is_attribute_p ("isr", identifier)
- || is_attribute_p ("interrupt", identifier))
- return arm_isr_value (args);
+ { "isr", 0, 1, false, false, false, arm_handle_isr_attribute },
+ { "interrupt", 0, 1, false, false, false, arm_handle_isr_attribute },
+ { "naked", 0, 0, true, false, false, arm_handle_fndecl_attribute },
+#ifdef ARM_PE
+ /* ARM/PE has three new attributes:
+ interfacearm - ?
+ dllexport - for exporting a function/variable that will live in a dll
+ dllimport - for importing a function/variable from a dll
+
+ Microsoft allows multiple declspecs in one __declspec, separating
+ them with spaces. We do NOT support this. Instead, use __declspec
+ multiple times.
+ */
+ { "dllimport", 0, 0, true, false, false, NULL },
+ { "dllexport", 0, 0, true, false, false, NULL },
+ { "interfacearm", 0, 0, true, false, false, arm_handle_fndecl_attribute },
+#endif
+ { NULL, 0, 0, false, false, false, NULL }
+};
- return 0;
+/* Handle an attribute requiring a FUNCTION_DECL;
+ arguments as in struct attribute_spec.handler. */
+static tree
+arm_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
+ tree *node;
+ tree name;
+ tree args ATTRIBUTE_UNUSED;
+ int flags ATTRIBUTE_UNUSED;
+ bool *no_add_attrs;
+{
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning ("`%s' attribute only applies to functions",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
+/* Handle an "interrupt" or "isr" attribute;
+ arguments as in struct attribute_spec.handler. */
+static tree
+arm_handle_isr_attribute (node, name, args, flags, no_add_attrs)
+ tree *node;
+ tree name;
+ tree args;
+ int flags;
+ bool *no_add_attrs;
+{
+ if (DECL_P (*node))
+ {
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning ("`%s' attribute only applies to functions",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+ /* FIXME: the argument if any is checked for type attributes;
+ should it be checked for decl ones? */
+ }
+ else
+ {
+ if (TREE_CODE (*node) == FUNCTION_TYPE
+ || TREE_CODE (*node) == METHOD_TYPE)
+ {
+ if (arm_isr_value (args) == ARM_FT_UNKNOWN)
+ {
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+ }
+ else if (TREE_CODE (*node) == POINTER_TYPE
+ && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE)
+ && arm_isr_value (args) != ARM_FT_UNKNOWN)
+ {
+ *node = build_type_copy (*node);
+ TREE_TYPE (*node) = build_type_attribute_variant (TREE_TYPE (*node),
+ tree_cons (name,
+ args,
+ TYPE_ATTRIBUTES (TREE_TYPE (*node))));
+ *no_add_attrs = true;
+ }
+ else
+ {
+ /* Possibly pass this attribute on from the type to a decl. */
+ if (flags & ((int) ATTR_FLAG_DECL_NEXT
+ | (int) ATTR_FLAG_FUNCTION_NEXT
+ | (int) ATTR_FLAG_ARRAY_NEXT))
+ {
+ *no_add_attrs = true;
+ return tree_cons (name, args, NULL_TREE);
+ }
+ else
+ {
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ }
+ }
+ }
+
+ return NULL_TREE;
}
/* Return 0 if the attributes for two types are incompatible, 1 if they
@@ -4132,85 +4204,6 @@ multi_register_push (op, mode)
return 1;
}
-/* Routines for use with attributes. */
-
-/* Return nonzero if ATTR is a valid attribute for DECL.
- ATTRIBUTES are any existing attributes and ARGS are
- the arguments supplied with ATTR.
-
- Supported attributes:
-
- naked:
- don't output any prologue or epilogue code, the user is assumed
- to do the right thing.
-
- isr or interrupt:
- Interrupt Service Routine.
-
- interfacearm:
- Always assume that this function will be entered in ARM mode,
- not Thumb mode, and that the caller wishes to be returned to in
- ARM mode. */
-static int
-arm_valid_decl_attribute_p (decl, attributes, attr, args)
- tree decl;
- tree attributes ATTRIBUTE_UNUSED;
- tree attr;
- tree args;
-{
- /* The interrupt attribute can take args, so check for it before
- rejecting other attributes on the grounds that they did have args. */
- if (is_attribute_p ("isr", attr)
- || is_attribute_p ("interrupt", attr))
- return TREE_CODE (decl) == FUNCTION_DECL;
-
- if (args != NULL_TREE)
- return 0;
-
- if (is_attribute_p ("naked", attr))
- return TREE_CODE (decl) == FUNCTION_DECL;
-
-#ifdef ARM_PE
- if (is_attribute_p ("interfacearm", attr))
- return TREE_CODE (decl) == FUNCTION_DECL;
-#endif /* ARM_PE */
-
- return 0;
-}
-
-#ifdef ARM_PE
-
-/* ARM/PE has three new attributes:
- naked - for interrupt functions
- dllexport - for exporting a function/variable that will live in a dll
- dllimport - for importing a function/variable from a dll
-
- Microsoft allows multiple declspecs in one __declspec, separating
- them with spaces. We do NOT support this. Instead, use __declspec
- multiple times.
-*/
-
-static int
-arm_pe_valid_decl_attribute_p (decl, attributes, attr, args)
- tree decl;
- tree attributes;
- tree attr;
- tree args;
-{
- if (args != NULL_TREE)
- return 0;
-
- if (is_attribute_p ("dllexport", attr))
- return 1;
-
- if (is_attribute_p ("dllimport", attr))
- return 1;
-
- return arm_valid_decl_attribute_p (decl, attributes, attr, args);
-}
-
-#endif /* ARM_PE */
-
/* Routines for use in generating RTL. */
rtx
arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
@@ -9742,7 +9735,7 @@ is_called_in_ARM_mode (func)
return TRUE;
#ifdef ARM_PE
- return lookup_attribute ("interfacearm", DECL_MACHINE_ATTRIBUTES (func)) != NULL_TREE;
+ return lookup_attribute ("interfacearm", DECL_ATTRIBUTES (func)) != NULL_TREE;
#else
return FALSE;
#endif
diff --git a/gcc/config/arm/pe.c b/gcc/config/arm/pe.c
index 29c470e3f3c..9e7e95a5765 100644
--- a/gcc/config/arm/pe.c
+++ b/gcc/config/arm/pe.c
@@ -1,5 +1,5 @@
/* Routines for GCC for ARM/pe.
- Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000, 2001 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
This file is part of GNU CC.
@@ -45,7 +45,7 @@ arm_dllexport_p (decl)
if (TREE_CODE (decl) != VAR_DECL
&& TREE_CODE (decl) != FUNCTION_DECL)
return 0;
- exp = lookup_attribute ("dllexport", DECL_MACHINE_ATTRIBUTES (decl));
+ exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
if (exp)
return 1;
@@ -67,7 +67,7 @@ arm_dllimport_p (decl)
if (TREE_CODE (decl) != VAR_DECL
&& TREE_CODE (decl) != FUNCTION_DECL)
return 0;
- imp = lookup_attribute ("dllimport", DECL_MACHINE_ATTRIBUTES (decl));
+ imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
if (imp)
return 1;