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