clang  9.0.0svn
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 "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 } // namespace llvm
30 
31 namespace clang {
32 
33 class 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 ///
38 class 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 
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 /// 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 
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  /// Return true if this is a valid SourceLocation object.
102  ///
103  /// Invalid SourceLocations are often used when events have no corresponding
104  /// location in the source (e.g. a diagnostic is required for a command line
105  /// option).
106  bool isValid() const { return ID != 0; }
107  bool isInvalid() const { return ID == 0; }
108 
109 private:
110  /// Return the offset into the manager's global input view.
111  unsigned getOffset() const {
112  return ID & ~MacroIDBit;
113  }
114 
115  static SourceLocation getFileLoc(unsigned ID) {
116  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  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  /// Return a source location with the specified offset from this
131  /// SourceLocation.
133  assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
134  SourceLocation L;
135  L.ID = ID+Offset;
136  return L;
137  }
138 
139  /// When a SourceLocation itself cannot be used, this returns
140  /// an (opaque) 32-bit integer encoding for it.
141  ///
142  /// This should only be passed to SourceLocation::getFromRawEncoding, it
143  /// should not be inspected directly.
144  unsigned getRawEncoding() const { return ID; }
145 
146  /// Turn a raw encoding of a SourceLocation object into
147  /// a real SourceLocation.
148  ///
149  /// \see getRawEncoding.
152  X.ID = Encoding;
153  return X;
154  }
155 
156  /// When a SourceLocation itself cannot be used, this returns
157  /// an (opaque) pointer encoding for it.
158  ///
159  /// This should only be passed to SourceLocation::getFromPtrEncoding, it
160  /// should not be inspected directly.
161  void* getPtrEncoding() const {
162  // Double cast to avoid a warning "cast to pointer from integer of different
163  // size".
164  return (void*)(uintptr_t)getRawEncoding();
165  }
166 
167  /// Turn a pointer encoding of a SourceLocation object back
168  /// into a real SourceLocation.
170  return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
171  }
172 
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 /// A trivial tuple used to represent a source range.
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 /// Represents a character-granular source range.
228 ///
229 /// The underlying SourceRange can either specify the starting/ending character
230 /// of the range, or it can specify the start of the range and the start of the
231 /// last token of the range (a "token range"). In the token range case, the
232 /// size of the last token must be measured to determine the actual end of the
233 /// range.
235  SourceRange Range;
236  bool IsTokenRange = false;
237 
238 public:
239  CharSourceRange() = default;
240  CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
241 
243  return CharSourceRange(R, true);
244  }
245 
247  return CharSourceRange(R, false);
248  }
249 
251  return getTokenRange(SourceRange(B, E));
252  }
253 
255  return getCharRange(SourceRange(B, E));
256  }
257 
258  /// Return true if the end of this range specifies the start of
259  /// the last token. Return false if the end of this range specifies the last
260  /// character in the range.
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 /// Represents an unpacked "presumed" location which can be presented
277 /// to the user.
278 ///
279 /// A 'presumed' location can be modified by \#line and GNU line marker
280 /// directives and is always the expansion point of a normal location.
281 ///
282 /// You can get a PresumedLoc from a SourceLocation with SourceManager.
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  /// Return true if this object is invalid or uninitialized.
294  ///
295  /// This occurs when created with invalid source locations or when walking
296  /// off the top of a \#include stack.
297  bool isInvalid() const { return Filename == nullptr; }
298  bool isValid() const { return Filename != nullptr; }
299 
300  /// Return the presumed filename of this location.
301  ///
302  /// This can be affected by \#line etc.
303  const char *getFilename() const {
304  assert(isValid());
305  return Filename;
306  }
307 
308  /// Return the presumed line number of this location.
309  ///
310  /// This can be affected by \#line etc.
311  unsigned getLine() const {
312  assert(isValid());
313  return Line;
314  }
315 
316  /// Return the presumed column number of this location.
317  ///
318  /// This cannot be affected by \#line, but is packaged here for convenience.
319  unsigned getColumn() const {
320  assert(isValid());
321  return Col;
322  }
323 
324  /// Return the presumed include location of this location.
325  ///
326  /// This can be affected by GNU linemarker directives.
328  assert(isValid());
329  return IncludeLoc;
330  }
331 };
332 
333 class FileEntry;
334 
335 /// A SourceLocation and its associated SourceManager.
336 ///
337 /// This is useful for argument passing to functions that expect both objects.
339  const SourceManager *SrcMgr = nullptr;
340 
341 public:
342  /// Creates a FullSourceLoc where isValid() returns \c false.
343  FullSourceLoc() = default;
344 
346  : SourceLocation(Loc), SrcMgr(&SM) {}
347 
348  bool hasManager() const {
349  bool hasSrcMgr = SrcMgr != nullptr;
350  assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager");
351  return hasSrcMgr;
352  }
353 
354  /// \pre This FullSourceLoc has an associated SourceManager.
355  const SourceManager &getManager() const {
356  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  /// Return a StringRef to the source buffer data for the
385  /// specified FileID.
386  StringRef getBufferData(bool *Invalid = nullptr) const;
387 
388  /// Decompose the specified location into a raw FileID + Offset pair.
389  ///
390  /// The first element is the FileID, the second is the offset from the
391  /// start of the buffer of the location.
392  std::pair<FileID, unsigned> getDecomposedLoc() const;
393 
394  bool isInSystemHeader() const;
395 
396  /// Determines the order of 2 source locations in the translation unit.
397  ///
398  /// \returns true if this source location comes before 'Loc', false otherwise.
399  bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
400 
401  /// Determines the order of 2 source locations in the translation unit.
402  ///
403  /// \returns true if this source location comes before 'Loc', false otherwise.
405  assert(Loc.isValid());
406  assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
407  return isBeforeInTranslationUnitThan((SourceLocation)Loc);
408  }
409 
410  /// Comparison function class, useful for sorting FullSourceLocs.
412  bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
413  return lhs.isBeforeInTranslationUnitThan(rhs);
414  }
415  };
416 
417  /// Prints information about this FullSourceLoc to stderr.
418  ///
419  /// This is useful for debugging.
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 } // namespace clang
435 
436 namespace llvm {
437 
438  /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
439  /// DenseSets.
440  template <>
441  struct DenseMapInfo<clang::FileID> {
443  return {};
444  }
445 
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  // Teach SmallPtrSet how to handle SourceLocation.
460  template<>
461  struct PointerLikeTypeTraits<clang::SourceLocation> {
462  enum { NumLowBitsAvailable = 0 };
463 
465  return L.getPtrEncoding();
466  }
467 
470  }
471  };
472 
473 } // namespace llvm
474 
475 #endif // LLVM_CLANG_BASIC_SOURCELOCATION_H
bool operator>=(const FileID &RHS) const
bool operator==(const SourceLocation &LHS, const SourceLocation &RHS)
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
friend bool operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS)
bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS)
void setBegin(SourceLocation b)
bool operator<(const SourceLocation &LHS, const SourceLocation &RHS)
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:29
static CharSourceRange getTokenRange(SourceRange R)
bool operator>(const FileID &RHS) const
StringRef P
static FileID getSentinel()
void setBegin(SourceLocation b)
SourceLocation getBegin() const
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
unsigned getHashValue() const
bool isInvalid() const
friend bool operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS)
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
SourceRange(SourceLocation loc)
static CharSourceRange getCharRange(SourceLocation B, SourceLocation E)
void setTokenRange(bool TR)
static void * getAsVoidPointer(clang::SourceLocation L)
static unsigned getHashValue(clang::FileID S)
bool operator==(const FileID &RHS) const
StringRef Filename
Definition: Format.cpp:1707
bool isValid() const
unsigned Offset
Definition: Format.cpp:1709
bool isValid() const
bool hasManager() const
SourceLocation End
Represents a character-granular source range.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
const AnnotatedLine * Line
bool operator<(const FileID &RHS) const
unsigned getLine() const
Return the presumed line number of this location.
bool operator!=(const SourceRange &X) const
const SourceManager & getManager() const
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
void setEnd(SourceLocation e)
SourceRange(SourceLocation begin, SourceLocation end)
bool isInvalid() const
Represents an unpacked "presumed" location which can be presented to the user.
SourceLocation getEnd() const
bool operator<=(const FileID &RHS) const
bool operator==(const SourceRange &X) const
const SourceManager & SM
Definition: Format.cpp:1568
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Definition: opencl-c.h:89
static CharSourceRange getCharRange(SourceRange R)
const char * getFilename() const
Return the presumed filename of this location.
unsigned getColumn() const
Return the presumed column number of this location.
bool isBeforeInTranslationUnitThan(SourceLocation Loc) const
Determines the order of 2 source locations in the translation unit.
Encodes a location in the source.
bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const
Determines the order of 2 source locations in the translation unit.
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:59
static bool isEqual(clang::FileID LHS, clang::FileID RHS)
static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E)
bool operator!=(const FileID &RHS) const
bool isTokenRange() const
Return true if the end of this range specifies the start of the last token.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
SourceRange getAsRange() const
Dataflow Directional Tag Classes.
static bool isPairOfFileLocations(SourceLocation Start, SourceLocation End)
bool isValid() const
Return true if this is a valid SourceLocation object.
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:354
static clang::FileID getEmptyKey()
bool isMacroID() const
FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
bool operator()(const FullSourceLoc &lhs, const FullSourceLoc &rhs) const
Comparison function class, useful for sorting FullSourceLocs.
SourceLocation getEnd() const
CharSourceRange(SourceRange R, bool ITR)
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:14051
void setEnd(SourceLocation e)
bool isValid() const
static clang::FileID getTombstoneKey()
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:103
A SourceLocation and its associated SourceManager.
static clang::SourceLocation getFromVoidPointer(void *P)
A trivial tuple used to represent a source range.
static SourceLocation getFromPtrEncoding(const void *Encoding)
Turn a pointer encoding of a SourceLocation object back into a real SourceLocation.
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
SourceLocation getBegin() const
This class handles loading and caching of source files into memory.
void * getPtrEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) pointer encoding for it...