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 [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id E23DF385800A for ; Sat, 1 May 2021 16:29:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E23DF385800A Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-519-VrQw8v9rO46kCea1a988pg-1; Sat, 01 May 2021 12:29:04 -0400 X-MC-Unique: VrQw8v9rO46kCea1a988pg-1 Received: by mail-qv1-f72.google.com with SMTP id c5-20020a0ca9c50000b02901aede9b5061so1243490qvb.14 for ; Sat, 01 May 2021 09:29:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=2rJLDBmfbEYwEYA46yX9f/jmfP5TLRIo4lutGhvn2H0=; b=ZrhfO/Im8hgpuIQlUug9QVeDjBKCSBvYvwMhKNV0AaOiMYT20u848QyZ36mzTGFMOA tidaD2XCu0QJ+7FKrQazjYOCjOamlqytO5slzRUb0L09WBuawWw96qtmCrtszYtzqh0k 2qyMqMUcZV4KBblk4txGKdCtTWxGmjm8Z1YDS3R68Dwq4sUAliWI0Ped1xvB22eiRbyP lMDBf1XGCUBxHAVT1FrC6SnfCzSc4qvO7YOROPnJGopyZ6faCBA/07yMhaWCYvjF8buJ kVn7o1lHlTCg/JraoI+aKYmRdEtwrCaSZCXfxL36CAZ5+0vF9/RQ7ijltIEbaWhLUXGz 6Mwg== X-Gm-Message-State: AOAM531xLlld/JosIFTkZBlXGMVO6Cc1P3aeOzDOPjDwJELIWOwbuKi+ StkfZWwJAazeJFjQfuDicJO7O4RNgR5uLZcam6F6F2FdeHUTPDGn+R5HGmgd9phnG/U+ZXx7+1d qyPODH1d2x11TduXGHXVrMvY2iyRI8HOxZDD2S5Z7YrEhN500p3MHMQmf5dbSEdzKTg== X-Received: by 2002:a05:6214:629:: with SMTP id a9mr11283603qvx.4.1619886543842; Sat, 01 May 2021 09:29:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyhfEWXMui0uWslRhHoBF9zvG6O5TZKz7MInBbg2VmXhMxLNa0ehvw9nUxwAE62tW+sQeViPA== X-Received: by 2002:a05:6214:629:: with SMTP id a9mr11283585qvx.4.1619886543520; Sat, 01 May 2021 09:29:03 -0700 (PDT) Received: from barrymore.redhat.com (209-6-216-142.s141.c3-0.smr-cbr1.sbo-smr.ma.cable.rcncustomer.com. [209.6.216.142]) by smtp.gmail.com with ESMTPSA id y29sm4857795qtm.13.2021.05.01.09.29.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 May 2021 09:29:02 -0700 (PDT) From: Jason Merrill To: gcc-patches@gcc.gnu.org Subject: [PATCH RFA] tree-iterator: C++11 range-for and tree_stmt_iterator Date: Sat, 1 May 2021 12:29:01 -0400 Message-Id: <20210501162901.3164931-1-jason@redhat.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-15.5 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_H4, RCVD_IN_MSPIKE_WL, 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: , X-List-Received-Date: Sat, 01 May 2021 16:29:09 -0000 Like my recent patch to add ovl_range and lkp_range in the C++ front end, this patch adds the tsi_range adaptor for using C++11 range-based 'for' with a STATEMENT_LIST, e.g. for (tree stmt : tsi_range (stmt_list)) { ... } This also involves adding some operators to tree_stmt_iterator that are needed for range-for iterators, and should also be useful in code that uses the iterators directly. The patch updates the suitable loops in the C++ front end, but does not touch any loops elsewhere in the compiler. gcc/ChangeLog: * tree-iterator.h (struct tree_stmt_iterator): Add operator++, operator--, operator*, operator==, and operator!=. (class tsi_range): New. gcc/cp/ChangeLog: * constexpr.c (build_data_member_initialization): Use tsi_range. (build_constexpr_constructor_member_initializers): Likewise. (constexpr_fn_retval, cxx_eval_statement_list): Likewise. (potential_constant_expression_1): Likewise. * coroutines.cc (await_statement_expander): Likewise. (await_statement_walker): Likewise. * module.cc (trees_out::core_vals): Likewise. * pt.c (tsubst_expr): Likewise. * semantics.c (set_cleanup_locs): Likewise. --- gcc/tree-iterator.h | 28 +++++++++++++++++++++++----- gcc/cp/constexpr.c | 42 ++++++++++++++---------------------------- gcc/cp/coroutines.cc | 10 ++++------ gcc/cp/module.cc | 5 ++--- gcc/cp/pt.c | 5 ++--- gcc/cp/semantics.c | 5 ++--- 6 files changed, 47 insertions(+), 48 deletions(-) diff --git a/gcc/tree-iterator.h b/gcc/tree-iterator.h index 076fff8644c..f57456bb473 100644 --- a/gcc/tree-iterator.h +++ b/gcc/tree-iterator.h @@ -1,4 +1,4 @@ -/* Iterator routines for manipulating GENERIC tree statement list. +/* Iterator routines for manipulating GENERIC tree statement list. -*- C++ -*- Copyright (C) 2003-2021 Free Software Foundation, Inc. Contributed by Andrew MacLeod @@ -32,6 +32,13 @@ along with GCC; see the file COPYING3. If not see struct tree_stmt_iterator { struct tree_statement_list_node *ptr; tree container; + + bool operator== (tree_stmt_iterator b) const + { return b.ptr == ptr && b.container == container; } + bool operator!= (tree_stmt_iterator b) const { return !(*this == b); } + tree_stmt_iterator &operator++ () { ptr = ptr->next; return *this; } + tree_stmt_iterator &operator-- () { ptr = ptr->prev; return *this; } + tree &operator* () { return ptr->stmt; } }; static inline tree_stmt_iterator @@ -71,27 +78,38 @@ tsi_one_before_end_p (tree_stmt_iterator i) static inline void tsi_next (tree_stmt_iterator *i) { - i->ptr = i->ptr->next; + ++(*i); } static inline void tsi_prev (tree_stmt_iterator *i) { - i->ptr = i->ptr->prev; + --(*i); } static inline tree * tsi_stmt_ptr (tree_stmt_iterator i) { - return &i.ptr->stmt; + return &(*i); } static inline tree tsi_stmt (tree_stmt_iterator i) { - return i.ptr->stmt; + return *i; } +/* Make tree_stmt_iterator work as a C++ range, e.g. + for (tree stmt : tsi_range (stmt_list)) { ... } */ +class tsi_range +{ + tree t; + public: + tsi_range (tree t): t(t) { } + tree_stmt_iterator begin() { return tsi_start (t); } + tree_stmt_iterator end() { return { nullptr, t }; } +}; + enum tsi_iterator_update { TSI_NEW_STMT, /* Only valid when single statement is added, move diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 9481a5bfd3c..260b0122f59 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -330,12 +330,9 @@ build_data_member_initialization (tree t, vec **vec) return false; if (TREE_CODE (t) == STATEMENT_LIST) { - tree_stmt_iterator i; - for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i)) - { - if (! build_data_member_initialization (tsi_stmt (i), vec)) - return false; - } + for (tree stmt : tsi_range (t)) + if (! build_data_member_initialization (stmt, vec)) + return false; return true; } if (TREE_CODE (t) == CLEANUP_STMT) @@ -577,10 +574,9 @@ build_constexpr_constructor_member_initializers (tree type, tree body) break; case STATEMENT_LIST: - for (tree_stmt_iterator i = tsi_start (body); - !tsi_end_p (i); tsi_next (&i)) + for (tree stmt : tsi_range (body)) { - body = tsi_stmt (i); + body = stmt; if (TREE_CODE (body) == BIND_EXPR) break; } @@ -617,10 +613,9 @@ build_constexpr_constructor_member_initializers (tree type, tree body) } else if (TREE_CODE (body) == STATEMENT_LIST) { - tree_stmt_iterator i; - for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i)) + for (tree stmt : tsi_range (body)) { - ok = build_data_member_initialization (tsi_stmt (i), &vec); + ok = build_data_member_initialization (stmt, &vec); if (!ok) break; } @@ -675,11 +670,10 @@ constexpr_fn_retval (tree body) { case STATEMENT_LIST: { - tree_stmt_iterator i; tree expr = NULL_TREE; - for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i)) + for (tree stmt : tsi_range (body)) { - tree s = constexpr_fn_retval (tsi_stmt (i)); + tree s = constexpr_fn_retval (stmt); if (s == error_mark_node) return error_mark_node; else if (s == NULL_TREE) @@ -5772,7 +5766,6 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t, bool *non_constant_p, bool *overflow_p, tree *jump_target) { - tree_stmt_iterator i; tree local_target; /* In a statement-expression we want to return the last value. For empty statement expression return void_node. */ @@ -5782,9 +5775,8 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t, local_target = NULL_TREE; jump_target = &local_target; } - for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i)) + for (tree stmt : tsi_range (t)) { - tree stmt = tsi_stmt (i); /* We've found a continue, so skip everything until we reach the label its jumping to. */ if (continues (jump_target)) @@ -8283,16 +8275,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, } case STATEMENT_LIST: - { - tree_stmt_iterator i; - for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i)) - { - if (!RECUR (tsi_stmt (i), any)) - return false; - } - return true; - } - break; + for (tree stmt : tsi_range (t)) + if (!RECUR (stmt, any)) + return false; + return true; case MODIFY_EXPR: if (cxx_dialect < cxx14) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index dbd703a67cc..9b498f9d0b4 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -1771,10 +1771,9 @@ await_statement_expander (tree *stmt, int *do_subtree, void *d) return NULL_TREE; /* Just process the sub-trees. */ else if (TREE_CODE (*stmt) == STATEMENT_LIST) { - tree_stmt_iterator i; - for (i = tsi_start (*stmt); !tsi_end_p (i); tsi_next (&i)) + for (tree &s : tsi_range (*stmt)) { - res = cp_walk_tree (tsi_stmt_ptr (i), await_statement_expander, + res = cp_walk_tree (&s, await_statement_expander, d, NULL); if (res) return res; @@ -3523,10 +3522,9 @@ await_statement_walker (tree *stmt, int *do_subtree, void *d) } else if (TREE_CODE (*stmt) == STATEMENT_LIST) { - tree_stmt_iterator i; - for (i = tsi_start (*stmt); !tsi_end_p (i); tsi_next (&i)) + for (tree &s : tsi_range (*stmt)) { - res = cp_walk_tree (tsi_stmt_ptr (i), await_statement_walker, + res = cp_walk_tree (&s, await_statement_walker, d, NULL); if (res) return res; diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 02c19f55548..f0fb0144706 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -6094,9 +6094,8 @@ trees_out::core_vals (tree t) break; case STATEMENT_LIST: - for (tree_stmt_iterator iter = tsi_start (t); - !tsi_end_p (iter); tsi_next (&iter)) - if (tree stmt = tsi_stmt (iter)) + for (tree stmt : tsi_range (t)) + if (stmt) WT (stmt); WT (NULL_TREE); break; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 116bdd2e42a..ad140cfd586 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -18234,9 +18234,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, { case STATEMENT_LIST: { - tree_stmt_iterator i; - for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i)) - RECUR (tsi_stmt (i)); + for (tree stmt : tsi_range (t)) + RECUR (stmt); break; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 6224f49f189..2912efad9be 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -613,9 +613,8 @@ set_cleanup_locs (tree stmts, location_t loc) set_cleanup_locs (CLEANUP_BODY (stmts), loc); } else if (TREE_CODE (stmts) == STATEMENT_LIST) - for (tree_stmt_iterator i = tsi_start (stmts); - !tsi_end_p (i); tsi_next (&i)) - set_cleanup_locs (tsi_stmt (i), loc); + for (tree stmt : tsi_range (stmts)) + set_cleanup_locs (stmt, loc); } /* Finish a scope. */ base-commit: 3c65858787dc52b65b26fa7018587c01510f442c prerequisite-patch-id: 7ce9dff1f7d449f4a13fb882bf7b1a962a56de95 -- 2.27.0