SourceManager.cpp revision 0e0e5da00e92a9ee97b2469009355926ee8d94bf
1//===--- SourceManager.cpp - Track and cache source files -----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file implements the SourceManager interface.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Basic/SourceManager.h"
15#include "clang/Basic/FileManager.h"
16#include "llvm/Support/Compiler.h"
17#include "llvm/Support/MemoryBuffer.h"
18#include "llvm/System/Path.h"
19#include "llvm/Bitcode/Serialize.h"
20#include "llvm/Bitcode/Deserialize.h"
21#include "llvm/Support/Streams.h"
22#include <algorithm>
23using namespace clang;
24using namespace SrcMgr;
25using llvm::MemoryBuffer;
26
27//===----------------------------------------------------------------------===//
28// SourceManager Helper Classes
29//===----------------------------------------------------------------------===//
30
31ContentCache::~ContentCache() {
32  delete Buffer;
33}
34
35/// getSizeBytesMapped - Returns the number of bytes actually mapped for
36///  this ContentCache.  This can be 0 if the MemBuffer was not actually
37///  instantiated.
38unsigned ContentCache::getSizeBytesMapped() const {
39  return Buffer ? Buffer->getBufferSize() : 0;
40}
41
42/// getSize - Returns the size of the content encapsulated by this ContentCache.
43///  This can be the size of the source file or the size of an arbitrary
44///  scratch buffer.  If the ContentCache encapsulates a source file, that
45///  file is not lazily brought in from disk to satisfy this query.
46unsigned ContentCache::getSize() const {
47  return Entry ? Entry->getSize() : Buffer->getBufferSize();
48}
49
50const llvm::MemoryBuffer *ContentCache::getBuffer() const {
51  // Lazily create the Buffer for ContentCaches that wrap files.
52  if (!Buffer && Entry) {
53    // FIXME: Should we support a way to not have to do this check over
54    //   and over if we cannot open the file?
55    Buffer = MemoryBuffer::getFile(Entry->getName(), 0, Entry->getSize());
56  }
57  return Buffer;
58}
59
60//===----------------------------------------------------------------------===//
61// Line Table Implementation
62//===----------------------------------------------------------------------===//
63
64namespace clang {
65struct LineEntry {
66  /// FileOffset - The offset in this file that the line entry occurs at.
67  unsigned FileOffset;
68  /// LineNo - The presumed line number of this line entry: #line 4.
69  unsigned LineNo;
70  /// FilenameID - The ID of the filename identified by this line entry:
71  /// #line 4 "foo.c".  This is -1 if not specified.
72  int FilenameID;
73
74  static LineEntry get(unsigned Offs, unsigned Line, int Filename) {
75    LineEntry E;
76    E.FileOffset = Offs;
77    E.LineNo = Line;
78    E.FilenameID = Filename;
79    return E;
80  }
81};
82
83
84/// LineTableInfo - This class is used to hold and unique data used to
85/// represent #line information.
86class LineTableInfo {
87  /// FilenameIDs - This map is used to assign unique IDs to filenames in
88  /// #line directives.  This allows us to unique the filenames that
89  /// frequently reoccur and reference them with indices.  FilenameIDs holds
90  /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
91  /// to string.
92  llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
93  std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
94
95  /// LineEntries - This is a map from FileIDs to a list of line entries (sorted
96  /// by the offset they occur in the file.
97  std::map<unsigned, std::vector<LineEntry> > LineEntries;
98public:
99  LineTableInfo() {
100  }
101
102  void clear() {
103    FilenameIDs.clear();
104    FilenamesByID.clear();
105  }
106
107  ~LineTableInfo() {}
108
109  unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
110  const char *getFilename(unsigned ID) const {
111    assert(ID < FilenamesByID.size() && "Invalid FilenameID");
112    return FilenamesByID[ID]->getKeyData();
113  }
114
115  void AddLineNote(unsigned FID, unsigned Offset,
116                   unsigned LineNo, int FilenameID);
117
118  /// FindNearestLineEntry - Find the line entry nearest to FID that is before
119  /// it.  If there is no line entry before Offset in FID, return null.
120  const LineEntry *FindNearestLineEntry(unsigned FID, unsigned Offset);
121};
122} // namespace clang
123
124unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) {
125  // Look up the filename in the string table, returning the pre-existing value
126  // if it exists.
127  llvm::StringMapEntry<unsigned> &Entry =
128    FilenameIDs.GetOrCreateValue(Ptr, Ptr+Len, ~0U);
129  if (Entry.getValue() != ~0U)
130    return Entry.getValue();
131
132  // Otherwise, assign this the next available ID.
133  Entry.setValue(FilenamesByID.size());
134  FilenamesByID.push_back(&Entry);
135  return FilenamesByID.size()-1;
136}
137
138/// AddLineNote - Add a line note to the line table that indicates that there
139/// is a #line at the specified FID/Offset location which changes the presumed
140/// location to LineNo/FilenameID.
141void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
142                                unsigned LineNo, int FilenameID) {
143  std::vector<LineEntry> &Entries = LineEntries[FID];
144
145  assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
146         "Adding line entries out of order!");
147
148  // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember that
149  // we are still in "foo.h".
150  if (FilenameID == -1 && !Entries.empty())
151    FilenameID = Entries.back().FilenameID;
152
153  Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID));
154}
155
156/// FindNearestLineEntry - Find the line entry nearest to FID that is before
157/// it.  If there is no line entry before Offset in FID, return null.
158const LineEntry *LineTableInfo::FindNearestLineEntry(unsigned FID,
159                                                     unsigned Offset) {
160  const std::vector<LineEntry> &Entries = LineEntries[FID];
161  assert(!Entries.empty() && "No #line entries for this FID after all!");
162
163  if (Entries[0].FileOffset > Offset) return 0;
164
165  // FIXME: Dumb linear search.
166  // Find the maximal element that is still before Offset.
167  for (unsigned i = 1, e = Entries.size(); i != e; ++i)
168    if (Entries[i].FileOffset > Offset) return &Entries[i-1];
169  // Otherwise, all entries are before Offset.
170  return &Entries.back();
171}
172
173
174/// getLineTableFilenameID - Return the uniqued ID for the specified filename.
175///
176unsigned SourceManager::getLineTableFilenameID(const char *Ptr, unsigned Len) {
177  if (LineTable == 0)
178    LineTable = new LineTableInfo();
179  return LineTable->getLineTableFilenameID(Ptr, Len);
180}
181
182
183/// AddLineNote - Add a line note to the line table for the FileID and offset
184/// specified by Loc.  If FilenameID is -1, it is considered to be
185/// unspecified.
186void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
187                                int FilenameID) {
188  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
189
190  const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile();
191
192  // Remember that this file has #line directives now if it doesn't already.
193  const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
194
195  if (LineTable == 0)
196    LineTable = new LineTableInfo();
197  LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID);
198}
199
200
201//===----------------------------------------------------------------------===//
202// Private 'Create' methods.
203//===----------------------------------------------------------------------===//
204
205SourceManager::~SourceManager() {
206  delete LineTable;
207
208  // Delete FileEntry objects corresponding to content caches.  Since the actual
209  // content cache objects are bump pointer allocated, we just have to run the
210  // dtors, but we call the deallocate method for completeness.
211  for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
212    MemBufferInfos[i]->~ContentCache();
213    ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
214  }
215  for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
216       I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
217    I->second->~ContentCache();
218    ContentCacheAlloc.Deallocate(I->second);
219  }
220}
221
222void SourceManager::clearIDTables() {
223  MainFileID = FileID();
224  SLocEntryTable.clear();
225  LastLineNoFileIDQuery = FileID();
226  LastLineNoContentCache = 0;
227  LastFileIDLookup = FileID();
228
229  if (LineTable)
230    LineTable->clear();
231
232  // Use up FileID #0 as an invalid instantiation.
233  NextOffset = 0;
234  createInstantiationLoc(SourceLocation(), SourceLocation(), 1);
235}
236
237/// getOrCreateContentCache - Create or return a cached ContentCache for the
238/// specified file.
239const ContentCache *
240SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) {
241  assert(FileEnt && "Didn't specify a file entry to use?");
242
243  // Do we already have information about this file?
244  ContentCache *&Entry = FileInfos[FileEnt];
245  if (Entry) return Entry;
246
247  // Nope, create a new Cache entry.  Make sure it is at least 8-byte aligned
248  // so that FileInfo can use the low 3 bits of the pointer for its own
249  // nefarious purposes.
250  unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
251  EntryAlign = std::max(8U, EntryAlign);
252  Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
253  new (Entry) ContentCache(FileEnt);
254  return Entry;
255}
256
257
258/// createMemBufferContentCache - Create a new ContentCache for the specified
259///  memory buffer.  This does no caching.
260const ContentCache*
261SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
262  // Add a new ContentCache to the MemBufferInfos list and return it.  Make sure
263  // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of
264  // the pointer for its own nefarious purposes.
265  unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
266  EntryAlign = std::max(8U, EntryAlign);
267  ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
268  new (Entry) ContentCache();
269  MemBufferInfos.push_back(Entry);
270  Entry->setBuffer(Buffer);
271  return Entry;
272}
273
274//===----------------------------------------------------------------------===//
275// Methods to create new FileID's and instantiations.
276//===----------------------------------------------------------------------===//
277
278/// createFileID - Create a new fileID for the specified ContentCache and
279/// include position.  This works regardless of whether the ContentCache
280/// corresponds to a file or some other input source.
281FileID SourceManager::createFileID(const ContentCache *File,
282                                   SourceLocation IncludePos,
283                                   SrcMgr::CharacteristicKind FileCharacter) {
284  SLocEntryTable.push_back(SLocEntry::get(NextOffset,
285                                          FileInfo::get(IncludePos, File,
286                                                        FileCharacter)));
287  unsigned FileSize = File->getSize();
288  assert(NextOffset+FileSize+1 > NextOffset && "Ran out of source locations!");
289  NextOffset += FileSize+1;
290
291  // Set LastFileIDLookup to the newly created file.  The next getFileID call is
292  // almost guaranteed to be from that file.
293  return LastFileIDLookup = FileID::get(SLocEntryTable.size()-1);
294}
295
296/// createInstantiationLoc - Return a new SourceLocation that encodes the fact
297/// that a token from SpellingLoc should actually be referenced from
298/// InstantiationLoc.
299SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc,
300                                                     SourceLocation InstantLoc,
301                                                     unsigned TokLength) {
302  SLocEntryTable.push_back(SLocEntry::get(NextOffset,
303                                          InstantiationInfo::get(InstantLoc,
304                                                                 SpellingLoc)));
305  assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!");
306  NextOffset += TokLength+1;
307  return SourceLocation::getMacroLoc(NextOffset-(TokLength+1));
308}
309
310/// getBufferData - Return a pointer to the start and end of the source buffer
311/// data for the specified FileID.
312std::pair<const char*, const char*>
313SourceManager::getBufferData(FileID FID) const {
314  const llvm::MemoryBuffer *Buf = getBuffer(FID);
315  return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
316}
317
318
319//===----------------------------------------------------------------------===//
320// SourceLocation manipulation methods.
321//===----------------------------------------------------------------------===//
322
323/// getFileIDSlow - Return the FileID for a SourceLocation.  This is a very hot
324/// method that is used for all SourceManager queries that start with a
325/// SourceLocation object.  It is responsible for finding the entry in
326/// SLocEntryTable which contains the specified location.
327///
328FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
329  assert(SLocOffset && "Invalid FileID");
330
331  // After the first and second level caches, I see two common sorts of
332  // behavior: 1) a lot of searched FileID's are "near" the cached file location
333  // or are "near" the cached instantiation location.  2) others are just
334  // completely random and may be a very long way away.
335  //
336  // To handle this, we do a linear search for up to 8 steps to catch #1 quickly
337  // then we fall back to a less cache efficient, but more scalable, binary
338  // search to find the location.
339
340  // See if this is near the file point - worst case we start scanning from the
341  // most newly created FileID.
342  std::vector<SrcMgr::SLocEntry>::const_iterator I;
343
344  if (SLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
345    // Neither loc prunes our search.
346    I = SLocEntryTable.end();
347  } else {
348    // Perhaps it is near the file point.
349    I = SLocEntryTable.begin()+LastFileIDLookup.ID;
350  }
351
352  // Find the FileID that contains this.  "I" is an iterator that points to a
353  // FileID whose offset is known to be larger than SLocOffset.
354  unsigned NumProbes = 0;
355  while (1) {
356    --I;
357    if (I->getOffset() <= SLocOffset) {
358#if 0
359      printf("lin %d -> %d [%s] %d %d\n", SLocOffset,
360             I-SLocEntryTable.begin(),
361             I->isInstantiation() ? "inst" : "file",
362             LastFileIDLookup.ID,  int(SLocEntryTable.end()-I));
363#endif
364      FileID Res = FileID::get(I-SLocEntryTable.begin());
365
366      // If this isn't an instantiation, remember it.  We have good locality
367      // across FileID lookups.
368      if (!I->isInstantiation())
369        LastFileIDLookup = Res;
370      NumLinearScans += NumProbes+1;
371      return Res;
372    }
373    if (++NumProbes == 8)
374      break;
375  }
376
377  // Convert "I" back into an index.  We know that it is an entry whose index is
378  // larger than the offset we are looking for.
379  unsigned GreaterIndex = I-SLocEntryTable.begin();
380  // LessIndex - This is the lower bound of the range that we're searching.
381  // We know that the offset corresponding to the FileID is is less than
382  // SLocOffset.
383  unsigned LessIndex = 0;
384  NumProbes = 0;
385  while (1) {
386    unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
387    unsigned MidOffset = SLocEntryTable[MiddleIndex].getOffset();
388
389    ++NumProbes;
390
391    // If the offset of the midpoint is too large, chop the high side of the
392    // range to the midpoint.
393    if (MidOffset > SLocOffset) {
394      GreaterIndex = MiddleIndex;
395      continue;
396    }
397
398    // If the middle index contains the value, succeed and return.
399    if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
400#if 0
401      printf("bin %d -> %d [%s] %d %d\n", SLocOffset,
402             I-SLocEntryTable.begin(),
403             I->isInstantiation() ? "inst" : "file",
404             LastFileIDLookup.ID, int(SLocEntryTable.end()-I));
405#endif
406      FileID Res = FileID::get(MiddleIndex);
407
408      // If this isn't an instantiation, remember it.  We have good locality
409      // across FileID lookups.
410      if (!I->isInstantiation())
411        LastFileIDLookup = Res;
412      NumBinaryProbes += NumProbes;
413      return Res;
414    }
415
416    // Otherwise, move the low-side up to the middle index.
417    LessIndex = MiddleIndex;
418  }
419}
420
421SourceLocation SourceManager::
422getInstantiationLocSlowCase(SourceLocation Loc) const {
423  do {
424    std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
425    Loc =getSLocEntry(LocInfo.first).getInstantiation().getInstantiationLoc();
426    Loc = Loc.getFileLocWithOffset(LocInfo.second);
427  } while (!Loc.isFileID());
428
429  return Loc;
430}
431
432SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const {
433  do {
434    std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
435    Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
436    Loc = Loc.getFileLocWithOffset(LocInfo.second);
437  } while (!Loc.isFileID());
438  return Loc;
439}
440
441
442std::pair<FileID, unsigned>
443SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
444                                                     unsigned Offset) const {
445  // If this is an instantiation record, walk through all the instantiation
446  // points.
447  FileID FID;
448  SourceLocation Loc;
449  do {
450    Loc = E->getInstantiation().getInstantiationLoc();
451
452    FID = getFileID(Loc);
453    E = &getSLocEntry(FID);
454    Offset += Loc.getOffset()-E->getOffset();
455  } while (!Loc.isFileID());
456
457  return std::make_pair(FID, Offset);
458}
459
460std::pair<FileID, unsigned>
461SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
462                                                unsigned Offset) const {
463  // If this is an instantiation record, walk through all the instantiation
464  // points.
465  FileID FID;
466  SourceLocation Loc;
467  do {
468    Loc = E->getInstantiation().getSpellingLoc();
469
470    FID = getFileID(Loc);
471    E = &getSLocEntry(FID);
472    Offset += Loc.getOffset()-E->getOffset();
473  } while (!Loc.isFileID());
474
475  return std::make_pair(FID, Offset);
476}
477
478
479//===----------------------------------------------------------------------===//
480// Queries about the code at a SourceLocation.
481//===----------------------------------------------------------------------===//
482
483/// getCharacterData - Return a pointer to the start of the specified location
484/// in the appropriate MemoryBuffer.
485const char *SourceManager::getCharacterData(SourceLocation SL) const {
486  // Note that this is a hot function in the getSpelling() path, which is
487  // heavily used by -E mode.
488  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL);
489
490  // Note that calling 'getBuffer()' may lazily page in a source file.
491  return getSLocEntry(LocInfo.first).getFile().getContentCache()
492              ->getBuffer()->getBufferStart() + LocInfo.second;
493}
494
495
496/// getColumnNumber - Return the column # for the specified file position.
497/// this is significantly cheaper to compute than the line number.
498unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos) const {
499  const char *Buf = getBuffer(FID)->getBufferStart();
500
501  unsigned LineStart = FilePos;
502  while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
503    --LineStart;
504  return FilePos-LineStart+1;
505}
506
507unsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc) const {
508  if (Loc.isInvalid()) return 0;
509  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
510  return getColumnNumber(LocInfo.first, LocInfo.second);
511}
512
513unsigned SourceManager::getInstantiationColumnNumber(SourceLocation Loc) const {
514  if (Loc.isInvalid()) return 0;
515  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
516  return getColumnNumber(LocInfo.first, LocInfo.second);
517}
518
519
520
521static void ComputeLineNumbers(ContentCache* FI,
522                               llvm::BumpPtrAllocator &Alloc) DISABLE_INLINE;
523static void ComputeLineNumbers(ContentCache* FI, llvm::BumpPtrAllocator &Alloc){
524  // Note that calling 'getBuffer()' may lazily page in the file.
525  const MemoryBuffer *Buffer = FI->getBuffer();
526
527  // Find the file offsets of all of the *physical* source lines.  This does
528  // not look at trigraphs, escaped newlines, or anything else tricky.
529  std::vector<unsigned> LineOffsets;
530
531  // Line #1 starts at char 0.
532  LineOffsets.push_back(0);
533
534  const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
535  const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
536  unsigned Offs = 0;
537  while (1) {
538    // Skip over the contents of the line.
539    // TODO: Vectorize this?  This is very performance sensitive for programs
540    // with lots of diagnostics and in -E mode.
541    const unsigned char *NextBuf = (const unsigned char *)Buf;
542    while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
543      ++NextBuf;
544    Offs += NextBuf-Buf;
545    Buf = NextBuf;
546
547    if (Buf[0] == '\n' || Buf[0] == '\r') {
548      // If this is \n\r or \r\n, skip both characters.
549      if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
550        ++Offs, ++Buf;
551      ++Offs, ++Buf;
552      LineOffsets.push_back(Offs);
553    } else {
554      // Otherwise, this is a null.  If end of file, exit.
555      if (Buf == End) break;
556      // Otherwise, skip the null.
557      ++Offs, ++Buf;
558    }
559  }
560
561  // Copy the offsets into the FileInfo structure.
562  FI->NumLines = LineOffsets.size();
563  FI->SourceLineCache = Alloc.Allocate<unsigned>(LineOffsets.size());
564  std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
565}
566
567/// getLineNumber - Given a SourceLocation, return the spelling line number
568/// for the position indicated.  This requires building and caching a table of
569/// line offsets for the MemoryBuffer, so this is not cheap: use only when
570/// about to emit a diagnostic.
571unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos) const {
572  ContentCache *Content;
573  if (LastLineNoFileIDQuery == FID)
574    Content = LastLineNoContentCache;
575  else
576    Content = const_cast<ContentCache*>(getSLocEntry(FID)
577                                        .getFile().getContentCache());
578
579  // If this is the first use of line information for this buffer, compute the
580  /// SourceLineCache for it on demand.
581  if (Content->SourceLineCache == 0)
582    ComputeLineNumbers(Content, ContentCacheAlloc);
583
584  // Okay, we know we have a line number table.  Do a binary search to find the
585  // line number that this character position lands on.
586  unsigned *SourceLineCache = Content->SourceLineCache;
587  unsigned *SourceLineCacheStart = SourceLineCache;
588  unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
589
590  unsigned QueriedFilePos = FilePos+1;
591
592  // If the previous query was to the same file, we know both the file pos from
593  // that query and the line number returned.  This allows us to narrow the
594  // search space from the entire file to something near the match.
595  if (LastLineNoFileIDQuery == FID) {
596    if (QueriedFilePos >= LastLineNoFilePos) {
597      SourceLineCache = SourceLineCache+LastLineNoResult-1;
598
599      // The query is likely to be nearby the previous one.  Here we check to
600      // see if it is within 5, 10 or 20 lines.  It can be far away in cases
601      // where big comment blocks and vertical whitespace eat up lines but
602      // contribute no tokens.
603      if (SourceLineCache+5 < SourceLineCacheEnd) {
604        if (SourceLineCache[5] > QueriedFilePos)
605          SourceLineCacheEnd = SourceLineCache+5;
606        else if (SourceLineCache+10 < SourceLineCacheEnd) {
607          if (SourceLineCache[10] > QueriedFilePos)
608            SourceLineCacheEnd = SourceLineCache+10;
609          else if (SourceLineCache+20 < SourceLineCacheEnd) {
610            if (SourceLineCache[20] > QueriedFilePos)
611              SourceLineCacheEnd = SourceLineCache+20;
612          }
613        }
614      }
615    } else {
616      SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
617    }
618  }
619
620  // If the spread is large, do a "radix" test as our initial guess, based on
621  // the assumption that lines average to approximately the same length.
622  // NOTE: This is currently disabled, as it does not appear to be profitable in
623  // initial measurements.
624  if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
625    unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];
626
627    // Take a stab at guessing where it is.
628    unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;
629
630    // Check for -10 and +10 lines.
631    unsigned LowerBound = std::max(int(ApproxPos-10), 0);
632    unsigned UpperBound = std::min(ApproxPos+10, FileLen);
633
634    // If the computed lower bound is less than the query location, move it in.
635    if (SourceLineCache < SourceLineCacheStart+LowerBound &&
636        SourceLineCacheStart[LowerBound] < QueriedFilePos)
637      SourceLineCache = SourceLineCacheStart+LowerBound;
638
639    // If the computed upper bound is greater than the query location, move it.
640    if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
641        SourceLineCacheStart[UpperBound] >= QueriedFilePos)
642      SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
643  }
644
645  unsigned *Pos
646    = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
647  unsigned LineNo = Pos-SourceLineCacheStart;
648
649  LastLineNoFileIDQuery = FID;
650  LastLineNoContentCache = Content;
651  LastLineNoFilePos = QueriedFilePos;
652  LastLineNoResult = LineNo;
653  return LineNo;
654}
655
656unsigned SourceManager::getInstantiationLineNumber(SourceLocation Loc) const {
657  if (Loc.isInvalid()) return 0;
658  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
659  return getLineNumber(LocInfo.first, LocInfo.second);
660}
661unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc) const {
662  if (Loc.isInvalid()) return 0;
663  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
664  return getLineNumber(LocInfo.first, LocInfo.second);
665}
666
667
668/// getPresumedLoc - This method returns the "presumed" location of a
669/// SourceLocation specifies.  A "presumed location" can be modified by #line
670/// or GNU line marker directives.  This provides a view on the data that a
671/// user should see in diagnostics, for example.
672///
673/// Note that a presumed location is always given as the instantiation point
674/// of an instantiation location, not at the spelling location.
675PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
676  if (Loc.isInvalid()) return PresumedLoc();
677
678  // Presumed locations are always for instantiation points.
679  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
680
681  const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile();
682  const SrcMgr::ContentCache *C = FI.getContentCache();
683
684  // To get the source name, first consult the FileEntry (if one exists)
685  // before the MemBuffer as this will avoid unnecessarily paging in the
686  // MemBuffer.
687  const char *Filename =
688    C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
689  unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second);
690  unsigned ColNo  = getColumnNumber(LocInfo.first, LocInfo.second);
691  SourceLocation IncludeLoc = FI.getIncludeLoc();
692
693  // If we have #line directives in this file, update and overwrite the physical
694  // location info if appropriate.
695  if (FI.hasLineDirectives()) {
696    assert(LineTable && "Can't have linetable entries without a LineTable!");
697    // See if there is a #line directive before this.  If so, get it.
698    if (const LineEntry *Entry =
699          LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second)) {
700      // If the LineEntry indicates a filename, use it.
701      if (Entry->FilenameID != -1)
702        Filename = LineTable->getFilename(Entry->FilenameID);
703
704      // Use the line number specified by the LineEntry.  This line number may
705      // be multiple lines down from the line entry.  Add the difference in
706      // physical line numbers from the query point and the line marker to the
707      // total.
708      unsigned MarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset);
709      LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
710
711      // Note that column numbers are not molested by line markers.
712    }
713  }
714
715  return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc);
716}
717
718//===----------------------------------------------------------------------===//
719// Other miscellaneous methods.
720//===----------------------------------------------------------------------===//
721
722
723/// PrintStats - Print statistics to stderr.
724///
725void SourceManager::PrintStats() const {
726  llvm::cerr << "\n*** Source Manager Stats:\n";
727  llvm::cerr << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
728             << " mem buffers mapped.\n";
729  llvm::cerr << SLocEntryTable.size() << " SLocEntry's allocated, "
730             << NextOffset << "B of Sloc address space used.\n";
731
732  unsigned NumLineNumsComputed = 0;
733  unsigned NumFileBytesMapped = 0;
734  for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){
735    NumLineNumsComputed += I->second->SourceLineCache != 0;
736    NumFileBytesMapped  += I->second->getSizeBytesMapped();
737  }
738
739  llvm::cerr << NumFileBytesMapped << " bytes of files mapped, "
740             << NumLineNumsComputed << " files with line #'s computed.\n";
741  llvm::cerr << "FileID scans: " << NumLinearScans << " linear, "
742             << NumBinaryProbes << " binary.\n";
743}
744
745//===----------------------------------------------------------------------===//
746// Serialization.
747//===----------------------------------------------------------------------===//
748
749void ContentCache::Emit(llvm::Serializer& S) const {
750  S.FlushRecord();
751  S.EmitPtr(this);
752
753  if (Entry) {
754    llvm::sys::Path Fname(Buffer->getBufferIdentifier());
755
756    if (Fname.isAbsolute())
757      S.EmitCStr(Fname.c_str());
758    else {
759      // Create an absolute path.
760      // FIXME: This will potentially contain ".." and "." in the path.
761      llvm::sys::Path path = llvm::sys::Path::GetCurrentDirectory();
762      path.appendComponent(Fname.c_str());
763      S.EmitCStr(path.c_str());
764    }
765  }
766  else {
767    const char* p = Buffer->getBufferStart();
768    const char* e = Buffer->getBufferEnd();
769
770    S.EmitInt(e-p);
771
772    for ( ; p != e; ++p)
773      S.EmitInt(*p);
774  }
775
776  S.FlushRecord();
777}
778
779void ContentCache::ReadToSourceManager(llvm::Deserializer& D,
780                                       SourceManager& SMgr,
781                                       FileManager* FMgr,
782                                       std::vector<char>& Buf) {
783  if (FMgr) {
784    llvm::SerializedPtrID PtrID = D.ReadPtrID();
785    D.ReadCStr(Buf,false);
786
787    // Create/fetch the FileEntry.
788    const char* start = &Buf[0];
789    const FileEntry* E = FMgr->getFile(start,start+Buf.size());
790
791    // FIXME: Ideally we want a lazy materialization of the ContentCache
792    //  anyway, because we don't want to read in source files unless this
793    //  is absolutely needed.
794    if (!E)
795      D.RegisterPtr(PtrID,NULL);
796    else
797      // Get the ContextCache object and register it with the deserializer.
798      D.RegisterPtr(PtrID, SMgr.getOrCreateContentCache(E));
799    return;
800  }
801
802  // Register the ContextCache object with the deserializer.
803  /* FIXME:
804  ContentCache *Entry
805  SMgr.MemBufferInfos.push_back(ContentCache());
806   = const_cast<ContentCache&>(SMgr.MemBufferInfos.back());
807  D.RegisterPtr(&Entry);
808
809  // Create the buffer.
810  unsigned Size = D.ReadInt();
811  Entry.Buffer = MemoryBuffer::getNewUninitMemBuffer(Size);
812
813  // Read the contents of the buffer.
814  char* p = const_cast<char*>(Entry.Buffer->getBufferStart());
815  for (unsigned i = 0; i < Size ; ++i)
816    p[i] = D.ReadInt();
817   */
818}
819
820void SourceManager::Emit(llvm::Serializer& S) const {
821  S.EnterBlock();
822  S.EmitPtr(this);
823  S.EmitInt(MainFileID.getOpaqueValue());
824
825  // Emit: FileInfos.  Just emit the file name.
826  S.EnterBlock();
827
828  // FIXME: Emit FileInfos.
829  //std::for_each(FileInfos.begin(), FileInfos.end(),
830  //              S.MakeEmitter<ContentCache>());
831
832  S.ExitBlock();
833
834  // Emit: MemBufferInfos
835  S.EnterBlock();
836
837  /* FIXME: EMIT.
838  std::for_each(MemBufferInfos.begin(), MemBufferInfos.end(),
839                S.MakeEmitter<ContentCache>());
840   */
841
842  S.ExitBlock();
843
844  // FIXME: Emit SLocEntryTable.
845
846  S.ExitBlock();
847}
848
849SourceManager*
850SourceManager::CreateAndRegister(llvm::Deserializer &D, FileManager &FMgr) {
851  SourceManager *M = new SourceManager();
852  D.RegisterPtr(M);
853
854  // Read: the FileID of the main source file of the translation unit.
855  M->MainFileID = FileID::get(D.ReadInt());
856
857  std::vector<char> Buf;
858
859  /*{ // FIXME Read: FileInfos.
860    llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
861    while (!D.FinishedBlock(BLoc))
862    ContentCache::ReadToSourceManager(D,*M,&FMgr,Buf);
863  }*/
864
865  { // Read: MemBufferInfos.
866    llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
867    while (!D.FinishedBlock(BLoc))
868    ContentCache::ReadToSourceManager(D,*M,NULL,Buf);
869  }
870
871  // FIXME: Read SLocEntryTable.
872
873  return M;
874}
875