From patchwork Tue Nov 27 10:37:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 1003768 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-490971-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="R+ygl0cd"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4340c13Zzhz9s4s for ; Tue, 27 Nov 2018 21:37:51 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=S5bqChai56wZ+1HZ RVAzieBSCzN8SG0N5oesGTf1buEvw4MQGoG48w6todDzfes8RuALBIE7MIDoCsD0 Ip+IO/au4xvAO9OUWm1ZDyyJReJvhA4YEW433G7g+c84Oiyd24SnUyUn/gH1+nrT dpco+MWtebZn2iIKHKzz7+qnKVA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=2QYdWSFrxgG8RAhIejeDs6 Tz3bc=; b=R+ygl0cdDp5xll5tikzqWwMmpDdEcYfijsPx+MYJZKIGjwe+mtVWtb yBBYBiLupcLPHFZQ/nYqEtS3KPndMDlvR5sN0Ep5EbSIIm7oL6SkrrInG6adB2ff OG8VKIQmmcrtihqIbyhKq86mhHcwS8+rkVIJxGcSc49h35Gcy8wOM= Received: (qmail 42665 invoked by alias); 27 Nov 2018 10:37:44 -0000 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 Received: (qmail 42648 invoked by uid 89); 27 Nov 2018 10:37:44 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=Deal, Anonymous, *slot X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 27 Nov 2018 10:37:40 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 0B35281391 for ; Tue, 27 Nov 2018 11:37:38 +0100 (CET) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id baKSbMyQkGT3 for ; Tue, 27 Nov 2018 11:37:37 +0100 (CET) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id CDF3A81369 for ; Tue, 27 Nov 2018 11:37:37 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [c-family] Fix -fdump-ada-spec regressions in C++ Date: Tue, 27 Nov 2018 11:37:37 +0100 Message-ID: <1725533.sPBkPR8aFK@polaris> MIME-Version: 1.0 This fixes a few regressions introduced by the switch to Ada 2012 for the output of -fdump-ada-spec that are present when the input is in C++. Tested on x86_64-suse-linux, applied on the mainline. 2018-11-27 Eric Botcazou * c-ada-spec.c: Include stringpool.h. (has_static_fields): Return false for incomplete types. (is_tagged_type): Likewise. (has_nontrivial_methods): Likewise. (dump_ada_node) : Deal specifically with __int128. (struct overloaded_name_hash): New structure. (struct overloaded_name_hasher): Likewise. (overloaded_names): New global variable. (init_overloaded_names): New static function. (overloaded_name_p): New predicate. (dump_ada_declaration) : Tidy up and set TREE_VISITED on the TYPE_STUB_DECL of the original type of a typedef, if any. : Bail out for an unsupported overloaded name. Remove always-true condition and dump forward types. (dump_ada_specs): Delete overloaded_names. Index: c-family/c-ada-spec.c =================================================================== --- c-family/c-ada-spec.c (revision 266268) +++ c-family/c-ada-spec.c (working copy) @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. #include "system.h" #include "coretypes.h" #include "tm.h" +#include "stringpool.h" #include "tree.h" #include "c-ada-spec.h" #include "fold-const.h" @@ -1041,7 +1042,7 @@ get_underlying_decl (tree type) static bool has_static_fields (const_tree type) { - if (!type || !RECORD_OR_UNION_TYPE_P (type)) + if (!type || !RECORD_OR_UNION_TYPE_P (type) || !COMPLETE_TYPE_P (type)) return false; for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld)) @@ -1057,7 +1058,7 @@ has_static_fields (const_tree type) static bool is_tagged_type (const_tree type) { - if (!type || !RECORD_OR_UNION_TYPE_P (type)) + if (!type || !RECORD_OR_UNION_TYPE_P (type) || !COMPLETE_TYPE_P (type)) return false; for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld)) @@ -1075,7 +1076,7 @@ is_tagged_type (const_tree type) static bool has_nontrivial_methods (tree type) { - if (!type || !RECORD_OR_UNION_TYPE_P (type)) + if (!type || !RECORD_OR_UNION_TYPE_P (type) || !COMPLETE_TYPE_P (type)) return false; /* Only C++ types can have methods. */ @@ -2092,7 +2093,10 @@ dump_ada_node (pretty_printer *buffer, t case INTEGER_TYPE: case FIXED_POINT_TYPE: case BOOLEAN_TYPE: - if (TYPE_NAME (node)) + if (TYPE_NAME (node) + && !(TREE_CODE (TYPE_NAME (node)) == TYPE_DECL + && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))), + "__int128"))) { if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE) pp_ada_tree_identifier (buffer, TYPE_NAME (node), node, @@ -2568,6 +2572,73 @@ dump_nested_type (pretty_printer *buffer } } +/* Hash table of overloaded names that we cannot support. It is needed even + in Ada 2012 because we merge different types, e.g. void * and const void * + in System.Address, so we cannot have overloading for them in Ada. */ + +struct overloaded_name_hash { + hashval_t hash; + tree name; + unsigned int n; +}; + +struct overloaded_name_hasher : delete_ptr_hash +{ + static inline hashval_t hash (overloaded_name_hash *t) + { return t->hash; } + static inline bool equal (overloaded_name_hash *a, overloaded_name_hash *b) + { return a->name == b->name; } +}; + +static hash_table *overloaded_names; + +/* Initialize the table with the problematic overloaded names. */ + +static hash_table * +init_overloaded_names (void) +{ + static const char *names[] = + /* The overloaded names from the /usr/include/string.h file. */ + { "memchr", "rawmemchr", "memrchr", "strchr", "strrchr", "strchrnul", + "strpbrk", "strstr", "strcasestr", "index", "rindex", "basename" }; + + hash_table *table + = new hash_table (64); + + for (unsigned int i = 0; i < ARRAY_SIZE (names); i++) + { + struct overloaded_name_hash in, *h, **slot; + tree id = get_identifier (names[i]); + hashval_t hash = htab_hash_pointer (id); + in.hash = hash; + in.name = id; + slot = table->find_slot_with_hash (&in, hash, INSERT); + h = new overloaded_name_hash; + h->hash = hash; + h->name = id; + h->n = 0; + *slot = h; + } + + return table; +} + +/* Return whether NAME cannot be supported as overloaded name. */ + +static bool +overloaded_name_p (tree name) +{ + if (!overloaded_names) + overloaded_names = init_overloaded_names (); + + struct overloaded_name_hash in, *h; + hashval_t hash = htab_hash_pointer (name); + in.hash = hash; + in.name = name; + h = overloaded_names->find_with_hash (&in, hash); + return h && ++h->n > 1; +} + /* Dump in BUFFER constructor spec corresponding to T for TYPE. */ static void @@ -2603,7 +2674,7 @@ type_name (tree t) return IDENTIFIER_POINTER (DECL_NAME (n)); } -/* Dump in BUFFER the declaration of a variable T of type TYPE in Ada syntax. +/* Dump in BUFFER the declaration of object T of type TYPE in Ada syntax. SPC is the indentation level. Return 1 if a declaration was printed, 0 otherwise. */ @@ -2628,22 +2699,24 @@ dump_ada_declaration (pretty_printer *bu { orig = DECL_ORIGINAL_TYPE (t); + /* This is a typedef. */ if (orig && TYPE_STUB_DECL (orig)) { tree stub = TYPE_STUB_DECL (orig); - tree typ = TREE_TYPE (stub); - if (TYPE_NAME (typ)) + /* If this is a typedef of a named type, then output it as a subtype + declaration. ??? Use a derived type declaration instead. */ + if (TYPE_NAME (orig)) { /* If the types have the same name (ignoring casing), then ignore the second type, but forward declare the first if need be. */ - if (type_name (typ) == type_name (TREE_TYPE (t)) - || !strcasecmp (type_name (typ), type_name (TREE_TYPE (t)))) + if (type_name (orig) == type_name (TREE_TYPE (t)) + || !strcasecmp (type_name (orig), type_name (TREE_TYPE (t)))) { - if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub)) + if (RECORD_OR_UNION_TYPE_P (orig) && !TREE_VISITED (stub)) { INDENT (spc); - dump_forward_type (buffer, typ, t, 0); + dump_forward_type (buffer, orig, t, 0); } TREE_VISITED (t) = 1; @@ -2652,19 +2725,25 @@ dump_ada_declaration (pretty_printer *bu INDENT (spc); - if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub)) - dump_forward_type (buffer, typ, t, spc); + if (RECORD_OR_UNION_TYPE_P (orig) && !TREE_VISITED (stub)) + dump_forward_type (buffer, orig, t, spc); pp_string (buffer, "subtype "); dump_ada_node (buffer, t, type, spc, false, true); pp_string (buffer, " is "); - dump_ada_node (buffer, typ, type, spc, false, true); + dump_ada_node (buffer, orig, type, spc, false, true); pp_string (buffer, "; -- "); dump_sloc (buffer, t); TREE_VISITED (t) = 1; return 1; } + + /* This is a typedef of an anonymous type. We'll output the full + type declaration of the anonymous type with the typedef'ed name + below. Prevent forward declarations for the anonymous type to + be emitted from now on. */ + TREE_VISITED (stub) = 1; } /* Skip unnamed or anonymous structs/unions/enum types. */ @@ -2764,6 +2843,7 @@ dump_ada_declaration (pretty_printer *bu default: pp_string (buffer, "subtype "); } + TREE_VISITED (t) = 1; } else @@ -2825,7 +2905,7 @@ dump_ada_declaration (pretty_printer *bu bool is_copy_constructor = false; bool is_move_constructor = false; - if (!decl_name) + if (!decl_name || overloaded_name_p (decl_name)) return 0; if (cpp_check) @@ -2863,8 +2943,9 @@ dump_ada_declaration (pretty_printer *bu return 1; } - if (need_indent) - INDENT (spc); + INDENT (spc); + + dump_forward_type (buffer, TREE_TYPE (t), t, spc); if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && !is_constructor) pp_string (buffer, "procedure "); @@ -2927,9 +3008,6 @@ dump_ada_declaration (pretty_printer *bu bool is_interface = false; bool is_abstract_record = false; - if (need_indent) - INDENT (spc); - /* Anonymous structs/unions. */ dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true); @@ -3346,4 +3424,5 @@ dump_ada_specs (void (*collect_all_refs) /* Free various tables. */ free (source_refs); + delete overloaded_names; }