blob: d107b0bd7044bfc2719d72517f69619c5b8576bf [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//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
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
Chris Lattner9dc1f532007-07-20 16:37:10 +000017#include <cassert>
18
Reid Spencer5f016e22007-07-11 17:01:13 +000019namespace clang {
20
21/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes
22/// a full include stack, line and column number information for a position in
23/// an input translation unit.
24class SourceLocation {
25 unsigned ID;
26public:
27 enum {
28 FileIDBits = 14,
Chris Lattner9dc1f532007-07-20 16:37:10 +000029 FilePosBits = 32-1-FileIDBits,
30
31 MacroIDBits = 23,
32 MacroPhysOffsBits = 5,
33 MacroLogOffBits = 3
Reid Spencer5f016e22007-07-11 17:01:13 +000034 };
35
36 SourceLocation() : ID(0) {} // 0 is an invalid FileID.
37
Chris Lattner9dc1f532007-07-20 16:37:10 +000038 bool isFileID() const { return (ID >> 31) == 0; }
39 bool isMacroID() const { return (ID >> 31) != 0; }
40
41 static SourceLocation getFileLoc(unsigned FileID, unsigned FilePos) {
42 SourceLocation L;
Reid Spencer5f016e22007-07-11 17:01:13 +000043 // If a FilePos is larger than (1<<FilePosBits), the SourceManager makes
44 // enough consequtive FileIDs that we have one for each chunk.
45 if (FilePos >= (1 << FilePosBits)) {
46 FileID += FilePos >> FilePosBits;
47 FilePos &= (1 << FilePosBits)-1;
48 }
49
50 // FIXME: Find a way to handle out of FileID bits! Maybe MaxFileID is an
51 // escape of some sort?
52 if (FileID >= (1 << FileIDBits))
53 FileID = (1 << FileIDBits)-1;
54
Chris Lattner9dc1f532007-07-20 16:37:10 +000055 L.ID = (FileID << FilePosBits) | FilePos;
56 return L;
Reid Spencer5f016e22007-07-11 17:01:13 +000057 }
58
Chris Lattner9dc1f532007-07-20 16:37:10 +000059 static SourceLocation getMacroLoc(unsigned MacroID, unsigned PhysOffs,
60 unsigned LogOffs) {
61 SourceLocation L;
62
63 assert(MacroID < (1 << MacroIDBits) && "Too many macros!");
64 assert(PhysOffs < (1 << MacroPhysOffsBits) && "Physoffs too large!");
65 assert(LogOffs < (1 << MacroLogOffBits) && "Logical offs too large!");
66
67 L.ID = (1 << 31) | (MacroID << (MacroPhysOffsBits+MacroLogOffBits)) |
68 (PhysOffs << MacroLogOffBits) | LogOffs;
69 return L;
70 }
71
72
Reid Spencer5f016e22007-07-11 17:01:13 +000073 /// isValid - Return true if this is a valid SourceLocation object. Invalid
74 /// SourceLocations are often used when events have no corresponding location
75 /// in the source (e.g. a diagnostic is required for a command line option).
76 ///
77 bool isValid() const { return ID != 0; }
Chris Lattner9dc1f532007-07-20 16:37:10 +000078 bool isInvalid() const { return ID == 0; }
Reid Spencer5f016e22007-07-11 17:01:13 +000079
80 /// getFileID - Return the file identifier for this SourceLocation. This
81 /// FileID can be used with the SourceManager object to obtain an entire
82 /// include stack for a file position reference.
Chris Lattner9dc1f532007-07-20 16:37:10 +000083 unsigned getFileID() const {
84 assert(isFileID() && "can't get the file id of a non-file sloc!");
85 return ID >> FilePosBits;
86 }
Reid Spencer5f016e22007-07-11 17:01:13 +000087
88 /// getRawFilePos - Return the byte offset from the start of the file-chunk
89 /// referred to by FileID. This method should not be used to get the offset
90 /// from the start of the file, instead you should use
91 /// SourceManager::getFilePos. This method will be incorrect for large files.
Chris Lattner9dc1f532007-07-20 16:37:10 +000092 unsigned getRawFilePos() const {
93 assert(isFileID() && "can't get the file id of a non-file sloc!");
94 return ID & ((1 << FilePosBits)-1);
95 }
96
97 unsigned getMacroID() const {
98 assert(isMacroID() && "Is not a macro id!");
99 return (ID >> (MacroPhysOffsBits+MacroLogOffBits)) & ((1 << MacroIDBits)-1);
100 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000101
Chris Lattner9dc1f532007-07-20 16:37:10 +0000102 unsigned getMacroPhysOffs() const {
103 assert(isMacroID() && "Is not a macro id!");
104 return (ID >> MacroLogOffBits) & ((1 << MacroPhysOffsBits)-1);
105 }
106
107 unsigned getMacroLogOffs() const {
108 assert(isMacroID() && "Is not a macro id!");
109 return ID & ((1 << MacroPhysOffsBits)-1);
110 }
111
112 /// getFileLocWithOffset - Return a source location with the specified offset
113 /// from this file SourceLocation.
114 SourceLocation getFileLocWithOffset(unsigned Offset) const {
115 return getFileLoc(getFileID(), getRawFilePos()+Offset);
116 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000117
118 /// 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; }
123
124 /// getFromRawEncoding - Turn a raw encoding of a SourceLocation object into
125 /// a real SourceLocation.
126 static SourceLocation getFromRawEncoding(unsigned Encoding) {
127 SourceLocation X;
128 X.ID = Encoding;
129 return X;
130 }
131};
132
133inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
134 return LHS.getRawEncoding() == RHS.getRawEncoding();
135}
136
137inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
138 return !(LHS == RHS);
139}
140
141/// SourceRange - a trival tuple used to represent a source range.
142class SourceRange {
143 SourceLocation B;
144 SourceLocation E;
145public:
146 SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
147 SourceRange(SourceLocation loc) : B(loc), E(loc) {}
148 SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
149
150 SourceLocation Begin() const { return B; }
151 SourceLocation End() const { return E; }
152
153 bool isValid() const { return B.isValid() && E.isValid(); }
154};
155
156} // end namespace clang
157
158#endif