blob: 7b637d7e1fb32db9c6e0e00faff452878092e9e4 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- SourceLocation.h - Compact identifier for Source Files -*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
James Dennett2f7f5b12012-07-02 07:01:42 +00009///
10/// \file
11/// \brief Defines the clang::SourceLocation class and associated facilities.
12///
Reid Spencer5f016e22007-07-11 17:01:13 +000013//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_SOURCELOCATION_H
16#define LLVM_CLANG_SOURCELOCATION_H
17
Chris Lattner686775d2011-07-20 06:58:45 +000018#include "clang/Basic/LLVM.h"
Argyrios Kyrtzidis0ee7d942012-02-21 05:04:44 +000019#include "llvm/Support/Compiler.h"
Chandler Carruth30a2e162012-12-04 09:18:49 +000020#include "llvm/Support/PointerLikeTypeTraits.h"
Chris Lattnerae50fa02009-03-05 00:00:31 +000021#include <cassert>
Chandler Carruth30a2e162012-12-04 09:18:49 +000022#include <functional>
Chad Rosierb328ee52012-11-09 20:00:52 +000023#include <string>
Chandler Carruth30a2e162012-12-04 09:18:49 +000024#include <utility>
Chris Lattner9dc1f532007-07-20 16:37:10 +000025
Ted Kremenek9c728dc2007-12-12 22:39:36 +000026namespace llvm {
Chris Lattner2b2453a2009-01-17 06:22:33 +000027 class MemoryBuffer;
28 template <typename T> struct DenseMapInfo;
Chris Lattner06159e82009-12-15 07:26:51 +000029 template <typename T> struct isPodLike;
Ted Kremenek9c728dc2007-12-12 22:39:36 +000030}
31
Reid Spencer5f016e22007-07-11 17:01:13 +000032namespace clang {
Mike Stump1eb44332009-09-09 15:08:12 +000033
Ted Kremeneka9793ed2007-12-12 18:16:46 +000034class SourceManager;
Mike Stump1eb44332009-09-09 15:08:12 +000035
James Dennett4bd495c2012-06-22 05:43:45 +000036/// \brief An opaque identifier used by SourceManager which refers to a
37/// source file (MemoryBuffer) along with its \#include path and \#line data.
Chris Lattner2b2453a2009-01-17 06:22:33 +000038///
39class FileID {
James Dennettaf50aab2012-07-02 23:17:34 +000040 /// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is
41 /// this module, and <-1 is something loaded from another module.
Douglas Gregorf62d43d2011-07-19 16:10:42 +000042 int ID;
Chris Lattner2b2453a2009-01-17 06:22:33 +000043public:
44 FileID() : ID(0) {}
Mike Stump1eb44332009-09-09 15:08:12 +000045
Chris Lattner2b2453a2009-01-17 06:22:33 +000046 bool isInvalid() const { return ID == 0; }
Mike Stump1eb44332009-09-09 15:08:12 +000047
Chris Lattner2b2453a2009-01-17 06:22:33 +000048 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; }
Mike Stump1eb44332009-09-09 15:08:12 +000054
Douglas Gregorf62d43d2011-07-19 16:10:42 +000055 static FileID getSentinel() { return get(-1); }
56 unsigned getHashValue() const { return static_cast<unsigned>(ID); }
Mike Stump1eb44332009-09-09 15:08:12 +000057
Chris Lattner2b2453a2009-01-17 06:22:33 +000058private:
59 friend class SourceManager;
Douglas Gregor31d375f2011-05-06 21:43:30 +000060 friend class ASTWriter;
61 friend class ASTReader;
62
Douglas Gregorf62d43d2011-07-19 16:10:42 +000063 static FileID get(int V) {
Chris Lattner2b2453a2009-01-17 06:22:33 +000064 FileID F;
65 F.ID = V;
66 return F;
67 }
Douglas Gregorf62d43d2011-07-19 16:10:42 +000068 int getOpaqueValue() const { return ID; }
Chris Lattner2b2453a2009-01-17 06:22:33 +000069};
Mike Stump1eb44332009-09-09 15:08:12 +000070
71
Douglas Gregorf62d43d2011-07-19 16:10:42 +000072/// \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
Chandler Carruth3201f382011-07-26 05:17:23 +000077/// 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,
Douglas Gregorf62d43d2011-07-19 16:10:42 +000080/// 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
Chandler Carruth3201f382011-07-26 05:17:23 +000084/// information whether the location is in a file or a macro expansion.
Douglas Gregorf62d43d2011-07-19 16:10:42 +000085///
86/// It is important that this type remains small. It is currently 32 bits wide.
Reid Spencer5f016e22007-07-11 17:01:13 +000087class SourceLocation {
88 unsigned ID;
Chris Lattnerbcc2a672009-01-19 06:46:35 +000089 friend class SourceManager;
Argyrios Kyrtzidis5a437482011-09-19 20:40:08 +000090 friend class ASTReader;
91 friend class ASTWriter;
Stephen Hines651f13c2014-04-23 16:59:28 -070092 enum : unsigned {
Chris Lattnerde7aeef2009-01-26 00:43:02 +000093 MacroIDBit = 1U << 31
Reid Spencer5f016e22007-07-11 17:01:13 +000094 };
Chris Lattner9ebac5e2009-01-19 06:57:37 +000095public:
Reid Spencer5f016e22007-07-11 17:01:13 +000096
Douglas Gregorf62d43d2011-07-19 16:10:42 +000097 SourceLocation() : ID(0) {}
Mike Stump1eb44332009-09-09 15:08:12 +000098
Chris Lattnerde7aeef2009-01-26 00:43:02 +000099 bool isFileID() const { return (ID & MacroIDBit) == 0; }
100 bool isMacroID() const { return (ID & MacroIDBit) != 0; }
Mike Stump1eb44332009-09-09 15:08:12 +0000101
Douglas Gregorf62d43d2011-07-19 16:10:42 +0000102 /// \brief Return true if this is a valid SourceLocation object.
Chris Lattnerb7489d82007-11-09 23:52:16 +0000103 ///
Douglas Gregorf62d43d2011-07-19 16:10:42 +0000104 /// Invalid SourceLocations are often used when events have no corresponding
105 /// location in the source (e.g. a diagnostic is required for a command line
106 /// option).
Chris Lattnerb7489d82007-11-09 23:52:16 +0000107 bool isValid() const { return ID != 0; }
108 bool isInvalid() const { return ID == 0; }
Mike Stump1eb44332009-09-09 15:08:12 +0000109
Chris Lattner6fda54c2009-01-19 07:00:35 +0000110private:
Douglas Gregorf62d43d2011-07-19 16:10:42 +0000111 /// \brief Return the offset into the manager's global input view.
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000112 unsigned getOffset() const {
113 return ID & ~MacroIDBit;
Chris Lattner4d10ef12009-01-19 06:55:08 +0000114 }
Chris Lattner6fda54c2009-01-19 07:00:35 +0000115
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000116 static SourceLocation getFileLoc(unsigned ID) {
117 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
Chris Lattner9dc1f532007-07-20 16:37:10 +0000118 SourceLocation L;
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000119 L.ID = ID;
Chris Lattner9dc1f532007-07-20 16:37:10 +0000120 return L;
Reid Spencer5f016e22007-07-11 17:01:13 +0000121 }
Mike Stump1eb44332009-09-09 15:08:12 +0000122
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000123 static SourceLocation getMacroLoc(unsigned ID) {
124 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
Chris Lattnerd1623a82007-07-21 06:41:57 +0000125 SourceLocation L;
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000126 L.ID = MacroIDBit | ID;
Chris Lattner9dc1f532007-07-20 16:37:10 +0000127 return L;
128 }
Chris Lattner4d10ef12009-01-19 06:55:08 +0000129public:
Mike Stump1eb44332009-09-09 15:08:12 +0000130
Argyrios Kyrtzidisa64ccef2011-09-19 20:40:19 +0000131 /// \brief Return a source location with the specified offset from this
132 /// SourceLocation.
133 SourceLocation getLocWithOffset(int Offset) const {
134 assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000135 SourceLocation L;
136 L.ID = ID+Offset;
137 return L;
Chris Lattner9dc1f532007-07-20 16:37:10 +0000138 }
Mike Stump1eb44332009-09-09 15:08:12 +0000139
James Dennett4bd495c2012-06-22 05:43:45 +0000140 /// \brief When a SourceLocation itself cannot be used, this returns
141 /// an (opaque) 32-bit integer encoding for it.
142 ///
143 /// This should only be passed to SourceLocation::getFromRawEncoding, it
144 /// should not be inspected directly.
Reid Spencer5f016e22007-07-11 17:01:13 +0000145 unsigned getRawEncoding() const { return ID; }
Mike Stump1eb44332009-09-09 15:08:12 +0000146
James Dennett4bd495c2012-06-22 05:43:45 +0000147 /// \brief Turn a raw encoding of a SourceLocation object into
Reid Spencer5f016e22007-07-11 17:01:13 +0000148 /// a real SourceLocation.
James Dennett4bd495c2012-06-22 05:43:45 +0000149 ///
150 /// \see getRawEncoding.
Reid Spencer5f016e22007-07-11 17:01:13 +0000151 static SourceLocation getFromRawEncoding(unsigned Encoding) {
152 SourceLocation X;
153 X.ID = Encoding;
154 return X;
155 }
Mike Stump1eb44332009-09-09 15:08:12 +0000156
James Dennett4bd495c2012-06-22 05:43:45 +0000157 /// \brief When a SourceLocation itself cannot be used, this returns
158 /// an (opaque) pointer encoding for it.
159 ///
160 /// This should only be passed to SourceLocation::getFromPtrEncoding, it
161 /// should not be inspected directly.
Jeffrey Yasskindec09842011-01-18 02:00:16 +0000162 void* getPtrEncoding() const {
163 // Double cast to avoid a warning "cast to pointer from integer of different
164 // size".
165 return (void*)(uintptr_t)getRawEncoding();
166 }
167
James Dennett12160152013-02-16 07:45:22 +0000168 /// \brief Turn a pointer encoding of a SourceLocation object back
Jeffrey Yasskindec09842011-01-18 02:00:16 +0000169 /// into a real SourceLocation.
Jordan Rose4a0beb22012-07-06 22:00:04 +0000170 static SourceLocation getFromPtrEncoding(const void *Encoding) {
Jeffrey Yasskindec09842011-01-18 02:00:16 +0000171 return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
172 }
173
Chris Lattner8cc488f2011-07-20 07:06:53 +0000174 void print(raw_ostream &OS, const SourceManager &SM) const;
Stephen Hines651f13c2014-04-23 16:59:28 -0700175 std::string printToString(const SourceManager &SM) const;
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000176 void dump(const SourceManager &SM) const;
Reid Spencer5f016e22007-07-11 17:01:13 +0000177};
178
179inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
180 return LHS.getRawEncoding() == RHS.getRawEncoding();
181}
182
183inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
184 return !(LHS == RHS);
185}
Mike Stump1eb44332009-09-09 15:08:12 +0000186
Chris Lattner6fda54c2009-01-19 07:00:35 +0000187inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
188 return LHS.getRawEncoding() < RHS.getRawEncoding();
189}
Reid Spencer5f016e22007-07-11 17:01:13 +0000190
Stephen Hines651f13c2014-04-23 16:59:28 -0700191/// \brief A trivial tuple used to represent a source range.
Reid Spencer5f016e22007-07-11 17:01:13 +0000192class SourceRange {
193 SourceLocation B;
194 SourceLocation E;
195public:
196 SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
197 SourceRange(SourceLocation loc) : B(loc), E(loc) {}
198 SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
Mike Stump1eb44332009-09-09 15:08:12 +0000199
Chris Lattner311ff022007-10-16 22:36:42 +0000200 SourceLocation getBegin() const { return B; }
201 SourceLocation getEnd() const { return E; }
Mike Stump1eb44332009-09-09 15:08:12 +0000202
Chris Lattnere80a59c2007-07-25 00:24:17 +0000203 void setBegin(SourceLocation b) { B = b; }
204 void setEnd(SourceLocation e) { E = e; }
Mike Stump1eb44332009-09-09 15:08:12 +0000205
Reid Spencer5f016e22007-07-11 17:01:13 +0000206 bool isValid() const { return B.isValid() && E.isValid(); }
Ted Kremenek782f2f52010-01-07 01:20:12 +0000207 bool isInvalid() const { return !isValid(); }
Mike Stump1eb44332009-09-09 15:08:12 +0000208
Ted Kremeneka8982832009-03-28 17:32:39 +0000209 bool operator==(const SourceRange &X) const {
210 return B == X.B && E == X.E;
211 }
Mike Stump1eb44332009-09-09 15:08:12 +0000212
Ted Kremeneka8982832009-03-28 17:32:39 +0000213 bool operator!=(const SourceRange &X) const {
214 return B != X.B || E != X.E;
215 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000216};
Chris Lattner0a76aae2010-06-18 22:45:06 +0000217
James Dennettaf50aab2012-07-02 23:17:34 +0000218/// \brief Represents a character-granular source range.
219///
Chris Lattner0a76aae2010-06-18 22:45:06 +0000220/// The underlying SourceRange can either specify the starting/ending character
Michael Han1f19c762012-12-01 04:35:48 +0000221/// of the range, or it can specify the start of the range and the start of the
Chris Lattner0a76aae2010-06-18 22:45:06 +0000222/// last token of the range (a "token range"). In the token range case, the
223/// size of the last token must be measured to determine the actual end of the
224/// range.
225class CharSourceRange {
226 SourceRange Range;
227 bool IsTokenRange;
228public:
229 CharSourceRange() : IsTokenRange(false) {}
Nico Weber4a2ef802013-01-07 01:21:02 +0000230 CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
Chris Lattner0a76aae2010-06-18 22:45:06 +0000231
232 static CharSourceRange getTokenRange(SourceRange R) {
Nico Weber4a2ef802013-01-07 01:21:02 +0000233 return CharSourceRange(R, true);
Chris Lattner0a76aae2010-06-18 22:45:06 +0000234 }
235
236 static CharSourceRange getCharRange(SourceRange R) {
Nico Weber4a2ef802013-01-07 01:21:02 +0000237 return CharSourceRange(R, false);
Chris Lattner0a76aae2010-06-18 22:45:06 +0000238 }
239
240 static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) {
241 return getTokenRange(SourceRange(B, E));
242 }
243 static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) {
244 return getCharRange(SourceRange(B, E));
245 }
246
James Dennettaf50aab2012-07-02 23:17:34 +0000247 /// \brief Return true if the end of this range specifies the start of
Chris Lattner0a76aae2010-06-18 22:45:06 +0000248 /// the last token. Return false if the end of this range specifies the last
249 /// character in the range.
250 bool isTokenRange() const { return IsTokenRange; }
Argyrios Kyrtzidisa83f4d22012-02-03 05:58:29 +0000251 bool isCharRange() const { return !IsTokenRange; }
Chris Lattner0a76aae2010-06-18 22:45:06 +0000252
253 SourceLocation getBegin() const { return Range.getBegin(); }
254 SourceLocation getEnd() const { return Range.getEnd(); }
255 const SourceRange &getAsRange() const { return Range; }
256
257 void setBegin(SourceLocation b) { Range.setBegin(b); }
258 void setEnd(SourceLocation e) { Range.setEnd(e); }
259
260 bool isValid() const { return Range.isValid(); }
261 bool isInvalid() const { return !isValid(); }
262};
Mike Stump1eb44332009-09-09 15:08:12 +0000263
James Dennettaf50aab2012-07-02 23:17:34 +0000264/// \brief A SourceLocation and its associated SourceManager.
265///
266/// This is useful for argument passing to functions that expect both objects.
Chris Lattnera50bd542009-01-16 23:03:56 +0000267class FullSourceLoc : public SourceLocation {
Chris Lattner5c5db4e2010-04-20 20:49:23 +0000268 const SourceManager *SrcMgr;
Ted Kremeneka9793ed2007-12-12 18:16:46 +0000269public:
James Dennettaf50aab2012-07-02 23:17:34 +0000270 /// \brief Creates a FullSourceLoc where isValid() returns \c false.
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700271 explicit FullSourceLoc() : SrcMgr(nullptr) {}
Ted Kremeneka9793ed2007-12-12 18:16:46 +0000272
Chris Lattner5c5db4e2010-04-20 20:49:23 +0000273 explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
Chris Lattnera50bd542009-01-16 23:03:56 +0000274 : SourceLocation(Loc), SrcMgr(&SM) {}
Mike Stump1eb44332009-09-09 15:08:12 +0000275
James Dennettaf50aab2012-07-02 23:17:34 +0000276 /// \pre This FullSourceLoc has an associated SourceManager.
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000277 const SourceManager &getManager() const {
278 assert(SrcMgr && "SourceManager is NULL.");
Ted Kremeneka9793ed2007-12-12 18:16:46 +0000279 return *SrcMgr;
280 }
Mike Stump1eb44332009-09-09 15:08:12 +0000281
Chris Lattner3b4d5e92009-01-17 08:45:21 +0000282 FileID getFileID() const;
Mike Stump1eb44332009-09-09 15:08:12 +0000283
Chandler Carruth40278532011-07-25 16:49:02 +0000284 FullSourceLoc getExpansionLoc() const;
Chris Lattnerdf7c17a2009-01-16 07:00:02 +0000285 FullSourceLoc getSpellingLoc() const;
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000286
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700287 unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
288 unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000289
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700290 unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
291 unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
Chris Lattner5c38b632008-09-29 21:46:13 +0000292
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700293 const char *getCharacterData(bool *Invalid = nullptr) const;
Mike Stump1eb44332009-09-09 15:08:12 +0000294
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700295 const llvm::MemoryBuffer* getBuffer(bool *Invalid = nullptr) const;
Mike Stump1eb44332009-09-09 15:08:12 +0000296
James Dennettaf50aab2012-07-02 23:17:34 +0000297 /// \brief Return a StringRef to the source buffer data for the
Benjamin Kramerceafc4b2010-03-16 14:48:07 +0000298 /// specified FileID.
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700299 StringRef getBufferData(bool *Invalid = nullptr) const;
Mike Stump1eb44332009-09-09 15:08:12 +0000300
James Dennettaf50aab2012-07-02 23:17:34 +0000301 /// \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.
Ted Kremenek321abd42009-03-10 05:13:43 +0000305 std::pair<FileID, unsigned> getDecomposedLoc() const;
306
Nico Weber7bfaaae2008-08-10 19:59:06 +0000307 bool isInSystemHeader() const;
Mike Stump1eb44332009-09-09 15:08:12 +0000308
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000309 /// \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.
312 bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
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.
317 bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const {
318 assert(Loc.isValid());
319 assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
320 return isBeforeInTranslationUnitThan((SourceLocation)Loc);
321 }
322
Argyrios Kyrtzidis8f896522011-04-07 18:10:07 +0000323 /// \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
James Dennettaf50aab2012-07-02 23:17:34 +0000331 /// \brief Prints information about this FullSourceLoc to stderr.
332 ///
333 /// This is useful for debugging.
Stephen Hines651f13c2014-04-23 16:59:28 -0700334 void dump() const;
Douglas Gregor0b7a1582009-01-17 00:42:38 +0000335
Mike Stump1eb44332009-09-09 15:08:12 +0000336 friend inline bool
Douglas Gregor0b7a1582009-01-17 00:42:38 +0000337 operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
338 return LHS.getRawEncoding() == RHS.getRawEncoding() &&
339 LHS.SrcMgr == RHS.SrcMgr;
340 }
341
Mike Stump1eb44332009-09-09 15:08:12 +0000342 friend inline bool
Douglas Gregor0b7a1582009-01-17 00:42:38 +0000343 operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
344 return !(LHS == RHS);
345 }
346
Ted Kremeneka9793ed2007-12-12 18:16:46 +0000347};
Mike Stump1eb44332009-09-09 15:08:12 +0000348
James Dennettaf50aab2012-07-02 23:17:34 +0000349/// \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.
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000354///
355/// You can get a PresumedLoc from a SourceLocation with SourceManager.
356class PresumedLoc {
357 const char *Filename;
358 unsigned Line, Col;
359 SourceLocation IncludeLoc;
360public:
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700361 PresumedLoc() : Filename(nullptr) {}
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000362 PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
363 : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
364 }
Mike Stump1eb44332009-09-09 15:08:12 +0000365
James Dennettaf50aab2012-07-02 23:17:34 +0000366 /// \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.
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700370 bool isInvalid() const { return Filename == nullptr; }
371 bool isValid() const { return Filename != nullptr; }
Mike Stump1eb44332009-09-09 15:08:12 +0000372
James Dennett4bd495c2012-06-22 05:43:45 +0000373 /// \brief Return the presumed filename of this location.
374 ///
375 /// This can be affected by \#line etc.
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000376 const char *getFilename() const { return Filename; }
377
James Dennett4bd495c2012-06-22 05:43:45 +0000378 /// \brief Return the presumed line number of this location.
379 ///
380 /// This can be affected by \#line etc.
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000381 unsigned getLine() const { return Line; }
Mike Stump1eb44332009-09-09 15:08:12 +0000382
James Dennett4bd495c2012-06-22 05:43:45 +0000383 /// \brief Return the presumed column number of this location.
384 ///
385 /// This cannot be affected by \#line, but is packaged here for convenience.
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000386 unsigned getColumn() const { return Col; }
387
James Dennett4bd495c2012-06-22 05:43:45 +0000388 /// \brief Return the presumed include location of this location.
389 ///
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000390 /// This can be affected by GNU linemarker directives.
391 SourceLocation getIncludeLoc() const { return IncludeLoc; }
392};
393
Mike Stump1eb44332009-09-09 15:08:12 +0000394
Reid Spencer5f016e22007-07-11 17:01:13 +0000395} // end namespace clang
396
Chris Lattner2b2453a2009-01-17 06:22:33 +0000397namespace 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() {
Mike Stump1eb44332009-09-09 15:08:12 +0000406 return clang::FileID::getSentinel();
Chris Lattner2b2453a2009-01-17 06:22:33 +0000407 }
Mike Stump1eb44332009-09-09 15:08:12 +0000408
Chris Lattner2b2453a2009-01-17 06:22:33 +0000409 static unsigned getHashValue(clang::FileID S) {
410 return S.getHashValue();
411 }
Mike Stump1eb44332009-09-09 15:08:12 +0000412
Chris Lattner2b2453a2009-01-17 06:22:33 +0000413 static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
414 return LHS == RHS;
415 }
Chris Lattner2b2453a2009-01-17 06:22:33 +0000416 };
Chris Lattner06159e82009-12-15 07:26:51 +0000417
418 template <>
419 struct isPodLike<clang::SourceLocation> { static const bool value = true; };
420 template <>
421 struct isPodLike<clang::FileID> { static const bool value = true; };
Mike Stump1eb44332009-09-09 15:08:12 +0000422
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000423 // Teach SmallPtrSet how to handle SourceLocation.
424 template<>
425 class PointerLikeTypeTraits<clang::SourceLocation> {
426 public:
427 static inline void *getAsVoidPointer(clang::SourceLocation L) {
Jeffrey Yasskindec09842011-01-18 02:00:16 +0000428 return L.getPtrEncoding();
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000429 }
430 static inline clang::SourceLocation getFromVoidPointer(void *P) {
431 return clang::SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)P);
432 }
433 enum { NumLowBitsAvailable = 0 };
434 };
435
Chris Lattner2b2453a2009-01-17 06:22:33 +0000436} // end namespace llvm
437
Reid Spencer5f016e22007-07-11 17:01:13 +0000438#endif