From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 4C7B03857731 for ; Tue, 3 Oct 2023 12:41:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4C7B03857731 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1696336910; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Yl6oxJdjAhCCQN+Rmj5GovASGdv3lxZf9c73qe2gd84=; b=fmmoqGiPlqmZ23HhCQDbR4eAlwQgl/L8IyEBtLqe+z0DAqmvOVB0I8MpWb1uquIBH+9jyx aPFhD7k61myuLbKGd6X8qsy0pX9FTZBy0XKrqco2sUrdX/ovMfo+l6R5o+BCHxVMOMgw5W Gw18QuMpfls3afcl6ognk+/wvonbO+s= Received: from mail-yw1-f200.google.com (mail-yw1-f200.google.com [209.85.128.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-249-pGHh586ANfOJGEeaTl8tjQ-1; Tue, 03 Oct 2023 08:41:48 -0400 X-MC-Unique: pGHh586ANfOJGEeaTl8tjQ-1 Received: by mail-yw1-f200.google.com with SMTP id 00721157ae682-5a1d352a86dso13062347b3.0 for ; Tue, 03 Oct 2023 05:41:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696336908; x=1696941708; h=mime-version:references:message-id:in-reply-to:subject:cc:to:date :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Yl6oxJdjAhCCQN+Rmj5GovASGdv3lxZf9c73qe2gd84=; b=obABP3No8aM0KFTk392/y4NZnDF+UpC/omYcJ+NIfEQNuZoYO5Q2PEH5USCDZM0Fj7 SgZjSoLxlFlV7yd6eoyn374xR1QZxANJQVmqdkiS6X3xl1QegCdZk57+LtU4bvNd29jv 2du9kS+b1KC8BFniL7SMkx036rL3N/HhiKzKUa0TynyF6nvMrQdid1pW7mpBWmdhJg03 qPzHJ4Li2X1suL44J57NgOgBw2Vjz+A6RTEB4amnu4ye82lRyom59HQcguhYcyYBETO6 H9wjgvqop6bMJcWwH2MYrCLpgV9YmiAqumlk7RveqmpdpGOgIB6We4VSSc1MkILZaPZh b7gg== X-Gm-Message-State: AOJu0YwgmmAstM1NlG4l22nUA33SWceqv03Nf6aWfm16oGs7v1M/Sx7O HWvC6MlHZ2J+ju0dbhCF7JEotnKd66ajwQEmEYS5XoTOIVEq9fkj4TIjWjy/zqj7CgLKDDLYGRC dTjTSbvUgmeBVxxSagw== X-Received: by 2002:a0d:eb44:0:b0:58f:af0f:1dcd with SMTP id u65-20020a0deb44000000b0058faf0f1dcdmr13943302ywe.17.1696336907272; Tue, 03 Oct 2023 05:41:47 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHBMzGR9XEVa3ASRoq/plZZKLP8h8msw/WeR7kkFe3etp+kxi1th2MwVgNsyTU+6ES0+tiCoQ== X-Received: by 2002:a0d:eb44:0:b0:58f:af0f:1dcd with SMTP id u65-20020a0deb44000000b0058faf0f1dcdmr13943252ywe.17.1696336906349; Tue, 03 Oct 2023 05:41:46 -0700 (PDT) Received: from [192.168.1.130] (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id u7-20020a0cdd07000000b00668bb8be252sm434602qvk.60.2023.10.03.05.41.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Oct 2023 05:41:45 -0700 (PDT) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Tue, 3 Oct 2023 08:41:45 -0400 (EDT) To: Patrick Palka cc: gcc-patches@gcc.gnu.org, jason@redhat.com Subject: Re: [PATCH] c++: merge tsubst_copy into tsubst_copy_and_build In-Reply-To: <20231002193738.3900509-1-ppalka@redhat.com> Message-ID: References: <20230925204302.1277285-2-ppalka@redhat.com> <20231002193738.3900509-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-13.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,WEIRD_PORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Mon, 2 Oct 2023, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > OK for trunk? > > -- >8 -- > > The relationship between tsubst_copy_and_build and tsubst_copy (two of > the main template argument substitution routines for expression trees) > is rather hazy. The former is mostly a superset of the latter, with > some differences. > > The main difference is that they handle many tree codes differently, but > much of the tree code handling in tsubst_copy appears to be dead code[1]. > This is because tsubst_copy only gets directly called in a few places > and mostly on id-expressions. The interesting exceptions are PARM_DECL, > VAR_DECL, BIT_NOT_EXPR, SCOPE_REF, TEMPLATE_ID_EXPR and IDENTIFIER_NODE: > > * for PARM_DECL and VAR_DECL, tsubst_copy_and_build calls tsubst_copy > followed by doing some extra handling of its own > * for BIT_NOT_EXPR tsubst_copy implicitly handles unresolved destructor > calls (i.e. the first operand is an identifier or a type) > * for SCOPE_REF, TEMPLATE_ID_EXPR and IDENTIFIER_NODE tsubst_copy > refrains from doing name lookup of the terminal name > > Other more minor differences are that tsubst_copy exits early when > 'args' is null, and it calls maybe_dependent_member_ref, and finally > it dispatches to tsubst for type trees. > > Thus tsubst_copy is (at this point) similar enough to tsubst_copy_and_build > that it makes sense to merge the two functions, with the main difference > being the name lookup behavior[2]. So this patch merges tsubst_copy into > tsubst_copy_and_build via a new tsubst tf_no_name_lookup which controls > name lookup and resolution of a (top-level) id-expression. > > [1]: http://thrifty.mooo.com:8008/gcc-lcov/gcc/cp/pt.cc.gcov.html#17231 > [2]: I don't know the history of tsubst_copy but I would guess it was > added before we settled on using processing_template_decl to control > whether our AST building routines perform semantic checking and return > non-templated trees, and so we needed a separate tsubst routine that > avoids semantic checking and always returns a templated tree for e.g. > partial substitution. Oops, this is wrong -- tsubst_copy_and_build came after tsubst_copy, and was introduced as an optimization with the intent of getting rid of tsubst_copy eventually: https://gcc.gnu.org/pipermail/gcc-patches/2003-January/093659.html > > gcc/cp/ChangeLog: > > * cp-tree.h (enum tsubst_flags): Add tf_no_name_lookup. > * pt.cc (tsubst_copy): > (tsubst_pack_expansion): Use tsubst for substituting BASES_TYPE. > (tsubst_decl) : Use tsubst_copy_and_build with > tf_no_name_lookup instead of tsubst_copy. > (tsubst) : Use tsubst_copy_and_build > instead of tsubst_copy for substituting > CLASS_PLACEHOLDER_TEMPLATE. > : Use tsubst_copy_and_build with > tf_no_name_lookup instead of tsubst_copy for substituting > TYPENAME_TYPE_FULLNAME. > (tsubst_qualified_id): Likewise for substituting the component > name of a SCOPE_REF. > (tsubst_copy): Remove. > (tsubst_copy_and_build): Clear tf_no_name_lookup at the start, > and remember if it was set. Call maybe_dependent_member_ref. > : Don't do name lookup if tf_no_name_lookup > was set. > : Don't finish a template-id if > tf_no_name_lookup was set. > : Handle identifier and type operand (if > tf_no_name_lookup was set). > : Avoid trying to resolve a SCOPE_REF if > tf_no_name_lookup by calling build_qualified_name directly > instead of tsubst_qualified_id. > : Handling of sizeof... copied from tsubst_copy. > : Use tsubst_copy_and_build with > tf_no_name_lookup instead of tsubst_copy to substitute > a TEMPLATE_ID_EXPR callee naming an unresolved template. > : Likewise to substitute the member. > : Copied from tsubst_copy and merged with ... > : ... these. Initial handling copied > from tsubst_copy. Optimize local variable substitution by > trying retrieve_local_specialization before checking > uses_template_parms. > : Copied from tsubst_copy. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Use tsubst and tsubst_copy_and_build instead > of tsubst_copy. > : Copied from tsubst_copy. > (tsubst_initializer_list): Use tsubst and tsubst_copy_and_build > instead of tsubst_copy. > --- > gcc/cp/cp-tree.h | 3 + > gcc/cp/pt.cc | 1742 +++++++++++++++++++--------------------------- > 2 files changed, 719 insertions(+), 1026 deletions(-) > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 8b9a7d58462..919eab34803 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -5619,6 +5619,9 @@ enum tsubst_flags { > tf_qualifying_scope = 1 << 14, /* Substituting the LHS of the :: operator. > Affects TYPENAME_TYPE resolution from > make_typename_type. */ > + tf_no_name_lookup = 1 << 15, /* Don't look up the terminal name of an > + outermost id-expression, or resolve its > + constituent template-ids or qualified-ids. */ > /* Convenient substitution flags combinations. */ > tf_warning_or_error = tf_warning | tf_error > }; > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 4400d429b6f..e1fb20994e3 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -204,7 +204,6 @@ static void copy_default_args_to_explicit_spec (tree); > static bool invalid_nontype_parm_type_p (tree, tsubst_flags_t); > static bool dependent_template_arg_p (tree); > static bool dependent_type_p_r (tree); > -static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); > static tree tsubst_decl (tree, tree, tsubst_flags_t, bool = true); > static tree tsubst_scope (tree, tree, tsubst_flags_t, tree); > static void perform_instantiation_time_access_checks (tree, tree); > @@ -13373,15 +13372,11 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, > if (TREE_CODE (parm_pack) == BASES) > { > gcc_assert (parm_pack == pattern); > + tree type = tsubst (BASES_TYPE (parm_pack), args, complain, in_decl); > if (BASES_DIRECT (parm_pack)) > - return calculate_direct_bases (tsubst_expr (BASES_TYPE (parm_pack), > - args, complain, > - in_decl), > - complain); > + return calculate_direct_bases (type, complain); > else > - return calculate_bases (tsubst_expr (BASES_TYPE (parm_pack), > - args, complain, in_decl), > - complain); > + return calculate_bases (type, complain); > } > else if (builtin_pack_call_p (parm_pack)) > { > @@ -15171,7 +15166,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, > variadic_p = true; > } > else > - name = tsubst_copy (name, args, complain, in_decl); > + name = tsubst_copy_and_build (name, args, > + complain | tf_no_name_lookup, in_decl); > > int len; > if (!variadic_p) > @@ -16108,7 +16104,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) > if (template_placeholder_p (t)) > { > tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (t); > - tmpl = tsubst_copy (tmpl, args, complain, in_decl); > + tmpl = tsubst_copy_and_build (tmpl, args, complain, in_decl); > if (TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM) > tmpl = TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (tmpl); > > @@ -16592,8 +16588,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) > if (ctx == error_mark_node) > return error_mark_node; > > - tree f = tsubst_copy (TYPENAME_TYPE_FULLNAME (t), args, > - complain, in_decl); > + tree f = tsubst_copy_and_build (TYPENAME_TYPE_FULLNAME (t), args, > + complain | tf_no_name_lookup, in_decl); > if (f == error_mark_node) > return error_mark_node; > > @@ -17045,7 +17041,8 @@ tsubst_qualified_id (tree qualified_id, tree args, > if (args) > { > scope = tsubst_scope (scope, args, complain, in_decl); > - expr = tsubst_copy (name, args, complain, in_decl); > + expr = tsubst_copy_and_build (name, args, > + complain | tf_no_name_lookup, in_decl); > } > else > expr = name; > @@ -17277,878 +17274,177 @@ maybe_dependent_member_ref (tree t, tree args, tsubst_flags_t complain, > TREE_CODE (t) == TEMPLATE_DECL); > } > > -/* Like tsubst, but deals with expressions. This function just replaces > - template parms; to finish processing the resultant expression, use > - tsubst_copy_and_build or tsubst_expr. */ > +/* Helper function for tsubst_omp_clauses, used for instantiation of > + OMP_CLAUSE_DECL of clauses. */ > > static tree > -tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) > +tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain, > + tree in_decl, tree *iterator_cache) > { > - enum tree_code code; > - tree r; > - > - if (t == NULL_TREE || t == error_mark_node || args == NULL_TREE) > - return t; > - > - if (TYPE_P (t)) > - return tsubst (t, args, complain, in_decl); > - > - if (tree d = maybe_dependent_member_ref (t, args, complain, in_decl)) > - return d; > - > - code = TREE_CODE (t); > + if (decl == NULL_TREE || decl == ridpointers[RID_OMP_ALL_MEMORY]) > + return decl; > > - switch (code) > + /* Handle OpenMP iterators. */ > + if (TREE_CODE (decl) == TREE_LIST > + && TREE_PURPOSE (decl) > + && TREE_CODE (TREE_PURPOSE (decl)) == TREE_VEC) > { > - case PARM_DECL: > - r = retrieve_local_specialization (t); > - > - if (r == NULL_TREE) > + tree ret; > + if (iterator_cache[0] == TREE_PURPOSE (decl)) > + ret = iterator_cache[1]; > + else > { > - /* We get here for a use of 'this' in an NSDMI. */ > - if (DECL_NAME (t) == this_identifier && current_class_ptr) > - return current_class_ptr; > - > - /* This can happen for a parameter name used later in a function > - declaration (such as in a late-specified return type). Just > - make a dummy decl, since it's only used for its type. */ > - gcc_assert (cp_unevaluated_operand); > - r = tsubst_decl (t, args, complain); > - /* Give it the template pattern as its context; its true context > - hasn't been instantiated yet and this is good enough for > - mangling. */ > - DECL_CONTEXT (r) = DECL_CONTEXT (t); > + tree *tp = &ret; > + begin_scope (sk_omp, NULL); > + for (tree it = TREE_PURPOSE (decl); it; it = TREE_CHAIN (it)) > + { > + *tp = copy_node (it); > + TREE_VEC_ELT (*tp, 0) > + = tsubst_decl (TREE_VEC_ELT (it, 0), args, complain); > + DECL_CONTEXT (TREE_VEC_ELT (*tp, 0)) = current_function_decl; > + pushdecl (TREE_VEC_ELT (*tp, 0)); > + TREE_VEC_ELT (*tp, 1) > + = tsubst_expr (TREE_VEC_ELT (it, 1), args, complain, in_decl); > + TREE_VEC_ELT (*tp, 2) > + = tsubst_expr (TREE_VEC_ELT (it, 2), args, complain, in_decl); > + TREE_VEC_ELT (*tp, 3) > + = tsubst_expr (TREE_VEC_ELT (it, 3), args, complain, in_decl); > + TREE_CHAIN (*tp) = NULL_TREE; > + tp = &TREE_CHAIN (*tp); > + } > + TREE_VEC_ELT (ret, 5) = poplevel (1, 1, 0); > + iterator_cache[0] = TREE_PURPOSE (decl); > + iterator_cache[1] = ret; > } > + return build_tree_list (ret, tsubst_omp_clause_decl (TREE_VALUE (decl), > + args, complain, > + in_decl, NULL)); > + } > > - if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) > - r = argument_pack_select_arg (r); > - if (!mark_used (r, complain) && !(complain & tf_error)) > - return error_mark_node; > - return r; > - > - case CONST_DECL: > - { > - tree enum_type; > - tree v; > - > - if (DECL_TEMPLATE_PARM_P (t)) > - return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl); > - if (!uses_template_parms (DECL_CONTEXT (t))) > - return t; > - > - /* Unfortunately, we cannot just call lookup_name here. > - Consider: > - > - template int f() { > - enum E { a = I }; > - struct S { void g() { E e = a; } }; > - }; > - > - When we instantiate f<7>::S::g(), say, lookup_name is not > - clever enough to find f<7>::a. */ > - enum_type > - = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl, > - /*entering_scope=*/0); > - > - for (v = TYPE_VALUES (enum_type); > - v != NULL_TREE; > - v = TREE_CHAIN (v)) > - if (TREE_PURPOSE (v) == DECL_NAME (t)) > - return TREE_VALUE (v); > - > - /* We didn't find the name. That should never happen; if > - name-lookup found it during preliminary parsing, we > - should find it again here during instantiation. */ > - gcc_unreachable (); > - } > - return t; > + /* Handle an OpenMP array section represented as a TREE_LIST (or > + OMP_CLAUSE_DOACROSS_KIND). An OMP_CLAUSE_DOACROSS (with a depend > + kind of OMP_CLAUSE_DOACROSS_SINK) can also be represented as a > + TREE_LIST. We can handle it exactly the same as an array section > + (purpose, value, and a chain), even though the nomenclature > + (low_bound, length, etc) is different. */ > + if (TREE_CODE (decl) == TREE_LIST) > + { > + tree low_bound > + = tsubst_expr (TREE_PURPOSE (decl), args, complain, in_decl); > + tree length = tsubst_expr (TREE_VALUE (decl), args, complain, in_decl); > + tree chain = tsubst_omp_clause_decl (TREE_CHAIN (decl), args, complain, > + in_decl, NULL); > + if (TREE_PURPOSE (decl) == low_bound > + && TREE_VALUE (decl) == length > + && TREE_CHAIN (decl) == chain) > + return decl; > + tree ret = tree_cons (low_bound, length, chain); > + OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (ret) > + = OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (decl); > + return ret; > + } > + tree ret = tsubst_expr (decl, args, complain, in_decl); > + /* Undo convert_from_reference tsubst_expr could have called. */ > + if (decl > + && REFERENCE_REF_P (ret) > + && !REFERENCE_REF_P (decl)) > + ret = TREE_OPERAND (ret, 0); > + return ret; > +} > > - case FIELD_DECL: > - if (DECL_CONTEXT (t)) > - { > - tree ctx; > +/* Like tsubst_copy, but specifically for OpenMP clauses. */ > > - ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl, > - /*entering_scope=*/1); > - if (ctx != DECL_CONTEXT (t)) > - { > - tree r = lookup_field (ctx, DECL_NAME (t), 0, false); > - if (!r) > - { > - if (complain & tf_error) > - error ("using invalid field %qD", t); > - return error_mark_node; > - } > - return r; > - } > - } > +static tree > +tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort, > + tree args, tsubst_flags_t complain, tree in_decl) > +{ > + tree new_clauses = NULL_TREE, nc, oc; > + tree linear_no_step = NULL_TREE; > + tree iterator_cache[2] = { NULL_TREE, NULL_TREE }; > > - return t; > + for (oc = clauses; oc ; oc = OMP_CLAUSE_CHAIN (oc)) > + { > + nc = copy_node (oc); > + OMP_CLAUSE_CHAIN (nc) = new_clauses; > + new_clauses = nc; > > - case VAR_DECL: > - case FUNCTION_DECL: > - if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)) > - r = tsubst (t, args, complain, in_decl); > - else if (DECL_LOCAL_DECL_P (t)) > + switch (OMP_CLAUSE_CODE (nc)) > { > - /* Local specialization will usually have been created when > - we instantiated the DECL_EXPR_DECL. */ > - r = retrieve_local_specialization (t); > - if (!r) > + case OMP_CLAUSE_LASTPRIVATE: > + if (OMP_CLAUSE_LASTPRIVATE_STMT (oc)) > { > - /* We're in a generic lambda referencing a local extern > - from an outer block-scope of a non-template. */ > - gcc_checking_assert (LAMBDA_FUNCTION_P (current_function_decl)); > - r = t; > + OMP_CLAUSE_LASTPRIVATE_STMT (nc) = push_stmt_list (); > + tsubst_expr (OMP_CLAUSE_LASTPRIVATE_STMT (oc), args, > + complain, in_decl); > + OMP_CLAUSE_LASTPRIVATE_STMT (nc) > + = pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (nc)); > } > - } > - else if (local_variable_p (t) > - && uses_template_parms (DECL_CONTEXT (t))) > - { > - r = retrieve_local_specialization (t); > - if (r == NULL_TREE) > + /* FALLTHRU */ > + case OMP_CLAUSE_PRIVATE: > + case OMP_CLAUSE_SHARED: > + case OMP_CLAUSE_FIRSTPRIVATE: > + case OMP_CLAUSE_COPYIN: > + case OMP_CLAUSE_COPYPRIVATE: > + case OMP_CLAUSE_UNIFORM: > + case OMP_CLAUSE_DEPEND: > + case OMP_CLAUSE_DOACROSS: > + case OMP_CLAUSE_AFFINITY: > + case OMP_CLAUSE_FROM: > + case OMP_CLAUSE_TO: > + case OMP_CLAUSE_MAP: > + case OMP_CLAUSE__CACHE_: > + case OMP_CLAUSE_NONTEMPORAL: > + case OMP_CLAUSE_USE_DEVICE_PTR: > + case OMP_CLAUSE_USE_DEVICE_ADDR: > + case OMP_CLAUSE_IS_DEVICE_PTR: > + case OMP_CLAUSE_HAS_DEVICE_ADDR: > + case OMP_CLAUSE_INCLUSIVE: > + case OMP_CLAUSE_EXCLUSIVE: > + OMP_CLAUSE_DECL (nc) > + = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain, > + in_decl, iterator_cache); > + break; > + case OMP_CLAUSE_NUM_TEAMS: > + if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (oc)) > + OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (nc) > + = tsubst_expr (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (oc), args, > + complain, in_decl); > + /* FALLTHRU */ > + case OMP_CLAUSE_TILE: > + case OMP_CLAUSE_IF: > + case OMP_CLAUSE_NUM_THREADS: > + case OMP_CLAUSE_SCHEDULE: > + case OMP_CLAUSE_COLLAPSE: > + case OMP_CLAUSE_FINAL: > + case OMP_CLAUSE_DEVICE: > + case OMP_CLAUSE_DIST_SCHEDULE: > + case OMP_CLAUSE_THREAD_LIMIT: > + case OMP_CLAUSE_SAFELEN: > + case OMP_CLAUSE_SIMDLEN: > + case OMP_CLAUSE_NUM_TASKS: > + case OMP_CLAUSE_GRAINSIZE: > + case OMP_CLAUSE_PRIORITY: > + case OMP_CLAUSE_ORDERED: > + case OMP_CLAUSE_HINT: > + case OMP_CLAUSE_FILTER: > + case OMP_CLAUSE_NUM_GANGS: > + case OMP_CLAUSE_NUM_WORKERS: > + case OMP_CLAUSE_VECTOR_LENGTH: > + case OMP_CLAUSE_WORKER: > + case OMP_CLAUSE_VECTOR: > + case OMP_CLAUSE_ASYNC: > + case OMP_CLAUSE_WAIT: > + case OMP_CLAUSE_DETACH: > + OMP_CLAUSE_OPERAND (nc, 0) > + = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, in_decl); > + break; > + case OMP_CLAUSE_REDUCTION: > + case OMP_CLAUSE_IN_REDUCTION: > + case OMP_CLAUSE_TASK_REDUCTION: > + if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (oc)) > { > - /* First try name lookup to find the instantiation. */ > - r = lookup_name (DECL_NAME (t)); > - if (r) > - { > - if (!VAR_P (r)) > - { > - /* During error-recovery we may find a non-variable, > - even an OVERLOAD: just bail out and avoid ICEs and > - duplicate diagnostics (c++/62207). */ > - gcc_assert (seen_error ()); > - return error_mark_node; > - } > - if (!is_capture_proxy (r)) > - { > - /* Make sure the one we found is the one we want. */ > - tree ctx = enclosing_instantiation_of (DECL_CONTEXT (t)); > - if (ctx != DECL_CONTEXT (r)) > - r = NULL_TREE; > - } > - } > - > - if (r) > - /* OK */; > - else > - { > - /* This can happen for a variable used in a > - late-specified return type of a local lambda, or for a > - local static or constant. Building a new VAR_DECL > - should be OK in all those cases. */ > - r = tsubst_decl (t, args, complain); > - if (local_specializations) > - /* Avoid infinite recursion (79640). */ > - register_local_specialization (r, t); > - if (decl_maybe_constant_var_p (r)) > - { > - /* We can't call cp_finish_decl, so handle the > - initializer by hand. */ > - tree init = tsubst_init (DECL_INITIAL (t), r, args, > - complain, in_decl); > - if (!processing_template_decl) > - init = maybe_constant_init (init); > - if (processing_template_decl > - ? potential_constant_expression (init) > - : reduced_constant_expression_p (init)) > - DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) > - = TREE_CONSTANT (r) = true; > - DECL_INITIAL (r) = init; > - if (tree auto_node = type_uses_auto (TREE_TYPE (r))) > - TREE_TYPE (r) > - = do_auto_deduction (TREE_TYPE (r), init, auto_node, > - complain, adc_variable_type); > - } > - gcc_assert (cp_unevaluated_operand > - || processing_contract_condition > - || TREE_STATIC (r) > - || decl_constant_var_p (r) > - || seen_error ()); > - if (!processing_template_decl > - && !TREE_STATIC (r)) > - r = process_outer_var_ref (r, complain); > - } > - /* Remember this for subsequent uses. */ > - if (local_specializations) > - register_local_specialization (r, t); > - } > - if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) > - r = argument_pack_select_arg (r); > - } > - else > - r = t; > - if (!mark_used (r, complain)) > - return error_mark_node; > - return r; > - > - case NAMESPACE_DECL: > - return t; > - > - case OVERLOAD: > - return t; > - > - case BASELINK: > - return tsubst_baselink (t, current_nonlambda_class_type (), > - args, complain, in_decl); > - > - case TEMPLATE_DECL: > - if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) > - return tsubst (TREE_TYPE (DECL_TEMPLATE_RESULT (t)), > - args, complain, in_decl); > - else if (DECL_FUNCTION_TEMPLATE_P (t) && DECL_MEMBER_TEMPLATE_P (t)) > - return tsubst (t, args, complain, in_decl); > - else if (DECL_CLASS_SCOPE_P (t) > - && uses_template_parms (DECL_CONTEXT (t))) > - { > - /* Template template argument like the following example need > - special treatment: > - > - template