clang  6.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/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 = 0;
43 
44 public:
45  bool isValid() const { return ID != 0; }
46  bool isInvalid() const { return ID == 0; }
47 
48  bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
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 !(*this == RHS); }
52  bool operator>(const FileID &RHS) const { return RHS < *this; }
53  bool operator>=(const FileID &RHS) const { return RHS <= *this; }
54 
55  static FileID getSentinel() { return get(-1); }
56  unsigned getHashValue() const { return static_cast<unsigned>(ID); }
57 
58 private:
59  friend class SourceManager;
60  friend class ASTWriter;
61  friend class ASTReader;
62 
63  static FileID get(int V) {
64  FileID F;
65  F.ID = V;
66  return F;
67  }
68  int getOpaqueValue() const { return ID; }
69 };
70 
71 
72 /// \brief Encodes a location in the source. The SourceManager can decode this
73 /// to get at the full include stack, line and column information.
74 ///
75 /// Technically, a source location is simply an offset into the manager's view
76 /// of the input source, which is all input buffers (including macro
77 /// expansions) concatenated in an effectively arbitrary order. The manager
78 /// actually maintains two blocks of input buffers. One, starting at offset
79 /// 0 and growing upwards, contains all buffers from this module. The other,
80 /// starting at the highest possible offset and growing downwards, contains
81 /// buffers of loaded modules.
82 ///
83 /// In addition, one bit of SourceLocation is used for quick access to the
84 /// information whether the location is in a file or a macro expansion.
85 ///
86 /// It is important that this type remains small. It is currently 32 bits wide.
88  unsigned ID = 0;
89  friend class SourceManager;
90  friend class ASTReader;
91  friend class ASTWriter;
92  enum : unsigned {
93  MacroIDBit = 1U << 31
94  };
95 
96 public:
97  bool isFileID() const { return (ID & MacroIDBit) == 0; }
98  bool isMacroID() const { return (ID & MacroIDBit) != 0; }
99 
100  /// \brief Return true if this is a valid SourceLocation object.
101  ///
102  /// Invalid SourceLocations are often used when events have no corresponding
103  /// location in the source (e.g. a diagnostic is required for a command line
104  /// option).
105  bool isValid() const { return ID != 0; }
106  bool isInvalid() const { return ID == 0; }
107 
108 private:
109  /// \brief Return the offset into the manager's global input view.
110  unsigned getOffset() const {
111  return ID & ~MacroIDBit;
112  }
113 
114  static SourceLocation getFileLoc(unsigned ID) {
115  assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
116  SourceLocation L;
117  L.ID = ID;
118  return L;
119  }
120 
121  static SourceLocation getMacroLoc(unsigned ID) {
122  assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
123  SourceLocation L;
124  L.ID = MacroIDBit | ID;
125  return L;
126  }
127 public:
128 
129  /// \brief Return a source location with the specified offset from this
130  /// SourceLocation.
132  assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
133  SourceLocation L;
134  L.ID = ID+Offset;
135  return L;
136  }
137 
138  /// \brief When a SourceLocation itself cannot be used, this returns
139  /// an (opaque) 32-bit integer encoding for it.
140  ///
141  /// This should only be passed to SourceLocation::getFromRawEncoding, it
142  /// should not be inspected directly.
143  unsigned getRawEncoding() const { return ID; }
144 
145  /// \brief Turn a raw encoding of a SourceLocation object into
146  /// a real SourceLocation.
147  ///
148  /// \see getRawEncoding.
151  X.ID = Encoding;
152  return X;
153  }
154 
155  /// \brief When a SourceLocation itself cannot be used, this returns
156  /// an (opaque) pointer encoding for it.
157  ///
158  /// This should only be passed to SourceLocation::getFromPtrEncoding, it
159  /// should not be inspected directly.
160  void* getPtrEncoding() const {
161  // Double cast to avoid a warning "cast to pointer from integer of different
162  // size".
163  return (void*)(uintptr_t)getRawEncoding();
164  }
165 
166  /// \brief Turn a pointer encoding of a SourceLocation object back
167  /// into a real SourceLocation.
169  return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
170  }
171 
173  return Start.isValid() && Start.isFileID() && End.isValid() &&
174  End.isFileID();
175  }
176 
177  void print(raw_ostream &OS, const SourceManager &SM) const;
178  std::string printToString(const SourceManager &SM) const;
179  void dump(const SourceManager &SM) const;
180 };
181 
182 inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
183  return LHS.getRawEncoding() == RHS.getRawEncoding();
184 }
185 
186 inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
187  return !(LHS == RHS);
188 }
189 
190 inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
191  return LHS.getRawEncoding() < RHS.getRawEncoding();
192 }
193 
194 /// \brief A trivial tuple used to represent a source range.
195 class SourceRange {
196  SourceLocation B;
197  SourceLocation E;
198 
199 public:
200  SourceRange() = default;
201  SourceRange(SourceLocation loc) : B(loc), E(loc) {}
202  SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
203 
204  SourceLocation getBegin() const { return B; }
205  SourceLocation getEnd() const { return E; }
206 
207  void setBegin(SourceLocation b) { B = b; }
208  void setEnd(SourceLocation e) { E = e; }
209 
210  bool isValid() const { return B.isValid() && E.isValid(); }
211  bool isInvalid() const { return !isValid(); }
212 
213  bool operator==(const SourceRange &X) const {
214  return B == X.B && E == X.E;
215  }
216 
217  bool operator!=(const SourceRange &X) const {
218  return B != X.B || E != X.E;
219  }
220 };
221 
222 /// \brief Represents a character-granular source range.
223 ///
224 /// The underlying SourceRange can either specify the starting/ending character
225 /// of the range, or it can specify the start of the range and the start of the
226 /// last token of the range (a "token range"). In the token range case, the
227 /// size of the last token must be measured to determine the actual end of the
228 /// range.
230  SourceRange Range;
231  bool IsTokenRange = false;
232 
233 public:
234  CharSourceRange() = default;
235  CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
236 
238  return CharSourceRange(R, true);
239  }
240 
242  return CharSourceRange(R, false);
243  }
244 
246  return getTokenRange(SourceRange(B, E));
247  }
249  return getCharRange(SourceRange(B, E));
250  }
251 
252  /// \brief Return true if the end of this range specifies the start of
253  /// the last token. Return false if the end of this range specifies the last
254  /// character in the range.
255  bool isTokenRange() const { return IsTokenRange; }
256  bool isCharRange() const { return !IsTokenRange; }
257 
258  SourceLocation getBegin() const { return Range.getBegin(); }
259  SourceLocation getEnd() const { return Range.getEnd(); }
260  SourceRange getAsRange() const { return Range; }
261 
262  void setBegin(SourceLocation b) { Range.setBegin(b); }
263  void setEnd(SourceLocation e) { Range.setEnd(e); }
264 
265  bool isValid() const { return Range.isValid(); }
266  bool isInvalid() const { return !isValid(); }
267 };
268 
269 /// \brief Represents an unpacked "presumed" location which can be presented
270 /// to the user.
271 ///
272 /// A 'presumed' location can be modified by \#line and GNU line marker
273 /// directives and is always the expansion point of a normal location.
274 ///
275 /// You can get a PresumedLoc from a SourceLocation with SourceManager.
276 class PresumedLoc {
277  const char *Filename;
278  unsigned Line, Col;
279  SourceLocation IncludeLoc;
280 
281 public:
282  PresumedLoc() : Filename(nullptr) {}
283  PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
284  : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {}
285 
286  /// \brief Return true if this object is invalid or uninitialized.
287  ///
288  /// This occurs when created with invalid source locations or when walking
289  /// off the top of a \#include stack.
290  bool isInvalid() const { return Filename == nullptr; }
291  bool isValid() const { return Filename != nullptr; }
292 
293  /// \brief Return the presumed filename of this location.
294  ///
295  /// This can be affected by \#line etc.
296  const char *getFilename() const {
297  assert(isValid());
298  return Filename;
299  }
300 
301  /// \brief Return the presumed line number of this location.
302  ///
303  /// This can be affected by \#line etc.
304  unsigned getLine() const {
305  assert(isValid());
306  return Line;
307  }
308 
309  /// \brief Return the presumed column number of this location.
310  ///
311  /// This cannot be affected by \#line, but is packaged here for convenience.
312  unsigned getColumn() const {
313  assert(isValid());
314  return Col;
315  }
316 
317  /// \brief Return the presumed include location of this location.
318  ///
319  /// This can be affected by GNU linemarker directives.
321  assert(isValid());
322  return IncludeLoc;
323  }
324 };
325 
326 class FileEntry;
327 
328 /// \brief A SourceLocation and its associated SourceManager.
329 ///
330 /// This is useful for argument passing to functions that expect both objects.
332  const SourceManager *SrcMgr = nullptr;
333 
334 public:
335  /// \brief Creates a FullSourceLoc where isValid() returns \c false.
336  FullSourceLoc() = default;
337 
339  : SourceLocation(Loc), SrcMgr(&SM) {}
340 
341  bool hasManager() const {
342  bool hasSrcMgr = SrcMgr != nullptr;
343  assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager");
344  return hasSrcMgr;
345  }
346 
347  /// \pre This FullSourceLoc has an associated SourceManager.
348  const SourceManager &getManager() const {
349  assert(SrcMgr && "SourceManager is NULL.");
350  return *SrcMgr;
351  }
352 
353  FileID getFileID() const;
354 
355  FullSourceLoc getExpansionLoc() const;
356  FullSourceLoc getSpellingLoc() const;
357  FullSourceLoc getFileLoc() const;
358  std::pair<FullSourceLoc, FullSourceLoc> getImmediateExpansionRange() const;
359  PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const;
360  bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const;
361  FullSourceLoc getImmediateMacroCallerLoc() const;
362  std::pair<FullSourceLoc, StringRef> getModuleImportLoc() const;
363  unsigned getFileOffset() const;
364 
365  unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
366  unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
367 
368  unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
369  unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
370 
371  const char *getCharacterData(bool *Invalid = nullptr) const;
372 
373  unsigned getLineNumber(bool *Invalid = nullptr) const;
374  unsigned getColumnNumber(bool *Invalid = nullptr) const;
375 
376  std::pair<FullSourceLoc, FullSourceLoc> getExpansionRange() const;
377 
378  const FileEntry *getFileEntry() const;
379 
380  /// \brief Return a StringRef to the source buffer data for the
381  /// specified FileID.
382  StringRef getBufferData(bool *Invalid = nullptr) const;
383 
384  /// \brief Decompose the specified location into a raw FileID + Offset pair.
385  ///
386  /// The first element is the FileID, the second is the offset from the
387  /// start of the buffer of the location.
388  std::pair<FileID, unsigned> getDecomposedLoc() const;
389 
390  bool isInSystemHeader() const;
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.
395  bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
396 
397  /// \brief Determines the order of 2 source locations in the translation unit.
398  ///
399  /// \returns true if this source location comes before 'Loc', false otherwise.
401  assert(Loc.isValid());
402  assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
403  return isBeforeInTranslationUnitThan((SourceLocation)Loc);
404  }
405 
406  /// \brief Comparison function class, useful for sorting FullSourceLocs.
408  bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
409  return lhs.isBeforeInTranslationUnitThan(rhs);
410  }
411  };
412 
413  /// \brief Prints information about this FullSourceLoc to stderr.
414  ///
415  /// This is useful for debugging.
416  void dump() const;
417 
418  friend inline bool
419  operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
420  return LHS.getRawEncoding() == RHS.getRawEncoding() &&
421  LHS.SrcMgr == RHS.SrcMgr;
422  }
423 
424  friend inline bool
425  operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
426  return !(LHS == RHS);
427  }
428 
429 };
430 
431 
432 
433 } // end namespace clang
434 
435 namespace llvm {
436  /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
437  /// DenseSets.
438  template <>
439  struct DenseMapInfo<clang::FileID> {
440  static inline clang::FileID getEmptyKey() {
441  return clang::FileID();
442  }
443  static inline clang::FileID getTombstoneKey() {
445  }
446 
447  static unsigned getHashValue(clang::FileID S) {
448  return S.getHashValue();
449  }
450 
451  static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
452  return LHS == RHS;
453  }
454  };
455 
456  template <>
457  struct isPodLike<clang::SourceLocation> { static const bool value = true; };
458  template <>
459  struct isPodLike<clang::FileID> { static const bool value = true; };
460 
461  // Teach SmallPtrSet how to handle SourceLocation.
462  template<>
463  struct PointerLikeTypeTraits<clang::SourceLocation> {
464  static inline void *getAsVoidPointer(clang::SourceLocation L) {
465  return L.getPtrEncoding();
466  }
469  }
470  enum { NumLowBitsAvailable = 0 };
471  };
472 
473 } // end namespace llvm
474 
475 #endif
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:1335
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:1327
__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:358
static clang::FileID getEmptyKey()
bool isMacroID() const
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:13194
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...