clang 17.0.0git
SourceLocation.h
Go to the documentation of this file.
1//===- SourceLocation.h - Compact identifier for Source Files ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines the clang::SourceLocation class and associated facilities.
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 <cassert>
20#include <cstdint>
21#include <string>
22#include <utility>
23
24namespace llvm {
25
26class FoldingSetNodeID;
27template <typename T, typename Enable> struct FoldingSetTrait;
28
29} // namespace llvm
30
31namespace clang {
32
33class SourceManager;
34
35/// An opaque identifier used by SourceManager which refers to a
36/// source file (MemoryBuffer) along with its \#include path and \#line data.
37///
38class FileID {
39 /// A mostly-opaque identifier, where 0 is "invalid", >0 is
40 /// this module, and <-1 is something loaded from another module.
41 int ID = 0;
42
43public:
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
57private:
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/// Encodes a location in the source. The SourceManager can decode this
72/// to get at the full include stack, line and column information.
73///
74/// Technically, a source location is simply an offset into the manager's view
75/// of the input source, which is all input buffers (including macro
76/// expansions) concatenated in an effectively arbitrary order. The manager
77/// actually maintains two blocks of input buffers. One, starting at offset
78/// 0 and growing upwards, contains all buffers from this module. The other,
79/// starting at the highest possible offset and growing downwards, contains
80/// buffers of loaded modules.
81///
82/// In addition, one bit of SourceLocation is used for quick access to the
83/// information whether the location is in a file or a macro expansion.
84///
85/// It is important that this type remains small. It is currently 32 bits wide.
87 friend class ASTReader;
88 friend class ASTWriter;
89 friend class SourceManager;
90 friend struct llvm::FoldingSetTrait<SourceLocation, void>;
91
92public:
93 using UIntTy = uint32_t;
94 using IntTy = int32_t;
95
96private:
97 UIntTy ID = 0;
98
99 enum : UIntTy { MacroIDBit = 1ULL << (8 * sizeof(UIntTy) - 1) };
100
101public:
102 bool isFileID() const { return (ID & MacroIDBit) == 0; }
103 bool isMacroID() const { return (ID & MacroIDBit) != 0; }
104
105 /// Return true if this is a valid SourceLocation object.
106 ///
107 /// Invalid SourceLocations are often used when events have no corresponding
108 /// location in the source (e.g. a diagnostic is required for a command line
109 /// option).
110 bool isValid() const { return ID != 0; }
111 bool isInvalid() const { return ID == 0; }
112
113private:
114 /// Return the offset into the manager's global input view.
115 UIntTy getOffset() const { return ID & ~MacroIDBit; }
116
117 static SourceLocation getFileLoc(UIntTy ID) {
118 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
119 SourceLocation L;
120 L.ID = ID;
121 return L;
122 }
123
124 static SourceLocation getMacroLoc(UIntTy ID) {
125 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
126 SourceLocation L;
127 L.ID = MacroIDBit | ID;
128 return L;
129 }
130
131public:
132 /// Return a source location with the specified offset from this
133 /// SourceLocation.
135 assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
137 L.ID = ID+Offset;
138 return L;
139 }
140
141 /// When a SourceLocation itself cannot be used, this returns
142 /// an (opaque) 32-bit integer encoding for it.
143 ///
144 /// This should only be passed to SourceLocation::getFromRawEncoding, it
145 /// should not be inspected directly.
146 UIntTy getRawEncoding() const { return ID; }
147
148 /// Turn a raw encoding of a SourceLocation object into
149 /// a real SourceLocation.
150 ///
151 /// \see getRawEncoding.
154 X.ID = Encoding;
155 return X;
156 }
157
158 /// When a SourceLocation itself cannot be used, this returns
159 /// an (opaque) pointer encoding for it.
160 ///
161 /// This should only be passed to SourceLocation::getFromPtrEncoding, it
162 /// should not be inspected directly.
163 void* getPtrEncoding() const {
164 // Double cast to avoid a warning "cast to pointer from integer of different
165 // size".
166 return (void*)(uintptr_t)getRawEncoding();
167 }
168
169 /// Turn a pointer encoding of a SourceLocation object back
170 /// into a real SourceLocation.
171 static SourceLocation getFromPtrEncoding(const void *Encoding) {
173 }
174
176 return Start.isValid() && Start.isFileID() && End.isValid() &&
177 End.isFileID();
178 }
179
180 unsigned getHashValue() const;
181 void print(raw_ostream &OS, const SourceManager &SM) const;
182 std::string printToString(const SourceManager &SM) const;
183 void dump(const SourceManager &SM) const;
184};
185
186inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
187 return LHS.getRawEncoding() == RHS.getRawEncoding();
188}
189
190inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
191 return !(LHS == RHS);
192}
193
194// Ordering is meaningful only if LHS and RHS have the same FileID!
195// Otherwise use SourceManager::isBeforeInTranslationUnit().
196inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
197 return LHS.getRawEncoding() < RHS.getRawEncoding();
198}
199inline bool operator>(const SourceLocation &LHS, const SourceLocation &RHS) {
200 return LHS.getRawEncoding() > RHS.getRawEncoding();
201}
202inline bool operator<=(const SourceLocation &LHS, const SourceLocation &RHS) {
203 return LHS.getRawEncoding() <= RHS.getRawEncoding();
204}
205inline bool operator>=(const SourceLocation &LHS, const SourceLocation &RHS) {
206 return LHS.getRawEncoding() >= RHS.getRawEncoding();
207}
208
209/// A trivial tuple used to represent a source range.
213
214public:
215 SourceRange() = default;
216 SourceRange(SourceLocation loc) : B(loc), E(loc) {}
217 SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
218
219 SourceLocation getBegin() const { return B; }
220 SourceLocation getEnd() const { return E; }
221
222 void setBegin(SourceLocation b) { B = b; }
223 void setEnd(SourceLocation e) { E = e; }
224
225 bool isValid() const { return B.isValid() && E.isValid(); }
226 bool isInvalid() const { return !isValid(); }
227
228 bool operator==(const SourceRange &X) const {
229 return B == X.B && E == X.E;
230 }
231
232 bool operator!=(const SourceRange &X) const {
233 return B != X.B || E != X.E;
234 }
235
236 // Returns true iff other is wholly contained within this range.
237 bool fullyContains(const SourceRange &other) const {
238 return B <= other.B && E >= other.E;
239 }
240
241 void print(raw_ostream &OS, const SourceManager &SM) const;
242 std::string printToString(const SourceManager &SM) const;
243 void dump(const SourceManager &SM) const;
244};
245
246/// Represents a character-granular source range.
247///
248/// The underlying SourceRange can either specify the starting/ending character
249/// of the range, or it can specify the start of the range and the start of the
250/// last token of the range (a "token range"). In the token range case, the
251/// size of the last token must be measured to determine the actual end of the
252/// range.
254 SourceRange Range;
255 bool IsTokenRange = false;
256
257public:
258 CharSourceRange() = default;
259 CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
260
262 return CharSourceRange(R, true);
263 }
264
266 return CharSourceRange(R, false);
267 }
268
270 return getTokenRange(SourceRange(B, E));
271 }
272
274 return getCharRange(SourceRange(B, E));
275 }
276
277 /// Return true if the end of this range specifies the start of
278 /// the last token. Return false if the end of this range specifies the last
279 /// character in the range.
280 bool isTokenRange() const { return IsTokenRange; }
281 bool isCharRange() const { return !IsTokenRange; }
282
283 SourceLocation getBegin() const { return Range.getBegin(); }
284 SourceLocation getEnd() const { return Range.getEnd(); }
285 SourceRange getAsRange() const { return Range; }
286
287 void setBegin(SourceLocation b) { Range.setBegin(b); }
288 void setEnd(SourceLocation e) { Range.setEnd(e); }
289 void setTokenRange(bool TR) { IsTokenRange = TR; }
290
291 bool isValid() const { return Range.isValid(); }
292 bool isInvalid() const { return !isValid(); }
293};
294
295/// Represents an unpacked "presumed" location which can be presented
296/// to the user.
297///
298/// A 'presumed' location can be modified by \#line and GNU line marker
299/// directives and is always the expansion point of a normal location.
300///
301/// You can get a PresumedLoc from a SourceLocation with SourceManager.
303 const char *Filename = nullptr;
304 FileID ID;
305 unsigned Line, Col;
306 SourceLocation IncludeLoc;
307
308public:
309 PresumedLoc() = default;
310 PresumedLoc(const char *FN, FileID FID, unsigned Ln, unsigned Co,
312 : Filename(FN), ID(FID), Line(Ln), Col(Co), IncludeLoc(IL) {}
313
314 /// Return true if this object is invalid or uninitialized.
315 ///
316 /// This occurs when created with invalid source locations or when walking
317 /// off the top of a \#include stack.
318 bool isInvalid() const { return Filename == nullptr; }
319 bool isValid() const { return Filename != nullptr; }
320
321 /// Return the presumed filename of this location.
322 ///
323 /// This can be affected by \#line etc.
324 const char *getFilename() const {
325 assert(isValid());
326 return Filename;
327 }
328
330 assert(isValid());
331 return ID;
332 }
333
334 /// Return the presumed line number of this location.
335 ///
336 /// This can be affected by \#line etc.
337 unsigned getLine() const {
338 assert(isValid());
339 return Line;
340 }
341
342 /// Return the presumed column number of this location.
343 ///
344 /// This cannot be affected by \#line, but is packaged here for convenience.
345 unsigned getColumn() const {
346 assert(isValid());
347 return Col;
348 }
349
350 /// Return the presumed include location of this location.
351 ///
352 /// This can be affected by GNU linemarker directives.
354 assert(isValid());
355 return IncludeLoc;
356 }
357};
358
359class FileEntry;
360
361/// A SourceLocation and its associated SourceManager.
362///
363/// This is useful for argument passing to functions that expect both objects.
364///
365/// This class does not guarantee the presence of either the SourceManager or
366/// a valid SourceLocation. Clients should use `isValid()` and `hasManager()`
367/// before calling the member functions.
369 const SourceManager *SrcMgr = nullptr;
370
371public:
372 /// Creates a FullSourceLoc where isValid() returns \c false.
373 FullSourceLoc() = default;
374
376 : SourceLocation(Loc), SrcMgr(&SM) {}
377
378 /// Checks whether the SourceManager is present.
379 bool hasManager() const { return SrcMgr != nullptr; }
380
381 /// \pre hasManager()
382 const SourceManager &getManager() const {
383 assert(SrcMgr && "SourceManager is NULL.");
384 return *SrcMgr;
385 }
386
387 FileID getFileID() const;
388
392 PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const;
393 bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const;
395 std::pair<FullSourceLoc, StringRef> getModuleImportLoc() const;
396 unsigned getFileOffset() const;
397
398 unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
399 unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
400
401 /// Decompose the underlying \c SourceLocation into a raw (FileID + Offset)
402 /// pair, after walking through all expansion records.
403 ///
404 /// \see SourceManager::getDecomposedExpansionLoc
405 std::pair<FileID, unsigned> getDecomposedExpansionLoc() const;
406
407 unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
408 unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
409
410 const char *getCharacterData(bool *Invalid = nullptr) const;
411
412 unsigned getLineNumber(bool *Invalid = nullptr) const;
413 unsigned getColumnNumber(bool *Invalid = nullptr) const;
414
415 const FileEntry *getFileEntry() const;
416
417 /// Return a StringRef to the source buffer data for the
418 /// specified FileID.
419 StringRef getBufferData(bool *Invalid = nullptr) const;
420
421 /// Decompose the specified location into a raw FileID + Offset pair.
422 ///
423 /// The first element is the FileID, the second is the offset from the
424 /// start of the buffer of the location.
425 std::pair<FileID, unsigned> getDecomposedLoc() const;
426
427 bool isInSystemHeader() const;
428
429 /// Determines the order of 2 source locations in the translation unit.
430 ///
431 /// \returns true if this source location comes before 'Loc', false otherwise.
433
434 /// Determines the order of 2 source locations in the translation unit.
435 ///
436 /// \returns true if this source location comes before 'Loc', false otherwise.
438 assert(Loc.isValid());
439 assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
441 }
442
443 /// Comparison function class, useful for sorting FullSourceLocs.
445 bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
446 return lhs.isBeforeInTranslationUnitThan(rhs);
447 }
448 };
449
450 /// Prints information about this FullSourceLoc to stderr.
451 ///
452 /// This is useful for debugging.
453 void dump() const;
454
455 friend bool
456 operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
457 return LHS.getRawEncoding() == RHS.getRawEncoding() &&
458 LHS.SrcMgr == RHS.SrcMgr;
459 }
460
461 friend bool
462 operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
463 return !(LHS == RHS);
464 }
465};
466
467} // namespace clang
468
469namespace llvm {
470
471 /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
472 /// DenseSets.
473 template <>
474 struct DenseMapInfo<clang::FileID, void> {
476 return {};
477 }
478
481 }
482
483 static unsigned getHashValue(clang::FileID S) {
484 return S.getHashValue();
485 }
486
487 static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
488 return LHS == RHS;
489 }
490 };
491
492 /// Define DenseMapInfo so that SourceLocation's can be used as keys in
493 /// DenseMap and DenseSet. This trait class is eqivalent to
494 /// DenseMapInfo<unsigned> which uses SourceLocation::ID is used as a key.
495 template <> struct DenseMapInfo<clang::SourceLocation, void> {
497 constexpr clang::SourceLocation::UIntTy Zero = 0;
499 }
500
502 constexpr clang::SourceLocation::UIntTy Zero = 0;
504 }
505
506 static unsigned getHashValue(clang::SourceLocation Loc) {
507 return Loc.getHashValue();
508 }
509
511 return LHS == RHS;
512 }
513 };
514
515 // Allow calling FoldingSetNodeID::Add with SourceLocation object as parameter
516 template <> struct FoldingSetTrait<clang::SourceLocation, void> {
517 static void Profile(const clang::SourceLocation &X, FoldingSetNodeID &ID);
518 };
519
520} // namespace llvm
521
522#endif // LLVM_CLANG_BASIC_SOURCELOCATION_H
#define V(N, I)
Definition: ASTContext.h:3230
#define SM(sm)
Definition: Cuda.cpp:80
unsigned Offset
Definition: Format.cpp:2797
StringRef Filename
Definition: Format.cpp:2795
#define X(type, name)
Definition: Value.h:142
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
__device__ __2f16 b
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:366
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:86
Represents a character-granular source range.
void setEnd(SourceLocation e)
bool isTokenRange() const
Return true if the end of this range specifies the start of the last token.
static CharSourceRange getCharRange(SourceLocation B, SourceLocation E)
static CharSourceRange getCharRange(SourceRange R)
void setBegin(SourceLocation b)
static CharSourceRange getTokenRange(SourceRange R)
static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E)
SourceLocation getEnd() const
SourceLocation getBegin() const
void setTokenRange(bool TR)
CharSourceRange(SourceRange R, bool ITR)
SourceRange getAsRange() const
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:353
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool operator<(const FileID &RHS) const
unsigned getHashValue() const
bool operator>(const FileID &RHS) const
bool isValid() const
bool operator==(const FileID &RHS) const
bool isInvalid() const
bool operator>=(const FileID &RHS) const
bool operator!=(const FileID &RHS) const
bool operator<=(const FileID &RHS) const
static FileID getSentinel()
A SourceLocation and its associated SourceManager.
FullSourceLoc getFileLoc() const
unsigned getColumnNumber(bool *Invalid=nullptr) const
FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
std::pair< FileID, unsigned > getDecomposedExpansionLoc() const
Decompose the underlying SourceLocation into a raw (FileID + Offset) pair, after walking through all ...
bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const
Determines the order of 2 source locations in the translation unit.
FullSourceLoc getExpansionLoc() const
unsigned getLineNumber(bool *Invalid=nullptr) const
FullSourceLoc getSpellingLoc() const
std::pair< FullSourceLoc, StringRef > getModuleImportLoc() const
FileID getFileID() const
unsigned getSpellingLineNumber(bool *Invalid=nullptr) const
FullSourceLoc getImmediateMacroCallerLoc() const
friend bool operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS)
const char * getCharacterData(bool *Invalid=nullptr) const
unsigned getExpansionColumnNumber(bool *Invalid=nullptr) const
StringRef getBufferData(bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
void dump() const
Prints information about this FullSourceLoc to stderr.
friend bool operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS)
bool isInSystemHeader() const
const FileEntry * getFileEntry() const
unsigned getFileOffset() const
std::pair< FileID, unsigned > getDecomposedLoc() const
Decompose the specified location into a raw FileID + Offset pair.
FullSourceLoc()=default
Creates a FullSourceLoc where isValid() returns false.
PresumedLoc getPresumedLoc(bool UseLineDirectives=true) const
bool hasManager() const
Checks whether the SourceManager is present.
bool isMacroArgExpansion(FullSourceLoc *StartLoc=nullptr) const
const SourceManager & getManager() const
unsigned getExpansionLineNumber(bool *Invalid=nullptr) const
bool isBeforeInTranslationUnitThan(SourceLocation Loc) const
Determines the order of 2 source locations in the translation unit.
unsigned getSpellingColumnNumber(bool *Invalid=nullptr) const
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
PresumedLoc(const char *FN, FileID FID, unsigned Ln, unsigned Co, SourceLocation IL)
const char * getFilename() const
Return the presumed filename of this location.
bool isValid() const
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
FileID getFileID() const
PresumedLoc()=default
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
Encodes a location in the source.
void * getPtrEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) pointer encoding for it.
static SourceLocation getFromRawEncoding(UIntTy Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
std::string printToString(const SourceManager &SM) const
void dump(const SourceManager &SM) const
static bool isPairOfFileLocations(SourceLocation Start, SourceLocation End)
bool isValid() const
Return true if this is a valid SourceLocation object.
void print(raw_ostream &OS, const SourceManager &SM) const
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
unsigned getHashValue() const
static SourceLocation getFromPtrEncoding(const void *Encoding)
Turn a pointer encoding of a SourceLocation object back into a real SourceLocation.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceRange(SourceLocation loc)
bool operator==(const SourceRange &X) const
void setBegin(SourceLocation b)
bool isInvalid() const
bool fullyContains(const SourceRange &other) const
SourceLocation getEnd() const
SourceLocation getBegin() const
bool isValid() const
std::string printToString(const SourceManager &SM) const
bool operator!=(const SourceRange &X) const
void dump(const SourceManager &SM) const
SourceRange()=default
void setEnd(SourceLocation e)
SourceRange(SourceLocation begin, SourceLocation end)
void print(raw_ostream &OS, const SourceManager &SM) const
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
Definition: CallGraph.h:207
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool operator!=(CanQual< T > x, CanQual< U > y)
bool operator<=(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool operator>(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool operator>=(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
YAML serialization mapping.
Definition: Dominators.h:30
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Comparison function class, useful for sorting FullSourceLocs.
bool operator()(const FullSourceLoc &lhs, const FullSourceLoc &rhs) const
static unsigned getHashValue(clang::FileID S)
static bool isEqual(clang::FileID LHS, clang::FileID RHS)
static clang::SourceLocation getTombstoneKey()
static bool isEqual(clang::SourceLocation LHS, clang::SourceLocation RHS)
static unsigned getHashValue(clang::SourceLocation Loc)
static void Profile(const clang::SourceLocation &X, FoldingSetNodeID &ID)