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