clang  7.0.0svn
SourceLocation.h
Go to the documentation of this file.
1 //===- SourceLocation.h - Compact identifier for Source Files ---*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// \brief Defines the clang::SourceLocation class and associated facilities.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_BASIC_SOURCELOCATION_H
16 #define LLVM_CLANG_BASIC_SOURCELOCATION_H
17 
18 #include "clang/Basic/LLVM.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/PointerLikeTypeTraits.h"
21 #include <cassert>
22 #include <cstdint>
23 #include <string>
24 #include <utility>
25 
26 namespace llvm {
27 
28 template <typename T> struct DenseMapInfo;
29 template <typename T> struct isPodLike;
30 
31 } // namespace llvm
32 
33 namespace clang {
34 
35 class SourceManager;
36 
37 /// \brief An opaque identifier used by SourceManager which refers to a
38 /// source file (MemoryBuffer) along with its \#include path and \#line data.
39 ///
40 class FileID {
41  /// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is
42  /// this module, and <-1 is something loaded from another module.
43  int ID = 0;
44 
45 public:
46  bool isValid() const { return ID != 0; }
47  bool isInvalid() const { return ID == 0; }
48 
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 ID <= RHS.ID; }
52  bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
53  bool operator>(const FileID &RHS) const { return RHS < *this; }
54  bool operator>=(const FileID &RHS) const { return RHS <= *this; }
55 
56  static FileID getSentinel() { return get(-1); }
57  unsigned getHashValue() const { return static_cast<unsigned>(ID); }
58 
59 private:
60  friend class ASTWriter;
61  friend class ASTReader;
62  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 /// \brief 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 
93  unsigned ID = 0;
94 
95  enum : unsigned {
96  MacroIDBit = 1U << 31
97  };
98 
99 public:
100  bool isFileID() const { return (ID & MacroIDBit) == 0; }
101  bool isMacroID() const { return (ID & MacroIDBit) != 0; }
102 
103  /// \brief Return true if this is a valid SourceLocation object.
104  ///
105  /// Invalid SourceLocations are often used when events have no corresponding
106  /// location in the source (e.g. a diagnostic is required for a command line
107  /// option).
108  bool isValid() const { return ID != 0; }
109  bool isInvalid() const { return ID == 0; }
110 
111 private:
112  /// \brief Return the offset into the manager's global input view.
113  unsigned getOffset() const {
114  return ID & ~MacroIDBit;
115  }
116 
117  static SourceLocation getFileLoc(unsigned 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(unsigned ID) {
125  assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
126  SourceLocation L;
127  L.ID = MacroIDBit | ID;
128  return L;
129  }
130 
131 public:
132  /// \brief Return a source location with the specified offset from this
133  /// SourceLocation.
135  assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
136  SourceLocation L;
137  L.ID = ID+Offset;
138  return L;
139  }
140 
141  /// \brief 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  unsigned getRawEncoding() const { return ID; }
147 
148  /// \brief 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  /// \brief 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  /// \brief Turn a pointer encoding of a SourceLocation object back
170  /// into a real SourceLocation.
172  return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
173  }
174 
176  return Start.isValid() && Start.isFileID() && End.isValid() &&
177  End.isFileID();
178  }
179 
180  void print(raw_ostream &OS, const SourceManager &SM) const;
181  std::string printToString(const SourceManager &SM) const;
182  void dump(const SourceManager &SM) const;
183 };
184 
185 inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
186  return LHS.getRawEncoding() == RHS.getRawEncoding();
187 }
188 
189 inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
190  return !(LHS == RHS);
191 }
192 
193 inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
194  return LHS.getRawEncoding() < RHS.getRawEncoding();
195 }
196 
197 /// \brief A trivial tuple used to represent a source range.
198 class SourceRange {
199  SourceLocation B;
200  SourceLocation E;
201 
202 public:
203  SourceRange() = default;
204  SourceRange(SourceLocation loc) : B(loc), E(loc) {}
205  SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
206 
207  SourceLocation getBegin() const { return B; }
208  SourceLocation getEnd() const { return E; }
209 
210  void setBegin(SourceLocation b) { B = b; }
211  void setEnd(SourceLocation e) { E = e; }
212 
213  bool isValid() const { return B.isValid() && E.isValid(); }
214  bool isInvalid() const { return !isValid(); }
215 
216  bool operator==(const SourceRange &X) const {
217  return B == X.B && E == X.E;
218  }
219 
220  bool operator!=(const SourceRange &X) const {
221  return B != X.B || E != X.E;
222  }
223 };
224 
225 /// \brief Represents a character-granular source range.
226 ///
227 /// The underlying SourceRange can either specify the starting/ending character
228 /// of the range, or it can specify the start of the range and the start of the
229 /// last token of the range (a "token range"). In the token range case, the
230 /// size of the last token must be measured to determine the actual end of the
231 /// range.
233  SourceRange Range;
234  bool IsTokenRange = false;
235 
236 public:
237  CharSourceRange() = default;
238  CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
239 
241  return CharSourceRange(R, true);
242  }
243 
245  return CharSourceRange(R, false);
246  }
247 
249  return getTokenRange(SourceRange(B, E));
250  }
251 
253  return getCharRange(SourceRange(B, E));
254  }
255 
256  /// \brief Return true if the end of this range specifies the start of
257  /// the last token. Return false if the end of this range specifies the last
258  /// character in the range.
259  bool isTokenRange() const { return IsTokenRange; }
260  bool isCharRange() const { return !IsTokenRange; }
261 
262  SourceLocation getBegin() const { return Range.getBegin(); }
263  SourceLocation getEnd() const { return Range.getEnd(); }
264  SourceRange getAsRange() const { return Range; }
265 
266  void setBegin(SourceLocation b) { Range.setBegin(b); }
267  void setEnd(SourceLocation e) { Range.setEnd(e); }
268 
269  bool isValid() const { return Range.isValid(); }
270  bool isInvalid() const { return !isValid(); }
271 };
272 
273 /// \brief Represents an unpacked "presumed" location which can be presented
274 /// to the user.
275 ///
276 /// A 'presumed' location can be modified by \#line and GNU line marker
277 /// directives and is always the expansion point of a normal location.
278 ///
279 /// You can get a PresumedLoc from a SourceLocation with SourceManager.
280 class PresumedLoc {
281  const char *Filename = nullptr;
282  unsigned Line, Col;
283  SourceLocation IncludeLoc;
284 
285 public:
286  PresumedLoc() = default;
287  PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
288  : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {}
289 
290  /// \brief Return true if this object is invalid or uninitialized.
291  ///
292  /// This occurs when created with invalid source locations or when walking
293  /// off the top of a \#include stack.
294  bool isInvalid() const { return Filename == nullptr; }
295  bool isValid() const { return Filename != nullptr; }
296 
297  /// \brief Return the presumed filename of this location.
298  ///
299  /// This can be affected by \#line etc.
300  const char *getFilename() const {
301  assert(isValid());
302  return Filename;
303  }
304 
305  /// \brief Return the presumed line number of this location.
306  ///
307  /// This can be affected by \#line etc.
308  unsigned getLine() const {
309  assert(isValid());
310  return Line;
311  }
312 
313  /// \brief Return the presumed column number of this location.
314  ///
315  /// This cannot be affected by \#line, but is packaged here for convenience.
316  unsigned getColumn() const {
317  assert(isValid());
318  return Col;
319  }
320 
321  /// \brief Return the presumed include location of this location.
322  ///
323  /// This can be affected by GNU linemarker directives.
325  assert(isValid());
326  return IncludeLoc;
327  }
328 };
329 
330 class FileEntry;
331 
332 /// \brief A SourceLocation and its associated SourceManager.
333 ///
334 /// This is useful for argument passing to functions that expect both objects.
336  const SourceManager *SrcMgr = nullptr;
337 
338 public:
339  /// \brief Creates a FullSourceLoc where isValid() returns \c false.
340  FullSourceLoc() = default;
341 
343  : SourceLocation(Loc), SrcMgr(&SM) {}
344 
345  bool hasManager() const {
346  bool hasSrcMgr = SrcMgr != nullptr;
347  assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager");
348  return hasSrcMgr;
349  }
350 
351  /// \pre This FullSourceLoc has an associated SourceManager.
352  const SourceManager &getManager() const {
353  assert(SrcMgr && "SourceManager is NULL.");
354  return *SrcMgr;
355  }
356 
357  FileID getFileID() const;
358 
359  FullSourceLoc getExpansionLoc() const;
360  FullSourceLoc getSpellingLoc() const;
361  FullSourceLoc getFileLoc() const;
362  std::pair<FullSourceLoc, FullSourceLoc> getImmediateExpansionRange() const;
363  PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const;
364  bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const;
365  FullSourceLoc getImmediateMacroCallerLoc() const;
366  std::pair<FullSourceLoc, StringRef> getModuleImportLoc() const;
367  unsigned getFileOffset() const;
368 
369  unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
370  unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
371 
372  unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
373  unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
374 
375  const char *getCharacterData(bool *Invalid = nullptr) const;
376 
377  unsigned getLineNumber(bool *Invalid = nullptr) const;
378  unsigned getColumnNumber(bool *Invalid = nullptr) const;
379 
380  std::pair<FullSourceLoc, FullSourceLoc> getExpansionRange() const;
381 
382  const FileEntry *getFileEntry() const;
383 
384  /// \brief Return a StringRef to the source buffer data for the
385  /// specified FileID.
386  StringRef getBufferData(bool *Invalid = nullptr) const;
387 
388  /// \brief 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  /// \brief 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  /// \brief 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  /// \brief 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  /// \brief 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  template <>
460  struct isPodLike<clang::SourceLocation> { static const bool value = true; };
461  template <>
462  struct isPodLike<clang::FileID> { static const bool value = true; };
463 
464  // Teach SmallPtrSet how to handle SourceLocation.
465  template<>
466  struct PointerLikeTypeTraits<clang::SourceLocation> {
467  enum { NumLowBitsAvailable = 0 };
468 
470  return L.getPtrEncoding();
471  }
472 
475  }
476  };
477 
478 } // namespace llvm
479 
480 #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:26
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)
uint32_t Offset
Definition: CacheTokens.cpp:43
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)
static void * getAsVoidPointer(clang::SourceLocation L)
static unsigned getHashValue(clang::FileID S)
bool operator==(const FileID &RHS) const
StringRef Filename
Definition: Format.cpp:1522
bool isValid() const
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:1412
__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:82
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()
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:13401
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:104
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...