gcc-rich-location.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /* Declarations relating to class gcc_rich_location
  2. Copyright (C) 2014-2019 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #ifndef GCC_RICH_LOCATION_H
  16. #define GCC_RICH_LOCATION_H
  17. /* A gcc_rich_location is libcpp's rich_location with additional
  18. helper methods for working with gcc's types. */
  19. class gcc_rich_location : public rich_location
  20. {
  21. public:
  22. /* Constructors. */
  23. /* Constructing from a location. */
  24. gcc_rich_location (location_t loc, const range_label *label = NULL)
  25. : rich_location (line_table, loc, label)
  26. {
  27. }
  28. /* Methods for adding ranges via gcc entities. */
  29. void
  30. add_expr (tree expr, range_label *label);
  31. void
  32. maybe_add_expr (tree t, range_label *label);
  33. void add_fixit_misspelled_id (location_t misspelled_token_loc,
  34. tree hint_id);
  35. /* If LOC is within the spans of lines that will already be printed for
  36. this gcc_rich_location, then add it as a secondary location
  37. and return true.
  38. Otherwise return false.
  39. This allows for a diagnostic to compactly print secondary locations
  40. in one diagnostic when these are near enough the primary locations for
  41. diagnostics-show-locus.c to cope with them, and to fall back to
  42. printing them via a note otherwise e.g.:
  43. gcc_rich_location richloc (primary_loc);
  44. bool added secondary = richloc.add_location_if_nearby (secondary_loc);
  45. error_at (&richloc, "main message");
  46. if (!added secondary)
  47. inform (secondary_loc, "message for secondary");
  48. Implemented in diagnostic-show-locus.c. */
  49. bool add_location_if_nearby (location_t loc);
  50. /* Add a fix-it hint suggesting the insertion of CONTENT before
  51. INSERTION_POINT.
  52. Attempt to handle formatting: if INSERTION_POINT is the first thing on
  53. its line, and INDENT is sufficiently sane, then add CONTENT on its own
  54. line, using the indentation of INDENT.
  55. Otherwise, add CONTENT directly before INSERTION_POINT.
  56. For example, adding "CONTENT;" with the closing brace as the insertion
  57. point and using "INDENT;" for indentation:
  58. if ()
  59. {
  60. INDENT;
  61. }
  62. would lead to:
  63. if ()
  64. {
  65. INDENT;
  66. CONTENT;
  67. }
  68. but adding it to:
  69. if () {INDENT;}
  70. would lead to:
  71. if () {INDENT;CONTENT;}
  72. */
  73. void add_fixit_insert_formatted (const char *content,
  74. location_t insertion_point,
  75. location_t indent);
  76. };
  77. /* Concrete subclass of libcpp's range_label.
  78. Simple implementation using a string literal. */
  79. class text_range_label : public range_label
  80. {
  81. public:
  82. text_range_label (const char *text) : m_text (text) {}
  83. label_text get_text (unsigned /*range_idx*/) const FINAL OVERRIDE
  84. {
  85. return label_text (const_cast <char *> (m_text), false);
  86. }
  87. private:
  88. const char *m_text;
  89. };
  90. /* Concrete subclass of libcpp's range_label for use in
  91. diagnostics involving mismatched types.
  92. Each frontend that uses this should supply its own implementation.
  93. Generate a label describing LABELLED_TYPE. The frontend may use
  94. OTHER_TYPE where appropriate for highlighting the differences between
  95. the two types (analogous to C++'s use of %H and %I with
  96. template types).
  97. Either or both of LABELLED_TYPE and OTHER_TYPE may be NULL_TREE.
  98. If LABELLED_TYPE is NULL_TREE, then there is no label.
  99. For example, this rich_location could use two instances of
  100. range_label_for_type_mismatch:
  101. printf ("arg0: %i arg1: %s arg2: %i",
  102. ^~
  103. |
  104. const char *
  105. 100, 101, 102);
  106. ~~~
  107. |
  108. int
  109. (a) the label for "%s" with LABELLED_TYPE for "const char*" and
  110. (b) the label for "101" with LABELLED TYPE for "int"
  111. where each one uses the other's type as OTHER_TYPE. */
  112. class range_label_for_type_mismatch : public range_label
  113. {
  114. public:
  115. range_label_for_type_mismatch (tree labelled_type, tree other_type)
  116. : m_labelled_type (labelled_type), m_other_type (other_type)
  117. {
  118. }
  119. label_text get_text (unsigned range_idx) const OVERRIDE;
  120. protected:
  121. tree m_labelled_type;
  122. tree m_other_type;
  123. };
  124. /* Subclass of range_label for labelling the type of EXPR when reporting
  125. a type mismatch between EXPR and OTHER_EXPR.
  126. Either or both of EXPR and OTHER_EXPR could be NULL. */
  127. class maybe_range_label_for_tree_type_mismatch : public range_label
  128. {
  129. public:
  130. maybe_range_label_for_tree_type_mismatch (tree expr, tree other_expr)
  131. : m_expr (expr), m_other_expr (other_expr)
  132. {
  133. }
  134. label_text get_text (unsigned range_idx) const FINAL OVERRIDE;
  135. private:
  136. tree m_expr;
  137. tree m_other_expr;
  138. };
  139. struct op_location_t;
  140. /* A subclass of rich_location for showing problems with binary operations.
  141. If enough location information is available, the ctor will make a
  142. 3-location rich_location of the form:
  143. arg_0 op arg_1
  144. ~~~~~ ^~ ~~~~~
  145. | |
  146. | arg1 type
  147. arg0 type
  148. labelling the types of the arguments if SHOW_TYPES is true.
  149. Otherwise, it will fall back to a 1-location rich_location using the
  150. compound location within LOC:
  151. arg_0 op arg_1
  152. ~~~~~~^~~~~~~~
  153. for which we can't label the types. */
  154. class binary_op_rich_location : public gcc_rich_location
  155. {
  156. public:
  157. binary_op_rich_location (const op_location_t &loc,
  158. tree arg0, tree arg1,
  159. bool show_types);
  160. private:
  161. static bool use_operator_loc_p (const op_location_t &loc,
  162. tree arg0, tree arg1);
  163. maybe_range_label_for_tree_type_mismatch m_label_for_arg0;
  164. maybe_range_label_for_tree_type_mismatch m_label_for_arg1;
  165. };
  166. #endif /* GCC_RICH_LOCATION_H */