This is a followup to the ideas posted at: https://gcc.gnu.org/ml/gcc-patches/2015-03/msg00837.html
I've been experimenting with capturing and printing richer information for our diagnostics, underlining pertinent source ranges when printing them, and potentially providing "fix-it" hints. Attached is a work-in-progress patch kit implementing these ideas. I posting it now to get feedback: some parts of it may be ready to commit, but other parts are definitely *not* ready yet. Some screenshots: https://dmalcolm.fedorapeople.org/gcc/2015-09-04/ranges-in-format-string-diagnostics.html https://dmalcolm.fedorapeople.org/gcc/2015-09-10/spellcheck-with-fixits.html (other screenshots can be seen in the individual patches). Overview of the patches: Patches 1-3: 01: Change of location_get_source_line signature 02: Testsuite: add dg-{begin|end}-multiline-output commands 03: Move diagnostic_show_locus and friends out into a new source file These patches are a preamble, setting things up for what's to come. Patches 4-5: 04: Reimplement diagnostic_show_locus, introducing rich_location classes 05: Add overloads of inform, warning_at, etc that take a source_range These patches introduce a "rich_location" class capable of storing multiple ranges, and use it internally throughout the diagnostic implementation, together with the code for printing such information. These patches and the ones leading up to it survive bootstrap and regression testing; after this point things start to get more "experimental". Patch 6: 06: PR/62314: add ability to add fixit-hints This adds some machinery to allow diagnostics to supply "fix-it" hints to the user. Patches 7-11: 07: Implement token range tracking within libcpp and C/C++ FEs 08: C frontend: use token ranges in various diagnostics 09: C frontend: store and use token ranges in c_declspecs 10: C++ FE: Use token ranges for various diagnostics 11: Objective C: c/c-parser.c: use token ranges in two places These patches capture source range information for *tokens* in libcpp, C and C++, and start using them in place of mere locations for various diagnostics, so that we get underlines. Patches 12-16: 12: Add source-ranges for trees 13: gcc-rich-location.[ch]: add methods for working with tree ranges 14: C: capture tree ranges for various expressions 15: Add plugin to recursively dump the source-ranges in a tree These patches capture source range information for *tree expressions*. The representation I'm using has both enlargements to core tree structures *and* will require lots of extra tree nodes, so it's clearly going to be unacceptable as-is; my aim here is to use this as a starting point for trying to optimize the implementation (e.g. to gather stats on real-world code). Patches 16: 16: C/C++ frontend: use tree ranges in various diagnostics This patches uses the tree expression source range information gathered above in various diagnostics, so that we get more underlines. This is probably just scratching the surface in terms of the diagnostics we could improve. Patches 17-20: 17: libcpp: add location tracking within string literals 18: Track locations within string literals in tree_string 19: gcc-rich-location.[ch]: add debug methods for cpp_string_location 20: Use rich locations in c-family/c-format.c These patches extend string-literal parsing to capture per-character source range information within string literals, then use it within c-format.c to robustly print string ranges for printf-style format string errors (even in the face of e.g. concatenation). This hasn't been optimized yet; I don't yet know the impact on compile-time and memory (but I have ideas for optimizing it if it's an issue). Patches 21-22: 21: Use Levenshtein distance for various misspellings in C frontend 22: Add fixit hints to spellchecker suggestions These patches use Levenshtein distance to provide hints in various places when the user misspells something, and starts adding the ability to add "fix-it" hints to diagnostics. Some of this could be split out and applied independently of the rich_location work. Thoughts? (the patches are on top of r227562) boehm-gc/testsuite/lib/boehm-gc.exp | 1 + gcc/Makefile.in | 5 +- gcc/box-drawing.c | 99 ++ gcc/box-drawing.h | 43 + gcc/c-family/c-common.c | 37 +- gcc/c-family/c-common.h | 8 +- gcc/c-family/c-format.c | 117 +- gcc/c-family/c-indentation.c | 10 +- gcc/c-family/c-lex.c | 32 +- gcc/c-family/c-pragma.h | 4 +- gcc/c-family/c-pretty-print.c | 4 + gcc/c/c-convert.c | 17 +- gcc/c/c-decl.c | 58 +- gcc/c/c-errors.c | 95 +- gcc/c/c-objc-common.c | 2 +- gcc/c/c-parser.c | 172 ++- gcc/c/c-tree.h | 26 +- gcc/c/c-typeck.c | 273 +++-- gcc/cp/error.c | 5 +- gcc/cp/parser.c | 54 +- gcc/cp/parser.h | 2 + gcc/cp/typeck.c | 3 +- gcc/diagnostic-color.c | 5 +- gcc/diagnostic-core.h | 15 + gcc/diagnostic-show-locus.c | 1116 ++++++++++++++++++++ gcc/diagnostic.c | 412 +++++--- gcc/diagnostic.h | 48 +- gcc/fortran/cpp.c | 13 +- gcc/fortran/error.c | 43 +- gcc/gcc-rich-location.c | 235 +++++ gcc/gcc-rich-location.h | 84 ++ gcc/genmatch.c | 27 +- gcc/gimplify.c | 4 + gcc/input.c | 21 +- gcc/input.h | 2 +- gcc/intl.c | 9 + gcc/objc/objc-act.c | 3 +- gcc/pretty-print.c | 21 + gcc/pretty-print.h | 25 +- gcc/print-tree.c | 21 + gcc/rtl-error.c | 3 +- gcc/spellcheck.c | 126 +++ gcc/spellcheck.h | 32 + gcc/testsuite/g++.dg/diagnostic/token-ranges.C | 104 ++ gcc/testsuite/gcc.dg/diagnostic-token-ranges.c | 135 +++ gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges.c | 159 +++ gcc/testsuite/gcc.dg/format/diagnostic-ranges.c | 101 ++ .../gcc.dg/plugin/diagnostic-test-expressions-1.c | 562 ++++++++++ .../plugin/diagnostic-test-show-locus-ascii-bw.c | 157 +++ .../diagnostic-test-show-locus-ascii-color.c | 78 ++ .../plugin/diagnostic-test-show-locus-utf-8-bw.c | 101 ++ .../diagnostic-test-show-locus-utf-8-color.c | 105 ++ .../gcc.dg/plugin/diagnostic-test-show-trees-1.c | 106 ++ .../plugin/diagnostic-test-string-literals-1.c | 139 +++ .../gcc.dg/plugin/diagnostic_plugin_show_trees.c | 179 ++++ .../plugin/diagnostic_plugin_test_show_locus.c | 396 +++++++ .../diagnostic_plugin_test_string_literals.c | 215 ++++ .../diagnostic_plugin_test_tree_expression_range.c | 162 +++ gcc/testsuite/gcc.dg/plugin/plugin.exp | 11 + gcc/testsuite/gcc.dg/spellcheck.c | 40 + gcc/testsuite/lib/gcc-dg.exp | 1 + gcc/testsuite/lib/multiline.exp | 241 +++++ gcc/testsuite/lib/prune.exp | 5 + gcc/tree-core.h | 5 + gcc/tree-diagnostic.c | 2 +- gcc/tree-pretty-print.c | 2 +- gcc/tree.c | 66 +- gcc/tree.def | 2 + gcc/tree.h | 33 + libatomic/testsuite/lib/libatomic.exp | 1 + libcpp/charset.c | 357 ++++++- libcpp/directives.c | 4 +- libcpp/errors.c | 7 +- libcpp/expr.c | 2 + libcpp/include/cpplib.h | 144 ++- libcpp/include/line-map.h | 329 ++++++ libcpp/internal.h | 7 +- libcpp/lex.c | 20 +- libcpp/line-map.c | 334 ++++++ libcpp/macro.c | 1 + libgo/testsuite/lib/libgo.exp | 1 + libgomp/testsuite/lib/libgomp.exp | 1 + libitm/testsuite/lib/libitm.exp | 1 + libvtv/testsuite/lib/libvtv.exp | 1 + 84 files changed, 7124 insertions(+), 525 deletions(-) create mode 100644 gcc/box-drawing.c create mode 100644 gcc/box-drawing.h create mode 100644 gcc/diagnostic-show-locus.c create mode 100644 gcc/gcc-rich-location.c create mode 100644 gcc/gcc-rich-location.h create mode 100644 gcc/spellcheck.c create mode 100644 gcc/spellcheck.h create mode 100644 gcc/testsuite/g++.dg/diagnostic/token-ranges.C create mode 100644 gcc/testsuite/gcc.dg/diagnostic-token-ranges.c create mode 100644 gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges.c create mode 100644 gcc/testsuite/gcc.dg/format/diagnostic-ranges.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-ascii-bw.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-ascii-color.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-utf-8-bw.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-utf-8-color.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c create mode 100644 gcc/testsuite/gcc.dg/spellcheck.c create mode 100644 gcc/testsuite/lib/multiline.exp -- 1.8.5.3