blob: 0bbeffefc725eff2c827892a9076066c1eb9c4e5 [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//===----------------------------------------------------------------------===//
9//
10// This file defines the SourceLocation class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_SOURCELOCATION_H
15#define LLVM_CLANG_SOURCELOCATION_H
16
Ted Kremenek3632a352009-01-28 20:46:26 +000017#include <utility>
Chris Lattnerae50fa02009-03-05 00:00:31 +000018#include <cassert>
Chris Lattner9dc1f532007-07-20 16:37:10 +000019
Ted Kremenek9c728dc2007-12-12 22:39:36 +000020namespace llvm {
Chris Lattner2b2453a2009-01-17 06:22:33 +000021 class MemoryBuffer;
Chris Lattnerae50fa02009-03-05 00:00:31 +000022 class raw_ostream;
Benjamin Kramerceafc4b2010-03-16 14:48:07 +000023 class StringRef;
Chris Lattner2b2453a2009-01-17 06:22:33 +000024 template <typename T> struct DenseMapInfo;
Chris Lattner06159e82009-12-15 07:26:51 +000025 template <typename T> struct isPodLike;
Ted Kremenek9c728dc2007-12-12 22:39:36 +000026}
27
Reid Spencer5f016e22007-07-11 17:01:13 +000028namespace clang {
Mike Stump1eb44332009-09-09 15:08:12 +000029
Ted Kremeneka9793ed2007-12-12 18:16:46 +000030class SourceManager;
Mike Stump1eb44332009-09-09 15:08:12 +000031
Chris Lattner2b2453a2009-01-17 06:22:33 +000032/// FileID - This is an opaque identifier used by SourceManager which refers to
33/// a source file (MemoryBuffer) along with its #include path and #line data.
34///
35class FileID {
36 /// ID - Opaque identifier, 0 is "invalid".
37 unsigned ID;
38public:
39 FileID() : ID(0) {}
Mike Stump1eb44332009-09-09 15:08:12 +000040
Chris Lattner2b2453a2009-01-17 06:22:33 +000041 bool isInvalid() const { return ID == 0; }
Mike Stump1eb44332009-09-09 15:08:12 +000042
Chris Lattner2b2453a2009-01-17 06:22:33 +000043 bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
44 bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
45 bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
46 bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
47 bool operator>(const FileID &RHS) const { return RHS < *this; }
48 bool operator>=(const FileID &RHS) const { return RHS <= *this; }
Mike Stump1eb44332009-09-09 15:08:12 +000049
Chris Lattnerde7aeef2009-01-26 00:43:02 +000050 static FileID getSentinel() { return get(~0U); }
Chris Lattner2b2453a2009-01-17 06:22:33 +000051 unsigned getHashValue() const { return ID; }
Mike Stump1eb44332009-09-09 15:08:12 +000052
Chris Lattner2b2453a2009-01-17 06:22:33 +000053private:
54 friend class SourceManager;
Chris Lattnerde7aeef2009-01-26 00:43:02 +000055 static FileID get(unsigned V) {
Chris Lattner2b2453a2009-01-17 06:22:33 +000056 FileID F;
57 F.ID = V;
58 return F;
59 }
60 unsigned getOpaqueValue() const { return ID; }
61};
Mike Stump1eb44332009-09-09 15:08:12 +000062
63
Reid Spencer5f016e22007-07-11 17:01:13 +000064/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes
65/// a full include stack, line and column number information for a position in
66/// an input translation unit.
67class SourceLocation {
68 unsigned ID;
Chris Lattnerbcc2a672009-01-19 06:46:35 +000069 friend class SourceManager;
Reid Spencer5f016e22007-07-11 17:01:13 +000070 enum {
Chris Lattnerde7aeef2009-01-26 00:43:02 +000071 MacroIDBit = 1U << 31
Reid Spencer5f016e22007-07-11 17:01:13 +000072 };
Chris Lattner9ebac5e2009-01-19 06:57:37 +000073public:
Reid Spencer5f016e22007-07-11 17:01:13 +000074
75 SourceLocation() : ID(0) {} // 0 is an invalid FileID.
Mike Stump1eb44332009-09-09 15:08:12 +000076
Chris Lattnerde7aeef2009-01-26 00:43:02 +000077 bool isFileID() const { return (ID & MacroIDBit) == 0; }
78 bool isMacroID() const { return (ID & MacroIDBit) != 0; }
Mike Stump1eb44332009-09-09 15:08:12 +000079
Chris Lattnerb7489d82007-11-09 23:52:16 +000080 /// isValid - Return true if this is a valid SourceLocation object. Invalid
81 /// SourceLocations are often used when events have no corresponding location
82 /// in the source (e.g. a diagnostic is required for a command line option).
83 ///
84 bool isValid() const { return ID != 0; }
85 bool isInvalid() const { return ID == 0; }
Mike Stump1eb44332009-09-09 15:08:12 +000086
Chris Lattner6fda54c2009-01-19 07:00:35 +000087private:
Chris Lattnerde7aeef2009-01-26 00:43:02 +000088 /// getOffset - Return the index for SourceManager's SLocEntryTable table,
89 /// note that this is not an index *into* it though.
90 unsigned getOffset() const {
91 return ID & ~MacroIDBit;
Chris Lattner4d10ef12009-01-19 06:55:08 +000092 }
Chris Lattner6fda54c2009-01-19 07:00:35 +000093
Chris Lattnerde7aeef2009-01-26 00:43:02 +000094 static SourceLocation getFileLoc(unsigned ID) {
95 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
Chris Lattner9dc1f532007-07-20 16:37:10 +000096 SourceLocation L;
Chris Lattnerde7aeef2009-01-26 00:43:02 +000097 L.ID = ID;
Chris Lattner9dc1f532007-07-20 16:37:10 +000098 return L;
Reid Spencer5f016e22007-07-11 17:01:13 +000099 }
Mike Stump1eb44332009-09-09 15:08:12 +0000100
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000101 static SourceLocation getMacroLoc(unsigned ID) {
102 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
Chris Lattnerd1623a82007-07-21 06:41:57 +0000103 SourceLocation L;
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000104 L.ID = MacroIDBit | ID;
Chris Lattner9dc1f532007-07-20 16:37:10 +0000105 return L;
106 }
Chris Lattner4d10ef12009-01-19 06:55:08 +0000107public:
Mike Stump1eb44332009-09-09 15:08:12 +0000108
Chris Lattner9dc1f532007-07-20 16:37:10 +0000109 /// getFileLocWithOffset - Return a source location with the specified offset
110 /// from this file SourceLocation.
Chris Lattnerd1623a82007-07-21 06:41:57 +0000111 SourceLocation getFileLocWithOffset(int Offset) const {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000112 assert(((getOffset()+Offset) & MacroIDBit) == 0 && "invalid location");
113 SourceLocation L;
114 L.ID = ID+Offset;
115 return L;
Chris Lattner9dc1f532007-07-20 16:37:10 +0000116 }
Mike Stump1eb44332009-09-09 15:08:12 +0000117
Reid Spencer5f016e22007-07-11 17:01:13 +0000118 /// getRawEncoding - When a SourceLocation itself cannot be used, this returns
119 /// an (opaque) 32-bit integer encoding for it. This should only be passed
120 /// to SourceLocation::getFromRawEncoding, it should not be inspected
121 /// directly.
122 unsigned getRawEncoding() const { return ID; }
Mike Stump1eb44332009-09-09 15:08:12 +0000123
124
Reid Spencer5f016e22007-07-11 17:01:13 +0000125 /// getFromRawEncoding - Turn a raw encoding of a SourceLocation object into
126 /// a real SourceLocation.
127 static SourceLocation getFromRawEncoding(unsigned Encoding) {
128 SourceLocation X;
129 X.ID = Encoding;
130 return X;
131 }
Mike Stump1eb44332009-09-09 15:08:12 +0000132
Chris Lattnerae50fa02009-03-05 00:00:31 +0000133 void print(llvm::raw_ostream &OS, const SourceManager &SM) const;
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000134 void dump(const SourceManager &SM) const;
Reid Spencer5f016e22007-07-11 17:01:13 +0000135};
136
137inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
138 return LHS.getRawEncoding() == RHS.getRawEncoding();
139}
140
141inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
142 return !(LHS == RHS);
143}
Mike Stump1eb44332009-09-09 15:08:12 +0000144
Chris Lattner6fda54c2009-01-19 07:00:35 +0000145inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
146 return LHS.getRawEncoding() < RHS.getRawEncoding();
147}
Reid Spencer5f016e22007-07-11 17:01:13 +0000148
149/// SourceRange - a trival tuple used to represent a source range.
150class SourceRange {
151 SourceLocation B;
152 SourceLocation E;
153public:
154 SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
155 SourceRange(SourceLocation loc) : B(loc), E(loc) {}
156 SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
Mike Stump1eb44332009-09-09 15:08:12 +0000157
Chris Lattner311ff022007-10-16 22:36:42 +0000158 SourceLocation getBegin() const { return B; }
159 SourceLocation getEnd() const { return E; }
Mike Stump1eb44332009-09-09 15:08:12 +0000160
Chris Lattnere80a59c2007-07-25 00:24:17 +0000161 void setBegin(SourceLocation b) { B = b; }
162 void setEnd(SourceLocation e) { E = e; }
Mike Stump1eb44332009-09-09 15:08:12 +0000163
Reid Spencer5f016e22007-07-11 17:01:13 +0000164 bool isValid() const { return B.isValid() && E.isValid(); }
Ted Kremenek782f2f52010-01-07 01:20:12 +0000165 bool isInvalid() const { return !isValid(); }
Mike Stump1eb44332009-09-09 15:08:12 +0000166
Ted Kremeneka8982832009-03-28 17:32:39 +0000167 bool operator==(const SourceRange &X) const {
168 return B == X.B && E == X.E;
169 }
Mike Stump1eb44332009-09-09 15:08:12 +0000170
Ted Kremeneka8982832009-03-28 17:32:39 +0000171 bool operator!=(const SourceRange &X) const {
172 return B != X.B || E != X.E;
173 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000174};
Mike Stump1eb44332009-09-09 15:08:12 +0000175
Chris Lattnera50bd542009-01-16 23:03:56 +0000176/// FullSourceLoc - A SourceLocation and its associated SourceManager. Useful
177/// for argument passing to functions that expect both objects.
178class FullSourceLoc : public SourceLocation {
Chris Lattner5c5db4e2010-04-20 20:49:23 +0000179 const SourceManager *SrcMgr;
Ted Kremeneka9793ed2007-12-12 18:16:46 +0000180public:
Ted Kremenek3632a352009-01-28 20:46:26 +0000181 /// Creates a FullSourceLoc where isValid() returns false.
Chris Lattner5c5db4e2010-04-20 20:49:23 +0000182 explicit FullSourceLoc() : SrcMgr(0) {}
Ted Kremeneka9793ed2007-12-12 18:16:46 +0000183
Chris Lattner5c5db4e2010-04-20 20:49:23 +0000184 explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
Chris Lattnera50bd542009-01-16 23:03:56 +0000185 : SourceLocation(Loc), SrcMgr(&SM) {}
Mike Stump1eb44332009-09-09 15:08:12 +0000186
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000187 const SourceManager &getManager() const {
188 assert(SrcMgr && "SourceManager is NULL.");
Ted Kremeneka9793ed2007-12-12 18:16:46 +0000189 return *SrcMgr;
190 }
Mike Stump1eb44332009-09-09 15:08:12 +0000191
Chris Lattner3b4d5e92009-01-17 08:45:21 +0000192 FileID getFileID() const;
Mike Stump1eb44332009-09-09 15:08:12 +0000193
Chris Lattnerf7cf85b2009-01-16 07:36:28 +0000194 FullSourceLoc getInstantiationLoc() const;
Chris Lattnerdf7c17a2009-01-16 07:00:02 +0000195 FullSourceLoc getSpellingLoc() const;
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000196
Douglas Gregor64e462d2010-03-16 20:53:17 +0000197 unsigned getInstantiationLineNumber(bool *Invalid = 0) const;
198 unsigned getInstantiationColumnNumber(bool *Invalid = 0) const;
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000199
Douglas Gregor64e462d2010-03-16 20:53:17 +0000200 unsigned getSpellingLineNumber(bool *Invalid = 0) const;
201 unsigned getSpellingColumnNumber(bool *Invalid = 0) const;
Chris Lattner5c38b632008-09-29 21:46:13 +0000202
Douglas Gregora5430162010-03-16 20:46:42 +0000203 const char *getCharacterData(bool *Invalid = 0) const;
Mike Stump1eb44332009-09-09 15:08:12 +0000204
Douglas Gregoraae58b02010-03-16 20:01:30 +0000205 const llvm::MemoryBuffer* getBuffer(bool *Invalid = 0) const;
Mike Stump1eb44332009-09-09 15:08:12 +0000206
Benjamin Kramerceafc4b2010-03-16 14:48:07 +0000207 /// getBufferData - Return a StringRef to the source buffer data for the
208 /// specified FileID.
Douglas Gregoraae58b02010-03-16 20:01:30 +0000209 llvm::StringRef getBufferData(bool *Invalid = 0) const;
Mike Stump1eb44332009-09-09 15:08:12 +0000210
Ted Kremenek321abd42009-03-10 05:13:43 +0000211 /// getDecomposedLoc - Decompose the specified location into a raw FileID +
212 /// Offset pair. The first element is the FileID, the second is the
213 /// offset from the start of the buffer of the location.
214 std::pair<FileID, unsigned> getDecomposedLoc() const;
215
Nico Weber7bfaaae2008-08-10 19:59:06 +0000216 bool isInSystemHeader() const;
Mike Stump1eb44332009-09-09 15:08:12 +0000217
Chris Lattner5c38b632008-09-29 21:46:13 +0000218 /// Prints information about this FullSourceLoc to stderr. Useful for
219 /// debugging.
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000220 void dump() const { SourceLocation::dump(*SrcMgr); }
Douglas Gregor0b7a1582009-01-17 00:42:38 +0000221
Mike Stump1eb44332009-09-09 15:08:12 +0000222 friend inline bool
Douglas Gregor0b7a1582009-01-17 00:42:38 +0000223 operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
224 return LHS.getRawEncoding() == RHS.getRawEncoding() &&
225 LHS.SrcMgr == RHS.SrcMgr;
226 }
227
Mike Stump1eb44332009-09-09 15:08:12 +0000228 friend inline bool
Douglas Gregor0b7a1582009-01-17 00:42:38 +0000229 operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
230 return !(LHS == RHS);
231 }
232
Ted Kremeneka9793ed2007-12-12 18:16:46 +0000233};
Mike Stump1eb44332009-09-09 15:08:12 +0000234
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000235/// PresumedLoc - This class represents an unpacked "presumed" location which
236/// can be presented to the user. A 'presumed' location can be modified by
237/// #line and GNU line marker directives and is always the instantiation point
238/// of a normal location.
239///
240/// You can get a PresumedLoc from a SourceLocation with SourceManager.
241class PresumedLoc {
242 const char *Filename;
243 unsigned Line, Col;
244 SourceLocation IncludeLoc;
245public:
246 PresumedLoc() : Filename(0) {}
247 PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
248 : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
249 }
Mike Stump1eb44332009-09-09 15:08:12 +0000250
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000251 /// isInvalid - Return true if this object is invalid or uninitialized. This
252 /// occurs when created with invalid source locations or when walking off
253 /// the top of a #include stack.
254 bool isInvalid() const { return Filename == 0; }
255 bool isValid() const { return Filename != 0; }
Mike Stump1eb44332009-09-09 15:08:12 +0000256
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000257 /// getFilename - Return the presumed filename of this location. This can be
258 /// affected by #line etc.
259 const char *getFilename() const { return Filename; }
260
261 /// getLine - Return the presumed line number of this location. This can be
262 /// affected by #line etc.
263 unsigned getLine() const { return Line; }
Mike Stump1eb44332009-09-09 15:08:12 +0000264
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000265 /// getColumn - Return the presumed column number of this location. This can
266 /// not be affected by #line, but is packaged here for convenience.
267 unsigned getColumn() const { return Col; }
268
269 /// getIncludeLoc - Return the presumed include location of this location.
270 /// This can be affected by GNU linemarker directives.
271 SourceLocation getIncludeLoc() const { return IncludeLoc; }
272};
273
Mike Stump1eb44332009-09-09 15:08:12 +0000274
Reid Spencer5f016e22007-07-11 17:01:13 +0000275} // end namespace clang
276
Chris Lattner2b2453a2009-01-17 06:22:33 +0000277namespace llvm {
278 /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
279 /// DenseSets.
280 template <>
281 struct DenseMapInfo<clang::FileID> {
282 static inline clang::FileID getEmptyKey() {
283 return clang::FileID();
284 }
285 static inline clang::FileID getTombstoneKey() {
Mike Stump1eb44332009-09-09 15:08:12 +0000286 return clang::FileID::getSentinel();
Chris Lattner2b2453a2009-01-17 06:22:33 +0000287 }
Mike Stump1eb44332009-09-09 15:08:12 +0000288
Chris Lattner2b2453a2009-01-17 06:22:33 +0000289 static unsigned getHashValue(clang::FileID S) {
290 return S.getHashValue();
291 }
Mike Stump1eb44332009-09-09 15:08:12 +0000292
Chris Lattner2b2453a2009-01-17 06:22:33 +0000293 static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
294 return LHS == RHS;
295 }
Chris Lattner2b2453a2009-01-17 06:22:33 +0000296 };
Chris Lattner06159e82009-12-15 07:26:51 +0000297
298 template <>
299 struct isPodLike<clang::SourceLocation> { static const bool value = true; };
300 template <>
301 struct isPodLike<clang::FileID> { static const bool value = true; };
Mike Stump1eb44332009-09-09 15:08:12 +0000302
Chris Lattner2b2453a2009-01-17 06:22:33 +0000303} // end namespace llvm
304
Reid Spencer5f016e22007-07-11 17:01:13 +0000305#endif