From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from rock.gnat.com (rock.gnat.com [205.232.38.15]) by sourceware.org (Postfix) with ESMTP id 456193A77C08 for ; Wed, 28 Apr 2021 09:41:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 456193A77C08 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=derodat@adacore.com Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 0511A5614F; Wed, 28 Apr 2021 05:41:40 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id d6ZVuKpQkAvv; Wed, 28 Apr 2021 05:41:39 -0400 (EDT) Received: from tron.gnat.com (tron.gnat.com [205.232.38.10]) by rock.gnat.com (Postfix) with ESMTP id C964056149; Wed, 28 Apr 2021 05:41:39 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4862) id C899C12D; Wed, 28 Apr 2021 05:41:39 -0400 (EDT) Date: Wed, 28 Apr 2021 05:41:39 -0400 From: Pierre-Marie de Rodat To: gcc-patches@gcc.gnu.org Cc: Yannick Moy Subject: [Ada] Use spans instead of locations for compiler diagnostics Message-ID: <20210428094139.GA139913@adacore.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="ZGiS0Q5IWpPtfppv" Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Spam-Status: No, score=-6.3 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, 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: Wed, 28 Apr 2021 09:41:45 -0000 --ZGiS0Q5IWpPtfppv Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Change the internal data structure that stores the compiler diagnostics to store spans instead of locations, where a span is a triplet of a main location, and a first-last pair of locations. Also change the main procedures for reporting an error in Errout to use spans instead of locations whenever possible. As nodes in the AST are associated to a location and not a span, the span is currently reconstructed when reporting an error on a node, by retrieving the span covered by the node subtree. Locations are still used whenever a span cannot be used because the diagnostic is associated with a location (coming from a token during parsing in many cases) rather than a node. There are minimal changes to the compiler output for now, only as a result of changes to First_Node that now applies to some declarations and statements and not only expressions. This has a result to change the location of some diagnostics. The effect of spans is visible when compiling with debug flag -gnatdF to display spans inline with the diagnstics in command-line usage, as used in GNATprove. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * errout.adb: (Error_Msg_Internal): Use span instead of location. (Error_Msg, Error_Msg_NEL): Add versions with span parameter. (Error_Msg_F, Error_Msg_FE, Error_Msg_N, Error_Msg_NE, Error_Msg_NW): Retrieve span from node. (First_Node): Use the new First_And_Last_Nodes. (First_And_Last_Nodes): Expand on previous First_Node. Apply to other nodes than expressions. (First_Sloc): Protect against inconsistent locations. (Last_Node): New function based on First_And_Last_Nodes. (Last_Sloc): New function similar to First_Sloc. (Output_Messages): Update output when -gnatdF is used. Use character ~ for making the span visible, similar to what is done in GCC and Clang. * errout.ads (Error_Msg, Error_Msg_NEL): Add versions with span parameter. (First_And_Last_Nodes, Last_Node, Last_Sloc): New subprograms. * erroutc.adb: Adapt to Sptr field being a span. * erroutc.ads (Error_Msg_Object): Change field Sptr from location to span. * errutil.adb: Adapt to Sptr field being a span. * freeze.adb: Use Errout reporting procedures for nodes to get spans. * par-ch3.adb: Likewise. * par-prag.adb: Likewise. * par-util.adb: Likewise. * sem_case.adb: Likewise. * sem_ch13.adb: Likewise. * sem_ch3.adb: Likewise. * sem_prag.adb: Likewise. * types.ads: (Source_Span): New type for spans. (To_Span): Basic constructors for spans. --ZGiS0Q5IWpPtfppv Content-Type: application/gzip Content-Disposition: attachment; filename="patch.diff.gz" Content-Transfer-Encoding: base64 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 I2YWTOgKXwvcixf/H5d6TkDtxQAA --ZGiS0Q5IWpPtfppv--