From patchwork Mon Oct 15 22:05:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gary Funck X-Patchwork-Id: 191673 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D0C6A2C009F for ; Tue, 16 Oct 2012 09:06:18 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1350943580; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Date:From:To:Cc:Subject:Message-ID:MIME-Version: Content-Type:Content-Disposition:User-Agent:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=b68t+V/pvjve0WFnZUKG6aXrBLc=; b=EMuJp/cgK+of3kFGf9FUPwbFjOITNDs+Nfd7TAW2sm7kNZ/IdRFMpzUNWO27G7 oLdjUfHrI+goUOJEU2+na2Rzr9icGDynGTvOG+xsDnkU0O/D5etUbzYAAg2ba6CL lJMSatJL0TPB7A1h27OW38imQc7gTJvJ7cs11eYtwVhfo= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type:Content-Disposition:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=oqac9Bl1aYk1xd3VU9vayx6NR64pZuJpScjcik468ssloh2NG/piWuEPMSErZ0 DbpB5wjm81SxPRxHltym4PuCZ+3hTRzSmJrTvoqFeJJL1PlzaqgxG4Cc2wRMVZPE h6xnsPok83lvUSQrZXzw5AQgB1/SOXBT+oOjFwiIXs4WI=; Received: (qmail 17064 invoked by alias); 15 Oct 2012 22:06:13 -0000 Received: (qmail 17053 invoked by uid 22791); 15 Oct 2012 22:06:12 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, TW_BJ X-Spam-Check-By: sourceware.org Received: from mail.intrepid.com (HELO mail.intrepid.com) (74.95.8.113) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 15 Oct 2012 22:06:01 +0000 Received: from screamer.local (screamer.local [10.10.1.2]) by mail.intrepid.com (8.14.5/8.14.5) with ESMTP id q9FM5sEK014750 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 15 Oct 2012 15:05:54 -0700 Received: from screamer.local (screamer.local [127.0.0.1]) by screamer.local (8.14.4/8.14.4) with ESMTP id q9FM5u95023007; Mon, 15 Oct 2012 15:05:56 -0700 Received: (from gary@localhost) by screamer.local (8.14.4/8.14.4/Submit) id q9FM5tGg023006; Mon, 15 Oct 2012 15:05:55 -0700 Date: Mon, 15 Oct 2012 15:05:55 -0700 From: Gary Funck To: Gcc Patches Cc: "Joseph S. Myers" , Richard Henderson , Jason Merrill , Mike Stump Subject: RFC: Merge the GUPC branch into the GCC 4.8 trunk (patch 02 of 16) Message-ID: <20121015220555.GG18153@intrepid.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Attached, patch 02 of 16. This patch set lists the small set of changes required in the C++ and Objective C front-end to accommodate changes needed for UPC. gcc/c/c-decl.c is also included here, to illustrate both the UPC front-end changes and to motivate the introduction of c_build_qualified_type_1() which accepts an additional argument which is the "layout qualifier" (blocking factor) that is unique to UPC. - Gary Other Languages (patch 02 of 16) -------------------------------- gcc/cp/lex.c gcc/cp/tree.c gcc/c/c-decl.c gcc/c/c-objc-common.h Index: gcc/cp/lex.c =================================================================== --- gcc/cp/lex.c (.../trunk) (revision 192449) +++ gcc/cp/lex.c (.../branches/gupc) (revision 192459) @@ -183,6 +183,9 @@ init_reswords (void) /* The Objective-C keywords are all context-dependent. */ mask |= D_OBJC; + if (!c_dialect_upc ()) + mask |= D_UPC; + ridpointers = ggc_alloc_cleared_vec_tree ((int) RID_MAX); for (i = 0; i < num_c_common_reswords; i++) { Index: gcc/cp/tree.c =================================================================== --- gcc/cp/tree.c (.../trunk) (revision 192449) +++ gcc/cp/tree.c (.../branches/gupc) (revision 192459) @@ -900,7 +900,7 @@ move (tree expr) the C version of this function does not properly maintain canonical types (which are not used in C). */ tree -c_build_qualified_type (tree type, int type_quals) +c_build_qualified_type_1 (tree type, int type_quals, tree ARG_UNUSED(layout_qualiefier)) { return cp_build_qualified_type (type, type_quals); } @@ -1849,7 +1849,7 @@ build_exception_variant (tree type, tree type_quals = TYPE_QUALS (type); for (v = TYPE_MAIN_VARIANT (type); v; v = TYPE_NEXT_VARIANT (v)) - if (check_qualified_type (v, type, type_quals) + if (check_qualified_type (v, type, type_quals, 0) && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), ce_exact)) return v; Index: gcc/c/c-decl.c =================================================================== --- gcc/c/c-decl.c (.../trunk) (revision 192449) +++ gcc/c/c-decl.c (.../branches/gupc) (revision 192459) @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. #include "timevar.h" #include "c-family/c-common.h" #include "c-family/c-objc.h" +#include "c-family/c-upc.h" #include "c-family/c-pragma.h" #include "c-lang.h" #include "langhooks.h" @@ -570,6 +571,8 @@ c_build_pointer_type (tree to_type) : TYPE_ADDR_SPACE (to_type); enum machine_mode pointer_mode; + if (upc_shared_type_p (to_type)) + return build_pointer_type (to_type); if (as != ADDR_SPACE_GENERIC || c_default_pointer_mode == VOIDmode) pointer_mode = targetm.addr_space.pointer_mode (as); else @@ -2236,6 +2239,13 @@ merge_decls (tree newdecl, tree olddecl, if (TREE_THIS_VOLATILE (newdecl)) TREE_THIS_VOLATILE (olddecl) = 1; + if (TREE_SHARED (newdecl)) + { + TREE_SHARED (olddecl) = 1; + if (TREE_CODE (newdecl) == VAR_DECL) + TREE_THIS_VOLATILE (newdecl) = 1; + } + /* Merge deprecatedness. */ if (TREE_DEPRECATED (newdecl)) TREE_DEPRECATED (olddecl) = 1; @@ -2872,6 +2882,8 @@ pushdecl_top_level (tree x) static void implicit_decl_warning (tree id, tree olddecl) { + if (upc_diagnose_deprecated_stmt (input_location, id)) + return; if (warn_implicit_function_declaration) { bool warned; @@ -3011,6 +3023,8 @@ undeclared_variable (location_t loc, tre } else { + if (upc_diagnose_deprecated_stmt (loc, id)) + return; if (!objc_diagnose_private_ivar (id)) error_at (loc, "%qE undeclared (first use in this function)", id); if (!already) @@ -3830,6 +3844,9 @@ quals_from_declspecs (const struct c_dec int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0) | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0) | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0) + | (specs->shared_p ? TYPE_QUAL_SHARED : 0) + | (specs->strict_p ? TYPE_QUAL_STRICT : 0) + | (specs->relaxed_p ? TYPE_QUAL_RELAXED : 0) | (ENCODE_QUAL_ADDR_SPACE (specs->address_space))); gcc_assert (!specs->type && !specs->decl_attr @@ -4359,7 +4376,23 @@ finish_decl (tree decl, location_t init_ constant_expression_warning (DECL_SIZE (decl)); else { - error ("storage size of %q+D isn%'t constant", decl); + if (upc_shared_type_p (TREE_TYPE (decl))) + { + gcc_assert (!flag_upc_threads); + if (TYPE_HAS_THREADS_FACTOR (TREE_TYPE (decl))) + error ("in the UPC dynamic translation environment, " "THREADS may not appear in declarations " + "of shared arrays with indefinite block size; " + "the storage size of %q+D cannot be calculated", + decl); + else + error ("in the UPC dynamic translation environment, " + "THREADS must appear exactly once in " + "declarations of shared arrays; " + "the storage size of %q+D cannot be calculated", + decl); + } + else + error ("storage size of %q+D isn%'t constant", decl); TREE_TYPE (decl) = error_mark_node; } } @@ -4398,6 +4431,10 @@ finish_decl (tree decl, location_t init_ if (c_dialect_objc ()) objc_check_decl (decl); + /* Give UPC a chance to check the declaration. */ + if (c_dialect_upc ()) + upc_check_decl (decl); + if (asmspec) { /* If this is not a static variable, issue a warning. @@ -4909,6 +4946,9 @@ grokdeclarator (const struct c_declarato int constp; int restrictp; int volatilep; + int sharedp; + int strictp; + int relaxedp; int type_quals = TYPE_UNQUALIFIED; tree name = NULL_TREE; bool funcdef_flag = false; @@ -4920,6 +4960,10 @@ grokdeclarator (const struct c_declarato int array_parm_static = 0; bool array_parm_vla_unspec_p = false; tree returned_attrs = NULL_TREE; + int upc_threads_ref = 0; /* for static declarations of shared arrays */ + tree upc_layout_qualifier; + tree upc_elem_block_factor; + tree upc_block_factor = NULL; bool bitfield = width != NULL; tree element_type; struct c_arg_info *arg_info = 0; @@ -5019,6 +5063,8 @@ grokdeclarator (const struct c_declarato size_varies = C_TYPE_VARIABLE_SIZE (type) != 0; + upc_threads_ref = TYPE_HAS_THREADS_FACTOR (type); + /* Diagnose defaulting to "int". */ if (declspecs->default_int_p && !in_system_header) @@ -5063,6 +5109,11 @@ grokdeclarator (const struct c_declarato constp = declspecs->const_p + TYPE_READONLY (element_type); restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type); volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type); + sharedp = declspecs->shared_p + upc_shared_type_p (element_type); + strictp = declspecs->strict_p + TYPE_STRICT (element_type); + relaxedp = declspecs->relaxed_p + TYPE_RELAXED (element_type); + upc_elem_block_factor = TYPE_BLOCK_FACTOR (element_type); + upc_layout_qualifier = declspecs->upc_layout_qualifier; as1 = declspecs->address_space; as2 = TYPE_ADDR_SPACE (element_type); address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1; @@ -5075,7 +5126,22 @@ grokdeclarator (const struct c_declarato pedwarn (loc, OPT_Wpedantic, "duplicate %"); if (volatilep > 1) pedwarn (loc, OPT_Wpedantic, "duplicate %"); - } + if (sharedp > 1) + pedwarn (loc, OPT_Wpedantic, "duplicate %"); + if (strictp > 1) + pedwarn (loc, OPT_Wpedantic, "duplicate %"); + if (relaxedp > 1) + pedwarn (loc, OPT_Wpedantic, "duplicate %"); + } + if (strictp && relaxedp) + error_at (loc, "UPC shared variable %qE is declared " + "both strict and relaxed", name); + if (strictp && !sharedp) + error_at (loc, "%qE is declared with UPC strict qualifier " + "but not shared", name); + if (relaxedp && !sharedp) + error_at (loc, "%qE is declared with UPC relaxed qualifier " + "but not shared", name); if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2) error_at (loc, "conflicting named address spaces (%s vs %s)", @@ -5088,8 +5154,11 @@ grokdeclarator (const struct c_declarato type_quals = ((constp ? TYPE_QUAL_CONST : 0) | (restrictp ? TYPE_QUAL_RESTRICT : 0) | (volatilep ? TYPE_QUAL_VOLATILE : 0) + | (sharedp ? TYPE_QUAL_SHARED : 0) + | (strictp ? TYPE_QUAL_STRICT : 0) + | (relaxedp ? TYPE_QUAL_RELAXED : 0) | ENCODE_QUAL_ADDR_SPACE (address_space)); - + /* Warn about storage classes that are invalid for certain kinds of declarations (parameters, typenames, etc.). */ @@ -5182,7 +5251,7 @@ grokdeclarator (const struct c_declarato threadp = false; } } - + /* Now figure out the structure of the declarator proper. Descend through it, creating more complex types, until we reach the declared identifier (or NULL_TREE, in an absolute declarator). @@ -5366,6 +5435,40 @@ grokdeclarator (const struct c_declarato warn_variable_length_array (name, size); } } + else if (sharedp && count_upc_threads_refs (size)) + { + /* We have a shared array with a non-constant + dimension. If the expression is a factor of + THREADS, then we'll need to set the flag + in the result type. Otherwise, it is an error. */ + int n_thread_refs = count_upc_threads_refs (size); + if (upc_threads_ref || n_thread_refs > 1) + { + error_at (loc, "UPC shared array declaration references THREADS " + "more than once; the size of %qE " + "cannot be calculated", name); + size = integer_one_node; + } + else if (!is_multiple_of_upc_threads (size)) + { + error_at (loc, "UPC shared array dimension is not a simple multiple " + "of THREADS; the size of %qE " + "cannot be calculated.", name); + size = integer_one_node; + } + else + { + upc_threads_ref = 1; + set_upc_threads_refs_to_one (&size); + size = fold (size); + if (TREE_CODE (size) != INTEGER_CST) + { + error_at (loc, "UPC forbids variable-size shared array %qE", + name); + size = integer_one_node; + } + } + } else if ((decl_context == NORMAL || decl_context == FIELD) && current_scope == file_scope) { @@ -5526,6 +5629,18 @@ grokdeclarator (const struct c_declarato C_TYPE_VARIABLE_SIZE (type) = 1; } + if (upc_threads_ref) + { + /* We need a unique type copy here for UPC shared + array types compiled in a dynamic threads enviroment + that reference THREADS as a multiplier; to avoid + setting the "has threads factor" bit in + a re-used non- UPC shared array type node. */ + if (size && TREE_CODE (size) == INTEGER_CST) + type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); + TYPE_HAS_THREADS_FACTOR (type) = 1; + } + /* The GCC extension for zero-length arrays differs from ISO flexible array members in that sizeof yields zero. */ @@ -5581,6 +5696,8 @@ grokdeclarator (const struct c_declarato continue; size_varies = false; + upc_threads_ref = 0; + upc_layout_qualifier = 0; /* Warn about some types functions can't return. */ if (TREE_CODE (type) == FUNCTION_TYPE) @@ -5628,6 +5745,12 @@ grokdeclarator (const struct c_declarato if (VOID_TYPE_P (type) && really_funcdef) pedwarn (loc, 0, "function definition has qualified void return type"); + else if (type_quals & TYPE_QUAL_SHARED) + { + error_at (loc, "function definition has UPC shared qualified return type"); + type_quals &= ~(TYPE_QUAL_SHARED | TYPE_QUAL_STRICT + | TYPE_QUAL_RELAXED); + } else warning_at (loc, OPT_Wignored_qualifiers, "type qualifiers ignored on function return type"); @@ -5660,9 +5783,19 @@ grokdeclarator (const struct c_declarato && type_quals) pedwarn (loc, OPT_Wpedantic, "ISO C forbids qualified function types"); + + if (upc_layout_qualifier) + upc_block_factor = upc_grok_layout_qualifier ( + loc, POINTER_TYPE, type, + NULL_TREE, upc_layout_qualifier); + if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type_1 (type, type_quals, + upc_block_factor); + size_varies = false; + upc_threads_ref = 0; + upc_block_factor = 0; /* When the pointed-to type involves components of variable size, care must be taken to ensure that the size evaluation code is @@ -5702,7 +5835,9 @@ grokdeclarator (const struct c_declarato /* Process type qualifiers (such as const or volatile) that were given inside the `*'. */ - type_quals = declarator->u.pointer_quals; + type_quals = declarator->u.pointer.quals; + upc_layout_qualifier = declarator->u.pointer.upc_layout_qual; + sharedp = ((type_quals & TYPE_QUAL_SHARED) != 0); declarator = declarator->declarator; break; @@ -5773,6 +5908,14 @@ grokdeclarator (const struct c_declarato if (bitfield) check_bitfield_type_and_width (&type, width, name); + /* Check for UPC's layout qualifier. */ + if (upc_layout_qualifier || upc_elem_block_factor) + { + upc_block_factor = upc_grok_layout_qualifier (loc, TREE_CODE (type), type, + upc_elem_block_factor, upc_layout_qualifier); + upc_layout_qualifier = 0; + } + /* Reject invalid uses of _Alignas. */ if (declspecs->alignas_p) { @@ -5839,7 +5982,8 @@ grokdeclarator (const struct c_declarato pedwarn (loc, OPT_Wpedantic, "ISO C forbids qualified function types"); if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type_1 (type, type_quals, upc_block_factor); + decl = build_decl (declarator->id_loc, TYPE_DECL, declarator->u.id, type); if (declspecs->explicit_signed_p) @@ -5885,7 +6029,7 @@ grokdeclarator (const struct c_declarato pedwarn (loc, OPT_Wpedantic, "ISO C forbids const or volatile function types"); if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type_1 (type, type_quals, upc_block_factor); return type; } @@ -5932,7 +6076,8 @@ grokdeclarator (const struct c_declarato /* Transfer const-ness of array into that of type pointed to. */ type = TREE_TYPE (type); if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type_1 (type, type_quals, + upc_block_factor); type = c_build_pointer_type (type); type_quals = array_ptr_quals; if (type_quals) @@ -5944,6 +6089,8 @@ grokdeclarator (const struct c_declarato "attributes in parameter array declarator ignored"); size_varies = false; + upc_threads_ref = 0; + upc_block_factor = 0; } else if (TREE_CODE (type) == FUNCTION_TYPE) { @@ -5955,6 +6102,12 @@ grokdeclarator (const struct c_declarato type = c_build_pointer_type (type); type_quals = TYPE_UNQUALIFIED; } + else if (type_quals & TYPE_QUAL_SHARED) + { + error ("parameter declared with UPC shared qualifier"); + type_quals &= ~(TYPE_QUAL_SHARED | TYPE_QUAL_STRICT + | TYPE_QUAL_RELAXED); + } else if (type_quals) type = c_build_qualified_type (type, type_quals); @@ -6002,6 +6155,13 @@ grokdeclarator (const struct c_declarato error_at (loc, "unnamed field has incomplete type"); type = error_mark_node; } + else if (type_quals & TYPE_QUAL_SHARED) + { + error_at (loc, "field %qE declared with UPC shared qualifier", + name); + type_quals &= ~(TYPE_QUAL_SHARED | TYPE_QUAL_STRICT + | TYPE_QUAL_RELAXED); + } type = c_build_qualified_type (type, type_quals); decl = build_decl (declarator->id_loc, FIELD_DECL, declarator->u.id, type); @@ -6111,7 +6271,16 @@ grokdeclarator (const struct c_declarato /* An uninitialized decl with `extern' is a reference. */ int extern_ref = !initialized && storage_class == csc_extern; - type = c_build_qualified_type (type, type_quals); + if ((type_quals & TYPE_QUAL_SHARED) + && !extern_ref + && !((current_scope == file_scope) + || (storage_class == csc_static))) + { + error_at (loc, "UPC does not support shared auto variables"); + type = error_mark_node; + } + + type = c_build_qualified_type_1 (type, type_quals, upc_block_factor); /* C99 6.2.2p7: It is invalid (compile-time undefined behavior) to create an 'extern' declaration for a @@ -6160,6 +6329,11 @@ grokdeclarator (const struct c_declarato else { TREE_STATIC (decl) = (storage_class == csc_static); + /* UPC's 'shared' attribute implies that the storage + is 'static' to the extent it is stored in + memory. */ + if (type_quals & TYPE_QUAL_SHARED) + TREE_STATIC (decl) = 1; TREE_PUBLIC (decl) = extern_ref; } @@ -6235,6 +6409,13 @@ grokdeclarator (const struct c_declarato "questionable in C++"), decl); + /* Shared variables are given their own link section on + most target platforms, and if compiling in pthreads mode + regular local file scope variables are made thread local. */ + if ((TREE_CODE(decl) == VAR_DECL) + && !threadp && (TREE_SHARED (decl) || flag_upc_pthreads)) + upc_set_decl_section (decl); + return decl; } } @@ -8441,7 +8622,8 @@ finish_function (void) if (!decl_function_context (fndecl)) { invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl); - c_genericize (fndecl); + /* Lower to GENERIC form before finalization. */ + lang_hooks.genericize (fndecl); /* ??? Objc emits functions after finalizing the compilation unit. This should be cleaned up later and this conditional removed. */ @@ -8769,18 +8951,21 @@ make_pointer_declarator (struct c_declsp { tree attrs; int quals = 0; + tree upc_layout_qual = 0; struct c_declarator *itarget = target; struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator); if (type_quals_attrs) { attrs = type_quals_attrs->attrs; quals = quals_from_declspecs (type_quals_attrs); + upc_layout_qual = type_quals_attrs->upc_layout_qualifier; if (attrs != NULL_TREE) itarget = build_attrs_declarator (attrs, target); } ret->kind = cdk_pointer; ret->declarator = itarget; - ret->u.pointer_quals = quals; + ret->u.pointer.quals = quals; + ret->u.pointer.upc_layout_qual = upc_layout_qual; return ret; } @@ -8796,6 +8981,7 @@ build_null_declspecs (void) ret->expr = 0; ret->decl_attr = 0; ret->attrs = 0; + ret->upc_layout_qualifier = 0; ret->align_log = -1; ret->typespec_word = cts_none; ret->storage_class = csc_none; @@ -8819,6 +9005,9 @@ build_null_declspecs (void) ret->const_p = false; ret->volatile_p = false; ret->restrict_p = false; + ret->shared_p = false; + ret->strict_p = false; + ret->relaxed_p = false; ret->saturating_p = false; ret->alignas_p = false; ret->address_space = ADDR_SPACE_GENERIC; @@ -8859,6 +9048,23 @@ declspecs_add_qual (source_location loc, bool dupe = false; specs->non_sc_seen_p = true; specs->declspecs_seen_p = true; + + /* A UPC layout qualifier is encoded as an ARRAY_REF, + further, it implies the presence of the 'shared' keyword. */ + if (TREE_CODE (qual) == ARRAY_REF) + { + if (specs->upc_layout_qualifier) + { + error ("two or more layout qualifiers specified"); + return specs; + } + else + { + specs->upc_layout_qualifier = qual; + qual = ridpointers[RID_SHARED]; + } + } + gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (qual)); i = C_RID_CODE (qual); @@ -8879,6 +9085,18 @@ declspecs_add_qual (source_location loc, specs->restrict_p = true; specs->locations[cdw_restrict] = loc; break; + case RID_SHARED: + dupe = specs->shared_p; + specs->shared_p = true; + break; + case RID_STRICT: + dupe = specs->strict_p; + specs->strict_p = true; + break; + case RID_RELAXED: + dupe = specs->relaxed_p; + specs->relaxed_p = true; + break; default: gcc_unreachable (); } Index: gcc/c/c-objc-common.h =================================================================== --- gcc/c/c-objc-common.h (.../trunk) (revision 192449) +++ gcc/c/c-objc-common.h (.../branches/gupc) (revision 192459) @@ -96,6 +96,10 @@ along with GCC; see the file COPYING3. #undef LANG_HOOKS_WRITE_GLOBALS #define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations +/* Hook for lowering function body to GENERIC before finalization. */ +#undef LANG_HOOKS_GENERICIZE +#define LANG_HOOKS_GENERICIZE c_genericize + /* Hooks for tree gimplification. */ #undef LANG_HOOKS_GIMPLIFY_EXPR #define LANG_HOOKS_GIMPLIFY_EXPR c_gimplify_expr