clang  8.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 /// 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 /// 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  /// 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 /// 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  /// 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  /// 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  /// 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  /// 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  /// 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.
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 /// 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  void print(raw_ostream &OS, const SourceManager &SM) const;
225  std::string printToString(const SourceManager &SM) const;
226  void dump(const SourceManager &SM) const;
227 };
228 
229 /// Represents a character-granular source range.
230 ///
231 /// The underlying SourceRange can either specify the starting/ending character
232 /// of the range, or it can specify the start of the range and the start of the
233 /// last token of the range (a "token range"). In the token range case, the
234 /// size of the last token must be measured to determine the actual end of the
235 /// range.
237  SourceRange Range;
238  bool IsTokenRange = false;
239 
240 public:
241  CharSourceRange() = default;
242  CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
243 
245  return CharSourceRange(R, true);
246  }
247 
249  return CharSourceRange(R, false);
250  }
251 
253  return getTokenRange(SourceRange(B, E));
254  }
255 
257  return getCharRange(SourceRange(B, E));
258  }
259 
260  /// Return true if the end of this range specifies the start of
261  /// the last token. Return false if the end of this range specifies the last
262  /// character in the range.
263  bool isTokenRange() const { return IsTokenRange; }
264  bool isCharRange() const { return !IsTokenRange; }
265 
266  SourceLocation getBegin() const { return Range.getBegin(); }
267  SourceLocation getEnd() const { return Range.getEnd(); }
268  SourceRange getAsRange() const { return Range; }
269 
270  void setBegin(SourceLocation b) { Range.setBegin(b); }
271  void setEnd(SourceLocation e) { Range.setEnd(e); }
272  void setTokenRange(bool TR) { IsTokenRange = TR; }
273 
274  bool isValid() const { return Range.isValid(); }
275  bool isInvalid() const { return !isValid(); }
276 };
277 
278 /// Represents an unpacked "presumed" location which can be presented
279 /// to the user.
280 ///
281 /// A 'presumed' location can be modified by \#line and GNU line marker
282 /// directives and is always the expansion point of a normal location.
283 ///
284 /// You can get a PresumedLoc from a SourceLocation with SourceManager.
285 class PresumedLoc {
286  const char *Filename = nullptr;
287  unsigned Line, Col;
288  SourceLocation IncludeLoc;
289 
290 public:
291  PresumedLoc() = default;
292  PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
293  : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {}
294 
295  /// Return true if this object is invalid or uninitialized.
296  ///
297  /// This occurs when created with invalid source locations or when walking
298  /// off the top of a \#include stack.
299  bool isInvalid() const { return Filename == nullptr; }
300  bool isValid() const { return Filename != nullptr; }
301 
302  /// Return the presumed filename of this location.
303  ///
304  /// This can be affected by \#line etc.
305  const char *getFilename() const {
306  assert(isValid());
307  return Filename;
308  }
309 
310  /// Return the presumed line number of this location.
311  ///
312  /// This can be affected by \#line etc.
313  unsigned getLine() const {
314  assert(isValid());
315  return Line;
316  }
317 
318  /// Return the presumed column number of this location.
319  ///
320  /// This cannot be affected by \#line, but is packaged here for convenience.
321  unsigned getColumn() const {
322  assert(isValid());
323  return Col;
324  }
325 
326  /// Return the presumed include location of this location.
327  ///
328  /// This can be affected by GNU linemarker directives.
330  assert(isValid());
331  return IncludeLoc;
332  }
333 };
334 
335 class FileEntry;
336 
337 /// A SourceLocation and its associated SourceManager.
338 ///
339 /// This is useful for argument passing to functions that expect both objects.
341  const SourceManager *SrcMgr = nullptr;
342 
343 public:
344  /// Creates a FullSourceLoc where isValid() returns \c false.
345  FullSourceLoc() = default;
346 
348  : SourceLocation(Loc), SrcMgr(&SM) {}
349 
350  bool hasManager() const {
351  bool hasSrcMgr = SrcMgr != nullptr;
352  assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager");
353  return hasSrcMgr;
354  }
355 
356  /// \pre This FullSourceLoc has an associated SourceManager.
357  const SourceManager &getManager() const {
358  assert(SrcMgr && "SourceManager is NULL.");
359  return *SrcMgr;
360  }
361 
362  FileID getFileID() const;
363 
364  FullSourceLoc getExpansionLoc() const;
365  FullSourceLoc getSpellingLoc() const;
366  FullSourceLoc getFileLoc() const;
367  PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const;
368  bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const;
369  FullSourceLoc getImmediateMacroCallerLoc() const;
370  std::pair<FullSourceLoc, StringRef> getModuleImportLoc() const;
371  unsigned getFileOffset() const;
372 
373  unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
374  unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
375 
376  unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
377  unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
378 
379  const char *getCharacterData(bool *Invalid = nullptr) const;
380 
381  unsigned getLineNumber(bool *Invalid = nullptr) const;
382  unsigned getColumnNumber(bool *Invalid = nullptr) const;
383 
384  const FileEntry *getFileEntry() const;
385 
386  /// Return a StringRef to the source buffer data for the
387  /// specified FileID.
388  StringRef getBufferData(bool *Invalid = nullptr) const;
389 
390  /// Decompose the specified location into a raw FileID + Offset pair.
391  ///
392  /// The first element is the FileID, the second is the offset from the
393  /// start of the buffer of the location.
394  std::pair<FileID, unsigned> getDecomposedLoc() const;
395 
396  bool isInSystemHeader() const;
397 
398  /// Determines the order of 2 source locations in the translation unit.
399  ///
400  /// \returns true if this source location comes before 'Loc', false otherwise.
401  bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
402 
403  /// Determines the order of 2 source locations in the translation unit.
404  ///
405  /// \returns true if this source location comes before 'Loc', false otherwise.
407  assert(Loc.isValid());
408  assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
409  return isBeforeInTranslationUnitThan((SourceLocation)Loc);
410  }
411 
412  /// Comparison function class, useful for sorting FullSourceLocs.
414  bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
415  return lhs.isBeforeInTranslationUnitThan(rhs);
416  }
417  };
418 
419  /// Prints information about this FullSourceLoc to stderr.
420  ///
421  /// This is useful for debugging.
422  void dump() const;
423 
424  friend bool
425  operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
426  return LHS.getRawEncoding() == RHS.getRawEncoding() &&
427  LHS.SrcMgr == RHS.SrcMgr;
428  }
429 
430  friend bool
431  operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
432  return !(LHS == RHS);
433  }
434 };
435 
436 } // namespace clang
437 
438 namespace llvm {
439 
440  /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
441  /// DenseSets.
442  template <>
443  struct DenseMapInfo<clang::FileID> {
445  return {};
446  }
447 
450  }
451 
452  static unsigned getHashValue(clang::FileID S) {
453  return S.getHashValue();
454  }
455 
456  static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
457  return LHS == RHS;
458  }
459  };
460 
461  template <>
462  struct isPodLike<clang::SourceLocation> { static const bool value = true; };
463  template <>
464  struct isPodLike<clang::FileID> { static const bool value = true; };
465 
466  // Teach SmallPtrSet how to handle SourceLocation.
467  template<>
468  struct PointerLikeTypeTraits<clang::SourceLocation> {
469  enum { NumLowBitsAvailable = 0 };
470 
472  return L.getPtrEncoding();
473  }
474 
477  }
478  };
479 
480 } // namespace llvm
481 
482 #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:30
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:1629
bool isValid() const
unsigned Offset
Definition: Format.cpp:1631
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:1490
__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:90
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:60
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:355
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:13956
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...