From patchwork Fri Oct 23 20:41:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 535250 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 2103B141364 for ; Sat, 24 Oct 2015 07:25:45 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=hm/Lq/IA; dkim-atps=neutral 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:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=EJXJpl7mMNBu1vSX79arHZFNTA/mEp9NG+z9CliUo4bJWSx972KvA 3zKMK5lFvi+Jxj1rP/Dxu0RPt2kh8gmgJv/BVrSxgZN3jPpxFJKjzVUy4oRvGVwt V6kz2sWKG1rPBEaHySofjg9k+c+1oz0RR91Hw+ikL1ne3fyn9FtWAI= 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:cc:subject:date:message-id:in-reply-to:references; s= default; bh=FdtzD35VLcVVlrSb69rZ87BJILc=; b=hm/Lq/IArkysBFOYfttm mOhaq0WboAsMZt5tMhTRc9gTG/Lstj9jbXR+1IebuwSaHIdRQMIXuGhYB62LDgeL Wb5fqGal4EjsADyDVtgEo6q1qwvtmIFRaP0cXWjI/rFbwRsN8QQq56oc6CgV7Gi9 GDeGlIezfpnhq0o90OISgT8= Received: (qmail 12053 invoked by alias); 23 Oct 2015 20:24:45 -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 11847 invoked by uid 89); 23 Oct 2015 20:24:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: eggs.gnu.org Received: from eggs.gnu.org (HELO eggs.gnu.org) (208.118.235.92) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Fri, 23 Oct 2015 20:24:31 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zpisz-0001RZ-4J for gcc-patches@gcc.gnu.org; Fri, 23 Oct 2015 16:24:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56955) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zpisy-0001RP-Qk for gcc-patches@gcc.gnu.org; Fri, 23 Oct 2015 16:24:25 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 1C69F8C1B2 for ; Fri, 23 Oct 2015 20:24:23 +0000 (UTC) Received: from c64.redhat.com (vpn-230-149.phx2.redhat.com [10.3.230.149]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NKOJgU007382; Fri, 23 Oct 2015 16:24:22 -0400 From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 05/10] Add ranges to libcpp tokens (via ad-hoc data, unoptimized) Date: Fri, 23 Oct 2015 16:41:53 -0400 Message-Id: <1445632918-29617-6-git-send-email-dmalcolm@redhat.com> In-Reply-To: <1445632918-29617-1-git-send-email-dmalcolm@redhat.com> References: <1442957171-22904-1-git-send-email-dmalcolm@redhat.com> <1445632918-29617-1-git-send-email-dmalcolm@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 X-IsSubscribed: yes This patch: - generalizes the meaning of the source_location (aka location_t) type from being a caret within the source code to being a caret plus a source_range. The latter data is stored purely in the ad-hoc data lookaside for now. - captures ranges for libcpp tokens by generating source_location values with caret == start and finish == the last character of the token This is elegant, since we can store caret+range data in location_t as before, without having to track ranges everywhere: all location_t values (such as input_location) become the ranges of tokens; a followup patch fixes the diagnostic machinery to automatically extract the ranges when building rich_location instances, which means that all calls to warning, warning_at, error, error_at etc get underlines showing the range of the pertinent token "for free". However, it's inefficient, since it means generating an ad-hoc location for every token in libcpp. A followup patch optimizes this by packing short ranges into location_t, without needing to use ad-hoc locations, which covers most tokens efficiently. gcc/ChangeLog: * gimple.h (gimple_set_block): Use set_block function. * tree-cfg.c (move_block_to_fn): Likewise. (move_block_to_fn): Likewise. * tree-inline.c (copy_phis_for_bb): Likewise. * tree.c (tree_set_block): Likewise. (set_block): New function. * tree.h (set_block): New declaration. libcpp/ChangeLog: * include/cpplib.h (struct cpp_token): Update comment for src_loc to indicate that the range of the token is "baked into" the source_location. * include/line-map.h (location_adhoc_data): Add source_range field. (get_combined_adhoc_loc): Add source_range param. (get_range_from_adhoc_loc): New declaration. (get_range_from_loc): New inline function. (COMBINE_LOCATION_DATA): Add source_range param. * lex.c (_cpp_lex_direct): Capture the range of the token, baking it into token->src_loc via a call to COMBINE_LOCATION_DATA. * line-map.c (location_adhoc_data_hash): Add the src_range into the hash value. (location_adhoc_data_eq): Require equality of the src_range values. (get_combined_adhoc_loc): Add src_range param, and store it within the lookaside table. Remove the requirement that data is non-NULL. (get_range_from_adhoc_loc): New function. (linemap_expand_location): Extract the data pointer before extracting the location. --- gcc/gimple.h | 6 +----- gcc/tree-cfg.c | 9 ++------- gcc/tree-inline.c | 5 +---- gcc/tree.c | 11 +++++++---- gcc/tree.h | 3 +++ libcpp/include/cpplib.h | 3 ++- libcpp/include/line-map.h | 23 ++++++++++++++++++++--- libcpp/lex.c | 10 ++++++++++ libcpp/line-map.c | 26 ++++++++++++++++++++------ 9 files changed, 66 insertions(+), 30 deletions(-) diff --git a/gcc/gimple.h b/gcc/gimple.h index a456f54..ba66931 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1709,11 +1709,7 @@ gimple_block (const gimple *g) static inline void gimple_set_block (gimple *g, tree block) { - if (block) - g->location = - COMBINE_LOCATION_DATA (line_table, g->location, block); - else - g->location = LOCATION_LOCUS (g->location); + g->location = set_block (g->location, block); } diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 735ac46..8ef2443 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -6739,10 +6739,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb, continue; if (d->orig_block == NULL_TREE || block == d->orig_block) { - if (d->new_block == NULL_TREE) - locus = LOCATION_LOCUS (locus); - else - locus = COMBINE_LOCATION_DATA (line_table, locus, d->new_block); + locus = set_block (locus, d->new_block); gimple_phi_arg_set_location (phi, i, locus); } } @@ -6802,9 +6799,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb, tree block = LOCATION_BLOCK (e->goto_locus); if (d->orig_block == NULL_TREE || block == d->orig_block) - e->goto_locus = d->new_block ? - COMBINE_LOCATION_DATA (line_table, e->goto_locus, d->new_block) : - LOCATION_LOCUS (e->goto_locus); + e->goto_locus = set_block (e->goto_locus, d->new_block); } } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 9b525f3..58eca90 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2352,10 +2352,7 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id) tree *n; n = id->decl_map->get (LOCATION_BLOCK (locus)); gcc_assert (n); - if (*n) - locus = COMBINE_LOCATION_DATA (line_table, locus, *n); - else - locus = LOCATION_LOCUS (locus); + locus = set_block (locus, *n); } else locus = LOCATION_LOCUS (locus); diff --git a/gcc/tree.c b/gcc/tree.c index f78a2c2..426803c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -11669,10 +11669,7 @@ tree_set_block (tree t, tree b) if (IS_EXPR_CODE_CLASS (c)) { - if (b) - t->exp.locus = COMBINE_LOCATION_DATA (line_table, t->exp.locus, b); - else - t->exp.locus = LOCATION_LOCUS (t->exp.locus); + t->exp.locus = set_block (t->exp.locus, b); } else gcc_unreachable (); @@ -13656,5 +13653,11 @@ nonnull_arg_p (const_tree arg) return false; } +location_t +set_block (location_t loc, tree block) +{ + source_range src_range = get_range_from_loc (line_table, loc); + return COMBINE_LOCATION_DATA (line_table, loc, src_range, block); +} #include "gt-tree.h" diff --git a/gcc/tree.h b/gcc/tree.h index 4c803f4..92cc929 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5139,6 +5139,9 @@ type_with_alias_set_p (const_tree t) return false; } +extern location_t +set_block (location_t loc, tree block); + extern void gt_ggc_mx (tree &); extern void gt_pch_nx (tree &); extern void gt_pch_nx (tree &, gt_pointer_operator, void *); diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index a2bdfa0..f5c2a21 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -237,7 +237,8 @@ struct GTY(()) cpp_identifier { /* A preprocessing token. This has been carefully packed and should occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */ struct GTY(()) cpp_token { - source_location src_loc; /* Location of first char of token. */ + source_location src_loc; /* Location of first char of token, + together with range of full token. */ ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */ unsigned short flags; /* flags - see above */ diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 84a5ab7..de1c55c 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -512,9 +512,11 @@ struct GTY(()) maps_info_macro { unsigned int cache; }; -/* Data structure to associate an arbitrary data to a source location. */ +/* Data structure to associate a source_range together with an arbitrary + data pointer with a source location. */ struct GTY(()) location_adhoc_data { source_location locus; + source_range src_range; void * GTY((skip)) data; }; @@ -813,10 +815,14 @@ LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set) extern void location_adhoc_data_fini (struct line_maps *); extern source_location get_combined_adhoc_loc (struct line_maps *, - source_location, void *); + source_location, + source_range, + void *); extern void *get_data_from_adhoc_loc (struct line_maps *, source_location); extern source_location get_location_from_adhoc_loc (struct line_maps *, source_location); +extern source_range get_range_from_adhoc_loc (struct line_maps *, + source_location); /* Get whether location LOC is an ad-hoc location. */ @@ -826,14 +832,25 @@ IS_ADHOC_LOC (source_location loc) return (loc & MAX_SOURCE_LOCATION) != loc; } +inline source_range +get_range_from_loc (struct line_maps *set, + source_location loc) +{ + if (IS_ADHOC_LOC (loc)) + return get_range_from_adhoc_loc (set, loc); + else + return source_range::from_location (loc); +} + /* Combine LOC and BLOCK, giving a combined adhoc location. */ inline source_location COMBINE_LOCATION_DATA (struct line_maps *set, source_location loc, + source_range src_range, void *block) { - return get_combined_adhoc_loc (set, loc, block); + return get_combined_adhoc_loc (set, loc, src_range, block); } extern void rebuild_location_adhoc_htab (struct line_maps *); diff --git a/libcpp/lex.c b/libcpp/lex.c index 0aa1090..f4c964f 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -2723,6 +2723,16 @@ _cpp_lex_direct (cpp_reader *pfile) break; } + source_range tok_range; + tok_range.m_start = result->src_loc; + tok_range.m_finish = + linemap_position_for_column (pfile->line_table, + CPP_BUF_COLUMN (buffer, buffer->cur)); + + result->src_loc = COMBINE_LOCATION_DATA (pfile->line_table, + result->src_loc, + tok_range, NULL); + return result; } diff --git a/libcpp/line-map.c b/libcpp/line-map.c index 3c19f93..3810c88 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -69,7 +69,10 @@ location_adhoc_data_hash (const void *l) { const struct location_adhoc_data *lb = (const struct location_adhoc_data *) l; - return (hashval_t) lb->locus + (size_t) lb->data; + return ((hashval_t) lb->locus + + (hashval_t) lb->src_range.m_start + + (hashval_t) lb->src_range.m_finish + + (size_t) lb->data); } /* Compare function for location_adhoc_data hashtable. */ @@ -81,7 +84,10 @@ location_adhoc_data_eq (const void *l1, const void *l2) (const struct location_adhoc_data *) l1; const struct location_adhoc_data *lb2 = (const struct location_adhoc_data *) l2; - return lb1->locus == lb2->locus && lb1->data == lb2->data; + return (lb1->locus == lb2->locus + && lb1->src_range.m_start == lb2->src_range.m_start + && lb1->src_range.m_finish == lb2->src_range.m_finish + && lb1->data == lb2->data); } /* Update the hashtable when location_adhoc_data is reallocated. */ @@ -110,19 +116,20 @@ rebuild_location_adhoc_htab (struct line_maps *set) source_location get_combined_adhoc_loc (struct line_maps *set, - source_location locus, void *data) + source_location locus, + source_range src_range, + void *data) { struct location_adhoc_data lb; struct location_adhoc_data **slot; - linemap_assert (data); - if (IS_ADHOC_LOC (locus)) locus = set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus; if (locus == 0 && data == NULL) return 0; lb.locus = locus; + lb.src_range = src_range; lb.data = data; slot = (struct location_adhoc_data **) htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT); @@ -177,6 +184,13 @@ get_location_from_adhoc_loc (struct line_maps *set, source_location loc) return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus; } +source_range +get_range_from_adhoc_loc (struct line_maps *set, source_location loc) +{ + linemap_assert (IS_ADHOC_LOC (loc)); + return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].src_range; +} + /* Finalize the location_adhoc_data structure. */ void location_adhoc_data_fini (struct line_maps *set) @@ -1478,9 +1492,9 @@ linemap_expand_location (struct line_maps *set, memset (&xloc, 0, sizeof (xloc)); if (IS_ADHOC_LOC (loc)) { - loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus; xloc.data = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data; + loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus; } if (loc < RESERVED_LOCATION_COUNT)