]>
Commit | Line | Data |
---|---|---|
83ffe9cd | 1 | // Copyright (C) 2020-2023 Free Software Foundation, Inc. |
fe6264fa PH |
2 | |
3 | // This file is part of GCC. | |
4 | ||
5 | // GCC is free software; you can redistribute it and/or modify it under | |
6 | // the terms of the GNU General Public License as published by the Free | |
7 | // Software Foundation; either version 3, or (at your option) any later | |
8 | // version. | |
9 | ||
10 | // GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
11 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 | // for more details. | |
14 | ||
15 | // You should have received a copy of the GNU General Public License | |
16 | // along with GCC; see the file COPYING3. If not see | |
17 | // <http://www.gnu.org/licenses/>. | |
18 | ||
19 | // rust-linemap.cc -- GCC implementation of Linemap. | |
20 | ||
21 | #include "rust-linemap.h" | |
22 | ||
23 | // This class implements the Linemap interface defined by the | |
24 | // frontend. | |
25 | ||
26 | class Gcc_linemap : public Linemap | |
27 | { | |
28 | public: | |
29 | Gcc_linemap () : Linemap (), in_file_ (false) {} | |
30 | ||
31 | void start_file (const char *file_name, unsigned int line_begin); | |
32 | ||
33 | void start_line (unsigned int line_number, unsigned int line_size); | |
34 | ||
35 | Location get_location (unsigned int column); | |
36 | ||
37 | void stop (); | |
38 | ||
39 | std::string to_string (Location); | |
40 | ||
41 | std::string location_file (Location); | |
42 | ||
43 | int location_line (Location); | |
44 | ||
45 | int location_column (Location); | |
46 | ||
47 | protected: | |
48 | Location get_predeclared_location (); | |
49 | ||
50 | Location get_unknown_location (); | |
51 | ||
52 | bool is_predeclared (Location); | |
53 | ||
54 | bool is_unknown (Location); | |
55 | ||
56 | private: | |
57 | // Whether we are currently reading a file. | |
58 | bool in_file_; | |
59 | }; | |
60 | ||
61 | Linemap *Linemap::instance_ = NULL; | |
62 | ||
63 | // Start getting locations from a new file. | |
64 | ||
65 | void | |
66 | Gcc_linemap::start_file (const char *file_name, unsigned line_begin) | |
67 | { | |
68 | if (this->in_file_) | |
69 | linemap_add (line_table, LC_LEAVE, 0, NULL, 0); | |
70 | linemap_add (line_table, LC_ENTER, 0, file_name, line_begin); | |
71 | this->in_file_ = true; | |
72 | } | |
73 | ||
74 | // Stringify a location | |
75 | ||
76 | std::string | |
77 | Gcc_linemap::to_string (Location location) | |
78 | { | |
79 | const line_map_ordinary *lmo; | |
80 | location_t resolved_location; | |
81 | ||
82 | // Screen out unknown and predeclared locations; produce output | |
83 | // only for simple file:line locations. | |
84 | resolved_location | |
85 | = linemap_resolve_location (line_table, location.gcc_location (), | |
86 | LRK_SPELLING_LOCATION, &lmo); | |
87 | if (lmo == NULL || resolved_location < RESERVED_LOCATION_COUNT) | |
88 | return ""; | |
89 | const char *path = LINEMAP_FILE (lmo); | |
90 | if (!path) | |
91 | return ""; | |
92 | ||
93 | // Strip the source file down to the base file, to reduce clutter. | |
94 | std::stringstream ss; | |
95 | ss << lbasename (path) << ":" << SOURCE_LINE (lmo, location.gcc_location ()) | |
96 | << ":" << SOURCE_COLUMN (lmo, location.gcc_location ()); | |
97 | return ss.str (); | |
98 | } | |
99 | ||
100 | // Return the file name for a given location. | |
101 | ||
102 | std::string | |
103 | Gcc_linemap::location_file (Location loc) | |
104 | { | |
105 | return LOCATION_FILE (loc.gcc_location ()); | |
106 | } | |
107 | ||
108 | // Return the line number for a given location. | |
109 | ||
110 | int | |
111 | Gcc_linemap::location_line (Location loc) | |
112 | { | |
113 | return LOCATION_LINE (loc.gcc_location ()); | |
114 | } | |
115 | ||
116 | // Return the column number for a given location. | |
117 | int | |
118 | Gcc_linemap::location_column (Location loc) | |
119 | { | |
120 | return LOCATION_COLUMN (loc.gcc_location ()); | |
121 | } | |
122 | ||
123 | // Stop getting locations. | |
124 | ||
125 | void | |
126 | Gcc_linemap::stop () | |
127 | { | |
128 | linemap_add (line_table, LC_LEAVE, 0, NULL, 0); | |
129 | this->in_file_ = false; | |
130 | } | |
131 | ||
132 | // Start a new line. | |
133 | ||
134 | void | |
135 | Gcc_linemap::start_line (unsigned lineno, unsigned linesize) | |
136 | { | |
137 | linemap_line_start (line_table, lineno, linesize); | |
138 | } | |
139 | ||
140 | // Get a location. | |
141 | ||
142 | Location | |
143 | Gcc_linemap::get_location (unsigned column) | |
144 | { | |
145 | return Location (linemap_position_for_column (line_table, column)); | |
146 | } | |
147 | ||
148 | // Get the unknown location. | |
149 | ||
150 | Location | |
151 | Gcc_linemap::get_unknown_location () | |
152 | { | |
153 | return Location (UNKNOWN_LOCATION); | |
154 | } | |
155 | ||
156 | // Get the predeclared location. | |
157 | ||
158 | Location | |
159 | Gcc_linemap::get_predeclared_location () | |
160 | { | |
161 | return Location (BUILTINS_LOCATION); | |
162 | } | |
163 | ||
164 | // Return whether a location is the predeclared location. | |
165 | ||
166 | bool | |
167 | Gcc_linemap::is_predeclared (Location loc) | |
168 | { | |
169 | return loc.gcc_location () == BUILTINS_LOCATION; | |
170 | } | |
171 | ||
172 | // Return whether a location is the unknown location. | |
173 | ||
174 | bool | |
175 | Gcc_linemap::is_unknown (Location loc) | |
176 | { | |
177 | return loc.gcc_location () == UNKNOWN_LOCATION; | |
178 | } | |
179 | ||
180 | // Return the Linemap to use for the gcc backend. | |
181 | ||
182 | Linemap * | |
183 | rust_get_linemap () | |
184 | { | |
185 | return new Gcc_linemap; | |
186 | } | |
187 | ||
188 | RichLocation::RichLocation (Location root) | |
189 | : gcc_rich_loc (line_table, root.gcc_location ()) | |
190 | { | |
191 | /*rich_location (line_maps *set, location_t loc, | |
192 | const range_label *label = NULL);*/ | |
193 | } | |
194 | ||
195 | RichLocation::~RichLocation () {} | |
196 | ||
197 | void | |
198 | RichLocation::add_range (Location loc) | |
199 | { | |
200 | gcc_rich_loc.add_range (loc.gcc_location ()); | |
201 | } | |
202 | ||
203 | void | |
204 | RichLocation::add_fixit_insert_before (const std::string &new_parent) | |
205 | { | |
206 | gcc_rich_loc.add_fixit_insert_before (new_parent.c_str ()); | |
207 | } | |
208 | ||
209 | void | |
210 | RichLocation::add_fixit_insert_before (Location where, | |
211 | const std::string &new_parent) | |
212 | { | |
213 | gcc_rich_loc.add_fixit_insert_before (where.gcc_location (), | |
214 | new_parent.c_str ()); | |
215 | } | |
216 | ||
217 | void | |
218 | RichLocation::add_fixit_insert_after (const std::string &new_parent) | |
219 | { | |
220 | gcc_rich_loc.add_fixit_insert_after (new_parent.c_str ()); | |
221 | } | |
222 | ||
223 | void | |
224 | RichLocation::add_fixit_insert_after (Location where, | |
225 | const std::string &new_parent) | |
226 | { | |
227 | gcc_rich_loc.add_fixit_insert_after (where.gcc_location (), | |
228 | new_parent.c_str ()); | |
229 | } |