@@ -94,50 +94,62 @@ struct LocationManager {
94
94
//
95
95
//
96
96
//
97
- std::vector<uint32_t > out_start; // consecutive intervals in the output code
98
- std::vector<uint32_t > in_start; // start + size in the original code
99
- std::vector<uint32_t > in_newlines; // position of all \n in the original code
97
+ struct FileLocations {
98
+ std::vector<uint32_t > out_start; // consecutive intervals in the output code
99
+ std::vector<uint32_t > in_start; // start + size in the original code
100
+ std::vector<uint32_t > in_newlines; // position of all \n in the original code
100
101
101
- // For preprocessor (if preprocessor==true).
102
- // TODO: design a common structure, that also works with #include, that
103
- // has these mappings for each file
104
- bool preprocessor = false ;
105
- std::string in_filename;
106
- uint32_t current_line=0 ;
107
- std::vector<uint32_t > out_start0; // consecutive intervals in the output code
108
- std::vector<uint32_t > in_start0; // start + size in the original code
109
- std::vector<uint32_t > in_size0; // Size of the `in` interval
110
- std::vector<uint32_t > interval_type0; // 0 .... 1:1; 1 ... many to many;
111
- std::vector<uint32_t > in_newlines0; // position of all \n in the original code
112
- // std::vector<uint32_t> filename_id; // file name for each interval, ID
113
- // std::vector<std::string> filenames; // filenames lookup for an ID
102
+ // For preprocessor (if preprocessor==true).
103
+ // TODO: design a common structure, that also works with #include, that
104
+ // has these mappings for each file
105
+ bool preprocessor = false ;
106
+ std::string in_filename;
107
+ uint32_t current_line=0 ;
108
+ std::vector<uint32_t > out_start0; // consecutive intervals in the output code
109
+ std::vector<uint32_t > in_start0; // start + size in the original code
110
+ std::vector<uint32_t > in_size0; // Size of the `in` interval
111
+ std::vector<uint32_t > interval_type0; // 0 .... 1:1; 1 ... many to many;
112
+ std::vector<uint32_t > in_newlines0; // position of all \n in the original code
113
+ };
114
+ std::vector<FileLocations> files;
115
+ std::vector<uint32_t > file_ends; // position of all ends of files
116
+ // For a given Location we use the `file_ends` and bisection to determine
117
+ // the file (index) which the location is from. Then we use this index into
118
+ // the `files` vector and use `in_newlines` and other information to
119
+ // determine the line and column inside this file, and the `in_filename`
120
+ // field to determine the filename. This happens when the diagnostic is
121
+ // printed. The `pos_to_linecol` function below should be modified to
122
+ // return line, column and the filename:
123
+ //
124
+ // void pos_to_linecol(uint32_t position, uint32_t &line, uint32_t &col,
125
+ // std::string &filename) const;
114
126
115
127
// Converts a position in the output code to a position in the original code
116
128
// Every character in the output code has a corresponding location in the
117
129
// original code, so this function always succeeds
118
130
uint32_t output_to_input_pos (uint32_t out_pos, bool show_last) const {
119
- if (out_start.size () == 0 ) return 0 ;
120
- uint32_t interval = bisection (out_start, out_pos)-1 ;
121
- uint32_t rel_pos = out_pos - out_start[interval];
122
- uint32_t in_pos = in_start[interval] + rel_pos;
123
- if (preprocessor) {
131
+ if (files. back (). out_start .size () == 0 ) return 0 ;
132
+ uint32_t interval = bisection (files. back (). out_start , out_pos)-1 ;
133
+ uint32_t rel_pos = out_pos - files. back (). out_start [interval];
134
+ uint32_t in_pos = files. back (). in_start [interval] + rel_pos;
135
+ if (files. back (). preprocessor ) {
124
136
// If preprocessor was used, do one more remapping
125
- uint32_t interval0 = bisection (out_start0, in_pos)-1 ;
126
- if (interval_type0[interval0] == 0 ) {
137
+ uint32_t interval0 = bisection (files. back (). out_start0 , in_pos)-1 ;
138
+ if (files. back (). interval_type0 [interval0] == 0 ) {
127
139
// 1:1 interval
128
- uint32_t rel_pos0 = in_pos - out_start0[interval0];
129
- uint32_t in_pos0 = in_start0[interval0] + rel_pos0;
140
+ uint32_t rel_pos0 = in_pos - files. back (). out_start0 [interval0];
141
+ uint32_t in_pos0 = files. back (). in_start0 [interval0] + rel_pos0;
130
142
return in_pos0;
131
143
} else {
132
144
// many to many interval
133
145
uint32_t in_pos0;
134
- if (in_pos == out_start0[interval0+1 ]-1 || show_last) {
146
+ if (in_pos == files. back (). out_start0 [interval0+1 ]-1 || show_last) {
135
147
// The end of the interval in "out" code
136
148
// Return the end of the interval in "in" code
137
- in_pos0 = in_start0[interval0]+in_size0[interval0]-1 ;
149
+ in_pos0 = files. back (). in_start0 [interval0]+files. back (). in_size0 [interval0]-1 ;
138
150
} else {
139
151
// Otherwise return the beginning of the interval in "in"
140
- in_pos0 = in_start0[interval0];
152
+ in_pos0 = files. back (). in_start0 [interval0];
141
153
}
142
154
return in_pos0;
143
155
}
@@ -152,10 +164,10 @@ struct LocationManager {
152
164
// `in_newlines` starts from 0
153
165
void pos_to_linecol (uint32_t position, uint32_t &line, uint32_t &col) const {
154
166
const std::vector<uint32_t > *newlines;
155
- if (preprocessor) {
156
- newlines = &in_newlines0;
167
+ if (files. back (). preprocessor ) {
168
+ newlines = &files. back (). in_newlines0 ;
157
169
} else {
158
- newlines = &in_newlines;
170
+ newlines = &files. back (). in_newlines ;
159
171
}
160
172
int32_t interval = bisection (*newlines, position);
161
173
if (interval >= 1 && position == (*newlines)[interval-1 ]) {
@@ -179,9 +191,9 @@ struct LocationManager {
179
191
180
192
void init_simple (const std::string &input) {
181
193
uint32_t n = input.size ();
182
- out_start = {0 , n};
183
- in_start = {0 , n};
184
- get_newlines (input, in_newlines);
194
+ files. back (). out_start = {0 , n};
195
+ files. back (). in_start = {0 , n};
196
+ get_newlines (input, files. back (). in_newlines );
185
197
}
186
198
187
199
};
0 commit comments