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 
225 /// 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  /// 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  void setTokenRange(bool TR) { IsTokenRange = TR; }
269 
270  bool isValid() const { return Range.isValid(); }
271  bool isInvalid() const { return !isValid(); }
272 };
273 
274 /// Represents an unpacked "presumed" location which can be presented
275 /// to the user.
276 ///
277 /// A 'presumed' location can be modified by \#line and GNU line marker
278 /// directives and is always the expansion point of a normal location.
279 ///
280 /// You can get a PresumedLoc from a SourceLocation with SourceManager.
281 class PresumedLoc {
282  const char *Filename = nullptr;
283  unsigned Line, Col;
284  SourceLocation IncludeLoc;
285 
286 public:
287  PresumedLoc() = default;
288  PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
289  : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {}
290 
291  /// Return true if this object is invalid or uninitialized.
292  ///
293  /// This occurs when created with invalid source locations or when walking
294  /// off the top of a \#include stack.
295  bool isInvalid() const { return Filename == nullptr; }
296  bool isValid() const { return Filename != nullptr; }
297 
298  /// Return the presumed filename of this location.
299  ///
300  /// This can be affected by \#line etc.
301  const char *getFilename() const {
302  assert(isValid());
303  return Filename;
304  }
305 
306  /// Return the presumed line number of this location.
307  ///
308  /// This can be affected by \#line etc.
309  unsigned getLine() const {
310  assert(isValid());
311  return Line;
312  }
313 
314  /// Return the presumed column number of this location.
315  ///
316  /// This cannot be affected by \#line, but is packaged here for convenience.
317  unsigned getColumn() const {
318  assert(isValid());
319  return Col;
320  }
321 
322  /// Return the presumed include location of this location.
323  ///
324  /// This can be affected by GNU linemarker directives.
326  assert(isValid());
327  return IncludeLoc;
328  }
329 };
330 
331 class FileEntry;
332 
333 /// A SourceLocation and its associated SourceManager.
334 ///
335 /// This is useful for argument passing to functions that expect both objects.
337  const SourceManager *SrcMgr = nullptr;
338 
339 public:
340  /// Creates a FullSourceLoc where isValid() returns \c false.
341  FullSourceLoc() = default;
342 
344  : SourceLocation(Loc), SrcMgr(&SM) {}
345 
346  bool hasManager() const {
347  bool hasSrcMgr = SrcMgr != nullptr;
348  assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager");
349  return hasSrcMgr;
350  }
351 
352  /// \pre This FullSourceLoc has an associated SourceManager.
353  const SourceManager &getManager() const {
354  assert(SrcMgr && "SourceManager is NULL.");
355  return *SrcMgr;
356  }
357 
358  FileID getFileID() const;
359 
360  FullSourceLoc getExpansionLoc() const;
361  FullSourceLoc getSpellingLoc() const;
362  FullSourceLoc getFileLoc() 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  const FileEntry *getFileEntry() const;
381 
382  /// Return a StringRef to the source buffer data for the
383  /// specified FileID.
384  StringRef getBufferData(bool *Invalid = nullptr) const;
385 
386  /// Decompose the specified location into a raw FileID + Offset pair.
387  ///
388  /// The first element is the FileID, the second is the offset from the
389  /// start of the buffer of the location.
390  std::pair<FileID, unsigned> getDecomposedLoc() const;
391 
392  bool isInSystemHeader() const;
393 
394  /// Determines the order of 2 source locations in the translation unit.
395  ///
396  /// \returns true if this source location comes before 'Loc', false otherwise.
397  bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
398 
399  /// Determines the order of 2 source locations in the translation unit.
400  ///
401  /// \returns true if this source location comes before 'Loc', false otherwise.
403  assert(Loc.isValid());
404  assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
405  return isBeforeInTranslationUnitThan((SourceLocation)Loc);
406  }
407 
408  /// Comparison function class, useful for sorting FullSourceLocs.
410  bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
411  return lhs.isBeforeInTranslationUnitThan(rhs);
412  }
413  };
414 
415  /// Prints information about this FullSourceLoc to stderr.
416  ///
417  /// This is useful for debugging.
418  void dump() const;
419 
420  friend bool
421  operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
422  return LHS.getRawEncoding() == RHS.getRawEncoding() &&
423  LHS.SrcMgr == RHS.SrcMgr;
424  }
425 
426  friend bool
427  operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
428  return !(LHS == RHS);
429  }
430 };
431 
432 } // namespace clang
433 
434 namespace llvm {
435 
436  /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
437  /// DenseSets.
438  template <>
439  struct DenseMapInfo<clang::FileID> {
441  return {};
442  }
443 
446  }
447 
448  static unsigned getHashValue(clang::FileID S) {
449  return S.getHashValue();
450  }
451 
452  static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
453  return LHS == RHS;
454  }
455  };
456 
457  template <>
458  struct isPodLike<clang::SourceLocation> { static const bool value = true; };
459  template <>
460  struct isPodLike<clang::FileID> { static const bool value = true; };
461 
462  // Teach SmallPtrSet how to handle SourceLocation.
463  template<>
464  struct PointerLikeTypeTraits<clang::SourceLocation> {
465  enum { NumLowBitsAvailable = 0 };
466 
468  return L.getPtrEncoding();
469  }
470 
473  }
474  };
475 
476 } // namespace llvm
477 
478 #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)
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)
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:1605
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:1475
__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:13790
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...