blob: 340c2e562a3ba868dd9c65cc9713eedc6b7dcbec [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"
Chris Lattner0d0bf8c2009-02-03 07:30:45 +000019#include "llvm/Support/Allocator.h"
Chris Lattner464c4b32009-01-26 18:21:04 +000020#include "llvm/Support/DataTypes.h"
Chris Lattner0d0bf8c2009-02-03 07:30:45 +000021#include "llvm/ADT/DenseMap.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000022#include <vector>
Chris Lattner9dc62f02007-07-12 15:32:57 +000023#include <cassert>
Reid Spencer5f016e22007-07-11 17:01:13 +000024
25namespace llvm {
26class MemoryBuffer;
27}
28
29namespace clang {
30
31class SourceManager;
Ted Kremenek099b4742007-12-05 00:14:18 +000032class FileManager;
Reid Spencer5f016e22007-07-11 17:01:13 +000033class FileEntry;
34class IdentifierTokenInfo;
Chris Lattner5b9a5042009-01-26 07:57:50 +000035class LineTableInfo;
Reid Spencer5f016e22007-07-11 17:01:13 +000036
Chris Lattner0b9e7362008-09-26 21:18:42 +000037/// SrcMgr - Public enums and private classes that are part of the
38/// SourceManager implementation.
Reid Spencer5f016e22007-07-11 17:01:13 +000039///
40namespace SrcMgr {
Chris Lattner9d728512008-10-27 01:19:25 +000041 /// CharacteristicKind - This is used to represent whether a file or directory
Chris Lattner0b9e7362008-09-26 21:18:42 +000042 /// holds normal user code, system code, or system code which is implicitly
43 /// 'extern "C"' in C++ mode. Entire directories can be tagged with this
44 /// (this is maintained by DirectoryLookup and friends) as can specific
45 /// FileIDInfos when a #pragma system_header is seen or various other cases.
46 ///
Chris Lattner9d728512008-10-27 01:19:25 +000047 enum CharacteristicKind {
Chris Lattner0b9e7362008-09-26 21:18:42 +000048 C_User, C_System, C_ExternCSystem
49 };
50
Ted Kremenek78d85f52007-10-30 21:08:08 +000051 /// ContentCache - Once instance of this struct is kept for every file
Chris Lattner06a062d2009-01-19 08:02:45 +000052 /// loaded or used. This object owns the MemoryBuffer object.
Ted Kremenekc16c2082009-01-06 01:55:26 +000053 class ContentCache {
54 /// Buffer - The actual buffer containing the characters from the input
55 /// file. This is owned by the ContentCache object.
Chris Lattner05816592009-01-17 03:54:16 +000056 mutable const llvm::MemoryBuffer *Buffer;
Ted Kremenekc16c2082009-01-06 01:55:26 +000057
58 public:
Ted Kremenek78d85f52007-10-30 21:08:08 +000059 /// Reference to the file entry. This reference does not own
60 /// the FileEntry object. It is possible for this to be NULL if
61 /// the ContentCache encapsulates an imaginary text buffer.
Chris Lattner05816592009-01-17 03:54:16 +000062 const FileEntry *Entry;
Ted Kremenek78d85f52007-10-30 21:08:08 +000063
Chris Lattner0d0bf8c2009-02-03 07:30:45 +000064 /// SourceLineCache - A bump pointer allocated array of offsets for each
65 /// source line. This is lazily computed. This is owned by the
66 /// SourceManager BumpPointerAllocator object.
Chris Lattner05816592009-01-17 03:54:16 +000067 unsigned *SourceLineCache;
Reid Spencer5f016e22007-07-11 17:01:13 +000068
Ted Kremenekb6427f82007-12-04 18:59:28 +000069 /// NumLines - The number of lines in this ContentCache. This is only valid
70 /// if SourceLineCache is non-null.
Reid Spencer5f016e22007-07-11 17:01:13 +000071 unsigned NumLines;
Ted Kremenekc16c2082009-01-06 01:55:26 +000072
73 /// getBuffer - Returns the memory buffer for the associated content.
Chris Lattner05816592009-01-17 03:54:16 +000074 const llvm::MemoryBuffer *getBuffer() const;
Ted Kremenekc16c2082009-01-06 01:55:26 +000075
76 /// getSize - Returns the size of the content encapsulated by this
77 /// ContentCache. This can be the size of the source file or the size of an
78 /// arbitrary scratch buffer. If the ContentCache encapsulates a source
79 /// file this size is retrieved from the file's FileEntry.
80 unsigned getSize() const;
81
82 /// getSizeBytesMapped - Returns the number of bytes actually mapped for
83 /// this ContentCache. This can be 0 if the MemBuffer was not actually
84 /// instantiated.
85 unsigned getSizeBytesMapped() const;
86
Chris Lattner05816592009-01-17 03:54:16 +000087 void setBuffer(const llvm::MemoryBuffer *B) {
Ted Kremenekc16c2082009-01-06 01:55:26 +000088 assert(!Buffer && "MemoryBuffer already set.");
89 Buffer = B;
90 }
Ted Kremenek78d85f52007-10-30 21:08:08 +000091
Chris Lattner0d0bf8c2009-02-03 07:30:45 +000092 ContentCache(const FileEntry *Ent = 0)
93 : Buffer(0), Entry(Ent), SourceLineCache(0), NumLines(0) {}
Ted Kremenek78d85f52007-10-30 21:08:08 +000094
95 ~ContentCache();
Ted Kremenek0d892d82007-10-30 22:57:35 +000096
97 /// The copy ctor does not allow copies where source object has either
98 /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
99 /// is not transfered, so this is a logical error.
Chris Lattner0d0bf8c2009-02-03 07:30:45 +0000100 ContentCache(const ContentCache &RHS) : Buffer(0), SourceLineCache(0) {
Ted Kremenek0d892d82007-10-30 22:57:35 +0000101 Entry = RHS.Entry;
102
Chris Lattner0d0bf8c2009-02-03 07:30:45 +0000103 assert (RHS.Buffer == 0 && RHS.SourceLineCache == 0
Ted Kremenek0d892d82007-10-30 22:57:35 +0000104 && "Passed ContentCache object cannot own a buffer.");
105
106 NumLines = RHS.NumLines;
107 }
108
Ted Kremeneke21272f2007-12-04 19:39:02 +0000109 /// Emit - Emit this ContentCache to Bitcode.
Chris Lattner05816592009-01-17 03:54:16 +0000110 void Emit(llvm::Serializer &S) const;
Ted Kremeneke21272f2007-12-04 19:39:02 +0000111
Ted Kremenek099b4742007-12-05 00:14:18 +0000112 /// ReadToSourceManager - Reconstitute a ContentCache from Bitcode
113 // and store it in the specified SourceManager.
Chris Lattner05816592009-01-17 03:54:16 +0000114 static void ReadToSourceManager(llvm::Deserializer &D, SourceManager &SM,
115 FileManager *FMgr, std::vector<char> &Buf);
Ted Kremenek099b4742007-12-05 00:14:18 +0000116
Ted Kremenek0d892d82007-10-30 22:57:35 +0000117 private:
118 // Disable assignments.
Chris Lattner05816592009-01-17 03:54:16 +0000119 ContentCache &operator=(const ContentCache& RHS);
Ted Kremenek78d85f52007-10-30 21:08:08 +0000120 };
Reid Spencer5f016e22007-07-11 17:01:13 +0000121
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000122 /// FileInfo - Information about a FileID, basically just the logical file
123 /// that it represents and include stack information.
Reid Spencer5f016e22007-07-11 17:01:13 +0000124 ///
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000125 /// Each FileInfo has include stack information, indicating where it came
126 /// from. This information encodes the #include chain that a token was
127 /// instantiated from. The main include file has an invalid IncludeLoc.
Reid Spencer5f016e22007-07-11 17:01:13 +0000128 ///
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000129 /// FileInfos contain a "ContentCache *", with the contents of the file.
Reid Spencer5f016e22007-07-11 17:01:13 +0000130 ///
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000131 class FileInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000132 /// IncludeLoc - The location of the #include that brought in this file.
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000133 /// This is an invalid SLOC for the main file (top of the #include chain).
134 unsigned IncludeLoc; // Really a SourceLocation
Chris Lattner9dc1f532007-07-20 16:37:10 +0000135
Chris Lattner6e1aff22009-01-26 06:49:09 +0000136 /// Data - This contains the ContentCache* and the bits indicating the
137 /// characteristic of the file and whether it has #line info, all bitmangled
138 /// together.
139 uintptr_t Data;
Ted Kremenek78d85f52007-10-30 21:08:08 +0000140 public:
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000141 /// get - Return a FileInfo object.
142 static FileInfo get(SourceLocation IL, const ContentCache *Con,
143 CharacteristicKind FileCharacter) {
144 FileInfo X;
145 X.IncludeLoc = IL.getRawEncoding();
Chris Lattner6e1aff22009-01-26 06:49:09 +0000146 X.Data = (uintptr_t)Con;
Chris Lattner00282d62009-02-03 07:41:46 +0000147 assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
Chris Lattner6e1aff22009-01-26 06:49:09 +0000148 assert((unsigned)FileCharacter < 4 && "invalid file character");
149 X.Data |= (unsigned)FileCharacter;
Reid Spencer5f016e22007-07-11 17:01:13 +0000150 return X;
151 }
152
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000153 SourceLocation getIncludeLoc() const {
154 return SourceLocation::getFromRawEncoding(IncludeLoc);
155 }
Chris Lattner6e1aff22009-01-26 06:49:09 +0000156 const ContentCache* getContentCache() const {
Chris Lattner00282d62009-02-03 07:41:46 +0000157 return reinterpret_cast<const ContentCache*>(Data & ~7UL);
Chris Lattner6e1aff22009-01-26 06:49:09 +0000158 }
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000159
Chris Lattner0b9e7362008-09-26 21:18:42 +0000160 /// getCharacteristic - Return whether this is a system header or not.
Chris Lattner9d728512008-10-27 01:19:25 +0000161 CharacteristicKind getFileCharacteristic() const {
Chris Lattner6e1aff22009-01-26 06:49:09 +0000162 return (CharacteristicKind)(Data & 3);
Chris Lattner0b9e7362008-09-26 21:18:42 +0000163 }
Chris Lattnerac50e342009-02-03 22:13:05 +0000164
165 /// hasLineDirectives - Return true if this FileID has #line directives in
166 /// it.
167 bool hasLineDirectives() const { return (Data & 4) != 0; }
168
169 /// setHasLineDirectives - Set the flag that indicates that this FileID has
170 /// line table entries associated with it.
171 void setHasLineDirectives() {
172 Data |= 4;
173 }
Chris Lattner9dc1f532007-07-20 16:37:10 +0000174 };
175
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000176 /// InstantiationInfo - Each InstantiationInfo encodes the Instantiation
177 /// location - where the token was ultimately instantiated, and the
178 /// SpellingLoc - where the actual character data for the token came from.
179 class InstantiationInfo {
180 unsigned InstantiationLoc, SpellingLoc; // Really these are SourceLocations.
Chris Lattner9dc1f532007-07-20 16:37:10 +0000181 public:
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000182 SourceLocation getInstantiationLoc() const {
183 return SourceLocation::getFromRawEncoding(InstantiationLoc);
184 }
185 SourceLocation getSpellingLoc() const {
186 return SourceLocation::getFromRawEncoding(SpellingLoc);
187 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000188
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000189 /// get - Return a InstantiationInfo for an expansion. VL specifies
Chris Lattnerdf7c17a2009-01-16 07:00:02 +0000190 /// the instantiation location (where the macro is expanded), and SL
191 /// specifies the spelling location (where the characters from the token
Chris Lattner18807d22007-11-09 23:59:17 +0000192 /// come from). Both VL and PL refer to normal File SLocs.
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000193 static InstantiationInfo get(SourceLocation IL, SourceLocation SL) {
194 InstantiationInfo X;
195 X.InstantiationLoc = IL.getRawEncoding();
196 X.SpellingLoc = SL.getRawEncoding();
Chris Lattner9dc1f532007-07-20 16:37:10 +0000197 return X;
Reid Spencer5f016e22007-07-11 17:01:13 +0000198 }
199 };
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000200
201 /// SLocEntry - This is a discriminated union of FileInfo and
202 /// InstantiationInfo. SourceManager keeps an array of these objects, and
203 /// they are uniquely identified by the FileID datatype.
204 class SLocEntry {
205 unsigned Offset; // low bit is set for instantiation info.
206 union {
207 FileInfo File;
208 InstantiationInfo Instantiation;
209 };
210 public:
211 unsigned getOffset() const { return Offset >> 1; }
212
213 bool isInstantiation() const { return Offset & 1; }
214 bool isFile() const { return !isInstantiation(); }
215
216 const FileInfo &getFile() const {
217 assert(isFile() && "Not a file SLocEntry!");
218 return File;
219 }
220
221 const InstantiationInfo &getInstantiation() const {
222 assert(isInstantiation() && "Not an instantiation SLocEntry!");
223 return Instantiation;
224 }
225
226 static SLocEntry get(unsigned Offset, const FileInfo &FI) {
227 SLocEntry E;
228 E.Offset = Offset << 1;
229 E.File = FI;
230 return E;
231 }
232
233 static SLocEntry get(unsigned Offset, const InstantiationInfo &II) {
234 SLocEntry E;
235 E.Offset = (Offset << 1) | 1;
236 E.Instantiation = II;
237 return E;
238 }
239 };
Reid Spencer5f016e22007-07-11 17:01:13 +0000240} // end SrcMgr namespace.
Ted Kremenek78d85f52007-10-30 21:08:08 +0000241
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 {
Chris Lattner0d0bf8c2009-02-03 07:30:45 +0000254 mutable llvm::BumpPtrAllocator ContentCacheAlloc;
255
Reid Spencer5f016e22007-07-11 17:01:13 +0000256 /// FileInfos - Memoized information about all of the files tracked by this
Ted Kremenek0d892d82007-10-30 22:57:35 +0000257 /// SourceManager. This set allows us to merge ContentCache entries based
258 /// on their FileEntry*. All ContentCache objects will thus have unique,
259 /// non-null, FileEntry pointers.
Chris Lattner0d0bf8c2009-02-03 07:30:45 +0000260 llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
Reid Spencer5f016e22007-07-11 17:01:13 +0000261
262 /// MemBufferInfos - Information about various memory buffers that we have
Chris Lattner0d0bf8c2009-02-03 07:30:45 +0000263 /// read in. All FileEntry* within the stored ContentCache objects are NULL,
264 /// as they do not refer to a file.
265 std::vector<SrcMgr::ContentCache*> MemBufferInfos;
Reid Spencer5f016e22007-07-11 17:01:13 +0000266
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000267 /// SLocEntryTable - This is an array of SLocEntry's that we have created.
268 /// FileID is an index into this vector. This array is sorted by the offset.
269 std::vector<SrcMgr::SLocEntry> SLocEntryTable;
270 /// NextOffset - This is the next available offset that a new SLocEntry can
271 /// start at. It is SLocEntryTable.back().getOffset()+size of back() entry.
272 unsigned NextOffset;
Reid Spencer5f016e22007-07-11 17:01:13 +0000273
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000274 /// LastFileIDLookup - This is a one-entry cache to speed up getFileID.
275 /// LastFileIDLookup records the last FileID looked up or created, because it
276 /// is very common to look up many tokens from the same file.
277 mutable FileID LastFileIDLookup;
Chris Lattner9dc1f532007-07-20 16:37:10 +0000278
Chris Lattner5b9a5042009-01-26 07:57:50 +0000279 /// LineTable - This holds information for #line directives. It is referenced
280 /// by indices from SLocEntryTable.
281 LineTableInfo *LineTable;
282
Chris Lattner5e36a7a2007-07-24 05:57:19 +0000283 /// LastLineNo - These ivars serve as a cache used in the getLineNumber
284 /// method which is used to speedup getLineNumber calls to nearby locations.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000285 mutable FileID LastLineNoFileIDQuery;
Chris Lattnerf812a452008-11-18 06:51:15 +0000286 mutable SrcMgr::ContentCache *LastLineNoContentCache;
287 mutable unsigned LastLineNoFilePos;
288 mutable unsigned LastLineNoResult;
Ted Kremenek78d85f52007-10-30 21:08:08 +0000289
Ted Kremenek76edd0e2007-12-19 22:29:55 +0000290 /// MainFileID - The file ID for the main source file of the translation unit.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000291 FileID MainFileID;
Steve Naroff49c1f4a2008-02-02 00:10:46 +0000292
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000293 // Statistics for -print-stats.
294 mutable unsigned NumLinearScans, NumBinaryProbes;
295
Steve Naroff49c1f4a2008-02-02 00:10:46 +0000296 // SourceManager doesn't support copy construction.
297 explicit SourceManager(const SourceManager&);
298 void operator=(const SourceManager&);
Reid Spencer5f016e22007-07-11 17:01:13 +0000299public:
Chris Lattner5b9a5042009-01-26 07:57:50 +0000300 SourceManager() : LineTable(0), NumLinearScans(0), NumBinaryProbes(0) {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000301 clearIDTables();
302 }
Chris Lattner5b9a5042009-01-26 07:57:50 +0000303 ~SourceManager();
Reid Spencer5f016e22007-07-11 17:01:13 +0000304
Chris Lattner5b9a5042009-01-26 07:57:50 +0000305 void clearIDTables();
306
Chris Lattner06a062d2009-01-19 08:02:45 +0000307 //===--------------------------------------------------------------------===//
308 // MainFileID creation and querying methods.
309 //===--------------------------------------------------------------------===//
310
Ted Kremenek76edd0e2007-12-19 22:29:55 +0000311 /// getMainFileID - Returns the FileID of the main source file.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000312 FileID getMainFileID() const { return MainFileID; }
Ted Kremenek76edd0e2007-12-19 22:29:55 +0000313
Chris Lattner06a062d2009-01-19 08:02:45 +0000314 /// createMainFileID - Create the FileID for the main source file.
315 FileID createMainFileID(const FileEntry *SourceFile,
316 SourceLocation IncludePos) {
317 assert(MainFileID.isInvalid() && "MainFileID already set!");
318 MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
319 return MainFileID;
320 }
321
322 //===--------------------------------------------------------------------===//
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000323 // Methods to create new FileID's and instantiations.
Chris Lattner06a062d2009-01-19 08:02:45 +0000324 //===--------------------------------------------------------------------===//
325
Reid Spencer5f016e22007-07-11 17:01:13 +0000326 /// createFileID - Create a new FileID that represents the specified file
327 /// being #included from the specified IncludePosition. This returns 0 on
328 /// error and translates NULL into standard input.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000329 FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
Chris Lattnera90a4d42009-01-19 07:30:29 +0000330 SrcMgr::CharacteristicKind FileCharacter) {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000331 const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
Chris Lattner2b2453a2009-01-17 06:22:33 +0000332 if (IR == 0) return FileID(); // Error opening file?
Chris Lattner0b9e7362008-09-26 21:18:42 +0000333 return createFileID(IR, IncludePos, FileCharacter);
Reid Spencer5f016e22007-07-11 17:01:13 +0000334 }
335
336 /// createFileIDForMemBuffer - Create a new FileID that represents the
337 /// specified memory buffer. This does no caching of the buffer and takes
338 /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000339 FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
Nico Weber7bfaaae2008-08-10 19:59:06 +0000340 return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
Chris Lattner0b9e7362008-09-26 21:18:42 +0000341 SrcMgr::C_User);
Reid Spencer5f016e22007-07-11 17:01:13 +0000342 }
343
Ted Kremenek1036b682007-12-19 23:48:45 +0000344 /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
345 /// that will represent the FileID for the main source. One example
346 /// of when this would be used is when the main source is read from STDIN.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000347 FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
348 assert(MainFileID.isInvalid() && "MainFileID already set!");
Chris Lattner7697b5c2007-12-20 01:38:17 +0000349 MainFileID = createFileIDForMemBuffer(Buffer);
Ted Kremenek1036b682007-12-19 23:48:45 +0000350 return MainFileID;
351 }
Chris Lattner06a062d2009-01-19 08:02:45 +0000352
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000353 /// createInstantiationLoc - Return a new SourceLocation that encodes the fact
354 /// that a token at Loc should actually be referenced from InstantiationLoc.
355 /// TokLength is the length of the token being instantiated.
356 SourceLocation createInstantiationLoc(SourceLocation Loc,
357 SourceLocation InstantiationLoc,
358 unsigned TokLength);
359
Chris Lattner06a062d2009-01-19 08:02:45 +0000360 //===--------------------------------------------------------------------===//
361 // FileID manipulation methods.
362 //===--------------------------------------------------------------------===//
363
364 /// getBuffer - Return the buffer for the specified FileID.
365 ///
366 const llvm::MemoryBuffer *getBuffer(FileID FID) const {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000367 return getSLocEntry(FID).getFile().getContentCache()->getBuffer();
Chris Lattner06a062d2009-01-19 08:02:45 +0000368 }
369
370 /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
371 const FileEntry *getFileEntryForID(FileID FID) const {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000372 return getSLocEntry(FID).getFile().getContentCache()->Entry;
Chris Lattner06a062d2009-01-19 08:02:45 +0000373 }
374
375 /// getBufferData - Return a pointer to the start and end of the source buffer
376 /// data for the specified FileID.
377 std::pair<const char*, const char*> getBufferData(FileID FID) const;
378
379
380 //===--------------------------------------------------------------------===//
381 // SourceLocation manipulation methods.
382 //===--------------------------------------------------------------------===//
Ted Kremenek1036b682007-12-19 23:48:45 +0000383
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000384 /// getFileIDSlow - Return the FileID for a SourceLocation. This is a very
385 /// hot method that is used for all SourceManager queries that start with a
386 /// SourceLocation object. It is responsible for finding the entry in
387 /// SLocEntryTable which contains the specified location.
388 ///
389 FileID getFileID(SourceLocation SpellingLoc) const {
390 unsigned SLocOffset = SpellingLoc.getOffset();
391
392 // If our one-entry cache covers this offset, just return it.
393 if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
394 return LastFileIDLookup;
395
396 return getFileIDSlow(SLocOffset);
397 }
398
Chris Lattner2b2453a2009-01-17 06:22:33 +0000399 /// getLocForStartOfFile - Return the source location corresponding to the
400 /// first byte of the specified file.
401 SourceLocation getLocForStartOfFile(FileID FID) const {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000402 assert(FID.ID < SLocEntryTable.size() && SLocEntryTable[FID.ID].isFile());
403 unsigned FileOffset = SLocEntryTable[FID.ID].getOffset();
404 return SourceLocation::getFileLoc(FileOffset);
Chris Lattner2b2453a2009-01-17 06:22:33 +0000405 }
406
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000407 /// Given a SourceLocation object, return the instantiation location
408 /// referenced by the ID.
409 SourceLocation getInstantiationLoc(SourceLocation Loc) const {
Chris Lattneraddb7972009-01-26 20:04:19 +0000410 // Handle the non-mapped case inline, defer to out of line code to handle
411 // instantiations.
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000412 if (Loc.isFileID()) return Loc;
Chris Lattneraddb7972009-01-26 20:04:19 +0000413 return getInstantiationLocSlowCase(Loc);
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000414 }
415
416 /// getSpellingLoc - Given a SourceLocation object, return the spelling
417 /// location referenced by the ID. This is the place where the characters
418 /// that make up the lexed token can be found.
419 SourceLocation getSpellingLoc(SourceLocation Loc) const {
Chris Lattneraddb7972009-01-26 20:04:19 +0000420 // Handle the non-mapped case inline, defer to out of line code to handle
421 // instantiations.
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000422 if (Loc.isFileID()) return Loc;
Chris Lattneraddb7972009-01-26 20:04:19 +0000423 return getSpellingLocSlowCase(Loc);
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000424 }
425
426 /// getDecomposedLoc - Decompose the specified location into a raw FileID +
427 /// Offset pair. The first element is the FileID, the second is the
428 /// offset from the start of the buffer of the location.
429 std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const {
430 FileID FID = getFileID(Loc);
431 return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset());
432 }
433
434 /// getDecomposedInstantiationLoc - Decompose the specified location into a
435 /// raw FileID + Offset pair. If the location is an instantiation record,
436 /// walk through it until we find the final location instantiated.
437 std::pair<FileID, unsigned>
438 getDecomposedInstantiationLoc(SourceLocation Loc) const {
439 FileID FID = getFileID(Loc);
440 const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
441
442 unsigned Offset = Loc.getOffset()-E->getOffset();
443 if (Loc.isFileID())
444 return std::make_pair(FID, Offset);
445
446 return getDecomposedInstantiationLocSlowCase(E, Offset);
447 }
448
449 /// getDecomposedSpellingLoc - Decompose the specified location into a raw
450 /// FileID + Offset pair. If the location is an instantiation record, walk
451 /// through it until we find its spelling record.
452 std::pair<FileID, unsigned>
453 getDecomposedSpellingLoc(SourceLocation Loc) const {
454 FileID FID = getFileID(Loc);
455 const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
456
457 unsigned Offset = Loc.getOffset()-E->getOffset();
458 if (Loc.isFileID())
459 return std::make_pair(FID, Offset);
460 return getDecomposedSpellingLocSlowCase(E, Offset);
461 }
462
Chris Lattner52c29082009-01-27 06:27:13 +0000463 /// getFileOffset - This method returns the offset from the start
464 /// of the file that the specified SourceLocation represents. This is not very
465 /// meaningful for a macro ID.
466 unsigned getFileOffset(SourceLocation SpellingLoc) const {
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000467 return getDecomposedLoc(SpellingLoc).second;
468 }
469
470
471 //===--------------------------------------------------------------------===//
472 // Queries about the code at a SourceLocation.
473 //===--------------------------------------------------------------------===//
474
Reid Spencer5f016e22007-07-11 17:01:13 +0000475 /// getCharacterData - Return a pointer to the start of the specified location
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000476 /// in the appropriate spelling MemoryBuffer.
Reid Spencer5f016e22007-07-11 17:01:13 +0000477 const char *getCharacterData(SourceLocation SL) const;
478
Chris Lattner9dc1f532007-07-20 16:37:10 +0000479 /// getColumnNumber - Return the column # for the specified file position.
480 /// This is significantly cheaper to compute than the line number. This
481 /// returns zero if the column number isn't known. This may only be called on
Chris Lattnerf7cf85b2009-01-16 07:36:28 +0000482 /// a file sloc, so you must choose a spelling or instantiation location
483 /// before calling this method.
Chris Lattner7da5aea2009-02-04 00:55:58 +0000484 unsigned getColumnNumber(FileID FID, unsigned FilePos) const;
485 unsigned getSpellingColumnNumber(SourceLocation Loc) const;
486 unsigned getInstantiationColumnNumber(SourceLocation Loc) const;
Chris Lattner9dc1f532007-07-20 16:37:10 +0000487
488
Chris Lattnerdf7c17a2009-01-16 07:00:02 +0000489 /// getLineNumber - Given a SourceLocation, return the spelling line number
Reid Spencer5f016e22007-07-11 17:01:13 +0000490 /// for the position indicated. This requires building and caching a table of
491 /// line offsets for the MemoryBuffer, so this is not cheap: use only when
492 /// about to emit a diagnostic.
Chris Lattnerf812a452008-11-18 06:51:15 +0000493 unsigned getLineNumber(SourceLocation Loc) const;
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000494
Chris Lattnerf7cf85b2009-01-16 07:36:28 +0000495 unsigned getInstantiationLineNumber(SourceLocation Loc) const {
496 return getLineNumber(getInstantiationLoc(Loc));
Chris Lattner9dc1f532007-07-20 16:37:10 +0000497 }
Chris Lattnerdf7c17a2009-01-16 07:00:02 +0000498 unsigned getSpellingLineNumber(SourceLocation Loc) const {
499 return getLineNumber(getSpellingLoc(Loc));
Chris Lattner9dc1f532007-07-20 16:37:10 +0000500 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000501
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000502 // FIXME: This should handle #line.
503 SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const {
504 FileID FID = getFileID(getSpellingLoc(Loc));
505 return getSLocEntry(FID).getFile().getFileCharacteristic();
506 }
507
Chris Lattnerb9c3f962009-01-27 07:57:44 +0000508 /// getPresumedLoc - This method returns the "presumed" location of a
509 /// SourceLocation specifies. A "presumed location" can be modified by #line
510 /// or GNU line marker directives. This provides a view on the data that a
511 /// user should see in diagnostics, for example.
512 ///
513 /// Note that a presumed location is always given as the instantiation point
514 /// of an instantiation location, not at the spelling location.
515 PresumedLoc getPresumedLoc(SourceLocation Loc) const;
Reid Spencer5f016e22007-07-11 17:01:13 +0000516
Chris Lattnera11d6172009-01-19 07:46:45 +0000517
Chris Lattner3457e8c2007-10-12 20:24:19 +0000518
Ted Kremenek9fd87b12008-04-14 21:04:18 +0000519 /// isFromSameFile - Returns true if both SourceLocations correspond to
520 /// the same file.
521 bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
Chris Lattnera11d6172009-01-19 07:46:45 +0000522 return getFileID(Loc1) == getFileID(Loc2);
Ted Kremenek9fd87b12008-04-14 21:04:18 +0000523 }
524
525 /// isFromMainFile - Returns true if the file of provided SourceLocation is
526 /// the main file.
527 bool isFromMainFile(SourceLocation Loc) const {
Chris Lattnera11d6172009-01-19 07:46:45 +0000528 return getFileID(Loc) == getMainFileID();
Ted Kremenek9fd87b12008-04-14 21:04:18 +0000529 }
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000530
Nico Weber7bfaaae2008-08-10 19:59:06 +0000531 /// isInSystemHeader - Returns if a SourceLocation is in a system header.
532 bool isInSystemHeader(SourceLocation Loc) const {
Chris Lattner0b9e7362008-09-26 21:18:42 +0000533 return getFileCharacteristic(Loc) != SrcMgr::C_User;
Nico Weber7bfaaae2008-08-10 19:59:06 +0000534 }
Chris Lattner06a062d2009-01-19 08:02:45 +0000535
536 //===--------------------------------------------------------------------===//
Chris Lattner5b9a5042009-01-26 07:57:50 +0000537 // Line Table Manipulation Routines
538 //===--------------------------------------------------------------------===//
539
540 /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
541 ///
542 unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
543
Chris Lattner4c4ea172009-02-03 21:52:55 +0000544 /// AddLineNote - Add a line note to the line table for the FileID and offset
545 /// specified by Loc. If FilenameID is -1, it is considered to be
546 /// unspecified.
547 void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
Chris Lattner5b9a5042009-01-26 07:57:50 +0000548
549 //===--------------------------------------------------------------------===//
Chris Lattner06a062d2009-01-19 08:02:45 +0000550 // Other miscellaneous methods.
551 //===--------------------------------------------------------------------===//
Ted Kremeneke55f4ee2008-11-19 22:41:46 +0000552
Chris Lattnerc6fe32a2009-01-17 03:48:08 +0000553 // Iterators over FileInfos.
Chris Lattner0d0bf8c2009-02-03 07:30:45 +0000554 typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
555 ::const_iterator fileinfo_iterator;
Chris Lattnerc6fe32a2009-01-17 03:48:08 +0000556 fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
557 fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
558
Reid Spencer5f016e22007-07-11 17:01:13 +0000559 /// PrintStats - Print statistics to stderr.
560 ///
561 void PrintStats() const;
Reid Spencer5f016e22007-07-11 17:01:13 +0000562
Ted Kremenek099b4742007-12-05 00:14:18 +0000563 /// Emit - Emit this SourceManager to Bitcode.
564 void Emit(llvm::Serializer& S) const;
565
566 /// Read - Reconstitute a SourceManager from Bitcode.
Ted Kremenek1f941002007-12-05 00:19:51 +0000567 static SourceManager* CreateAndRegister(llvm::Deserializer& S,
568 FileManager &FMgr);
Ted Kremenek099b4742007-12-05 00:14:18 +0000569
Ted Kremenek78d85f52007-10-30 21:08:08 +0000570private:
Cedric Venet8429fca2008-06-26 12:50:52 +0000571 friend struct SrcMgr::ContentCache; // Used for deserialization.
Ted Kremenek099b4742007-12-05 00:14:18 +0000572
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000573 /// isOffsetInFileID - Return true if the specified FileID contains the
574 /// specified SourceLocation offset. This is a very hot method.
575 inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
576 const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
577 // If the entry is after the offset, it can't contain it.
578 if (SLocOffset < Entry.getOffset()) return false;
579
580 // If this is the last entry than it does. Otherwise, the entry after it
581 // has to not include it.
582 if (FID.ID+1 == SLocEntryTable.size()) return true;
583 return SLocOffset < SLocEntryTable[FID.ID+1].getOffset();
584 }
585
Ted Kremenek78d85f52007-10-30 21:08:08 +0000586 /// createFileID - Create a new fileID for the specified ContentCache and
587 /// include position. This works regardless of whether the ContentCache
588 /// corresponds to a file or some other input source.
Chris Lattner2b2453a2009-01-17 06:22:33 +0000589 FileID createFileID(const SrcMgr::ContentCache* File,
590 SourceLocation IncludePos,
591 SrcMgr::CharacteristicKind DirCharacter);
Ted Kremenek78d85f52007-10-30 21:08:08 +0000592
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000593 const SrcMgr::ContentCache *
594 getOrCreateContentCache(const FileEntry *SourceFile);
Ted Kremenekc16c2082009-01-06 01:55:26 +0000595
Ted Kremenek78d85f52007-10-30 21:08:08 +0000596 /// createMemBufferContentCache - Create a new ContentCache for the specified
597 /// memory buffer.
598 const SrcMgr::ContentCache*
Chris Lattner2b2453a2009-01-17 06:22:33 +0000599 createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
Ted Kremenek78d85f52007-10-30 21:08:08 +0000600
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000601 const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
602 assert(FID.ID < SLocEntryTable.size() && "Invalid id");
603 return SLocEntryTable[FID.ID];
Reid Spencer5f016e22007-07-11 17:01:13 +0000604 }
Chris Lattner9dc1f532007-07-20 16:37:10 +0000605
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000606 FileID getFileIDSlow(unsigned SLocOffset) const;
607
Chris Lattneraddb7972009-01-26 20:04:19 +0000608 SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const;
609 SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
610
Chris Lattnerde7aeef2009-01-26 00:43:02 +0000611 std::pair<FileID, unsigned>
612 getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
613 unsigned Offset) const;
614 std::pair<FileID, unsigned>
615 getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
616 unsigned Offset) const;
Reid Spencer5f016e22007-07-11 17:01:13 +0000617};
618
619
620} // end namespace clang
621
622#endif