clang  3.9.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) {}
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 A SourceLocation and its associated SourceManager.
266 ///
267 /// This is useful for argument passing to functions that expect both objects.
269  const SourceManager *SrcMgr;
270 public:
271  /// \brief Creates a FullSourceLoc where isValid() returns \c false.
272  explicit FullSourceLoc() : SrcMgr(nullptr) {}
273 
275  : SourceLocation(Loc), SrcMgr(&SM) {}
276 
277  /// \pre This FullSourceLoc has an associated SourceManager.
278  const SourceManager &getManager() const {
279  assert(SrcMgr && "SourceManager is NULL.");
280  return *SrcMgr;
281  }
282 
283  FileID getFileID() const;
284 
287 
288  unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
289  unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
290 
291  unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
292  unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
293 
294  const char *getCharacterData(bool *Invalid = nullptr) const;
295 
296 
297  /// \brief Return a StringRef to the source buffer data for the
298  /// specified FileID.
299  StringRef getBufferData(bool *Invalid = nullptr) const;
300 
301  /// \brief Decompose the specified location into a raw FileID + Offset pair.
302  ///
303  /// The first element is the FileID, the second is the offset from the
304  /// start of the buffer of the location.
305  std::pair<FileID, unsigned> getDecomposedLoc() const;
306 
307  bool isInSystemHeader() const;
308 
309  /// \brief Determines the order of 2 source locations in the translation unit.
310  ///
311  /// \returns true if this source location comes before 'Loc', false otherwise.
313 
314  /// \brief Determines the order of 2 source locations in the translation unit.
315  ///
316  /// \returns true if this source location comes before 'Loc', false otherwise.
318  assert(Loc.isValid());
319  assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
321  }
322 
323  /// \brief Comparison function class, useful for sorting FullSourceLocs.
324  struct BeforeThanCompare : public std::binary_function<FullSourceLoc,
325  FullSourceLoc, bool> {
326  bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
327  return lhs.isBeforeInTranslationUnitThan(rhs);
328  }
329  };
330 
331  /// \brief Prints information about this FullSourceLoc to stderr.
332  ///
333  /// This is useful for debugging.
334  void dump() const;
335 
336  friend inline bool
337  operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
338  return LHS.getRawEncoding() == RHS.getRawEncoding() &&
339  LHS.SrcMgr == RHS.SrcMgr;
340  }
341 
342  friend inline bool
343  operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
344  return !(LHS == RHS);
345  }
346 
347 };
348 
349 /// \brief Represents an unpacked "presumed" location which can be presented
350 /// to the user.
351 ///
352 /// A 'presumed' location can be modified by \#line and GNU line marker
353 /// directives and is always the expansion point of a normal location.
354 ///
355 /// You can get a PresumedLoc from a SourceLocation with SourceManager.
356 class PresumedLoc {
357  const char *Filename;
358  unsigned Line, Col;
359  SourceLocation IncludeLoc;
360 public:
361  PresumedLoc() : Filename(nullptr) {}
362  PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
363  : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
364  }
365 
366  /// \brief Return true if this object is invalid or uninitialized.
367  ///
368  /// This occurs when created with invalid source locations or when walking
369  /// off the top of a \#include stack.
370  bool isInvalid() const { return Filename == nullptr; }
371  bool isValid() const { return Filename != nullptr; }
372 
373  /// \brief Return the presumed filename of this location.
374  ///
375  /// This can be affected by \#line etc.
376  const char *getFilename() const { assert(isValid()); return Filename; }
377 
378  /// \brief Return the presumed line number of this location.
379  ///
380  /// This can be affected by \#line etc.
381  unsigned getLine() const { assert(isValid()); return Line; }
382 
383  /// \brief Return the presumed column number of this location.
384  ///
385  /// This cannot be affected by \#line, but is packaged here for convenience.
386  unsigned getColumn() const { assert(isValid()); return Col; }
387 
388  /// \brief Return the presumed include location of this location.
389  ///
390  /// This can be affected by GNU linemarker directives.
391  SourceLocation getIncludeLoc() const { assert(isValid()); return IncludeLoc; }
392 };
393 
394 
395 } // end namespace clang
396 
397 namespace llvm {
398  /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
399  /// DenseSets.
400  template <>
401  struct DenseMapInfo<clang::FileID> {
402  static inline clang::FileID getEmptyKey() {
403  return clang::FileID();
404  }
405  static inline clang::FileID getTombstoneKey() {
407  }
408 
409  static unsigned getHashValue(clang::FileID S) {
410  return S.getHashValue();
411  }
412 
413  static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
414  return LHS == RHS;
415  }
416  };
417 
418  template <>
419  struct isPodLike<clang::SourceLocation> { static const bool value = true; };
420  template <>
421  struct isPodLike<clang::FileID> { static const bool value = true; };
422 
423  // Teach SmallPtrSet how to handle SourceLocation.
424  template<>
425  class PointerLikeTypeTraits<clang::SourceLocation> {
426  public:
427  static inline void *getAsVoidPointer(clang::SourceLocation L) {
428  return L.getPtrEncoding();
429  }
432  }
433  enum { NumLowBitsAvailable = 0 };
434  };
435 
436 } // end namespace llvm
437 
438 #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.
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)
iterator begin() const
Definition: Type.h:4235
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.
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:44
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
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
iterator end() 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)
bool operator<(const FileID &RHS) const
SourceRange(SourceLocation begin, SourceLocation end)
Represents an unpacked "presumed" location which can be presented to the user.
const SourceManager & SM
Definition: Format.cpp:1184
__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:75
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
FullSourceLoc()
Creates a FullSourceLoc where isValid() returns false.
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
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.
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:312
detail::InMemoryDirectory::const_iterator E
static clang::FileID getEmptyKey()
bool operator!=(const FileID &RHS) const
FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
bool isInvalid() const
bool operator==(const FileID &RHS) 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:12171
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:84
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