clang  5.0.0
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/Support/Compiler.h"
20 #include "llvm/Support/PointerLikeTypeTraits.h"
21 #include <cassert>
22 #include <functional>
23 #include <string>
24 #include <utility>
25 
26 namespace llvm {
27  class MemoryBuffer;
28  template <typename T> struct DenseMapInfo;
29  template <typename T> struct isPodLike;
30 }
31 
32 namespace clang {
33 
34 class SourceManager;
35 
36 /// \brief An opaque identifier used by SourceManager which refers to a
37 /// source file (MemoryBuffer) along with its \#include path and \#line data.
38 ///
39 class FileID {
40  /// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is
41  /// this module, and <-1 is something loaded from another module.
42  int ID;
43 public:
44  FileID() : ID(0) {}
45 
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 SourceManager;
61  friend class ASTWriter;
62  friend class ASTReader;
63 
64  static FileID get(int V) {
65  FileID F;
66  F.ID = V;
67  return F;
68  }
69  int getOpaqueValue() const { return ID; }
70 };
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  unsigned ID;
90  friend class SourceManager;
91  friend class ASTReader;
92  friend class ASTWriter;
93  enum : unsigned {
94  MacroIDBit = 1U << 31
95  };
96 public:
97 
98  SourceLocation() : ID(0) {}
99 
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 public:
131 
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 
175  void print(raw_ostream &OS, const SourceManager &SM) const;
176  std::string printToString(const SourceManager &SM) const;
177  void dump(const SourceManager &SM) const;
178 };
179 
180 inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
181  return LHS.getRawEncoding() == RHS.getRawEncoding();
182 }
183 
184 inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
185  return !(LHS == RHS);
186 }
187 
188 inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
189  return LHS.getRawEncoding() < RHS.getRawEncoding();
190 }
191 
192 /// \brief A trivial tuple used to represent a source range.
193 class SourceRange {
194  SourceLocation B;
195  SourceLocation E;
196 public:
198  SourceRange(SourceLocation loc) : B(loc), E(loc) {}
199  SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
200 
201  SourceLocation getBegin() const { return B; }
202  SourceLocation getEnd() const { return E; }
203 
204  void setBegin(SourceLocation b) { B = b; }
205  void setEnd(SourceLocation e) { E = e; }
206 
207  bool isValid() const { return B.isValid() && E.isValid(); }
208  bool isInvalid() const { return !isValid(); }
209 
210  bool operator==(const SourceRange &X) const {
211  return B == X.B && E == X.E;
212  }
213 
214  bool operator!=(const SourceRange &X) const {
215  return B != X.B || E != X.E;
216  }
217 };
218 
219 /// \brief Represents a character-granular source range.
220 ///
221 /// The underlying SourceRange can either specify the starting/ending character
222 /// of the range, or it can specify the start of the range and the start of the
223 /// last token of the range (a "token range"). In the token range case, the
224 /// size of the last token must be measured to determine the actual end of the
225 /// range.
227  SourceRange Range;
228  bool IsTokenRange;
229 public:
230  CharSourceRange() : IsTokenRange(false) {}
231  CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
232 
234  return CharSourceRange(R, true);
235  }
236 
238  return CharSourceRange(R, false);
239  }
240 
242  return getTokenRange(SourceRange(B, E));
243  }
245  return getCharRange(SourceRange(B, E));
246  }
247 
248  /// \brief Return true if the end of this range specifies the start of
249  /// the last token. Return false if the end of this range specifies the last
250  /// character in the range.
251  bool isTokenRange() const { return IsTokenRange; }
252  bool isCharRange() const { return !IsTokenRange; }
253 
254  SourceLocation getBegin() const { return Range.getBegin(); }
255  SourceLocation getEnd() const { return Range.getEnd(); }
256  SourceRange getAsRange() const { return Range; }
257 
258  void setBegin(SourceLocation b) { Range.setBegin(b); }
259  void setEnd(SourceLocation e) { Range.setEnd(e); }
260 
261  bool isValid() const { return Range.isValid(); }
262  bool isInvalid() const { return !isValid(); }
263 };
264 
265 /// \brief Represents an unpacked "presumed" location which can be presented
266 /// to the user.
267 ///
268 /// A 'presumed' location can be modified by \#line and GNU line marker
269 /// directives and is always the expansion point of a normal location.
270 ///
271 /// You can get a PresumedLoc from a SourceLocation with SourceManager.
272 class PresumedLoc {
273  const char *Filename;
274  unsigned Line, Col;
275  SourceLocation IncludeLoc;
276 
277 public:
278  PresumedLoc() : Filename(nullptr) {}
279  PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
280  : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {}
281 
282  /// \brief Return true if this object is invalid or uninitialized.
283  ///
284  /// This occurs when created with invalid source locations or when walking
285  /// off the top of a \#include stack.
286  bool isInvalid() const { return Filename == nullptr; }
287  bool isValid() const { return Filename != nullptr; }
288 
289  /// \brief Return the presumed filename of this location.
290  ///
291  /// This can be affected by \#line etc.
292  const char *getFilename() const {
293  assert(isValid());
294  return Filename;
295  }
296 
297  /// \brief Return the presumed line number of this location.
298  ///
299  /// This can be affected by \#line etc.
300  unsigned getLine() const {
301  assert(isValid());
302  return Line;
303  }
304 
305  /// \brief Return the presumed column number of this location.
306  ///
307  /// This cannot be affected by \#line, but is packaged here for convenience.
308  unsigned getColumn() const {
309  assert(isValid());
310  return Col;
311  }
312 
313  /// \brief Return the presumed include location of this location.
314  ///
315  /// This can be affected by GNU linemarker directives.
317  assert(isValid());
318  return IncludeLoc;
319  }
320 };
321 
322 class FileEntry;
323 
324 /// \brief A SourceLocation and its associated SourceManager.
325 ///
326 /// This is useful for argument passing to functions that expect both objects.
328  const SourceManager *SrcMgr;
329 public:
330  /// \brief Creates a FullSourceLoc where isValid() returns \c false.
331  explicit FullSourceLoc() : SrcMgr(nullptr) {}
332 
334  : SourceLocation(Loc), SrcMgr(&SM) {}
335 
336  bool hasManager() const {
337  bool hasSrcMgr = SrcMgr != nullptr;
338  assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager");
339  return hasSrcMgr;
340  }
341 
342  /// \pre This FullSourceLoc has an associated SourceManager.
343  const SourceManager &getManager() const {
344  assert(SrcMgr && "SourceManager is NULL.");
345  return *SrcMgr;
346  }
347 
348  FileID getFileID() const;
349 
352  FullSourceLoc getFileLoc() const;
353  std::pair<FullSourceLoc, FullSourceLoc> getImmediateExpansionRange() const;
354  PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const;
355  bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const;
357  std::pair<FullSourceLoc, StringRef> getModuleImportLoc() const;
358  unsigned getFileOffset() const;
359 
360  unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
361  unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
362 
363  unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
364  unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
365 
366  const char *getCharacterData(bool *Invalid = nullptr) const;
367 
368  unsigned getLineNumber(bool *Invalid = nullptr) const;
369  unsigned getColumnNumber(bool *Invalid = nullptr) const;
370 
371  std::pair<FullSourceLoc, FullSourceLoc> getExpansionRange() const;
372 
373  const FileEntry *getFileEntry() const;
374 
375  /// \brief Return a StringRef to the source buffer data for the
376  /// specified FileID.
377  StringRef getBufferData(bool *Invalid = nullptr) const;
378 
379  /// \brief Decompose the specified location into a raw FileID + Offset pair.
380  ///
381  /// The first element is the FileID, the second is the offset from the
382  /// start of the buffer of the location.
383  std::pair<FileID, unsigned> getDecomposedLoc() const;
384 
385  bool isInSystemHeader() const;
386 
387  /// \brief Determines the order of 2 source locations in the translation unit.
388  ///
389  /// \returns true if this source location comes before 'Loc', false otherwise.
391 
392  /// \brief Determines the order of 2 source locations in the translation unit.
393  ///
394  /// \returns true if this source location comes before 'Loc', false otherwise.
396  assert(Loc.isValid());
397  assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
399  }
400 
401  /// \brief Comparison function class, useful for sorting FullSourceLocs.
403  bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
404  return lhs.isBeforeInTranslationUnitThan(rhs);
405  }
406  };
407 
408  /// \brief Prints information about this FullSourceLoc to stderr.
409  ///
410  /// This is useful for debugging.
411  void dump() const;
412 
413  friend inline bool
414  operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
415  return LHS.getRawEncoding() == RHS.getRawEncoding() &&
416  LHS.SrcMgr == RHS.SrcMgr;
417  }
418 
419  friend inline bool
420  operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
421  return !(LHS == RHS);
422  }
423 
424 };
425 
426 
427 
428 } // end namespace clang
429 
430 namespace llvm {
431  /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
432  /// DenseSets.
433  template <>
434  struct DenseMapInfo<clang::FileID> {
435  static inline clang::FileID getEmptyKey() {
436  return clang::FileID();
437  }
438  static inline clang::FileID getTombstoneKey() {
440  }
441 
442  static unsigned getHashValue(clang::FileID S) {
443  return S.getHashValue();
444  }
445 
446  static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
447  return LHS == RHS;
448  }
449  };
450 
451  template <>
452  struct isPodLike<clang::SourceLocation> { static const bool value = true; };
453  template <>
454  struct isPodLike<clang::FileID> { static const bool value = true; };
455 
456  // Teach SmallPtrSet how to handle SourceLocation.
457  template<>
458  class PointerLikeTypeTraits<clang::SourceLocation> {
459  public:
460  static inline void *getAsVoidPointer(clang::SourceLocation L) {
461  return L.getPtrEncoding();
462  }
465  }
466  enum { NumLowBitsAvailable = 0 };
467  };
468 
469 } // end namespace llvm
470 
471 #endif
SourceLocation getEnd() const
std::string printToString(const SourceManager &SM) const
SourceLocation getBegin() const
unsigned getColumn() const
Return the presumed column number of this location.
bool isMacroID() const
bool isValid() const
bool operator>=(const FileID &RHS) const
friend bool operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS)
bool operator==(CanQual< T > x, CanQual< U > y)
void setBegin(SourceLocation b)
bool isInvalid() const
Return true if this object is invalid or uninitialized.
std::pair< FullSourceLoc, StringRef > getModuleImportLoc() const
static CharSourceRange getTokenRange(SourceRange R)
StringRef P
static FileID getSentinel()
const SourceManager & getManager() const
static void * getAsVoidPointer(clang::SourceLocation L)
FileID getFileID() const
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
void setBegin(SourceLocation b)
unsigned getExpansionLineNumber(bool *Invalid=nullptr) const
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
bool isFileID() const
unsigned getExpansionColumnNumber(bool *Invalid=nullptr) const
std::pair< FileID, unsigned > getDecomposedLoc() const
Decompose the specified location into a raw FileID + Offset pair.
FullSourceLoc getFileLoc() const
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
friend bool operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS)
uint32_t Offset
Definition: CacheTokens.cpp:43
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
unsigned getFileOffset() const
SourceRange(SourceLocation loc)
void dump() const
Prints information about this FullSourceLoc to stderr.
static CharSourceRange getCharRange(SourceLocation B, SourceLocation E)
void dump(const SourceManager &SM) const
unsigned getColumnNumber(bool *Invalid=nullptr) const
unsigned getLine() const
Return the presumed line number of this location.
bool operator<=(const FileID &RHS) const
SourceLocation getIncludeLoc() const
Return the presumed include location of this location.
bool isInvalid() const
static unsigned getHashValue(clang::FileID S)
Represents a character-granular source range.
SourceLocation getEnd() const
static clang::SourceLocation getFromVoidPointer(void *P)
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
void setEnd(SourceLocation e)
std::pair< FullSourceLoc, FullSourceLoc > getImmediateExpansionRange() const
bool operator<(const FileID &RHS) const
SourceRange(SourceLocation begin, SourceLocation end)
bool isMacroArgExpansion(FullSourceLoc *StartLoc=nullptr) const
Represents an unpacked "presumed" location which can be presented to the user.
const SourceManager & SM
Definition: Format.cpp:1293
__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)
unsigned getHashValue() const
#define false
Definition: stdbool.h:33
bool isTokenRange() const
Return true if the end of this range specifies the start of the last token.
void print(raw_ostream &OS, const SourceManager &SM) const
const char * getFilename() const
Return the presumed filename of this location.
Encodes a location in the source.
const char * getCharacterData(bool *Invalid=nullptr) const
bool isValid() const
Return true if this is a valid SourceLocation object.
const std::string ID
bool isCharRange() const
bool isValid() const
const FileEntry * getFileEntry() const
FullSourceLoc()
Creates a FullSourceLoc where isValid() returns false.
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:59
bool operator>(const FileID &RHS) const
static bool isEqual(clang::FileID LHS, clang::FileID RHS)
static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E)
unsigned getSpellingLineNumber(bool *Invalid=nullptr) const
unsigned getLineNumber(bool *Invalid=nullptr) const
SourceLocation getBegin() const
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool operator!=(const SourceRange &X) const
bool isInSystemHeader() const
bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const
Determines the order of 2 source locations in the translation unit.
bool hasManager() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool operator==(const SourceRange &X) const
SourceRange getAsRange() const
bool operator()(const FullSourceLoc &lhs, const FullSourceLoc &rhs) const
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:328
detail::InMemoryDirectory::const_iterator E
static clang::FileID getEmptyKey()
PresumedLoc getPresumedLoc(bool UseLineDirectives=true) const
std::pair< FullSourceLoc, FullSourceLoc > getExpansionRange() const
bool operator!=(const FileID &RHS) const
FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
bool isInvalid() const
bool operator==(const FileID &RHS) const
FullSourceLoc getImmediateMacroCallerLoc() const
Comparison function class, useful for sorting FullSourceLocs.
CharSourceRange(SourceRange R, bool ITR)
bool isInvalid() const
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:13074
StringRef getBufferData(bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
bool isBeforeInTranslationUnitThan(SourceLocation Loc) const
Determines the order of 2 source locations in the translation unit.
void setEnd(SourceLocation e)
static clang::FileID getTombstoneKey()
bool operator!=(CanQual< T > x, CanQual< U > y)
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:82
A SourceLocation and its associated SourceManager.
FullSourceLoc getExpansionLoc() const
A trivial tuple used to represent a source range.
bool isValid() 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.
void * getPtrEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) pointer encoding for it...
FullSourceLoc getSpellingLoc() const
unsigned getSpellingColumnNumber(bool *Invalid=nullptr) const