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 <string_view>
26#include <vector>
27
28#include "cstring.h"
29#include "stringify.h"
30
31// GTest
32#ifdef P4C_GTEST_ENABLED
33#include "gtest/gtest_prod.h"
34#endif
35
36namespace Test {
37class UtilSourceFile;
38}
39
40namespace Util {
41using namespace P4::literals;
42
43struct SourceFileLine;
53class SourcePosition final {
54 public:
56 SourcePosition() = default;
57
58 SourcePosition(unsigned lineNumber, unsigned columnNumber);
59
60 SourcePosition(const SourcePosition &other) = default;
61 SourcePosition &operator=(const SourcePosition &) = default;
62
63 inline bool operator==(const SourcePosition &rhs) const {
64 return columnNumber == rhs.columnNumber && lineNumber == rhs.lineNumber;
65 }
66 inline bool operator!=(const SourcePosition &rhs) const { return !this->operator==(rhs); }
67
68 inline bool operator<(const SourcePosition &rhs) const {
69 return (lineNumber < rhs.lineNumber) ||
70 (lineNumber == rhs.lineNumber && columnNumber < rhs.columnNumber);
71 }
72 inline bool operator>(const SourcePosition &rhs) const { return rhs.operator<(*this); }
73 inline bool operator<=(const SourcePosition &rhs) const { return !this->operator>(rhs); }
74 inline bool operator>=(const SourcePosition &rhs) const { return !this->operator<(rhs); }
75
78 if (columnNumber > 0) columnNumber--;
79 return *this;
80 }
82 SourcePosition tmp(*this);
83 this->operator--();
84 return tmp;
85 }
86
87 inline const SourcePosition &min(const SourcePosition &rhs) const {
88 if (this->operator<(rhs)) return *this;
89 return rhs;
90 }
91
92 inline const SourcePosition &max(const SourcePosition &rhs) const {
93 if (this->operator>(rhs)) return *this;
94 return rhs;
95 }
96
97 cstring toString() const;
98
99 bool isValid() const { return lineNumber != 0; }
100
101 unsigned getLineNumber() const { return lineNumber; }
102
103 unsigned getColumnNumber() const { return columnNumber; }
104
105 private:
106 // Input sources where this character position is interpreted.
107 unsigned lineNumber = 0;
108 unsigned columnNumber = 0;
109};
110
111class InputSources;
112
123class SourceInfo final {
124 public:
125 cstring filename = ""_cs;
126 int line = -1;
127 int column = -1;
128 cstring srcBrief = ""_cs;
129 SourceInfo(cstring filename, int line, int column, cstring srcBrief) {
130 this->filename = filename;
131 this->line = line;
132 this->column = column;
133 this->srcBrief = srcBrief;
134 }
136 SourceInfo() = default;
137
140 : sources(sources), start(point), end(point) {}
141
142 SourceInfo(const InputSources *sources, SourcePosition start, SourcePosition end);
143
144 SourceInfo(const SourceInfo &other) = default;
145 SourceInfo &operator=(const SourceInfo &other) = default;
146 ~SourceInfo() = default;
147
151 SourceInfo operator+(const SourceInfo &rhs) const {
152 if (!this->isValid()) return rhs;
153 if (!rhs.isValid()) return *this;
154 SourcePosition s = start.min(rhs.start);
155 SourcePosition e = end.max(rhs.end);
156 return SourceInfo(sources, s, e);
157 }
158 SourceInfo &operator+=(const SourceInfo &rhs) {
159 if (!isValid()) {
160 *this = rhs;
161 } else if (rhs.isValid()) {
162 start = start.min(rhs.start);
163 end = end.max(rhs.end);
164 }
165 return *this;
166 }
167
168 bool operator==(const SourceInfo &rhs) const { return start == rhs.start && end == rhs.end; }
169
170 cstring toString() const;
171
172 void dbprint(std::ostream &out) const { out << this->toString(); }
173
174 cstring toSourceFragment(bool useMarker = true) const;
175 cstring toBriefSourceFragment() const;
176 cstring toPositionString() const;
177 cstring toSourcePositionData(unsigned *outLineNumber, unsigned *outColumnNumber) const;
178 SourceFileLine toPosition() const;
179
180 bool isValid() const { return this->start.isValid(); }
181 explicit operator bool() const { return isValid(); }
182
183 cstring getSourceFile() const;
184 cstring getLineNum() const;
185
186 const SourcePosition &getStart() const { return this->start; }
187
188 const SourcePosition &getEnd() const { return this->end; }
189
195 bool operator<(const SourceInfo &rhs) const {
196 if (!rhs.isValid()) return false;
197 if (!isValid()) return true;
198 return this->start < rhs.start;
199 }
200 inline bool operator>(const SourceInfo &rhs) const { return rhs.operator<(*this); }
201 inline bool operator<=(const SourceInfo &rhs) const { return !this->operator>(rhs); }
202 inline bool operator>=(const SourceInfo &rhs) const { return !this->operator<(rhs); }
203
204 private:
205 const InputSources *sources = nullptr;
206 SourcePosition start = SourcePosition();
207 SourcePosition end = SourcePosition();
208};
209
211 public:
212 virtual SourceInfo getSourceInfo() const = 0;
213 virtual cstring toString() const = 0;
214 virtual ~IHasSourceInfo() {}
215};
216
217template <class T>
218inline constexpr bool has_SourceInfo_v = std::is_base_of_v<Util::IHasSourceInfo, T>;
219
224 unsigned sourceLine;
225
226 SourceFileLine(std::string_view 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 std::string_view 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(std::string_view 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 stringify.h:31
Definition source_file.h:231
Definition source_file.h:210
Definition source_file.h:263
void seal()
Prevents further changes; currently not used.
Definition source_file.cpp:76
void appendText(const char *text)
Append this text; it is either a newline or a text with no newlines.
Definition source_file.cpp:110
void mapLine(std::string_view file, unsigned originalSourceLineNo)
Definition source_file.cpp:152
cstring getSourceFragment(const SourcePosition &position, bool useMarker) const
Definition source_file.cpp:187
SourceFileLine getSourceLine(unsigned line) const
Original source line that produced the line with the specified number.
Definition source_file.cpp:158
Definition source_file.h:123
bool operator<(const SourceInfo &rhs) const
Definition source_file.h:195
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:139
SourceInfo operator+(const SourceInfo &rhs) const
Definition source_file.h:151
Definition source_file.h:53
SourcePosition()=default
Creates an invalid source position.
SourcePosition & operator--()
Move one column back. This never moves one line back.
Definition source_file.h:77
Definition cstring.h:80
Definition cstring.h:76
Definition source_file.h:221
cstring fileName
an empty filename indicates stdin
Definition source_file.h:223