From patchwork Mon Oct 18 08:54:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 46328 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 56A653858024 for ; Mon, 18 Oct 2021 08:55:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 56A653858024 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1634547302; bh=APwQi3eBCREdQMtN8xU7xeO9FlsIF2NkUIUnMYesdYI=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:From; b=c5G0UYTO3jlBZ6jZK5SHAF4EqAw64LCuEFAwwoNZBPEQeyrHWxvB12tfO6kNGbAp6 L+OrcRVEyApwM70tj1yqBzHbWs2ECMPBjgXZm3yb0QpWPzNZGhO3JkEzfxIoDehpRA W0lhvUGoId74tjpFLdeo20LVAWb3xorXCMzdP6pU= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTPS id A56123858433 for ; Mon, 18 Oct 2021 08:54:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A56123858433 Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-585--qUTaf5LPz6jmf0kRKkfBw-1; Mon, 18 Oct 2021 04:54:31 -0400 X-MC-Unique: -qUTaf5LPz6jmf0kRKkfBw-1 Received: by mail-qt1-f200.google.com with SMTP id k1-20020ac80201000000b002a7200b449eso10156984qtg.18 for ; Mon, 18 Oct 2021 01:54:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:organization:date:message-id :user-agent:mime-version; bh=APwQi3eBCREdQMtN8xU7xeO9FlsIF2NkUIUnMYesdYI=; b=YfsDaJqi8AO2upFixJnv1sx4l8cOyHpTk5RzUpChSxgGSka05oGCz7l1+lrOwhG/RV H5LaMrBmqLTuqKT5h3VwFNWoHE1jlBEINErp670jJFuUC/tU2o1sdqbJFbp77qO67dg/ oKoICOFlKztrxac9/wDnDXZJt1lew8GdhBJugl8FFeSWxU5zPUONeBkgAifvjUV8kmc7 XAudy/tgIjZWEZslthCF0cSR7jxyr0HPQ133/2ZUO701icPRvwmdUsjzZ8P2ZuARenCY Er2p6A/1hkIQM/Cupbqv12XrnfZ0rSQ8q9e9PWKt12jPLxjP+QWgVKdOAn16Xu6TMDhg 4log== X-Gm-Message-State: AOAM5302cUq/XXOHH6PsXKlUQpKz4S4MUQMOyf76HIS/+Tn5FfJZun1c Qwl76A5bnIyGeRxRHGFg7C/jFPyKEZjWTeuN2h3O8HPYoGrkXkuKUiZSqjYCQ2+2UgrqNnvXzGA f5DwVHIz+YphxgLOtvu/2h1mB1VK0t32rYbXCtyZl5asqWzAvuM0GCTnbhZP52Roc2BBK X-Received: by 2002:a05:6214:190a:: with SMTP id er10mr24149027qvb.2.1634547270947; Mon, 18 Oct 2021 01:54:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx5YA3B8RKhX9O2tMibmf3lb9LPeorKtPxPHfB9xElbAhTZwMKiGLbDS2eT0V7K0tUA8zSZFw== X-Received: by 2002:a05:6214:190a:: with SMTP id er10mr24149010qvb.2.1634547270527; Mon, 18 Oct 2021 01:54:30 -0700 (PDT) Received: from localhost ([88.120.130.27]) by smtp.gmail.com with ESMTPSA id h68sm6393089qkf.126.2021.10.18.01.54.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Oct 2021 01:54:29 -0700 (PDT) Received: by localhost (Postfix, from userid 1000) id 30ACA5802BD; Mon, 18 Oct 2021 10:54:28 +0200 (CEST) To: libabigail@sourceware.org Subject: [PATCH, applied] writer: Don't forget to emit types referenced by function types Organization: Red Hat / France X-Operating-System: Fedora 36 X-URL: http://www.redhat.com Date: Mon, 18 Oct 2021 10:54:28 +0200 Message-ID: <871r4id86z.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Dodji Seketeli via Libabigail From: Dodji Seketeli Reply-To: Dodji Seketeli Errors-To: libabigail-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libabigail" Hello, While looking into something else, I noticed that sometimes the writer would forget to emit types referenced by function types. Fixed thus. * src/abg-writer.cc (write_referenced_types): Factorize out of ... (write_translation_unit): ... here. Also, use it to write the types referenced by emitted function types. Signed-off-by: Dodji Seketeli Applied to master. --- src/abg-writer.cc | 199 ++++++++++++++++++++++++++-------------------- 1 file changed, 112 insertions(+), 87 deletions(-) diff --git a/src/abg-writer.cc b/src/abg-writer.cc index efc01fa7..3848df77 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -2286,103 +2286,24 @@ referenced_type_should_be_emitted(const type_base *t, return false; } -/// Serialize a translation unit to an output stream. +/// Emit the types that were referenced by other emitted types. /// -/// @param ctxt the context of the serialization. It contains e.g, -/// the output stream to serialize to. +/// This is a sub-routine of write_translation_unit. /// -/// @param tu the translation unit to serialize. +/// @param ctxt the write context to use. /// -/// @param indent how many indentation spaces to use during the -/// serialization. +/// @param tu the current translation unit that is being emitted. /// -/// @param is_last If true, it means the TU to emit is the last one of -/// the corpus. If this is the case, all the remaining referenced -/// types that were not emitted are going to be emitted here, -/// irrespective of if they belong to this TU or not. This is quite a -/// hack. Ideally, we should have a pass that walks all the TUs, -/// detect their non-emitted referenced types, before hand. Then, -/// when we start emitting the TUs, we know for each TU which -/// non-emitted referenced type should be emitted. As we don't yet -/// have such a pass, we do our best for now. +/// @param indent the indentation string. /// -/// @return true upon successful completion, false otherwise. -bool -write_translation_unit(write_context& ctxt, +/// @param is_last whether @p tu is the last translation unit or not. +static void +write_referenced_types(write_context & ctxt, const translation_unit& tu, const unsigned indent, bool is_last) { - if (tu.is_empty() && !is_last) - return false; - - if (is_last - && tu.is_empty() - && ctxt.has_non_emitted_referenced_types()) - return false; - - ostream& o = ctxt.get_ostream(); const config& c = ctxt.get_config(); - - do_indent(o, indent); - - o << "\n"; - return true; - } - - o << ">\n"; - - write_canonical_types_of_scope(*tu.get_global_scope(), - ctxt, indent + c.get_xml_element_indent()); - - typedef scope_decl::declarations declarations; - typedef declarations::const_iterator const_iterator; - const declarations& d = tu.get_global_scope()->get_sorted_member_decls(); - - for (const_iterator i = d.begin(); i != d.end(); ++i) - { - if (type_base_sptr t = is_type(*i)) - { - // Emit declaration-only classes that are needed. Some of - // these classes can be empty. Those beasts can be classes - // that only contain member types. They can also be classes - // considered "opaque". - if (class_decl_sptr class_type = is_class_type(t)) - if (class_type->get_is_declaration_only() - && !ctxt.type_is_emitted(class_type)) - write_type(class_type, ctxt, - indent + c.get_xml_element_indent()); - continue; - } - - if (decl_base_sptr d = is_decl(*i)) - if (ctxt.decl_is_emitted(d)) - continue; - write_decl(*i, ctxt, indent + c.get_xml_element_indent()); - } - // Now let's handle types that were referenced, but not yet // emitted because they are either: // 1/ Types without canonical type @@ -2479,6 +2400,106 @@ write_translation_unit(write_context& ctxt, if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last)) referenced_types_to_emit.insert(*i); } +} + +/// Serialize a translation unit to an output stream. +/// +/// @param ctxt the context of the serialization. It contains e.g, +/// the output stream to serialize to. +/// +/// @param tu the translation unit to serialize. +/// +/// @param indent how many indentation spaces to use during the +/// serialization. +/// +/// @param is_last If true, it means the TU to emit is the last one of +/// the corpus. If this is the case, all the remaining referenced +/// types that were not emitted are going to be emitted here, +/// irrespective of if they belong to this TU or not. This is quite a +/// hack. Ideally, we should have a pass that walks all the TUs, +/// detect their non-emitted referenced types, before hand. Then, +/// when we start emitting the TUs, we know for each TU which +/// non-emitted referenced type should be emitted. As we don't yet +/// have such a pass, we do our best for now. +/// +/// @return true upon successful completion, false otherwise. +bool +write_translation_unit(write_context& ctxt, + const translation_unit& tu, + const unsigned indent, + bool is_last) +{ + if (tu.is_empty() && !is_last) + return false; + + if (is_last + && tu.is_empty() + && ctxt.has_non_emitted_referenced_types()) + return false; + + ostream& o = ctxt.get_ostream(); + const config& c = ctxt.get_config(); + + do_indent(o, indent); + + o << "\n"; + return true; + } + + o << ">\n"; + + write_canonical_types_of_scope(*tu.get_global_scope(), + ctxt, indent + c.get_xml_element_indent()); + + typedef scope_decl::declarations declarations; + typedef declarations::const_iterator const_iterator; + const declarations& d = tu.get_global_scope()->get_sorted_member_decls(); + + for (const_iterator i = d.begin(); i != d.end(); ++i) + { + if (type_base_sptr t = is_type(*i)) + { + // Emit declaration-only classes that are needed. Some of + // these classes can be empty. Those beasts can be classes + // that only contain member types. They can also be classes + // considered "opaque". + if (class_decl_sptr class_type = is_class_type(t)) + if (class_type->get_is_declaration_only() + && !ctxt.type_is_emitted(class_type)) + write_type(class_type, ctxt, + indent + c.get_xml_element_indent()); + continue; + } + + if (decl_base_sptr d = is_decl(*i)) + if (ctxt.decl_is_emitted(d)) + continue; + write_decl(*i, ctxt, indent + c.get_xml_element_indent()); + } + + write_referenced_types(ctxt, tu, indent, is_last); // Now handle all function types that were not only referenced by // emitted types. @@ -2502,6 +2523,10 @@ write_translation_unit(write_context& ctxt, write_function_type(fn_type, ctxt, indent + c.get_xml_element_indent()); } + // After we've written out the live function types, we need to write + // the types they referenced. + write_referenced_types(ctxt, tu, indent, is_last); + do_indent(o, indent); o << "\n";