SourceManager.h revision 8673ae73569d3417854527cebfe95b4c3e37d311
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===//
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//                     The LLVM Compiler Infrastructure
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com//
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// This file is distributed under the University of Illinois Open Source
6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com// License. See LICENSE.TXT for details.
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com//
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com//===----------------------------------------------------------------------===//
9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com//
10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com//  This file defines the SourceManager interface.
11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com//
128d033a1b125886c62906d975b5cc28a382064526bsalomon@google.com//===----------------------------------------------------------------------===//
13ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
147d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org#ifndef LLVM_CLANG_SOURCEMANAGER_H
15ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#define LLVM_CLANG_SOURCEMANAGER_H
16ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
17ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "clang/Basic/SourceLocation.h"
18ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "llvm/Bitcode/SerializationFwd.h"
19ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include <vector>
20ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include <set>
21ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include <list>
22ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include <cassert>
23ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
24ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comnamespace llvm {
257d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.orgclass MemoryBuffer;
268d033a1b125886c62906d975b5cc28a382064526bsalomon@google.com}
27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
28ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comnamespace clang {
29d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips
30ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comclass SourceManager;
31fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgclass FileManager;
327d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.orgclass FileEntry;
33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comclass IdentifierTokenInfo;
34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
35ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/// SrcMgr - Public enums and private classes that are part of the
36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/// SourceManager implementation.
37ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com///
38fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comnamespace SrcMgr {
39ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  /// Characteristic_t - This is used to represent whether a file or directory
40ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  /// holds normal user code, system code, or system code which is implicitly
41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  /// 'extern "C"' in C++ mode.  Entire directories can be tagged with this
42ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  /// (this is maintained by DirectoryLookup and friends) as can specific
43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  /// FileIDInfos when a #pragma system_header is seen or various other cases.
44ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  ///
45fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com  enum Characteristic_t {
46ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    C_User, C_System, C_ExternCSystem
47ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  };
48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  /// ContentCache - Once instance of this struct is kept for every file
50ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  ///  loaded or used.  This object owns the MemoryBuffer object.
51ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com  struct ContentCache {
52fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    /// Reference to the file entry.  This reference does not own
53972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    /// the FileEntry object.  It is possible for this to be NULL if
54ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    /// the ContentCache encapsulates an imaginary text buffer.
55ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    const FileEntry* Entry;
56ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
57fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    /// Buffer - The actual buffer containing the characters from the input
58972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    /// file.  This is owned by the ContentCache object.
59ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    const llvm::MemoryBuffer* Buffer;
60ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
61ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    /// SourceLineCache - A new[]'d array of offsets for each source line.  This
62ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    /// is lazily computed.  This is owned by the ContentCache object.
63fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    unsigned* SourceLineCache;
64972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org
65ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    /// NumLines - The number of lines in this ContentCache.  This is only valid
66ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    /// if SourceLineCache is non-null.
67fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    unsigned NumLines;
68972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org
69ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    ContentCache(const FileEntry* e = NULL)
70ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    : Entry(e), Buffer(NULL), SourceLineCache(NULL), NumLines(0) {}
71fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    ~ContentCache();
73ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
74ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    /// The copy ctor does not allow copies where source object has either
75ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    ///  a non-NULL Buffer or SourceLineCache.  Ownership of allocated memory
76ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    ///  is not transfered, so this is a logical error.
77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    ContentCache(const ContentCache& RHS) : Buffer(NULL),SourceLineCache(NULL) {
78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com      Entry = RHS.Entry;
79
80      assert (RHS.Buffer == NULL && RHS.SourceLineCache == NULL
81              && "Passed ContentCache object cannot own a buffer.");
82
83      NumLines = RHS.NumLines;
84    }
85
86    /// Emit - Emit this ContentCache to Bitcode.
87    void Emit(llvm::Serializer& S) const;
88
89    /// ReadToSourceManager - Reconstitute a ContentCache from Bitcode
90    //   and store it in the specified SourceManager.
91    static void ReadToSourceManager(llvm::Deserializer& D, SourceManager& SMgr,
92                                    FileManager* FMgr, std::vector<char>&  Buf);
93
94  private:
95    // Disable assignments.
96    ContentCache& operator=(const ContentCache& RHS);
97  };
98
99  /// FileIDInfo - Information about a FileID, basically just the logical file
100  /// that it represents and include stack information.  A File SourceLocation
101  /// is a byte offset from the start of this.
102  ///
103  /// FileID's are used to compute the location of a character in memory as well
104  /// as the logical source location, which can be differ from the physical
105  /// location.  It is different when #line's are active or when macros have
106  /// been expanded.
107  ///
108  /// Each FileID has include stack information, indicating where it came from.
109  /// For the primary translation unit, it comes from SourceLocation() aka 0.
110  /// This information encodes the #include chain that a token was instantiated
111  /// from.
112  ///
113  /// FileIDInfos contain a "ContentCache *", describing the source file,
114  /// and a Chunk number, which allows a SourceLocation to index into very
115  /// large files (those which there are not enough FilePosBits to address).
116  ///
117  struct FileIDInfo {
118  private:
119    /// IncludeLoc - The location of the #include that brought in this file.
120    /// This SourceLocation object has an invalid SLOC for the main file.
121    SourceLocation IncludeLoc;
122
123    /// ChunkNo - Really large buffers are broken up into chunks that are
124    /// each (1 << SourceLocation::FilePosBits) in size.  This specifies the
125    /// chunk number of this FileID.
126    unsigned ChunkNo : 30;
127
128    /// FileCharacteristic - This is an instance of Characteristic_t,
129    /// indicating whether this is a system header dir or not.
130    unsigned FileCharacteristic : 2;
131
132    /// Content - Information about the source buffer itself.
133    const ContentCache* Content;
134
135  public:
136    /// get - Return a FileIDInfo object.
137    static FileIDInfo get(SourceLocation IL, unsigned CN,
138                          const ContentCache *Con,
139                          Characteristic_t FileCharacter) {
140      FileIDInfo X;
141      X.IncludeLoc = IL;
142      X.ChunkNo = CN;
143      X.Content = Con;
144      X.FileCharacteristic = FileCharacter;
145      return X;
146    }
147
148    SourceLocation getIncludeLoc() const { return IncludeLoc; }
149    unsigned getChunkNo() const { return ChunkNo; }
150    const ContentCache* getContentCache() const { return Content; }
151
152    /// getCharacteristic - Return whether this is a system header or not.
153    Characteristic_t getFileCharacteristic() const {
154      return (Characteristic_t)FileCharacteristic;
155    }
156
157    /// Emit - Emit this FileIDInfo to Bitcode.
158    void Emit(llvm::Serializer& S) const;
159
160    /// ReadVal - Reconstitute a FileIDInfo from Bitcode.
161    static FileIDInfo ReadVal(llvm::Deserializer& S);
162  };
163
164  /// MacroIDInfo - Macro SourceLocations refer to these records by their ID.
165  /// Each MacroIDInfo encodes the Instantiation location - where the macro was
166  /// instantiated, and the PhysicalLoc - where the actual character data for
167  /// the token came from.  An actual macro SourceLocation stores deltas from
168  /// these positions.
169  class MacroIDInfo {
170    SourceLocation VirtualLoc, PhysicalLoc;
171  public:
172    SourceLocation getVirtualLoc() const { return VirtualLoc; }
173    SourceLocation getPhysicalLoc() const { return PhysicalLoc; }
174
175    /// get - Return a MacroID for a macro expansion.  VL specifies
176    /// the instantiation location (where the macro is expanded), and PL
177    /// specifies the physical location (where the characters from the token
178    /// come from).  Both VL and PL refer to normal File SLocs.
179    static MacroIDInfo get(SourceLocation VL, SourceLocation PL) {
180      MacroIDInfo X;
181      X.VirtualLoc = VL;
182      X.PhysicalLoc = PL;
183      return X;
184    }
185
186    /// Emit - Emit this MacroIDInfo to Bitcode.
187    void Emit(llvm::Serializer& S) const;
188
189    /// ReadVal - Reconstitute a MacroIDInfo from Bitcode.
190    static MacroIDInfo ReadVal(llvm::Deserializer& S);
191  };
192}  // end SrcMgr namespace.
193} // end clang namespace
194
195namespace std {
196template <> struct less<clang::SrcMgr::ContentCache> {
197  inline bool operator()(const clang::SrcMgr::ContentCache& L,
198                         const clang::SrcMgr::ContentCache& R) const {
199    return L.Entry < R.Entry;
200  }
201};
202} // end std namespace
203
204namespace clang {
205
206/// SourceManager - This file handles loading and caching of source files into
207/// memory.  This object owns the MemoryBuffer objects for all of the loaded
208/// files and assigns unique FileID's for each unique #include chain.
209///
210/// The SourceManager can be queried for information about SourceLocation
211/// objects, turning them into either physical or logical locations.  Physical
212/// locations represent where the bytes corresponding to a token came from and
213/// logical locations represent where the location is in the user's view.  In
214/// the case of a macro expansion, for example, the physical location indicates
215/// where the expanded token came from and the logical location specifies where
216/// it was expanded.  Logical locations are also influenced by #line directives,
217/// etc.
218class SourceManager {
219  /// FileInfos - Memoized information about all of the files tracked by this
220  /// SourceManager.  This set allows us to merge ContentCache entries based
221  /// on their FileEntry*.  All ContentCache objects will thus have unique,
222  /// non-null, FileEntry pointers.
223  std::set<SrcMgr::ContentCache> FileInfos;
224
225  /// MemBufferInfos - Information about various memory buffers that we have
226  /// read in.  This is a list, instead of a vector, because we need pointers to
227  /// the ContentCache objects to be stable.  All FileEntry* within the
228  /// stored ContentCache objects are NULL, as they do not refer to a file.
229  std::list<SrcMgr::ContentCache> MemBufferInfos;
230
231  /// FileIDs - Information about each FileID.  FileID #0 is not valid, so all
232  /// entries are off by one.
233  std::vector<SrcMgr::FileIDInfo> FileIDs;
234
235  /// MacroIDs - Information about each MacroID.
236  std::vector<SrcMgr::MacroIDInfo> MacroIDs;
237
238  /// LastLineNo - These ivars serve as a cache used in the getLineNumber
239  /// method which is used to speedup getLineNumber calls to nearby locations.
240  unsigned LastLineNoFileIDQuery;
241  SrcMgr::ContentCache *LastLineNoContentCache;
242  unsigned LastLineNoFilePos;
243  unsigned LastLineNoResult;
244
245  /// MainFileID - The file ID for the main source file of the translation unit.
246  unsigned MainFileID;
247
248  // SourceManager doesn't support copy construction.
249  explicit SourceManager(const SourceManager&);
250  void operator=(const SourceManager&);
251public:
252  SourceManager() : LastLineNoFileIDQuery(~0U), MainFileID(0) {}
253  ~SourceManager() {}
254
255  void clearIDTables() {
256    MainFileID = 0;
257    FileIDs.clear();
258    MacroIDs.clear();
259    LastLineNoFileIDQuery = ~0U;
260    LastLineNoContentCache = 0;
261  }
262
263  /// getMainFileID - Returns the FileID of the main source file.
264  unsigned getMainFileID() const { return MainFileID; }
265
266  /// createFileID - Create a new FileID that represents the specified file
267  /// being #included from the specified IncludePosition.  This returns 0 on
268  /// error and translates NULL into standard input.
269  unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
270                        SrcMgr::Characteristic_t FileCharacter) {
271    const SrcMgr::ContentCache *IR = getContentCache(SourceFile);
272    if (IR == 0) return 0;    // Error opening file?
273    return createFileID(IR, IncludePos, FileCharacter);
274  }
275
276  /// createMainFileID - Create the FileID for the main source file.
277  unsigned createMainFileID(const FileEntry *SourceFile,
278                            SourceLocation IncludePos) {
279
280    assert (MainFileID == 0 && "MainFileID already set!");
281    MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
282    return MainFileID;
283  }
284
285  /// createFileIDForMemBuffer - Create a new FileID that represents the
286  /// specified memory buffer.  This does no caching of the buffer and takes
287  /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
288  unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
289    return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
290                        SrcMgr::C_User);
291  }
292
293  /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
294  ///  that will represent the FileID for the main source.  One example
295  ///  of when this would be used is when the main source is read from STDIN.
296  unsigned createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
297    assert (MainFileID == 0 && "MainFileID already set!");
298    MainFileID = createFileIDForMemBuffer(Buffer);
299    return MainFileID;
300  }
301
302  /// getInstantiationLoc - Return a new SourceLocation that encodes the fact
303  /// that a token at Loc should actually be referenced from InstantiationLoc.
304  SourceLocation getInstantiationLoc(SourceLocation Loc,
305                                     SourceLocation InstantiationLoc);
306
307  /// getBuffer - Return the buffer for the specified FileID.
308  ///
309  const llvm::MemoryBuffer *getBuffer(unsigned FileID) const {
310    return getContentCache(FileID)->Buffer;
311  }
312
313  /// getBufferData - Return a pointer to the start and end of the character
314  /// data for the specified FileID.
315  std::pair<const char*, const char*> getBufferData(unsigned FileID) const;
316
317  /// getIncludeLoc - Return the location of the #include for the specified
318  /// SourceLocation.  If this is a macro expansion, this transparently figures
319  /// out which file includes the file being expanded into.
320  SourceLocation getIncludeLoc(SourceLocation ID) const {
321    return getFIDInfo(getLogicalLoc(ID).getFileID())->getIncludeLoc();
322  }
323
324  /// getCharacterData - Return a pointer to the start of the specified location
325  /// in the appropriate MemoryBuffer.
326  const char *getCharacterData(SourceLocation SL) const;
327
328  /// getColumnNumber - Return the column # for the specified file position.
329  /// This is significantly cheaper to compute than the line number.  This
330  /// returns zero if the column number isn't known.  This may only be called on
331  /// a file sloc, so you must choose a physical or logical location before
332  /// calling this method.
333  unsigned getColumnNumber(SourceLocation Loc) const;
334
335  unsigned getPhysicalColumnNumber(SourceLocation Loc) const {
336    return getColumnNumber(getPhysicalLoc(Loc));
337  }
338  unsigned getLogicalColumnNumber(SourceLocation Loc) const {
339    return getColumnNumber(getLogicalLoc(Loc));
340  }
341
342
343  /// getLineNumber - Given a SourceLocation, return the physical line number
344  /// for the position indicated.  This requires building and caching a table of
345  /// line offsets for the MemoryBuffer, so this is not cheap: use only when
346  /// about to emit a diagnostic.
347  unsigned getLineNumber(SourceLocation Loc);
348
349  unsigned getLogicalLineNumber(SourceLocation Loc) {
350    return getLineNumber(getLogicalLoc(Loc));
351  }
352  unsigned getPhysicalLineNumber(SourceLocation Loc) {
353    return getLineNumber(getPhysicalLoc(Loc));
354  }
355
356  /// getSourceName - This method returns the name of the file or buffer that
357  /// the SourceLocation specifies.  This can be modified with #line directives,
358  /// etc.
359  const char *getSourceName(SourceLocation Loc) const;
360
361  /// Given a SourceLocation object, return the logical location referenced by
362  /// the ID.  This logical location is subject to #line directives, etc.
363  SourceLocation getLogicalLoc(SourceLocation Loc) const {
364    // File locations are both physical and logical.
365    if (Loc.isFileID()) return Loc;
366
367    return MacroIDs[Loc.getMacroID()].getVirtualLoc();
368  }
369
370  /// getPhysicalLoc - Given a SourceLocation object, return the physical
371  /// location referenced by the ID.
372  SourceLocation getPhysicalLoc(SourceLocation Loc) const {
373    // File locations are both physical and logical.
374    if (Loc.isFileID()) return Loc;
375
376    SourceLocation PLoc = MacroIDs[Loc.getMacroID()].getPhysicalLoc();
377    return PLoc.getFileLocWithOffset(Loc.getMacroPhysOffs());
378  }
379
380  /// getContentCacheForLoc - Return the ContentCache for the physloc of the
381  /// specified SourceLocation, if one exists.
382  const SrcMgr::ContentCache* getContentCacheForLoc(SourceLocation Loc) const {
383    Loc = getPhysicalLoc(Loc);
384    unsigned FileID = Loc.getFileID();
385    assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
386    return FileIDs[FileID-1].getContentCache();
387  }
388
389  /// getFileEntryForLoc - Return the FileEntry record for the physloc of the
390  ///  specified SourceLocation, if one exists.
391  const FileEntry* getFileEntryForLoc(SourceLocation Loc) const {
392    return getContentCacheForLoc(Loc)->Entry;
393  }
394
395  /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
396  const FileEntry* getFileEntryForID(unsigned id) const {
397    return getContentCache(id)->Entry;
398  }
399
400  /// getCanonicalFileID - Return the canonical FileID for a SourceLocation.
401  ///  A file can have multiple FileIDs if it is large enough to be broken
402  ///  into multiple chunks.  This method returns the unique FileID without
403  ///  chunk information for a given SourceLocation.  Use this method when
404  ///  you want to compare FileIDs across SourceLocations.
405  unsigned getCanonicalFileID(SourceLocation PhysLoc) const {
406    return getDecomposedFileLoc(PhysLoc).first;
407  }
408
409  /// getDecomposedFileLoc - Decompose the specified file location into a raw
410  /// FileID + Offset pair.  The first element is the FileID, the second is the
411  /// offset from the start of the buffer of the location.
412  std::pair<unsigned, unsigned> getDecomposedFileLoc(SourceLocation Loc) const {
413    assert(Loc.isFileID() && "Isn't a File SourceLocation");
414
415    // TODO: Add a flag "is first chunk" to SLOC.
416    const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getFileID());
417
418    // If this file has been split up into chunks, factor in the chunk number
419    // that the FileID references.
420    unsigned ChunkNo = FIDInfo->getChunkNo();
421    unsigned Offset = Loc.getRawFilePos();
422    Offset += (ChunkNo << SourceLocation::FilePosBits);
423
424    assert(Loc.getFileID() >= ChunkNo && "Unexpected offset");
425
426    return std::make_pair(Loc.getFileID()-ChunkNo, Offset);
427  }
428
429  /// getFullFilePos - This (efficient) method returns the offset from the start
430  /// of the file that the specified physical SourceLocation represents.  This
431  /// returns the location of the physical character data, not the logical file
432  /// position.
433  unsigned getFullFilePos(SourceLocation PhysLoc) const {
434    return getDecomposedFileLoc(PhysLoc).second;
435  }
436
437  /// isFromSameFile - Returns true if both SourceLocations correspond to
438  ///  the same file.
439  bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
440    return getCanonicalFileID(Loc1) == getCanonicalFileID(Loc2);
441  }
442
443  /// isFromMainFile - Returns true if the file of provided SourceLocation is
444  ///   the main file.
445  bool isFromMainFile(SourceLocation Loc) const {
446    return getCanonicalFileID(Loc) == getMainFileID();
447  }
448
449  /// isInSystemHeader - Returns if a SourceLocation is in a system header.
450  bool isInSystemHeader(SourceLocation Loc) const {
451    return getFileCharacteristic(Loc) != SrcMgr::C_User;
452  }
453  SrcMgr::Characteristic_t getFileCharacteristic(SourceLocation Loc) const {
454    return getFIDInfo(getPhysicalLoc(Loc).getFileID())->getFileCharacteristic();
455  }
456
457  // Iterators over FileIDs.
458
459  class fileid_iterator {
460    std::vector<SrcMgr::FileIDInfo>::iterator I;
461    unsigned fid;
462  public:
463    fileid_iterator(std::vector<SrcMgr::FileIDInfo>::iterator i, unsigned f)
464      : I(i), fid(f) {}
465
466    bool operator==(const fileid_iterator& X) const { return X.fid == fid; }
467    bool operator!=(const fileid_iterator& X) const { return X.fid != fid; }
468    fileid_iterator& operator++() { ++fid; ++I; return *this; }
469
470    unsigned getFileID() const { return fid; }
471    SrcMgr::FileIDInfo& getFileIDInfo() { return *I; }
472  };
473
474  fileid_iterator fileid_begin() {
475    return fileid_iterator(FileIDs.begin(), 1);
476  }
477
478  fileid_iterator fileid_end() {
479    return fileid_iterator(FileIDs.end(), FileIDs.size()+1);
480  }
481
482  /// PrintStats - Print statistics to stderr.
483  ///
484  void PrintStats() const;
485
486  /// Emit - Emit this SourceManager to Bitcode.
487  void Emit(llvm::Serializer& S) const;
488
489  /// Read - Reconstitute a SourceManager from Bitcode.
490  static SourceManager* CreateAndRegister(llvm::Deserializer& S,
491                                          FileManager &FMgr);
492
493private:
494  friend struct SrcMgr::ContentCache; // Used for deserialization.
495
496  /// createFileID - Create a new fileID for the specified ContentCache and
497  ///  include position.  This works regardless of whether the ContentCache
498  ///  corresponds to a file or some other input source.
499  unsigned createFileID(const SrcMgr::ContentCache* File,
500                        SourceLocation IncludePos,
501                        SrcMgr::Characteristic_t DirCharacter);
502
503  /// getContentCache - Create or return a cached ContentCache for the specified
504  ///  file.  This returns null on failure.
505  const SrcMgr::ContentCache* getContentCache(const FileEntry* SourceFile);
506
507  /// createMemBufferContentCache - Create a new ContentCache for the specified
508  ///  memory buffer.
509  const SrcMgr::ContentCache*
510  createMemBufferContentCache(const llvm::MemoryBuffer* Buf);
511
512  const SrcMgr::FileIDInfo* getFIDInfo(unsigned FileID) const {
513    assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
514    return &FileIDs[FileID-1];
515  }
516
517  const SrcMgr::ContentCache *getContentCache(unsigned FileID) const {
518    return getContentCache(getFIDInfo(FileID));
519  }
520
521  /// Return the ContentCache structure for the specified FileID.
522  ///  This is always the physical reference for the ID.
523  const SrcMgr::ContentCache*
524  getContentCache(const SrcMgr::FileIDInfo* FIDInfo) const {
525    return FIDInfo->getContentCache();
526  }
527};
528
529
530}  // end namespace clang
531
532#endif
533