From patchwork Thu Nov 19 21:24:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1403284 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=j9m4G5wO; dkim-atps=neutral Received: from sourceware.org (unknown [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CcXl152g2z9sVH for ; Fri, 20 Nov 2020 08:25:00 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0012039ACC9F; Thu, 19 Nov 2020 21:24:57 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qk1-x72c.google.com (mail-qk1-x72c.google.com [IPv6:2607:f8b0:4864:20::72c]) by sourceware.org (Postfix) with ESMTPS id 864FD3857C68 for ; Thu, 19 Nov 2020 21:24:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 864FD3857C68 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qk1-x72c.google.com with SMTP id l2so7008906qkf.0 for ; Thu, 19 Nov 2020 13:24:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=HtjWxbOPLQ0vtPMX6iuh88qfwS4Myi8RRAOUwHoEfO0=; b=j9m4G5wOAgcVKQ0MpP3ihr72rzUAaLfSrw0J+8+RGTofbrsT5sLVgk8vZ6balyfXW4 MFzDV3A26hxBcCbL7znMThhg5t+LmzYm8dHpukd7oszlzLmV7lGFPRgVYS/TK04yw5N+ mEizU9psov5RHMZiYcWNZKcHGO6fR5ZEQqugHINC2sgeeG58v8YDUAB0Dm0BnJgmYp7Y U0wwgm0I0ETj8pZFdvpVm/rtoWye+dN4j7dRzn89kKAFMe7idbvJCw9vm9DRk3aLvoii xIgcvQc/VqT0hqsogP1dVHJ+nYGJtQU24eEq1FKzRsfk9Oo+fT7EB9J3l1Q7GKl/YIHe B+zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=HtjWxbOPLQ0vtPMX6iuh88qfwS4Myi8RRAOUwHoEfO0=; b=I950liPONKFUGD0D7GfCFbPD9f02TAQ+Az2LV/idi7cELiLHNtrMxvBxWqB/D1Iyqv LAsa7xAiS00rNw4d9BuiD5ejh1Gfk9JqLcGqCw2Nvdg3mloY4KDhY4DVrbRpD3XMvopP TY/mGS+HbIQJo9CdjjR7ymp9eRBZxipBnNLrfvYsF05TeBRn1vss1gmVe3GO3rcLDQdj nAITwJZ5urnV+UAphRvO5HItHzXscgSq+7YCe2hP0PT3rcpBkDkJNHELQDGygmcS0lIQ P9ryODOYu6m8uNOCRH59SX9uw7UaOipV62kk4/o+xcYjOz5jEBrtQi+NYKcy2u4Kb2a7 sBDA== X-Gm-Message-State: AOAM532g9xFilZKBo2T1CD5nHH0ME9DVrFbxL4QeoI5ThXTual+AQS6V SEqj//TKQutSJXKBJVxVRaI= X-Google-Smtp-Source: ABdhPJwb8jzSj39FTpVOl6PQ3gju5nEwqk+nOJVJ1lr9y92CVeuLK12yPeH7VHH8BAdH+C20Ewh3AA== X-Received: by 2002:a37:b701:: with SMTP id h1mr13134174qkf.147.1605821094916; Thu, 19 Nov 2020 13:24:54 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:8ced:f443:fdee:6e3a? ([2620:10d:c091:480::1:ec4d]) by smtp.googlemail.com with ESMTPSA id p134sm771801qke.66.2020.11.19.13.24.53 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 19 Nov 2020 13:24:53 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: c++: Template hash access Message-ID: Date: Thu, 19 Nov 2020 16:24:52 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" This exposes the template specialization table, so the modules machinery may access it. The hashed entity (tmpl, args & spec) is available, along with a hash table walker. We also need a way of finding or inserting entries, along with some bookkeeping fns to deal with the instantiation and (partial) specialization lists. This is slightly modified from the earlier posting -- one of the functions, used for checking, isn't needed as match_mergeable_specialization is modified to allow that use. gcc/cp/ * cp-tree.h (struct spec_entry): Moved from pt.c. (walk_specializations, match_mergeable_specialization) (get_mergeable_specialization_flags) (add_mergeable_specialization): Declare. * pt.c (struct spec_entry): Moved to cp-tree.h. (walk_specializations, match_mergeable_specialization) (get_mergeable_specialization_flags) (add_mergeable_specialization): New. pushing to trunk diff --git i/gcc/cp/cp-tree.h w/gcc/cp/cp-tree.h index 0c4b74a8895..021de76e142 100644 --- i/gcc/cp/cp-tree.h +++ w/gcc/cp/cp-tree.h @@ -5403,6 +5403,14 @@ public: hash_map *saved; }; +/* Entry in the specialization hash table. */ +struct GTY((for_user)) spec_entry +{ + tree tmpl; /* The general template this is a specialization of. */ + tree args; /* The args for this (maybe-partial) specialization. */ + tree spec; /* The specialization itself. */ +}; + /* in class.c */ extern int current_class_depth; @@ -6994,6 +7002,15 @@ extern bool copy_guide_p (const_tree); extern bool template_guide_p (const_tree); extern bool builtin_guide_p (const_tree); extern void store_explicit_specifier (tree, tree); +extern void walk_specializations (bool, + void (*)(bool, spec_entry *, + void *), + void *); +extern tree match_mergeable_specialization (bool is_decl, tree tmpl, + tree args, tree spec); +extern unsigned get_mergeable_specialization_flags (tree tmpl, tree spec); +extern void add_mergeable_specialization (tree tmpl, tree args, + tree spec, unsigned); extern tree add_outermost_template_args (tree, tree); extern tree add_extra_args (tree, tree); extern tree build_extra_args (tree, tree, tsubst_flags_t); diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c index a1b6631d691..463b1c3a57d 100644 --- i/gcc/cp/pt.c +++ w/gcc/cp/pt.c @@ -103,13 +103,6 @@ local_specialization_stack::~local_specialization_stack () /* True if we've recursed into fn_type_unification too many times. */ static bool excessive_deduction_depth; -struct GTY((for_user)) spec_entry -{ - tree tmpl; - tree args; - tree spec; -}; - struct spec_hasher : ggc_ptr_hash { static hashval_t hash (spec_entry *); @@ -29625,6 +29618,101 @@ declare_integer_pack (void) CP_BUILT_IN_INTEGER_PACK); } +/* Walk the decl or type specialization table calling FN on each + entry. */ + +void +walk_specializations (bool decls_p, + void (*fn) (bool decls_p, spec_entry *entry, void *data), + void *data) +{ + spec_hash_table *table = decls_p ? decl_specializations + : type_specializations; + spec_hash_table::iterator end (table->end ()); + for (spec_hash_table::iterator iter (table->begin ()); iter != end; ++iter) + fn (decls_p, *iter, data); +} + +/* Lookup the specialization of TMPL, ARGS in the decl or type + specialization table. Return what's there, or if SPEC is non-null, + add it and return NULL. */ + +tree +match_mergeable_specialization (bool decl_p, tree tmpl, tree args, tree spec) +{ + spec_entry elt = {tmpl, args, spec}; + hash_table *specializations + = decl_p ? decl_specializations : type_specializations; + hashval_t hash = spec_hasher::hash (&elt); + spec_entry **slot + = specializations->find_slot_with_hash (&elt, hash, + spec ? INSERT : NO_INSERT); + spec_entry *entry = slot ? *slot: NULL; + + if (entry) + return entry->spec; + + if (spec) + { + entry = ggc_alloc (); + *entry = elt; + *slot = entry; + } + + return NULL_TREE; +} + +/* Return flags encoding whether SPEC is on the instantiation and/or + specialization lists of TMPL. */ + +unsigned +get_mergeable_specialization_flags (tree tmpl, tree decl) +{ + unsigned flags = 0; + + for (tree inst = DECL_TEMPLATE_INSTANTIATIONS (tmpl); + inst; inst = TREE_CHAIN (inst)) + if (TREE_VALUE (inst) == decl) + { + flags |= 1; + break; + } + + if (CLASS_TYPE_P (TREE_TYPE (decl)) + && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl)) + && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)) == 2) + /* Only need to search if DECL is a partial specialization. */ + for (tree part = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); + part; part = TREE_CHAIN (part)) + if (TREE_VALUE (part) == decl) + { + flags |= 2; + break; + } + + return flags; +} + +/* Add a new specialization of TMPL. FLAGS is as returned from + get_mergeable_specialization_flags. */ + +void +add_mergeable_specialization (tree tmpl, tree args, tree decl, unsigned flags) +{ + if (flags & 1) + DECL_TEMPLATE_INSTANTIATIONS (tmpl) + = tree_cons (args, decl, DECL_TEMPLATE_INSTANTIATIONS (tmpl)); + + if (flags & 2) + { + /* A partial specialization. */ + DECL_TEMPLATE_SPECIALIZATIONS (tmpl) + = tree_cons (args, decl, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); + TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (tmpl)) + = TREE_TYPE (DECL_TEMPLATE_RESULT (decl)); + } +} + /* Set up the hash tables for template instantiations. */ void