111
|
1 // go-linemap.cc -- GCC implementation of Linemap.
|
|
2
|
|
3 // Copyright 2011 The Go Authors. All rights reserved.
|
|
4 // Use of this source code is governed by a BSD-style
|
|
5 // license that can be found in the LICENSE file.
|
|
6
|
|
7 #include "go-linemap.h"
|
|
8
|
|
9 #include "go-gcc.h"
|
|
10
|
|
11 // This class implements the Linemap interface defined by the
|
|
12 // frontend.
|
|
13
|
|
14 class Gcc_linemap : public Linemap
|
|
15 {
|
|
16 public:
|
|
17 Gcc_linemap()
|
|
18 : Linemap(),
|
|
19 in_file_(false)
|
|
20 { }
|
|
21
|
|
22 void
|
|
23 start_file(const char* file_name, unsigned int line_begin);
|
|
24
|
|
25 void
|
|
26 start_line(unsigned int line_number, unsigned int line_size);
|
|
27
|
|
28 Location
|
|
29 get_location(unsigned int column);
|
|
30
|
|
31 void
|
|
32 stop();
|
|
33
|
|
34 std::string
|
|
35 to_string(Location);
|
|
36
|
|
37 int
|
|
38 location_line(Location);
|
|
39
|
|
40 protected:
|
|
41 Location
|
|
42 get_predeclared_location();
|
|
43
|
|
44 Location
|
|
45 get_unknown_location();
|
|
46
|
|
47 bool
|
|
48 is_predeclared(Location);
|
|
49
|
|
50 bool
|
|
51 is_unknown(Location);
|
|
52
|
|
53 private:
|
|
54 // Whether we are currently reading a file.
|
|
55 bool in_file_;
|
|
56 };
|
|
57
|
|
58 Linemap* Linemap::instance_ = NULL;
|
|
59
|
|
60 // Start getting locations from a new file.
|
|
61
|
|
62 void
|
|
63 Gcc_linemap::start_file(const char *file_name, unsigned line_begin)
|
|
64 {
|
|
65 if (this->in_file_)
|
|
66 linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
|
|
67 linemap_add(line_table, LC_ENTER, 0, file_name, line_begin);
|
|
68 this->in_file_ = true;
|
|
69 }
|
|
70
|
|
71 // Stringify a location
|
|
72
|
|
73 std::string
|
|
74 Gcc_linemap::to_string(Location location)
|
|
75 {
|
|
76 const line_map_ordinary *lmo;
|
|
77 source_location resolved_location;
|
|
78
|
|
79 // Screen out unknown and predeclared locations; produce output
|
|
80 // only for simple file:line locations.
|
|
81 resolved_location =
|
|
82 linemap_resolve_location (line_table, location.gcc_location(),
|
|
83 LRK_SPELLING_LOCATION, &lmo);
|
|
84 if (lmo == NULL || resolved_location < RESERVED_LOCATION_COUNT)
|
|
85 return "";
|
|
86 const char *path = LINEMAP_FILE (lmo);
|
|
87 if (!path)
|
|
88 return "";
|
|
89
|
|
90 // Strip the source file down to the base file, to reduce clutter.
|
|
91 std::stringstream ss;
|
|
92 ss << lbasename(path) << ":" << SOURCE_LINE (lmo, location.gcc_location());
|
|
93 return ss.str();
|
|
94 }
|
|
95
|
|
96 // Return the line number for a given location (for debugging dumps)
|
|
97 int
|
|
98 Gcc_linemap::location_line(Location loc)
|
|
99 {
|
|
100 return LOCATION_LINE(loc.gcc_location());
|
|
101 }
|
|
102
|
|
103 // Stop getting locations.
|
|
104
|
|
105 void
|
|
106 Gcc_linemap::stop()
|
|
107 {
|
|
108 linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
|
|
109 this->in_file_ = false;
|
|
110 }
|
|
111
|
|
112 // Start a new line.
|
|
113
|
|
114 void
|
|
115 Gcc_linemap::start_line(unsigned lineno, unsigned linesize)
|
|
116 {
|
|
117 linemap_line_start(line_table, lineno, linesize);
|
|
118 }
|
|
119
|
|
120 // Get a location.
|
|
121
|
|
122 Location
|
|
123 Gcc_linemap::get_location(unsigned column)
|
|
124 {
|
|
125 return Location(linemap_position_for_column(line_table, column));
|
|
126 }
|
|
127
|
|
128 // Get the unknown location.
|
|
129
|
|
130 Location
|
|
131 Gcc_linemap::get_unknown_location()
|
|
132 {
|
|
133 return Location(UNKNOWN_LOCATION);
|
|
134 }
|
|
135
|
|
136 // Get the predeclared location.
|
|
137
|
|
138 Location
|
|
139 Gcc_linemap::get_predeclared_location()
|
|
140 {
|
|
141 return Location(BUILTINS_LOCATION);
|
|
142 }
|
|
143
|
|
144 // Return whether a location is the predeclared location.
|
|
145
|
|
146 bool
|
|
147 Gcc_linemap::is_predeclared(Location loc)
|
|
148 {
|
|
149 return loc.gcc_location() == BUILTINS_LOCATION;
|
|
150 }
|
|
151
|
|
152 // Return whether a location is the unknown location.
|
|
153
|
|
154 bool
|
|
155 Gcc_linemap::is_unknown(Location loc)
|
|
156 {
|
|
157 return loc.gcc_location() == UNKNOWN_LOCATION;
|
|
158 }
|
|
159
|
|
160 // Return the Linemap to use for the gcc backend.
|
|
161
|
|
162 Linemap*
|
|
163 go_get_linemap()
|
|
164 {
|
|
165 return new Gcc_linemap;
|
|
166 }
|