blob: a58662443d14bdc9331671fd54f62b23a32635da [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- SourceManager.h - Track and cache 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 SourceManager interface.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_SOURCEMANAGER_H
15#define LLVM_CLANG_SOURCEMANAGER_H
16
17#include "clang/Basic/SourceLocation.h"
Ted Kremenek78d85f52007-10-30 21:08:08 +000018#include "llvm/Bitcode/SerializationFwd.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000019#include <vector>
Ted Kremenek78d85f52007-10-30 21:08:08 +000020#include <set>
Reid Spencer5f016e22007-07-11 17:01:13 +000021#include <list>
Chris Lattner9dc62f02007-07-12 15:32:57 +000022#include <cassert>
Reid Spencer5f016e22007-07-11 17:01:13 +000023
24namespace llvm {
25class MemoryBuffer;
26}
27
28namespace clang {
29
30class SourceManager;
Ted Kremenek099b4742007-12-05 00:14:18 +000031class FileManager;
Reid Spencer5f016e22007-07-11 17:01:13 +000032class FileEntry;
33class IdentifierTokenInfo;
34
Chris Lattner0b9e7362008-09-26 21:18:42 +000035/// SrcMgr - Public enums and private classes that are part of the
36/// SourceManager implementation.
Reid Spencer5f016e22007-07-11 17:01:13 +000037///
38namespace SrcMgr {
Chris Lattner9d728512008-10-27 01:19:25 +000039 /// CharacteristicKind - This is used to represent whether a file or directory
Chris Lattner0b9e7362008-09-26 21:18:42 +000040 /// holds normal user code, system code, or system code which is implicitly
41 /// 'extern "C"' in C++ mode. Entire directories can be tagged with this
42 /// (this is maintained by DirectoryLookup and friends) as can specific
43 /// FileIDInfos when a #pragma system_header is seen or various other cases.
44 ///
Chris Lattner9d728512008-10-27 01:19:25 +000045 enum CharacteristicKind {
Chris Lattner0b9e7362008-09-26 21:18:42 +000046 C_User, C_System, C_ExternCSystem
47 };
48
Ted Kremenek78d85f52007-10-30 21:08:08 +000049 /// ContentCache - Once instance of this struct is kept for every file
Chris Lattner06a062d2009-01-19 08:02:45 +000050 /// loaded or used. This object owns the MemoryBuffer object.
Ted Kremenekc16c2082009-01-06 01:55:26 +000051 class ContentCache {
52 /// Buffer - The actual buffer containing the characters from the input
53 /// file. This is owned by the ContentCache object.
Chris Lattner05816592009-01-17 03:54:16 +000054 mutable const llvm::MemoryBuffer *Buffer;
Ted Kremenekc16c2082009-01-06 01:55:26 +000055
56 public:
Ted Kremenek78d85f52007-10-30 21:08:08 +000057 /// Reference to the file entry. This reference does not own
58 /// the FileEntry object. It is possible for this to be NULL if
59 /// the ContentCache encapsulates an imaginary text buffer.
Chris Lattner05816592009-01-17 03:54:16 +000060 const FileEntry *Entry;
Ted Kremenek78d85f52007-10-30 21:08:08 +000061
Reid Spencer5f016e22007-07-11 17:01:13 +000062 /// SourceLineCache - A new[]'d array of offsets for each source line. This
Ted Kremenekb6427f82007-12-04 18:59:28 +000063 /// is lazily computed. This is owned by the ContentCache object.
Chris Lattner05816592009-01-17 03:54:16 +000064 unsigned *SourceLineCache;
Reid Spencer5f016e22007-07-11 17:01:13 +000065
Ted Kremenekb6427f82007-12-04 18:59:28 +000066 /// NumLines - The number of lines in this ContentCache. This is only valid
67 /// if SourceLineCache is non-null.
Reid Spencer5f016e22007-07-11 17:01:13 +000068 unsigned NumLines;
Ted Kremenekc16c2082009-01-06 01:55:26 +000069
70 /// getBuffer - Returns the memory buffer for the associated content.
Chris Lattner05816592009-01-17 03:54:16 +000071 const llvm::MemoryBuffer *getBuffer() const;
Ted Kremenekc16c2082009-01-06 01:55:26 +000072
73 /// getSize - Returns the size of the content encapsulated by this
74 /// ContentCache. This can be the size of the source file or the size of an
75 /// arbitrary scratch buffer. If the ContentCache encapsulates a source
76 /// file this size is retrieved from the file's FileEntry.
77 unsigned getSize() const;
78
79 /// getSizeBytesMapped - Returns the number of bytes actually mapped for
80 /// this ContentCache. This can be 0 if the MemBuffer was not actually
81 /// instantiated.
82 unsigned getSizeBytesMapped() const;
83
Chris Lattner05816592009-01-17 03:54:16 +000084 void setBuffer(const llvm::MemoryBuffer *B) {
Ted Kremenekc16c2082009-01-06 01:55:26 +000085 assert(!Buffer && "MemoryBuffer already set.");
86 Buffer = B;
87 }
Ted Kremenek78d85f52007-10-30 21:08:08 +000088
Chris Lattner05816592009-01-17 03:54:16 +000089 ContentCache(const FileEntry *e = NULL)
Ted Kremenekc16c2082009-01-06 01:55:26 +000090 : Buffer(NULL), Entry(e), SourceLineCache(NULL), NumLines(0) {}
Ted Kremenek78d85f52007-10-30 21:08:08 +000091
92 ~ContentCache();
Ted Kremenek0d892d82007-10-30 22:57:35 +000093
94 /// The copy ctor does not allow copies where source object has either
95 /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
96 /// is not transfered, so this is a logical error.
Chris Lattner05816592009-01-17 03:54:16 +000097 ContentCache(const ContentCache &RHS) : Buffer(NULL),SourceLineCache(NULL) {
Ted Kremenek0d892d82007-10-30 22:57:35 +000098 Entry = RHS.Entry;
99
100 assert (RHS.Buffer == NULL && RHS.SourceLineCache == NULL
101 && "Passed ContentCache object cannot own a buffer.");
102
103 NumLines = RHS.NumLines;
104 }
105
Ted Kremeneke21272f2007-12-04 19:39:02 +0000106 /// Emit - Emit this ContentCache to Bitcode.
Chris Lattner05816592009-01-17 03:54:16 +0000107 void Emit(llvm::Serializer &S) const;
Ted Kremeneke21272f2007-12-04 19:39:02 +0000108
Ted Kremenek099b4742007-12-05 00:14:18 +0000109 /// ReadToSourceManager - Reconstitute a ContentCache from Bitcode
110 // and store it in the specified SourceManager.
Chris Lattner05816592009-01-17 03:54:16 +0000111 static void ReadToSourceManager(llvm::Deserializer &D, SourceManager &SM,
112 FileManager *FMgr, std::vector<char> &Buf);
Ted Kremenek099b4742007-12-05 00:14:18 +0000113
Ted Kremenek0d892d82007-10-30 22:57:35 +0000114 private:
115 // Disable assignments.
Chris Lattner05816592009-01-17 03:54:16 +0000116 ContentCache &operator=(const ContentCache& RHS);
Ted Kremenek78d85f52007-10-30 21:08:08 +0000117 };
Reid Spencer5f016e22007-07-11 17:01:13 +0000118
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000119 /// FileInfo - Information about a FileID, basically just the logical file
120 /// that it represents and include stack information.
Reid Spencer5f016e22007-07-11 17:01:13 +0000121 ///
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000122 /// Each FileInfo has include stack information, indicating where it came
123 /// from. This information encodes the #include chain that a token was
124 /// instantiated from. The main include file has an invalid IncludeLoc.
Reid Spencer5f016e22007-07-11 17:01:13 +0000125 ///
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000126 /// FileInfos contain a "ContentCache *", with the contents of the file.
Reid Spencer5f016e22007-07-11 17:01:13 +0000127 ///
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000128 class FileInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000129 /// IncludeLoc - The location of the #include that brought in this file.
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000130 /// This is an invalid SLOC for the main file (top of the #include chain).
131 unsigned IncludeLoc; // Really a SourceLocation
Chris Lattner9dc1f532007-07-20 16:37:10 +0000132
Chris Lattner6e1aff22009-01-26 06:49:09 +0000133 /// Data - This contains the ContentCache* and the bits indicating the
134 /// characteristic of the file and whether it has #line info, all bitmangled
135 /// together.
136 uintptr_t Data;
Ted Kremenek78d85f52007-10-30 21:08:08 +0000137 public:
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000138 /// get - Return a FileInfo object.
139 static FileInfo get(SourceLocation IL, const ContentCache *Con,
140 CharacteristicKind FileCharacter) {
141 FileInfo X;
142 X.IncludeLoc = IL.getRawEncoding();
Chris Lattner6e1aff22009-01-26 06:49:09 +0000143 X.Data = (uintptr_t)Con;
144 assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
145 assert((unsigned)FileCharacter < 4 && "invalid file character");
146 X.Data |= (unsigned)FileCharacter;
Reid Spencer5f016e22007-07-11 17:01:13 +0000147 return X;
148 }
149
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000150 SourceLocation getIncludeLoc() const {
151 return SourceLocation::getFromRawEncoding(IncludeLoc);
152 }
Chris Lattner6e1aff22009-01-26 06:49:09 +0000153 const ContentCache* getContentCache() const {
154 return reinterpret_cast<const ContentCache*>(Data & ~7UL);
155 }
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000156
Chris Lattner0b9e7362008-09-26 21:18:42 +0000157 /// getCharacteristic - Return whether this is a system header or not.
Chris Lattner9d728512008-10-27 01:19:25 +0000158 CharacteristicKind getFileCharacteristic() const {
Chris Lattner6e1aff22009-01-26 06:49:09 +0000159 return (CharacteristicKind)(Data & 3);
Chris Lattner0b9e7362008-09-26 21:18:42 +0000160 }
Chris Lattner9dc1f532007-07-20 16:37:10 +0000161 };
162
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000163 /// InstantiationInfo - Each InstantiationInfo encodes the Instantiation
164 /// location - where the token was ultimately instantiated, and the
165 /// SpellingLoc - where the actual character data for the token came from.
166 class InstantiationInfo {
167 unsigned InstantiationLoc, SpellingLoc; // Really these are SourceLocations.
Chris Lattner9dc1f532007-07-20 16:37:10 +0000168 public:
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000169 SourceLocation getInstantiationLoc() const {
170 return SourceLocation::getFromRawEncoding(InstantiationLoc);
171 }
172 SourceLocation getSpellingLoc() const {
173 return SourceLocation::getFromRawEncoding(SpellingLoc);
174 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000175
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000176 /// get - Return a InstantiationInfo for an expansion. VL specifies
Chris Lattnerdf7c17a2009-01-16 07:00:02 +0000177 /// the instantiation location (where the macro is expanded), and SL
178 /// specifies the spelling location (where the characters from the token
Chris Lattner18807d22007-11-09 23:59:17 +0000179 /// come from). Both VL and PL refer to normal File SLocs.
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000180 static InstantiationInfo get(SourceLocation IL, SourceLocation SL) {
181 InstantiationInfo X;
182 X.InstantiationLoc = IL.getRawEncoding();
183 X.SpellingLoc = SL.getRawEncoding();
Chris Lattner9dc1f532007-07-20 16:37:10 +0000184 return X;
Reid Spencer5f016e22007-07-11 17:01:13 +0000185 }
186 };
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000187
188 /// SLocEntry - This is a discriminated union of FileInfo and
189 /// InstantiationInfo. SourceManager keeps an array of these objects, and
190 /// they are uniquely identified by the FileID datatype.
191 class SLocEntry {
192 unsigned Offset; // low bit is set for instantiation info.
193 union {
194 FileInfo File;
195 InstantiationInfo Instantiation;
196 };
197 public:
198 unsigned getOffset() const { return Offset >> 1; }
199
200 bool isInstantiation() const { return Offset & 1; }
201 bool isFile() const { return !isInstantiation(); }
202
203 const FileInfo &getFile() const {
204 assert(isFile() && "Not a file SLocEntry!");
205 return File;
206 }
207
208 const InstantiationInfo &getInstantiation() const {
209 assert(isInstantiation() && "Not an instantiation SLocEntry!");
210 return Instantiation;
211 }
212
213 static SLocEntry get(unsigned Offset, const FileInfo &FI) {
214 SLocEntry E;
215 E.Offset = Offset << 1;
216 E.File = FI;
217 return E;
218 }
219
220 static SLocEntry get(unsigned Offset, const InstantiationInfo &II) {
221 SLocEntry E;
222 E.Offset = (Offset << 1) | 1;
223 E.Instantiation = II;
224 return E;
225 }
226 };
227
Reid Spencer5f016e22007-07-11 17:01:13 +0000228} // end SrcMgr namespace.
Ted Kremenek78d85f52007-10-30 21:08:08 +0000229} // end clang namespace
Reid Spencer5f016e22007-07-11 17:01:13 +0000230
Ted Kremenek78d85f52007-10-30 21:08:08 +0000231namespace std {
232template <> struct less<clang::SrcMgr::ContentCache> {
233 inline bool operator()(const clang::SrcMgr::ContentCache& L,
234 const clang::SrcMgr::ContentCache& R) const {
235 return L.Entry < R.Entry;
236 }
237};
238} // end std namespace
Reid Spencer5f016e22007-07-11 17:01:13 +0000239
Ted Kremenek78d85f52007-10-30 21:08:08 +0000240namespace clang {
241
Reid Spencer5f016e22007-07-11 17:01:13 +0000242/// SourceManager - This file handles loading and caching of source files into
243/// memory. This object owns the MemoryBuffer objects for all of the loaded
244/// files and assigns unique FileID's for each unique #include chain.
245///
246/// The SourceManager can be queried for information about SourceLocation
Chris Lattnerf7cf85b2009-01-16 07:36:28 +0000247/// objects, turning them into either spelling or instantiation locations.
248/// Spelling locations represent where the bytes corresponding to a token came
249/// from and instantiation locations represent where the location is in the
250/// user's view. In the case of a macro expansion, for example, the spelling
251/// location indicates where the expanded token came from and the instantiation
252/// location specifies where it was expanded.
Reid Spencer5f016e22007-07-11 17:01:13 +0000253class SourceManager {
254 /// FileInfos - Memoized information about all of the files tracked by this
Ted Kremenek0d892d82007-10-30 22:57:35 +0000255 /// SourceManager. This set allows us to merge ContentCache entries based
256 /// on their FileEntry*. All ContentCache objects will thus have unique,
257 /// non-null, FileEntry pointers.
Ted Kremenek78d85f52007-10-30 21:08:08 +0000258 std::set<SrcMgr::ContentCache> FileInfos;
Reid Spencer5f016e22007-07-11 17:01:13 +0000259
260 /// MemBufferInfos - Information about various memory buffers that we have
261 /// read in. This is a list, instead of a vector, because we need pointers to
Ted Kremenekb6427f82007-12-04 18:59:28 +0000262 /// the ContentCache objects to be stable. All FileEntry* within the
Ted Kremenek0d892d82007-10-30 22:57:35 +0000263 /// stored ContentCache objects are NULL, as they do not refer to a file.
Ted Kremenek78d85f52007-10-30 21:08:08 +0000264 std::list<SrcMgr::ContentCache> MemBufferInfos;
Reid Spencer5f016e22007-07-11 17:01:13 +0000265
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000266 /// SLocEntryTable - This is an array of SLocEntry's that we have created.
267 /// FileID is an index into this vector. This array is sorted by the offset.
268 std::vector<SrcMgr::SLocEntry> SLocEntryTable;
269 /// NextOffset - This is the next available offset that a new SLocEntry can
270 /// start at. It is SLocEntryTable.back().getOffset()+size of back() entry.
271 unsigned NextOffset;
Reid Spencer5f016e22007-07-11 17:01:13 +0000272
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000273 /// LastFileIDLookup - This is a one-entry cache to speed up getFileID.
274 /// LastFileIDLookup records the last FileID looked up or created, because it
275 /// is very common to look up many tokens from the same file.
276 mutable FileID LastFileIDLookup;
Chris Lattner9dc1f532007-07-20 16:37:10 +0000277
Chris Lattner5e36a7a2007-07-24 05:57:19 +0000278 /// LastLineNo - These ivars serve as a cache used in the getLineNumber
279 /// method which is used to speedup getLineNumber calls to nearby locations.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000280 mutable FileID LastLineNoFileIDQuery;
Chris Lattnerf812a452008-11-18 06:51:15 +0000281 mutable SrcMgr::ContentCache *LastLineNoContentCache;
282 mutable unsigned LastLineNoFilePos;
283 mutable unsigned LastLineNoResult;
Ted Kremenek78d85f52007-10-30 21:08:08 +0000284
Ted Kremenek76edd0e2007-12-19 22:29:55 +0000285 /// MainFileID - The file ID for the main source file of the translation unit.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000286 FileID MainFileID;
Steve Naroff49c1f4a2008-02-02 00:10:46 +0000287
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000288 // Statistics for -print-stats.
289 mutable unsigned NumLinearScans, NumBinaryProbes;
290
Steve Naroff49c1f4a2008-02-02 00:10:46 +0000291 // SourceManager doesn't support copy construction.
292 explicit SourceManager(const SourceManager&);
293 void operator=(const SourceManager&);
Reid Spencer5f016e22007-07-11 17:01:13 +0000294public:
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000295 SourceManager() : NumLinearScans(0), NumBinaryProbes(0) {
296 clearIDTables();
297 }
Ted Kremenek78d85f52007-10-30 21:08:08 +0000298 ~SourceManager() {}
Reid Spencer5f016e22007-07-11 17:01:13 +0000299
Chris Lattnerbd247762007-07-22 06:05:44 +0000300 void clearIDTables() {
Chris Lattner2b2453a2009-01-17 06:22:33 +0000301 MainFileID = FileID();
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000302 SLocEntryTable.clear();
Chris Lattner2b2453a2009-01-17 06:22:33 +0000303 LastLineNoFileIDQuery = FileID();
Ted Kremenek78d85f52007-10-30 21:08:08 +0000304 LastLineNoContentCache = 0;
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000305 LastFileIDLookup = FileID();
306
307 // Use up FileID #0 as an invalid instantiation.
308 NextOffset = 0;
309 createInstantiationLoc(SourceLocation(), SourceLocation(), 1);
Chris Lattnerbd247762007-07-22 06:05:44 +0000310 }
Chris Lattner06a062d2009-01-19 08:02:45 +0000311
312 //===--------------------------------------------------------------------===//
313 // MainFileID creation and querying methods.
314 //===--------------------------------------------------------------------===//
315
Ted Kremenek76edd0e2007-12-19 22:29:55 +0000316 /// getMainFileID - Returns the FileID of the main source file.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000317 FileID getMainFileID() const { return MainFileID; }
Ted Kremenek76edd0e2007-12-19 22:29:55 +0000318
Chris Lattner06a062d2009-01-19 08:02:45 +0000319 /// createMainFileID - Create the FileID for the main source file.
320 FileID createMainFileID(const FileEntry *SourceFile,
321 SourceLocation IncludePos) {
322 assert(MainFileID.isInvalid() && "MainFileID already set!");
323 MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
324 return MainFileID;
325 }
326
327 //===--------------------------------------------------------------------===//
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000328 // Methods to create new FileID's and instantiations.
Chris Lattner06a062d2009-01-19 08:02:45 +0000329 //===--------------------------------------------------------------------===//
330
Reid Spencer5f016e22007-07-11 17:01:13 +0000331 /// createFileID - Create a new FileID that represents the specified file
332 /// being #included from the specified IncludePosition. This returns 0 on
333 /// error and translates NULL into standard input.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000334 FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
Chris Lattnera90a4d42009-01-19 07:30:29 +0000335 SrcMgr::CharacteristicKind FileCharacter) {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000336 const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
Chris Lattner2b2453a2009-01-17 06:22:33 +0000337 if (IR == 0) return FileID(); // Error opening file?
Chris Lattner0b9e7362008-09-26 21:18:42 +0000338 return createFileID(IR, IncludePos, FileCharacter);
Reid Spencer5f016e22007-07-11 17:01:13 +0000339 }
340
341 /// createFileIDForMemBuffer - Create a new FileID that represents the
342 /// specified memory buffer. This does no caching of the buffer and takes
343 /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000344 FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
Nico Weber7bfaaae2008-08-10 19:59:06 +0000345 return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
Chris Lattner0b9e7362008-09-26 21:18:42 +0000346 SrcMgr::C_User);
Reid Spencer5f016e22007-07-11 17:01:13 +0000347 }
348
Ted Kremenek1036b682007-12-19 23:48:45 +0000349 /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
350 /// that will represent the FileID for the main source. One example
351 /// of when this would be used is when the main source is read from STDIN.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000352 FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
353 assert(MainFileID.isInvalid() && "MainFileID already set!");
Chris Lattner7697b5c2007-12-20 01:38:17 +0000354 MainFileID = createFileIDForMemBuffer(Buffer);
Ted Kremenek1036b682007-12-19 23:48:45 +0000355 return MainFileID;
356 }
Chris Lattner06a062d2009-01-19 08:02:45 +0000357
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000358 /// createInstantiationLoc - Return a new SourceLocation that encodes the fact
359 /// that a token at Loc should actually be referenced from InstantiationLoc.
360 /// TokLength is the length of the token being instantiated.
361 SourceLocation createInstantiationLoc(SourceLocation Loc,
362 SourceLocation InstantiationLoc,
363 unsigned TokLength);
364
Chris Lattner06a062d2009-01-19 08:02:45 +0000365 //===--------------------------------------------------------------------===//
366 // FileID manipulation methods.
367 //===--------------------------------------------------------------------===//
368
369 /// getBuffer - Return the buffer for the specified FileID.
370 ///
371 const llvm::MemoryBuffer *getBuffer(FileID FID) const {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000372 return getSLocEntry(FID).getFile().getContentCache()->getBuffer();
Chris Lattner06a062d2009-01-19 08:02:45 +0000373 }
374
375 /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
376 const FileEntry *getFileEntryForID(FileID FID) const {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000377 return getSLocEntry(FID).getFile().getContentCache()->Entry;
Chris Lattner06a062d2009-01-19 08:02:45 +0000378 }
379
380 /// getBufferData - Return a pointer to the start and end of the source buffer
381 /// data for the specified FileID.
382 std::pair<const char*, const char*> getBufferData(FileID FID) const;
383
384
385 //===--------------------------------------------------------------------===//
386 // SourceLocation manipulation methods.
387 //===--------------------------------------------------------------------===//
Ted Kremenek1036b682007-12-19 23:48:45 +0000388
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000389 /// getFileIDSlow - Return the FileID for a SourceLocation. This is a very
390 /// hot method that is used for all SourceManager queries that start with a
391 /// SourceLocation object. It is responsible for finding the entry in
392 /// SLocEntryTable which contains the specified location.
393 ///
394 FileID getFileID(SourceLocation SpellingLoc) const {
395 unsigned SLocOffset = SpellingLoc.getOffset();
396
397 // If our one-entry cache covers this offset, just return it.
398 if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
399 return LastFileIDLookup;
400
401 return getFileIDSlow(SLocOffset);
402 }
403
Chris Lattner2b2453a2009-01-17 06:22:33 +0000404 /// getLocForStartOfFile - Return the source location corresponding to the
405 /// first byte of the specified file.
406 SourceLocation getLocForStartOfFile(FileID FID) const {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000407 assert(FID.ID < SLocEntryTable.size() && SLocEntryTable[FID.ID].isFile());
408 unsigned FileOffset = SLocEntryTable[FID.ID].getOffset();
409 return SourceLocation::getFileLoc(FileOffset);
Chris Lattner2b2453a2009-01-17 06:22:33 +0000410 }
411
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000412 /// getIncludeLoc - Return the location of the #include for the specified
Chris Lattner9dc1f532007-07-20 16:37:10 +0000413 /// SourceLocation. If this is a macro expansion, this transparently figures
414 /// out which file includes the file being expanded into.
415 SourceLocation getIncludeLoc(SourceLocation ID) const {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000416 return getSLocEntry(getFileID(getInstantiationLoc(ID)))
417 .getFile().getIncludeLoc();
Reid Spencer5f016e22007-07-11 17:01:13 +0000418 }
419
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000420 /// Given a SourceLocation object, return the instantiation location
421 /// referenced by the ID.
422 SourceLocation getInstantiationLoc(SourceLocation Loc) const {
423 // File locations work!
424 if (Loc.isFileID()) return Loc;
425
426 std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
427 Loc = getSLocEntry(LocInfo.first).getInstantiation().getInstantiationLoc();
428 return Loc.getFileLocWithOffset(LocInfo.second);
429 }
430
431 /// getSpellingLoc - Given a SourceLocation object, return the spelling
432 /// location referenced by the ID. This is the place where the characters
433 /// that make up the lexed token can be found.
434 SourceLocation getSpellingLoc(SourceLocation Loc) const {
435 // File locations work!
436 if (Loc.isFileID()) return Loc;
437
438 std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
439 Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
440 return Loc.getFileLocWithOffset(LocInfo.second);
441 }
442
443 /// getDecomposedLoc - Decompose the specified location into a raw FileID +
444 /// Offset pair. The first element is the FileID, the second is the
445 /// offset from the start of the buffer of the location.
446 std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const {
447 FileID FID = getFileID(Loc);
448 return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset());
449 }
450
451 /// getDecomposedInstantiationLoc - Decompose the specified location into a
452 /// raw FileID + Offset pair. If the location is an instantiation record,
453 /// walk through it until we find the final location instantiated.
454 std::pair<FileID, unsigned>
455 getDecomposedInstantiationLoc(SourceLocation Loc) const {
456 FileID FID = getFileID(Loc);
457 const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
458
459 unsigned Offset = Loc.getOffset()-E->getOffset();
460 if (Loc.isFileID())
461 return std::make_pair(FID, Offset);
462
463 return getDecomposedInstantiationLocSlowCase(E, Offset);
464 }
465
466 /// getDecomposedSpellingLoc - Decompose the specified location into a raw
467 /// FileID + Offset pair. If the location is an instantiation record, walk
468 /// through it until we find its spelling record.
469 std::pair<FileID, unsigned>
470 getDecomposedSpellingLoc(SourceLocation Loc) const {
471 FileID FID = getFileID(Loc);
472 const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
473
474 unsigned Offset = Loc.getOffset()-E->getOffset();
475 if (Loc.isFileID())
476 return std::make_pair(FID, Offset);
477 return getDecomposedSpellingLocSlowCase(E, Offset);
478 }
479
480 /// getFullFilePos - This (efficient) method returns the offset from the start
481 /// of the file that the specified spelling SourceLocation represents. This
482 /// returns the location of the actual character data, not the instantiation
483 /// position.
484 unsigned getFullFilePos(SourceLocation SpellingLoc) const {
485 return getDecomposedLoc(SpellingLoc).second;
486 }
487
488
489 //===--------------------------------------------------------------------===//
490 // Queries about the code at a SourceLocation.
491 //===--------------------------------------------------------------------===//
492
Reid Spencer5f016e22007-07-11 17:01:13 +0000493 /// getCharacterData - Return a pointer to the start of the specified location
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000494 /// in the appropriate spelling MemoryBuffer.
Reid Spencer5f016e22007-07-11 17:01:13 +0000495 const char *getCharacterData(SourceLocation SL) const;
496
Chris Lattner9dc1f532007-07-20 16:37:10 +0000497 /// getColumnNumber - Return the column # for the specified file position.
498 /// This is significantly cheaper to compute than the line number. This
499 /// returns zero if the column number isn't known. This may only be called on
Chris Lattnerf7cf85b2009-01-16 07:36:28 +0000500 /// a file sloc, so you must choose a spelling or instantiation location
501 /// before calling this method.
Reid Spencer5f016e22007-07-11 17:01:13 +0000502 unsigned getColumnNumber(SourceLocation Loc) const;
503
Chris Lattnerdf7c17a2009-01-16 07:00:02 +0000504 unsigned getSpellingColumnNumber(SourceLocation Loc) const {
505 return getColumnNumber(getSpellingLoc(Loc));
Chris Lattner9dc1f532007-07-20 16:37:10 +0000506 }
Chris Lattnerf7cf85b2009-01-16 07:36:28 +0000507 unsigned getInstantiationColumnNumber(SourceLocation Loc) const {
508 return getColumnNumber(getInstantiationLoc(Loc));
Chris Lattner9dc1f532007-07-20 16:37:10 +0000509 }
510
511
Chris Lattnerdf7c17a2009-01-16 07:00:02 +0000512 /// getLineNumber - Given a SourceLocation, return the spelling line number
Reid Spencer5f016e22007-07-11 17:01:13 +0000513 /// for the position indicated. This requires building and caching a table of
514 /// line offsets for the MemoryBuffer, so this is not cheap: use only when
515 /// about to emit a diagnostic.
Chris Lattnerf812a452008-11-18 06:51:15 +0000516 unsigned getLineNumber(SourceLocation Loc) const;
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000517
Chris Lattnerf7cf85b2009-01-16 07:36:28 +0000518 unsigned getInstantiationLineNumber(SourceLocation Loc) const {
519 return getLineNumber(getInstantiationLoc(Loc));
Chris Lattner9dc1f532007-07-20 16:37:10 +0000520 }
Chris Lattnerdf7c17a2009-01-16 07:00:02 +0000521 unsigned getSpellingLineNumber(SourceLocation Loc) const {
522 return getLineNumber(getSpellingLoc(Loc));
Chris Lattner9dc1f532007-07-20 16:37:10 +0000523 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000524
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000525 // FIXME: This should handle #line.
526 SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const {
527 FileID FID = getFileID(getSpellingLoc(Loc));
528 return getSLocEntry(FID).getFile().getFileCharacteristic();
529 }
530
Reid Spencer5f016e22007-07-11 17:01:13 +0000531 /// getSourceName - This method returns the name of the file or buffer that
532 /// the SourceLocation specifies. This can be modified with #line directives,
533 /// etc.
Chris Lattner8b6ca882007-08-30 05:59:30 +0000534 const char *getSourceName(SourceLocation Loc) const;
Reid Spencer5f016e22007-07-11 17:01:13 +0000535
Chris Lattnera11d6172009-01-19 07:46:45 +0000536
Chris Lattner3457e8c2007-10-12 20:24:19 +0000537
Ted Kremenek9fd87b12008-04-14 21:04:18 +0000538 /// isFromSameFile - Returns true if both SourceLocations correspond to
539 /// the same file.
540 bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
Chris Lattnera11d6172009-01-19 07:46:45 +0000541 return getFileID(Loc1) == getFileID(Loc2);
Ted Kremenek9fd87b12008-04-14 21:04:18 +0000542 }
543
544 /// isFromMainFile - Returns true if the file of provided SourceLocation is
545 /// the main file.
546 bool isFromMainFile(SourceLocation Loc) const {
Chris Lattnera11d6172009-01-19 07:46:45 +0000547 return getFileID(Loc) == getMainFileID();
Ted Kremenek9fd87b12008-04-14 21:04:18 +0000548 }
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000549
Nico Weber7bfaaae2008-08-10 19:59:06 +0000550 /// isInSystemHeader - Returns if a SourceLocation is in a system header.
551 bool isInSystemHeader(SourceLocation Loc) const {
Chris Lattner0b9e7362008-09-26 21:18:42 +0000552 return getFileCharacteristic(Loc) != SrcMgr::C_User;
Nico Weber7bfaaae2008-08-10 19:59:06 +0000553 }
Chris Lattner06a062d2009-01-19 08:02:45 +0000554
555 //===--------------------------------------------------------------------===//
556 // Other miscellaneous methods.
557 //===--------------------------------------------------------------------===//
Ted Kremeneke55f4ee2008-11-19 22:41:46 +0000558
Chris Lattnerc6fe32a2009-01-17 03:48:08 +0000559 // Iterators over FileInfos.
560 typedef std::set<SrcMgr::ContentCache>::const_iterator fileinfo_iterator;
561 fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
562 fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
563
Reid Spencer5f016e22007-07-11 17:01:13 +0000564 /// PrintStats - Print statistics to stderr.
565 ///
566 void PrintStats() const;
Reid Spencer5f016e22007-07-11 17:01:13 +0000567
Ted Kremenek099b4742007-12-05 00:14:18 +0000568 /// Emit - Emit this SourceManager to Bitcode.
569 void Emit(llvm::Serializer& S) const;
570
571 /// Read - Reconstitute a SourceManager from Bitcode.
Ted Kremenek1f941002007-12-05 00:19:51 +0000572 static SourceManager* CreateAndRegister(llvm::Deserializer& S,
573 FileManager &FMgr);
Ted Kremenek099b4742007-12-05 00:14:18 +0000574
Ted Kremenek78d85f52007-10-30 21:08:08 +0000575private:
Cedric Venet8429fca2008-06-26 12:50:52 +0000576 friend struct SrcMgr::ContentCache; // Used for deserialization.
Ted Kremenek099b4742007-12-05 00:14:18 +0000577
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000578 /// isOffsetInFileID - Return true if the specified FileID contains the
579 /// specified SourceLocation offset. This is a very hot method.
580 inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
581 const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
582 // If the entry is after the offset, it can't contain it.
583 if (SLocOffset < Entry.getOffset()) return false;
584
585 // If this is the last entry than it does. Otherwise, the entry after it
586 // has to not include it.
587 if (FID.ID+1 == SLocEntryTable.size()) return true;
588 return SLocOffset < SLocEntryTable[FID.ID+1].getOffset();
589 }
590
Ted Kremenek78d85f52007-10-30 21:08:08 +0000591 /// createFileID - Create a new fileID for the specified ContentCache and
592 /// include position. This works regardless of whether the ContentCache
593 /// corresponds to a file or some other input source.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000594 FileID createFileID(const SrcMgr::ContentCache* File,
595 SourceLocation IncludePos,
596 SrcMgr::CharacteristicKind DirCharacter);
Ted Kremenek78d85f52007-10-30 21:08:08 +0000597
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000598 const SrcMgr::ContentCache *
599 getOrCreateContentCache(const FileEntry *SourceFile);
Ted Kremenekc16c2082009-01-06 01:55:26 +0000600
Ted Kremenek78d85f52007-10-30 21:08:08 +0000601 /// createMemBufferContentCache - Create a new ContentCache for the specified
602 /// memory buffer.
603 const SrcMgr::ContentCache*
Chris Lattner2b2453a2009-01-17 06:22:33 +0000604 createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
Ted Kremenek78d85f52007-10-30 21:08:08 +0000605
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000606 const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
607 assert(FID.ID < SLocEntryTable.size() && "Invalid id");
608 return SLocEntryTable[FID.ID];
Reid Spencer5f016e22007-07-11 17:01:13 +0000609 }
Chris Lattner9dc1f532007-07-20 16:37:10 +0000610
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000611 FileID getFileIDSlow(unsigned SLocOffset) const;
612
613 std::pair<FileID, unsigned>
614 getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
615 unsigned Offset) const;
616 std::pair<FileID, unsigned>
617 getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
618 unsigned Offset) const;
Reid Spencer5f016e22007-07-11 17:01:13 +0000619};
620
621
622} // end namespace clang
623
624#endif