diff options
Diffstat (limited to 'gcc/config/i386')
-rw-r--r-- | gcc/config/i386/cygwin.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 125 | ||||
-rw-r--r-- | gcc/config/i386/winnt.c | 79 |
4 files changed, 126 insertions, 86 deletions
diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h index d325167673c..138d96fc740 100644 --- a/gcc/config/i386/cygwin.h +++ b/gcc/config/i386/cygwin.h @@ -191,7 +191,7 @@ union tree_node; It's also used to handle dllimport override semantics. */ #if 0 #define REDO_SECTION_INFO_P(DECL) \ - ((DECL_MACHINE_ATTRIBUTES (DECL) != NULL_TREE) \ + ((DECL_ATTRIBUTES (DECL) != NULL_TREE) \ || (TREE_CODE (DECL) == VAR_DECL && DECL_VIRTUAL_P (DECL))) #else #define REDO_SECTION_INFO_P(DECL) 1 diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index b6462e1f65f..a81a29b02d8 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -173,9 +173,9 @@ extern int ix86_return_pops_args PARAMS ((tree, tree, int)); extern int ix86_data_alignment PARAMS ((tree, int)); extern int ix86_local_alignment PARAMS ((tree, int)); extern int ix86_constant_alignment PARAMS ((tree, int)); -extern int ix86_valid_type_attribute_p PARAMS ((tree, tree, tree, tree)); -extern int i386_pe_valid_decl_attribute_p PARAMS ((tree, tree, tree, tree)); -extern int i386_pe_valid_type_attribute_p PARAMS ((tree, tree, tree, tree)); +extern tree ix86_handle_dll_attribute PARAMS ((tree *, tree, tree, int, bool *)); +extern tree ix86_handle_shared_attribute PARAMS ((tree *, tree, tree, int, bool *)); + extern unsigned int i386_pe_section_type_flags PARAMS ((tree, const char *, int)); extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int)); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c89a0ab591d..028c1ac8a17 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -657,6 +657,9 @@ static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code)); static int ix86_save_reg PARAMS ((int, int)); static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *)); static int ix86_comp_type_attributes PARAMS ((tree, tree)); +const struct attribute_spec ix86_attribute_table[]; +static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *)); +static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *)); #ifdef DO_GLOBAL_CTORS_BODY static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int)); @@ -667,15 +670,11 @@ static void sco_asm_out_constructor PARAMS ((rtx, int)); #endif /* Initialize the GCC target structure. */ -#undef TARGET_VALID_TYPE_ATTRIBUTE +#undef TARGET_ATTRIBUTE_TABLE +#define TARGET_ATTRIBUTE_TABLE ix86_attribute_table #ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES -# define TARGET_VALID_TYPE_ATTRIBUTE i386_pe_valid_type_attribute_p -# undef TARGET_VALID_DECL_ATTRIBUTE -# define TARGET_VALID_DECL_ATTRIBUTE i386_pe_valid_decl_attribute_p # undef TARGET_MERGE_DECL_ATTRIBUTES # define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes -#else -# define TARGET_VALID_TYPE_ATTRIBUTE ix86_valid_type_attribute_p #endif #undef TARGET_COMP_TYPE_ATTRIBUTES @@ -977,56 +976,94 @@ optimization_options (level, size) #endif } -/* 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. */ - -int -ix86_valid_type_attribute_p (type, attributes, identifier, args) - tree type; - tree attributes ATTRIBUTE_UNUSED; - tree identifier; - tree args; +/* Table of valid machine attributes. */ +const struct attribute_spec ix86_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 } */ /* Stdcall attribute says callee is responsible for popping arguments if they are not variable. */ - if (is_attribute_p ("stdcall", identifier) - && !TARGET_64BIT) - return (args == NULL_TREE); - - /* Cdecl attribute says the callee is a normal C declaration. */ - if (is_attribute_p ("cdecl", identifier) - && !TARGET_64BIT) - return (args == NULL_TREE); - + { "stdcall", 0, 0, false, true, true, ix86_handle_cdecl_attribute }, + /* Cdecl attribute says the callee is a normal C declaration */ + { "cdecl", 0, 0, false, true, true, ix86_handle_cdecl_attribute }, /* Regparm attribute specifies how many integer arguments are to be passed in registers. */ - if (is_attribute_p ("regparm", identifier)) + { "regparm", 1, 1, false, true, true, ix86_handle_regparm_attribute }, +#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES + { "dllimport", 1, 1, false, false, false, ix86_handle_dll_attribute }, + { "dllexport", 1, 1, false, false, false, ix86_handle_dll_attribute }, + { "shared", 1, 1, true, false, false, ix86_handle_shared_attribute }, +#endif + { NULL, 0, 0, false, false, false, NULL } +}; + +/* Handle a "cdecl" or "stdcall" attribute; + arguments as in struct attribute_spec.handler. */ +static tree +ix86_handle_cdecl_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_TYPE + && TREE_CODE (*node) != METHOD_TYPE + && TREE_CODE (*node) != FIELD_DECL + && TREE_CODE (*node) != TYPE_DECL) { - tree cst; + warning ("`%s' attribute only applies to functions", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } - if (! args || TREE_CODE (args) != TREE_LIST - || TREE_CHAIN (args) != NULL_TREE - || TREE_VALUE (args) == NULL_TREE) - return 0; + if (TARGET_64BIT) + { + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } - cst = TREE_VALUE (args); - if (TREE_CODE (cst) != INTEGER_CST) - return 0; + return NULL_TREE; +} - if (compare_tree_int (cst, REGPARM_MAX) > 0) - return 0; +/* Handle a "regparm" attribute; + arguments as in struct attribute_spec.handler. */ +static tree +ix86_handle_regparm_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; + tree args; + int flags ATTRIBUTE_UNUSED; + bool *no_add_attrs; +{ + if (TREE_CODE (*node) != FUNCTION_TYPE + && TREE_CODE (*node) != METHOD_TYPE + && TREE_CODE (*node) != FIELD_DECL + && TREE_CODE (*node) != TYPE_DECL) + { + warning ("`%s' attribute only applies to functions", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + else + { + tree cst; - return 1; + cst = TREE_VALUE (args); + if (TREE_CODE (cst) != INTEGER_CST) + { + warning ("`%s' attribute requires an integer constant argument", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + else if (compare_tree_int (cst, REGPARM_MAX) > 0) + { + warning ("argument to `%s' attribute larger than %d", + IDENTIFIER_POINTER (name), REGPARM_MAX); + *no_add_attrs = true; + } } - return 0; + return NULL_TREE; } #if defined (OSF_OS) || defined (TARGET_OSF1ELF) diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index d32224f2382..e14359d1c4b 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -1,6 +1,6 @@ /* Subroutines for insn-output.c for Windows NT. Contributed by Douglas Rupp (drupp@cs.washington.edu) - Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GNU CC. @@ -49,51 +49,54 @@ int i386_pe_dllimport_p PARAMS ((tree)); void i386_pe_mark_dllexport PARAMS ((tree)); void i386_pe_mark_dllimport PARAMS ((tree)); -/* Return nonzero if ATTR is a valid attribute for DECL. - ATTRIBUTES are any existing attributes and ARGS are the arguments - supplied with ATTR. */ - -int -i386_pe_valid_decl_attribute_p (decl, attributes, attr, args) - tree decl; - tree attributes ATTRIBUTE_UNUSED; - tree attr; +/* Handle a "dllimport" or "dllexport" attribute; + arguments as in struct attribute_spec.handler. */ +tree +ix86_handle_dll_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; tree args; + int flags; + bool *no_add_attrs; { - if (args == NULL_TREE) + /* These attributes may apply to structure and union types being created, + but otherwise should pass to the declaration involved. */ + if (!DECL_P (*node)) { - if (is_attribute_p ("dllexport", attr)) - return 1; - if (is_attribute_p ("dllimport", attr)) - return 1; - if (is_attribute_p ("shared", attr)) - return TREE_CODE (decl) == VAR_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); + } + if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE) + { + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } } - return 0; + return NULL_TREE; } -/* Return nonzero if ATTR is a valid attribute for TYPE. - ATTRIBUTES are any existing attributes and ARGS are the arguments - supplied with ATTR. */ - -int -i386_pe_valid_type_attribute_p (type, attributes, attr, args) - tree type; - tree attributes; - tree attr; - tree args; +/* Handle a "shared" attribute; + arguments as in struct attribute_spec.handler. */ +tree +ix86_handle_shared_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 (args == NULL_TREE - && (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE)) + if (TREE_CODE (*node) != VAR_DECL) { - if (is_attribute_p ("dllexport", attr)) - return 1; - if (is_attribute_p ("dllimport", attr)) - return 1; + warning ("`%s' attribute only applies to variables", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; } - return ix86_valid_type_attribute_p (type, attributes, attr, args); + return NULL_TREE; } /* Return the type that we should use to determine if DECL is @@ -132,7 +135,7 @@ i386_pe_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; @@ -163,7 +166,7 @@ i386_pe_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; @@ -499,7 +502,7 @@ i386_pe_section_type_flags (decl, name, reloc) flags = SECTION_WRITE; if (decl && TREE_CODE (decl) == VAR_DECL - && lookup_attribute ("shared", DECL_MACHINE_ATTRIBUTES (decl))) + && lookup_attribute ("shared", DECL_ATTRIBUTES (decl))) flags |= SECTION_PE_SHARED; } |