P4C
The P4 Compiler
 
Loading...
Searching...
No Matches
source_file.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17/* -*-c++-*- */
18
19/* Source-level information for a P4 program */
20
21#ifndef LIB_SOURCE_FILE_H_
22#define LIB_SOURCE_FILE_H_
23
24#include <map>
25#include <vector>
26
27#include "cstring.h"
28
29// GTest
30#ifdef P4C_GTEST_ENABLED
31#include "gtest/gtest_prod.h"
32#endif
33
34namespace Test {
35class UtilSourceFile;
36}
37
39 public:
40 virtual void dbprint(std::ostream &out) const = 0;
41 void print() const; // useful in the debugger
42 virtual ~IHasDbPrint() = default;
43};
44
45namespace Util {
46struct SourceFileLine;
56class SourcePosition final {
57 public:
59 SourcePosition() = default;
60
61 SourcePosition(unsigned lineNumber, unsigned columnNumber);
62
63 SourcePosition(const SourcePosition &other) = default;
64 SourcePosition &operator=(const SourcePosition &) = default;
65
66 inline bool operator==(const SourcePosition &rhs) const {
67 return columnNumber == rhs.columnNumber && lineNumber == rhs.lineNumber;
68 }
69 inline bool operator!=(const SourcePosition &rhs) const { return !this->operator==(rhs); }
70
71 inline bool operator<(const SourcePosition &rhs) const {
72 return (lineNumber < rhs.lineNumber) ||
73 (lineNumber == rhs.lineNumber && columnNumber < rhs.columnNumber);
74 }
75 inline bool operator>(const SourcePosition &rhs) const { return rhs.operator<(*this); }
76 inline bool operator<=(const SourcePosition &rhs) const { return !this->operator>(rhs); }
77 inline bool operator>=(const SourcePosition &rhs) const { return !this->operator<(rhs); }
78
81 if (columnNumber > 0) columnNumber--;
82 return *this;
83 }
85 SourcePosition tmp(*this);
86 this->operator--();
87 return tmp;
88 }
89
90 inline const SourcePosition &min(const SourcePosition &rhs) const {
91 if (this->operator<(rhs)) return *this;
92 return rhs;
93 }
94
95 inline const SourcePosition &max(const SourcePosition &rhs) const {
96 if (this->operator>(rhs)) return *this;
97 return rhs;
98 }
99
100 cstring toString() const;
101
102 bool isValid() const { return lineNumber != 0; }
103
104 unsigned getLineNumber() const { return lineNumber; }
105
106 unsigned getColumnNumber() const { return columnNumber; }
107
108 private:
109 // Input sources where this character position is interpreted.
110 unsigned lineNumber = 0;
111 unsigned columnNumber = 0;
112};
113
114class InputSources;
115
126class SourceInfo final {
127 public:
128 cstring filename = "";
129 int line = -1;
130 int column = -1;
131 cstring srcBrief = "";
132 SourceInfo(cstring filename, int line, int column, cstring srcBrief) {
133 this->filename = filename;
134 this->line = line;
135 this->column = column;
136 this->srcBrief = srcBrief;
137 }
139 SourceInfo() = default;
140
143 : sources(sources), start(point), end(point) {}
144
145 SourceInfo(const InputSources *sources, SourcePosition start, SourcePosition end);
146
147 SourceInfo(const SourceInfo &other) = default;
148 SourceInfo &operator=(const SourceInfo &other) = default;
149 ~SourceInfo() = default;
150
154 SourceInfo operator+(const SourceInfo &rhs) const {
155 if (!this->isValid()) return rhs;
156 if (!rhs.isValid()) return *this;
157 SourcePosition s = start.min(rhs.start);
158 SourcePosition e = end.max(rhs.end);
159 return SourceInfo(sources, s, e);
160 }
161 SourceInfo &operator+=(const SourceInfo &rhs) {
162 if (!isValid()) {
163 *this = rhs;
164 } else if (rhs.isValid()) {
165 start = start.min(rhs.start);
166 end = end.max(rhs.end);
167 }
168 return *this;
169 }
170
171 bool operator==(const SourceInfo &rhs) const { return start == rhs.start && end == rhs.end; }
172
173 cstring toDebugString() const;
174
175 void dbprint(std::ostream &out) const { out << this->toDebugString(); }
176
177 cstring toSourceFragment(bool useMarker = true) const;
178 cstring toBriefSourceFragment() const;
179 cstring toPositionString() const;
180 cstring toSourcePositionData(unsigned *outLineNumber, unsigned *outColumnNumber) const;
181 SourceFileLine toPosition() const;
182
183 bool isValid() const { return this->start.isValid(); }
184 explicit operator bool() const { return isValid(); }
185
186 cstring getSourceFile() const;
187 cstring getLineNum() const;
188
189 const SourcePosition &getStart() const { return this->start; }
190
191 const SourcePosition &getEnd() const { return this->end; }
192
198 bool operator<(const SourceInfo &rhs) const {
199 if (!rhs.isValid()) return false;
200 if (!isValid()) return true;
201 return this->start < rhs.start;
202 }
203 inline bool operator>(const SourceInfo &rhs) const { return rhs.operator<(*this); }
204 inline bool operator<=(const SourceInfo &rhs) const { return !this->operator>(rhs); }
205 inline bool operator>=(const SourceInfo &rhs) const { return !this->operator<(rhs); }
206
207 private:
208 const InputSources *sources = nullptr;
209 SourcePosition start = SourcePosition();
210 SourcePosition end = SourcePosition();
211};
212
214 public:
215 virtual SourceInfo getSourceInfo() const = 0;
216 virtual cstring toString() const = 0;
217 virtual ~IHasSourceInfo() {}
218};
219
224 unsigned sourceLine;
225
226 SourceFileLine(cstring file, unsigned line) : fileName(file), sourceLine(line) {}
227
228 cstring toString() const;
229};
230
231class Comment final : IHasDbPrint {
232 private:
233 SourceInfo srcInfo;
234 bool singleLine;
235 cstring body;
236
237 public:
238 Comment(SourceInfo srcInfo, bool singleLine, cstring body)
239 : srcInfo(srcInfo), singleLine(singleLine), body(body) {}
240 cstring toString() const {
241 std::string result;
242 if (singleLine)
243 result = "//";
244 else
245 result = "/*";
246 result += body;
247 if (!singleLine) result += "*/";
248 return result;
249 }
250 void dbprint(std::ostream &out) const { out << toString(); }
251};
252
263class InputSources final {
264#ifdef P4C_GTEST_ENABLED
265 FRIEND_TEST(UtilSourceFile, InputSources);
266#endif
267
268 public:
269 InputSources();
270
271 cstring getLine(unsigned lineNumber) const;
273 SourceFileLine getSourceLine(unsigned line) const;
274
275 unsigned lineCount() const;
276 SourcePosition getCurrentPosition() const;
277 unsigned getCurrentLineNumber() const;
278
280 void seal();
281
283 void appendText(const char *text);
284
288 void mapLine(cstring file, unsigned originalSourceLineNo);
289
295 cstring getSourceFragment(const SourcePosition &position, bool useMarker) const;
296 cstring getSourceFragment(const SourceInfo &position, bool useMarker) const;
297 cstring getBriefSourceFragment(const SourceInfo &position) const;
298
299 cstring toDebugString() const;
300 void addComment(SourceInfo srcInfo, bool singleLine, cstring body);
301
302 private:
304 void appendToLastLine(std::string_view text);
306 void appendNewline(std::string_view newline);
307
309 bool sealed;
310
311 std::map<unsigned, SourceFileLine> line_file_map;
312
314 std::vector<std::string> contents;
316 std::vector<Comment *> comments;
317};
318
319} // namespace Util
320
321void dbprint(const IHasDbPrint *o);
322
323#endif /* LIB_SOURCE_FILE_H_ */
Definition source_file.h:38
Definition source_file.h:231
Definition source_file.h:213
Definition source_file.h:263
void seal()
Prevents further changes; currently not used.
Definition source_file.cpp:71
void mapLine(cstring file, unsigned originalSourceLineNo)
Definition source_file.cpp:147
void appendText(const char *text)
Append this text; it is either a newline or a text with no newlines.
Definition source_file.cpp:105
cstring getSourceFragment(const SourcePosition &position, bool useMarker) const
Definition source_file.cpp:182
SourceFileLine getSourceLine(unsigned line) const
Original source line that produced the line with the specified number.
Definition source_file.cpp:153
Definition source_file.h:126
bool operator<(const SourceInfo &rhs) const
Definition source_file.h:198
SourceInfo()=default
Creates an "invalid" SourceInfo.
SourceInfo(const InputSources *sources, SourcePosition point)
Creates a SourceInfo for a 'point' in the source, or invalid.
Definition source_file.h:142
SourceInfo operator+(const SourceInfo &rhs) const
Definition source_file.h:154
Definition source_file.h:56
SourcePosition()=default
Creates an invalid source position.
SourcePosition & operator--()
Move one column back. This never moves one line back.
Definition source_file.h:80
Definition cstring.h:72
Definition source_file.h:221
cstring fileName
an empty filename indicates stdin
Definition source_file.h:223