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