1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #ifndef LLVM_CLANG_BASIC_SOURCELOCATION_H |
15 | #define LLVM_CLANG_BASIC_SOURCELOCATION_H |
16 | |
17 | #include "clang/Basic/LLVM.h" |
18 | #include "llvm/ADT/StringRef.h" |
19 | #include "llvm/Support/PointerLikeTypeTraits.h" |
20 | #include <cassert> |
21 | #include <cstdint> |
22 | #include <string> |
23 | #include <utility> |
24 | |
25 | namespace llvm { |
26 | |
27 | template <typename T> struct DenseMapInfo; |
28 | |
29 | } |
30 | |
31 | namespace clang { |
32 | |
33 | class SourceManager; |
34 | |
35 | |
36 | |
37 | |
38 | class FileID { |
39 | |
40 | |
41 | int ID = 0; |
42 | |
43 | public: |
44 | bool isValid() const { return ID != 0; } |
45 | bool isInvalid() const { return ID == 0; } |
46 | |
47 | bool operator==(const FileID &RHS) const { return ID == RHS.ID; } |
48 | bool operator<(const FileID &RHS) const { return ID < RHS.ID; } |
49 | bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; } |
50 | bool operator!=(const FileID &RHS) const { return !(*this == RHS); } |
51 | bool operator>(const FileID &RHS) const { return RHS < *this; } |
52 | bool operator>=(const FileID &RHS) const { return RHS <= *this; } |
53 | |
54 | static FileID getSentinel() { return get(-1); } |
55 | unsigned getHashValue() const { return static_cast<unsigned>(ID); } |
56 | |
57 | private: |
58 | friend class ASTWriter; |
59 | friend class ASTReader; |
60 | friend class SourceManager; |
61 | |
62 | static FileID get(int V) { |
63 | FileID F; |
64 | F.ID = V; |
65 | return F; |
66 | } |
67 | |
68 | int getOpaqueValue() const { return ID; } |
69 | }; |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | class SourceLocation { |
87 | friend class ASTReader; |
88 | friend class ASTWriter; |
89 | friend class SourceManager; |
90 | |
91 | unsigned ID = 0; |
92 | |
93 | enum : unsigned { |
94 | MacroIDBit = 1U << 31 |
95 | }; |
96 | |
97 | public: |
98 | bool isFileID() const { return (ID & MacroIDBit) == 0; } |
99 | bool isMacroID() const { return (ID & MacroIDBit) != 0; } |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | bool isValid() const { return ID != 0; } |
107 | bool isInvalid() const { return ID == 0; } |
108 | |
109 | private: |
110 | |
111 | unsigned getOffset() const { |
112 | return ID & ~MacroIDBit; |
113 | } |
114 | |
115 | static SourceLocation getFileLoc(unsigned ID) { |
116 | (0) . __assert_fail ("(ID & MacroIDBit) == 0 && \"Ran out of source locations!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/SourceLocation.h", 116, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert((ID & MacroIDBit) == 0 && "Ran out of source locations!"); |
117 | SourceLocation L; |
118 | L.ID = ID; |
119 | return L; |
120 | } |
121 | |
122 | static SourceLocation getMacroLoc(unsigned ID) { |
123 | (0) . __assert_fail ("(ID & MacroIDBit) == 0 && \"Ran out of source locations!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/SourceLocation.h", 123, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert((ID & MacroIDBit) == 0 && "Ran out of source locations!"); |
124 | SourceLocation L; |
125 | L.ID = MacroIDBit | ID; |
126 | return L; |
127 | } |
128 | |
129 | public: |
130 | |
131 | |
132 | SourceLocation getLocWithOffset(int Offset) const { |
133 | (0) . __assert_fail ("((getOffset()+Offset) & MacroIDBit) == 0 && \"offset overflow\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/SourceLocation.h", 133, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow"); |
134 | SourceLocation L; |
135 | L.ID = ID+Offset; |
136 | return L; |
137 | } |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | unsigned getRawEncoding() const { return ID; } |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | static SourceLocation getFromRawEncoding(unsigned Encoding) { |
151 | SourceLocation X; |
152 | X.ID = Encoding; |
153 | return X; |
154 | } |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | void* getPtrEncoding() const { |
162 | |
163 | |
164 | return (void*)(uintptr_t)getRawEncoding(); |
165 | } |
166 | |
167 | |
168 | |
169 | static SourceLocation getFromPtrEncoding(const void *Encoding) { |
170 | return getFromRawEncoding((unsigned)(uintptr_t)Encoding); |
171 | } |
172 | |
173 | static bool isPairOfFileLocations(SourceLocation Start, SourceLocation End) { |
174 | return Start.isValid() && Start.isFileID() && End.isValid() && |
175 | End.isFileID(); |
176 | } |
177 | |
178 | void print(raw_ostream &OS, const SourceManager &SM) const; |
179 | std::string printToString(const SourceManager &SM) const; |
180 | void dump(const SourceManager &SM) const; |
181 | }; |
182 | |
183 | inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) { |
184 | return LHS.getRawEncoding() == RHS.getRawEncoding(); |
185 | } |
186 | |
187 | inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) { |
188 | return !(LHS == RHS); |
189 | } |
190 | |
191 | inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) { |
192 | return LHS.getRawEncoding() < RHS.getRawEncoding(); |
193 | } |
194 | |
195 | |
196 | class SourceRange { |
197 | SourceLocation B; |
198 | SourceLocation E; |
199 | |
200 | public: |
201 | SourceRange() = default; |
202 | SourceRange(SourceLocation loc) : B(loc), E(loc) {} |
203 | SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {} |
204 | |
205 | SourceLocation getBegin() const { return B; } |
206 | SourceLocation getEnd() const { return E; } |
207 | |
208 | void setBegin(SourceLocation b) { B = b; } |
209 | void setEnd(SourceLocation e) { E = e; } |
210 | |
211 | bool isValid() const { return B.isValid() && E.isValid(); } |
212 | bool isInvalid() const { return !isValid(); } |
213 | |
214 | bool operator==(const SourceRange &X) const { |
215 | return B == X.B && E == X.E; |
216 | } |
217 | |
218 | bool operator!=(const SourceRange &X) const { |
219 | return B != X.B || E != X.E; |
220 | } |
221 | |
222 | void print(raw_ostream &OS, const SourceManager &SM) const; |
223 | std::string printToString(const SourceManager &SM) const; |
224 | void dump(const SourceManager &SM) const; |
225 | }; |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | |
232 | |
233 | |
234 | class CharSourceRange { |
235 | SourceRange Range; |
236 | bool IsTokenRange = false; |
237 | |
238 | public: |
239 | CharSourceRange() = default; |
240 | CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {} |
241 | |
242 | static CharSourceRange getTokenRange(SourceRange R) { |
243 | return CharSourceRange(R, true); |
244 | } |
245 | |
246 | static CharSourceRange getCharRange(SourceRange R) { |
247 | return CharSourceRange(R, false); |
248 | } |
249 | |
250 | static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) { |
251 | return getTokenRange(SourceRange(B, E)); |
252 | } |
253 | |
254 | static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) { |
255 | return getCharRange(SourceRange(B, E)); |
256 | } |
257 | |
258 | |
259 | |
260 | |
261 | bool isTokenRange() const { return IsTokenRange; } |
262 | bool isCharRange() const { return !IsTokenRange; } |
263 | |
264 | SourceLocation getBegin() const { return Range.getBegin(); } |
265 | SourceLocation getEnd() const { return Range.getEnd(); } |
266 | SourceRange getAsRange() const { return Range; } |
267 | |
268 | void setBegin(SourceLocation b) { Range.setBegin(b); } |
269 | void setEnd(SourceLocation e) { Range.setEnd(e); } |
270 | void setTokenRange(bool TR) { IsTokenRange = TR; } |
271 | |
272 | bool isValid() const { return Range.isValid(); } |
273 | bool isInvalid() const { return !isValid(); } |
274 | }; |
275 | |
276 | |
277 | |
278 | |
279 | |
280 | |
281 | |
282 | |
283 | class PresumedLoc { |
284 | const char *Filename = nullptr; |
285 | unsigned Line, Col; |
286 | SourceLocation IncludeLoc; |
287 | |
288 | public: |
289 | PresumedLoc() = default; |
290 | PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL) |
291 | : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {} |
292 | |
293 | |
294 | |
295 | |
296 | |
297 | bool isInvalid() const { return Filename == nullptr; } |
298 | bool isValid() const { return Filename != nullptr; } |
299 | |
300 | |
301 | |
302 | |
303 | const char *getFilename() const { |
304 | assert(isValid()); |
305 | return Filename; |
306 | } |
307 | |
308 | |
309 | |
310 | |
311 | unsigned getLine() const { |
312 | assert(isValid()); |
313 | return Line; |
314 | } |
315 | |
316 | |
317 | |
318 | |
319 | unsigned getColumn() const { |
320 | assert(isValid()); |
321 | return Col; |
322 | } |
323 | |
324 | |
325 | |
326 | |
327 | SourceLocation getIncludeLoc() const { |
328 | assert(isValid()); |
329 | return IncludeLoc; |
330 | } |
331 | }; |
332 | |
333 | class FileEntry; |
334 | |
335 | |
336 | |
337 | |
338 | class FullSourceLoc : public SourceLocation { |
339 | const SourceManager *SrcMgr = nullptr; |
340 | |
341 | public: |
342 | |
343 | FullSourceLoc() = default; |
344 | |
345 | explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM) |
346 | : SourceLocation(Loc), SrcMgr(&SM) {} |
347 | |
348 | bool hasManager() const { |
349 | bool hasSrcMgr = SrcMgr != nullptr; |
350 | (0) . __assert_fail ("hasSrcMgr == isValid() && \"FullSourceLoc has location but no manager\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/SourceLocation.h", 350, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager"); |
351 | return hasSrcMgr; |
352 | } |
353 | |
354 | |
355 | const SourceManager &getManager() const { |
356 | (0) . __assert_fail ("SrcMgr && \"SourceManager is NULL.\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/SourceLocation.h", 356, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(SrcMgr && "SourceManager is NULL."); |
357 | return *SrcMgr; |
358 | } |
359 | |
360 | FileID getFileID() const; |
361 | |
362 | FullSourceLoc getExpansionLoc() const; |
363 | FullSourceLoc getSpellingLoc() const; |
364 | FullSourceLoc getFileLoc() const; |
365 | PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const; |
366 | bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const; |
367 | FullSourceLoc getImmediateMacroCallerLoc() const; |
368 | std::pair<FullSourceLoc, StringRef> getModuleImportLoc() const; |
369 | unsigned getFileOffset() const; |
370 | |
371 | unsigned getExpansionLineNumber(bool *Invalid = nullptr) const; |
372 | unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const; |
373 | |
374 | unsigned getSpellingLineNumber(bool *Invalid = nullptr) const; |
375 | unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const; |
376 | |
377 | const char *getCharacterData(bool *Invalid = nullptr) const; |
378 | |
379 | unsigned getLineNumber(bool *Invalid = nullptr) const; |
380 | unsigned getColumnNumber(bool *Invalid = nullptr) const; |
381 | |
382 | const FileEntry *getFileEntry() const; |
383 | |
384 | |
385 | |
386 | StringRef getBufferData(bool *Invalid = nullptr) const; |
387 | |
388 | |
389 | |
390 | |
391 | |
392 | std::pair<FileID, unsigned> getDecomposedLoc() const; |
393 | |
394 | bool () const; |
395 | |
396 | |
397 | |
398 | |
399 | bool isBeforeInTranslationUnitThan(SourceLocation Loc) const; |
400 | |
401 | |
402 | |
403 | |
404 | bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const { |
405 | assert(Loc.isValid()); |
406 | (0) . __assert_fail ("SrcMgr == Loc.SrcMgr && \"Loc comes from another SourceManager!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/SourceLocation.h", 406, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!"); |
407 | return isBeforeInTranslationUnitThan((SourceLocation)Loc); |
408 | } |
409 | |
410 | |
411 | struct BeforeThanCompare { |
412 | bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const { |
413 | return lhs.isBeforeInTranslationUnitThan(rhs); |
414 | } |
415 | }; |
416 | |
417 | |
418 | |
419 | |
420 | void dump() const; |
421 | |
422 | friend bool |
423 | operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) { |
424 | return LHS.getRawEncoding() == RHS.getRawEncoding() && |
425 | LHS.SrcMgr == RHS.SrcMgr; |
426 | } |
427 | |
428 | friend bool |
429 | operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) { |
430 | return !(LHS == RHS); |
431 | } |
432 | }; |
433 | |
434 | } |
435 | |
436 | namespace llvm { |
437 | |
438 | |
439 | |
440 | template <> |
441 | struct DenseMapInfo<clang::FileID> { |
442 | static clang::FileID getEmptyKey() { |
443 | return {}; |
444 | } |
445 | |
446 | static clang::FileID getTombstoneKey() { |
447 | return clang::FileID::getSentinel(); |
448 | } |
449 | |
450 | static unsigned getHashValue(clang::FileID S) { |
451 | return S.getHashValue(); |
452 | } |
453 | |
454 | static bool isEqual(clang::FileID LHS, clang::FileID RHS) { |
455 | return LHS == RHS; |
456 | } |
457 | }; |
458 | |
459 | |
460 | template<> |
461 | struct PointerLikeTypeTraits<clang::SourceLocation> { |
462 | enum { NumLowBitsAvailable = 0 }; |
463 | |
464 | static void *getAsVoidPointer(clang::SourceLocation L) { |
465 | return L.getPtrEncoding(); |
466 | } |
467 | |
468 | static clang::SourceLocation getFromVoidPointer(void *P) { |
469 | return clang::SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)P); |
470 | } |
471 | }; |
472 | |
473 | } |
474 | |
475 | #endif |
476 | |