diff options
author | Ben Elliston <bje@au.ibm.com> | 2009-10-26 21:58:06 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2009-10-26 21:58:06 +0000 |
commit | 36c5e70a3aab4f1c25bfe706648aab258e89be1a (patch) | |
tree | 309434d678721acedb299f20cdc2b4778062b180 /gcc/c-decl.c | |
parent | d4ebfa65c962f1f0b50223e34184dc5a81d907c6 (diff) | |
download | gcc-36c5e70a3aab4f1c25bfe706648aab258e89be1a.zip gcc-36c5e70a3aab4f1c25bfe706648aab258e89be1a.tar.gz gcc-36c5e70a3aab4f1c25bfe706648aab258e89be1a.tar.bz2 |
tm.texi (TARGET_ADDR_SPACE_KEYWORDS): Document.
2009-10-26 Ben Elliston <bje@au.ibm.com>
Michael Meissner <meissner@linux.vnet.ibm.com>
Ulrich Weigand <uweigand@de.ibm.com>
* doc/tm.texi (TARGET_ADDR_SPACE_KEYWORDS): Document.
* c-common.c (c_common_reswords): If TARGET_ADDR_SPACE_KEYWORDS is
defined, add the named address space keywords.
(c_addr_space_name): New function.
(complete_array_type): Preserve named address space.
(handle_mode_attribute): Use targetm.addr_space.valid_pointer_mode
instead of targetm.valid_pointer_mode.
* c-common.h (enum rid): Add RID_ADDR_SPACE_0 .. RID_ADDR_SPACE_15,
RID_FIRST_ADDR_SPACE and RID_LAST_ADDR_SPACE.
(ADDR_SPACE_KEYWORD): New macro.
(c_addr_space_name): Add prototype.
* c-tree.h (struct c_declspecs): Add address_space member.
(declspecs_add_addrspace): Add prototype.
* c-pretty-print.c (pp_c_type_qualifier_list): Handle address spaces.
* c-parser.c (c_parse_init): Add assertion.
(typedef enum c_id_kind): Add C_ID_ADDRSPACE.
(c_lex_one_token): Handle address space keywords.
(c_token_starts_typename): Likewise.
(c_token_starts_declspecs): Likewise.
(c_parser_declspecs): Likewise.
(c_parser_postfix_expression_after_paren_type): Diagnose compound
literal within function qualified with named address space.
* c-decl.c (diagnose_mismatched_decls): Diagnose conflicting named
address space qualifiers.
(shadow_tag_warned): Warn about useless address space qualifiers.
(quals_from_declspecs): Handle address space qualifiers.
(grokdeclarator): Likewise.
(build_null_declspecs): Likewise.
(declspecs_add_addrspace): New function.
* c-typeck.c (addr_space_superset): New function.
(qualify_type): Handle named address spaces.
(composite_type): Likewise.
(common_pointer_type): Likewise.
(comp_target_types): Likewise.
(build_conditional_expr): Likewise.
(handle_warn_cast_qual): Likewise.
(build_c_cast): Likewise.
(convert_for_assignment): Likewise.
(build_binary_op): Likewise.
(pointer_diff): Handle named address spaces. Use intermediate
integer type of sufficient size if required.
Co-Authored-By: Michael Meissner <meissner@linux.vnet.ibm.com>
Co-Authored-By: Ulrich Weigand <uweigand@de.ibm.com>
From-SVN: r153574
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 135 |
1 files changed, 128 insertions, 7 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index e237332..492d2e6 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1746,8 +1746,35 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } else { - if (TYPE_QUALS (newtype) != TYPE_QUALS (oldtype)) - error ("conflicting type qualifiers for %q+D", newdecl); + int new_quals = TYPE_QUALS (newtype); + int old_quals = TYPE_QUALS (oldtype); + + if (new_quals != old_quals) + { + addr_space_t new_addr = DECODE_QUAL_ADDR_SPACE (new_quals); + addr_space_t old_addr = DECODE_QUAL_ADDR_SPACE (old_quals); + if (new_addr != old_addr) + { + if (ADDR_SPACE_GENERIC_P (new_addr)) + error ("conflicting named address spaces (generic vs %s) " + "for %q+D", + c_addr_space_name (old_addr), newdecl); + else if (ADDR_SPACE_GENERIC_P (old_addr)) + error ("conflicting named address spaces (%s vs generic) " + "for %q+D", + c_addr_space_name (new_addr), newdecl); + else + error ("conflicting named address spaces (%s vs %s) " + "for %q+D", + c_addr_space_name (new_addr), + c_addr_space_name (old_addr), + newdecl); + } + + if (CLEAR_QUAL_ADDR_SPACE (new_quals) + != CLEAR_QUAL_ADDR_SPACE (old_quals)) + error ("conflicting type qualifiers for %q+D", newdecl); + } else error ("conflicting types for %q+D", newdecl); diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype); @@ -3605,7 +3632,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) else if (!declspecs->tag_defined_p && (declspecs->const_p || declspecs->volatile_p - || declspecs->restrict_p)) + || declspecs->restrict_p + || declspecs->address_space)) { if (warned != 1) pedwarn (input_location, 0, @@ -3676,7 +3704,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) if (!warned && !in_system_header && (declspecs->const_p || declspecs->volatile_p - || declspecs->restrict_p)) + || declspecs->restrict_p + || declspecs->address_space)) { warning (0, "useless type qualifier in empty declaration"); warned = 2; @@ -3699,7 +3728,8 @@ quals_from_declspecs (const struct c_declspecs *specs) { int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0) | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0) - | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0)); + | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0) + | (ENCODE_QUAL_ADDR_SPACE (specs->address_space))); gcc_assert (!specs->type && !specs->decl_attr && specs->typespec_word == cts_none @@ -4750,6 +4780,7 @@ grokdeclarator (const struct c_declarator *declarator, bool bitfield = width != NULL; tree element_type; struct c_arg_info *arg_info = 0; + addr_space_t as1, as2, address_space; location_t loc = UNKNOWN_LOCATION; const char *errmsg; tree expr_dummy; @@ -4880,6 +4911,10 @@ grokdeclarator (const struct c_declarator *declarator, constp = declspecs->const_p + TYPE_READONLY (element_type); restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type); volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type); + as1 = declspecs->address_space; + as2 = TYPE_ADDR_SPACE (element_type); + address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1; + if (pedantic && !flag_isoc99) { if (constp > 1) @@ -4889,11 +4924,17 @@ grokdeclarator (const struct c_declarator *declarator, if (volatilep > 1) pedwarn (loc, OPT_pedantic, "duplicate %<volatile%>"); } + + if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2) + error_at (loc, "conflicting named address spaces (%s vs %s)", + c_addr_space_name (as1), c_addr_space_name (as2)); + if (!flag_gen_aux_info && (TYPE_QUALS (element_type))) type = TYPE_MAIN_VARIANT (type); type_quals = ((constp ? TYPE_QUAL_CONST : 0) | (restrictp ? TYPE_QUAL_RESTRICT : 0) - | (volatilep ? TYPE_QUAL_VOLATILE : 0)); + | (volatilep ? TYPE_QUAL_VOLATILE : 0) + | ENCODE_QUAL_ADDR_SPACE (address_space)); /* Warn about storage classes that are invalid for certain kinds of declarations (parameters, typenames, etc.). */ @@ -5309,7 +5350,14 @@ grokdeclarator (const struct c_declarator *declarator, it, but here we want to make sure we don't ever modify the shared type, so we gcc_assert (itype) below. */ - type = build_array_type (type, itype); + { + addr_space_t as = DECODE_QUAL_ADDR_SPACE (type_quals); + if (!ADDR_SPACE_GENERIC_P (as) && as != TYPE_ADDR_SPACE (type)) + type = build_qualified_type (type, + ENCODE_QUAL_ADDR_SPACE (as)); + + type = build_array_type (type, itype); + } if (type != error_mark_node) { @@ -5515,6 +5563,59 @@ grokdeclarator (const struct c_declarator *declarator, /* Now TYPE has the actual type, apart from any qualifiers in TYPE_QUALS. */ + /* Warn about address space used for things other than static memory or + pointers. */ + address_space = DECODE_QUAL_ADDR_SPACE (type_quals); + if (!ADDR_SPACE_GENERIC_P (address_space)) + { + if (decl_context == NORMAL) + { + switch (storage_class) + { + case csc_auto: + error ("%qs combined with %<auto%> qualifier for %qE", + c_addr_space_name (address_space), name); + break; + case csc_register: + error ("%qs combined with %<register%> qualifier for %qE", + c_addr_space_name (address_space), name); + break; + case csc_none: + if (current_function_scope) + { + error ("%qs specified for auto variable %qE", + c_addr_space_name (address_space), name); + break; + } + break; + case csc_static: + case csc_extern: + case csc_typedef: + break; + default: + gcc_unreachable (); + } + } + else if (decl_context == PARM && TREE_CODE (type) != ARRAY_TYPE) + { + if (name) + error ("%qs specified for parameter %qE", + c_addr_space_name (address_space), name); + else + error ("%qs specified for unnamed parameter", + c_addr_space_name (address_space)); + } + else if (decl_context == FIELD) + { + if (name) + error ("%qs specified for structure field %qE", + c_addr_space_name (address_space), name); + else + error ("%qs specified for structure field", + c_addr_space_name (address_space)); + } + } + /* Check the type and width of a bit-field. */ if (bitfield) check_bitfield_type_and_width (&type, width, name); @@ -8297,9 +8398,29 @@ build_null_declspecs (void) ret->volatile_p = false; ret->restrict_p = false; ret->saturating_p = false; + ret->address_space = ADDR_SPACE_GENERIC; return ret; } +/* Add the address space ADDRSPACE to the declaration specifiers + SPECS, returning SPECS. */ + +struct c_declspecs * +declspecs_add_addrspace (struct c_declspecs *specs, addr_space_t as) +{ + specs->non_sc_seen_p = true; + specs->declspecs_seen_p = true; + + if (!ADDR_SPACE_GENERIC_P (specs->address_space) + && specs->address_space != as) + error ("incompatible address space qualifiers %qs and %qs", + c_addr_space_name (as), + c_addr_space_name (specs->address_space)); + else + specs->address_space = as; + return specs; +} + /* Add the type qualifier QUAL to the declaration specifiers SPECS, returning SPECS. */ |