SourceManager.cpp revision de7aeefc5573d669ed476d7bda7a8940d3bcadb7
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
31// This (temporary) directive toggles between lazy and eager creation of
32// MemBuffers.  This directive is not permanent, and is here to test a few
33// potential optimizations in PTH.  Once it is clear whether eager or lazy
34// creation of MemBuffers is better this directive will get removed.
35#define LAZY
36
37ContentCache::~ContentCache() {
38  delete Buffer;
39  delete [] SourceLineCache;
40}
41
42/// getSizeBytesMapped - Returns the number of bytes actually mapped for
43///  this ContentCache.  This can be 0 if the MemBuffer was not actually
44///  instantiated.
45unsigned ContentCache::getSizeBytesMapped() const {
46  return Buffer ? Buffer->getBufferSize() : 0;
47}
48
49/// getSize - Returns the size of the content encapsulated by this ContentCache.
50///  This can be the size of the source file or the size of an arbitrary
51///  scratch buffer.  If the ContentCache encapsulates a source file, that
52///  file is not lazily brought in from disk to satisfy this query.
53unsigned ContentCache::getSize() const {
54  return Entry ? Entry->getSize() : Buffer->getBufferSize();
55}
56
57const llvm::MemoryBuffer* ContentCache::getBuffer() const {
58#ifdef LAZY
59  // Lazily create the Buffer for ContentCaches that wrap files.
60  if (!Buffer && Entry) {
61    // FIXME: Should we support a way to not have to do this check over
62    //   and over if we cannot open the file?
63    Buffer = MemoryBuffer::getFile(Entry->getName(), 0, Entry->getSize());
64  }
65#endif
66  return Buffer;
67}
68
69//===--------------------------------------------------------------------===//
70// Private 'Create' methods.
71//===--------------------------------------------------------------------===//
72
73/// getOrCreateContentCache - Create or return a cached ContentCache for the
74/// specified file.
75const ContentCache *
76SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) {
77  assert(FileEnt && "Didn't specify a file entry to use?");
78
79  // Do we already have information about this file?
80  std::set<ContentCache>::iterator I =
81    FileInfos.lower_bound(ContentCache(FileEnt));
82
83  if (I != FileInfos.end() && I->Entry == FileEnt)
84    return &*I;
85
86  // Nope, get information.
87#ifndef LAZY
88  const MemoryBuffer *File =
89    MemoryBuffer::getFile(FileEnt->getName(), 0, FileEnt->getSize());
90  if (File == 0)
91    return 0;
92#endif
93
94  ContentCache& Entry = const_cast<ContentCache&>(*FileInfos.insert(I,FileEnt));
95#ifndef LAZY
96  Entry.setBuffer(File);
97#endif
98  Entry.SourceLineCache = 0;
99  Entry.NumLines = 0;
100  return &Entry;
101}
102
103
104/// createMemBufferContentCache - Create a new ContentCache for the specified
105///  memory buffer.  This does no caching.
106const ContentCache*
107SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
108  // Add a new ContentCache to the MemBufferInfos list and return it.  We
109  // must default construct the object first that the instance actually
110  // stored within MemBufferInfos actually owns the Buffer, and not any
111  // temporary we would use in the call to "push_back".
112  MemBufferInfos.push_back(ContentCache());
113  ContentCache& Entry = const_cast<ContentCache&>(MemBufferInfos.back());
114  Entry.setBuffer(Buffer);
115  return &Entry;
116}
117
118//===----------------------------------------------------------------------===//
119// Methods to create new FileID's and instantiations.
120//===----------------------------------------------------------------------===//
121
122/// createFileID - Create a new fileID for the specified ContentCache and
123/// include position.  This works regardless of whether the ContentCache
124/// corresponds to a file or some other input source.
125FileID SourceManager::createFileID(const ContentCache *File,
126                                   SourceLocation IncludePos,
127                                   SrcMgr::CharacteristicKind FileCharacter) {
128  SLocEntryTable.push_back(SLocEntry::get(NextOffset,
129                                          FileInfo::get(IncludePos, File,
130                                                        FileCharacter)));
131  unsigned FileSize = File->getSize();
132  assert(NextOffset+FileSize+1 > NextOffset && "Ran out of source locations!");
133  NextOffset += FileSize+1;
134
135  // Set LastFileIDLookup to the newly created file.  The next getFileID call is
136  // almost guaranteed to be from that file.
137  return LastFileIDLookup = FileID::get(SLocEntryTable.size()-1);
138}
139
140/// createInstantiationLoc - Return a new SourceLocation that encodes the fact
141/// that a token from SpellingLoc should actually be referenced from
142/// InstantiationLoc.
143SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc,
144                                                     SourceLocation InstantLoc,
145                                                     unsigned TokLength) {
146  // The specified source location may be a mapped location, due to a macro
147  // instantiation or #line directive.  Strip off this information to find out
148  // where the characters are actually located.
149  SpellingLoc = getSpellingLoc(SpellingLoc);
150
151  // Resolve InstantLoc down to a real instantiation location.
152  InstantLoc = getInstantiationLoc(InstantLoc);
153
154  SLocEntryTable.push_back(SLocEntry::get(NextOffset,
155                                          InstantiationInfo::get(InstantLoc,
156                                                                 SpellingLoc)));
157  assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!");
158  NextOffset += TokLength+1;
159  return SourceLocation::getMacroLoc(NextOffset-(TokLength+1));
160}
161
162/// getBufferData - Return a pointer to the start and end of the source buffer
163/// data for the specified FileID.
164std::pair<const char*, const char*>
165SourceManager::getBufferData(FileID FID) const {
166  const llvm::MemoryBuffer *Buf = getBuffer(FID);
167  return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
168}
169
170
171//===--------------------------------------------------------------------===//
172// SourceLocation manipulation methods.
173//===--------------------------------------------------------------------===//
174
175/// getFileIDSlow - Return the FileID for a SourceLocation.  This is a very hot
176/// method that is used for all SourceManager queries that start with a
177/// SourceLocation object.  It is responsible for finding the entry in
178/// SLocEntryTable which contains the specified location.
179///
180FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
181  assert(SLocOffset && "Invalid FileID");
182
183  // After the first and second level caches, I see two common sorts of
184  // behavior: 1) a lot of searched FileID's are "near" the cached file location
185  // or are "near" the cached instantiation location.  2) others are just
186  // completely random and may be a very long way away.
187  //
188  // To handle this, we do a linear search for up to 8 steps to catch #1 quickly
189  // then we fall back to a less cache efficient, but more scalable, binary
190  // search to find the location.
191
192  // See if this is near the file point - worst case we start scanning from the
193  // most newly created FileID.
194  std::vector<SrcMgr::SLocEntry>::const_iterator I;
195
196  if (SLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
197    // Neither loc prunes our search.
198    I = SLocEntryTable.end();
199  } else {
200    // Perhaps it is near the file point.
201    I = SLocEntryTable.begin()+LastFileIDLookup.ID;
202  }
203
204  // Find the FileID that contains this.  "I" is an iterator that points to a
205  // FileID whose offset is known to be larger than SLocOffset.
206  unsigned NumProbes = 0;
207  while (1) {
208    --I;
209    if (I->getOffset() <= SLocOffset) {
210#if 0
211      printf("lin %d -> %d [%s] %d %d\n", SLocOffset,
212             I-SLocEntryTable.begin(),
213             I->isInstantiation() ? "inst" : "file",
214             LastFileIDLookup.ID,  int(SLocEntryTable.end()-I));
215#endif
216      FileID Res = FileID::get(I-SLocEntryTable.begin());
217
218      // If this isn't an instantiation, remember it.  We have good locality
219      // across FileID lookups.
220      if (!I->isInstantiation())
221        LastFileIDLookup = Res;
222      NumLinearScans += NumProbes+1;
223      return Res;
224    }
225    if (++NumProbes == 8)
226      break;
227  }
228
229  // Convert "I" back into an index.  We know that it is an entry whose index is
230  // larger than the offset we are looking for.
231  unsigned GreaterIndex = I-SLocEntryTable.begin();
232  // LessIndex - This is the lower bound of the range that we're searching.
233  // We know that the offset corresponding to the FileID is is less than
234  // SLocOffset.
235  unsigned LessIndex = 0;
236  NumProbes = 0;
237  while (1) {
238    unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
239    unsigned MidOffset = SLocEntryTable[MiddleIndex].getOffset();
240
241    ++NumProbes;
242
243    // If the offset of the midpoint is too large, chop the high side of the
244    // range to the midpoint.
245    if (MidOffset > SLocOffset) {
246      GreaterIndex = MiddleIndex;
247      continue;
248    }
249
250    // If the middle index contains the value, succeed and return.
251    if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
252#if 0
253      printf("bin %d -> %d [%s] %d %d\n", SLocOffset,
254             I-SLocEntryTable.begin(),
255             I->isInstantiation() ? "inst" : "file",
256             LastFileIDLookup.ID, int(SLocEntryTable.end()-I));
257#endif
258      FileID Res = FileID::get(MiddleIndex);
259
260      // If this isn't an instantiation, remember it.  We have good locality
261      // across FileID lookups.
262      if (!I->isInstantiation())
263        LastFileIDLookup = Res;
264      NumBinaryProbes += NumProbes;
265      return Res;
266    }
267
268    // Otherwise, move the low-side up to the middle index.
269    LessIndex = MiddleIndex;
270  }
271}
272
273std::pair<FileID, unsigned>
274SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
275                                                     unsigned Offset) const {
276  // If this is an instantiation record, walk through all the instantiation
277  // points.
278  FileID FID;
279  SourceLocation Loc;
280  do {
281    Loc = E->getInstantiation().getInstantiationLoc();
282
283    FID = getFileID(Loc);
284    E = &getSLocEntry(FID);
285    Offset += Loc.getOffset()-E->getOffset();
286  } while (Loc.isFileID());
287
288  return std::make_pair(FID, Offset);
289}
290
291std::pair<FileID, unsigned>
292SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
293                                                unsigned Offset) const {
294  // If this is an instantiation record, get and return the spelling.
295  SourceLocation Loc = E->getInstantiation().getSpellingLoc();
296  FileID FID = getFileID(Loc);
297  E = &getSLocEntry(FID);
298  Offset += Loc.getOffset()-E->getOffset();
299  assert(Loc.isFileID() && "Should only have one spelling link");
300  return std::make_pair(FID, Offset);
301}
302
303
304//===----------------------------------------------------------------------===//
305// Queries about the code at a SourceLocation.
306//===----------------------------------------------------------------------===//
307
308/// getCharacterData - Return a pointer to the start of the specified location
309/// in the appropriate MemoryBuffer.
310const char *SourceManager::getCharacterData(SourceLocation SL) const {
311  // Note that this is a hot function in the getSpelling() path, which is
312  // heavily used by -E mode.
313  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL);
314
315  // Note that calling 'getBuffer()' may lazily page in a source file.
316  return getSLocEntry(LocInfo.first).getFile().getContentCache()
317              ->getBuffer()->getBufferStart() + LocInfo.second;
318}
319
320
321/// getColumnNumber - Return the column # for the specified file position.
322/// this is significantly cheaper to compute than the line number.  This returns
323/// zero if the column number isn't known.
324unsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
325  if (Loc.isInvalid()) return 0;
326  assert(Loc.isFileID() && "Don't know what part of instantiation loc to get");
327
328  std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
329  unsigned FilePos = LocInfo.second;
330
331  const char *Buf = getBuffer(LocInfo.first)->getBufferStart();
332
333  unsigned LineStart = FilePos;
334  while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
335    --LineStart;
336  return FilePos-LineStart+1;
337}
338
339static void ComputeLineNumbers(ContentCache* FI) DISABLE_INLINE;
340static void ComputeLineNumbers(ContentCache* FI) {
341  // Note that calling 'getBuffer()' may lazily page in the file.
342  const MemoryBuffer *Buffer = FI->getBuffer();
343
344  // Find the file offsets of all of the *physical* source lines.  This does
345  // not look at trigraphs, escaped newlines, or anything else tricky.
346  std::vector<unsigned> LineOffsets;
347
348  // Line #1 starts at char 0.
349  LineOffsets.push_back(0);
350
351  const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
352  const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
353  unsigned Offs = 0;
354  while (1) {
355    // Skip over the contents of the line.
356    // TODO: Vectorize this?  This is very performance sensitive for programs
357    // with lots of diagnostics and in -E mode.
358    const unsigned char *NextBuf = (const unsigned char *)Buf;
359    while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
360      ++NextBuf;
361    Offs += NextBuf-Buf;
362    Buf = NextBuf;
363
364    if (Buf[0] == '\n' || Buf[0] == '\r') {
365      // If this is \n\r or \r\n, skip both characters.
366      if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
367        ++Offs, ++Buf;
368      ++Offs, ++Buf;
369      LineOffsets.push_back(Offs);
370    } else {
371      // Otherwise, this is a null.  If end of file, exit.
372      if (Buf == End) break;
373      // Otherwise, skip the null.
374      ++Offs, ++Buf;
375    }
376  }
377
378  // Copy the offsets into the FileInfo structure.
379  FI->NumLines = LineOffsets.size();
380  FI->SourceLineCache = new unsigned[LineOffsets.size()];
381  std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
382}
383
384/// getLineNumber - Given a SourceLocation, return the spelling line number
385/// for the position indicated.  This requires building and caching a table of
386/// line offsets for the MemoryBuffer, so this is not cheap: use only when
387/// about to emit a diagnostic.
388unsigned SourceManager::getLineNumber(SourceLocation Loc) const {
389  if (Loc.isInvalid()) return 0;
390  assert(Loc.isFileID() && "Don't know what part of instantiation loc to get");
391
392  std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
393
394  ContentCache *Content;
395  if (LastLineNoFileIDQuery == LocInfo.first)
396    Content = LastLineNoContentCache;
397  else
398    Content = const_cast<ContentCache*>(getSLocEntry(LocInfo.first)
399                                        .getFile().getContentCache());
400
401  // If this is the first use of line information for this buffer, compute the
402  /// SourceLineCache for it on demand.
403  if (Content->SourceLineCache == 0)
404    ComputeLineNumbers(Content);
405
406  // Okay, we know we have a line number table.  Do a binary search to find the
407  // line number that this character position lands on.
408  unsigned *SourceLineCache = Content->SourceLineCache;
409  unsigned *SourceLineCacheStart = SourceLineCache;
410  unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
411
412  unsigned QueriedFilePos = LocInfo.second+1;
413
414  // If the previous query was to the same file, we know both the file pos from
415  // that query and the line number returned.  This allows us to narrow the
416  // search space from the entire file to something near the match.
417  if (LastLineNoFileIDQuery == LocInfo.first) {
418    if (QueriedFilePos >= LastLineNoFilePos) {
419      SourceLineCache = SourceLineCache+LastLineNoResult-1;
420
421      // The query is likely to be nearby the previous one.  Here we check to
422      // see if it is within 5, 10 or 20 lines.  It can be far away in cases
423      // where big comment blocks and vertical whitespace eat up lines but
424      // contribute no tokens.
425      if (SourceLineCache+5 < SourceLineCacheEnd) {
426        if (SourceLineCache[5] > QueriedFilePos)
427          SourceLineCacheEnd = SourceLineCache+5;
428        else if (SourceLineCache+10 < SourceLineCacheEnd) {
429          if (SourceLineCache[10] > QueriedFilePos)
430            SourceLineCacheEnd = SourceLineCache+10;
431          else if (SourceLineCache+20 < SourceLineCacheEnd) {
432            if (SourceLineCache[20] > QueriedFilePos)
433              SourceLineCacheEnd = SourceLineCache+20;
434          }
435        }
436      }
437    } else {
438      SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
439    }
440  }
441
442  // If the spread is large, do a "radix" test as our initial guess, based on
443  // the assumption that lines average to approximately the same length.
444  // NOTE: This is currently disabled, as it does not appear to be profitable in
445  // initial measurements.
446  if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
447    unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];
448
449    // Take a stab at guessing where it is.
450    unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;
451
452    // Check for -10 and +10 lines.
453    unsigned LowerBound = std::max(int(ApproxPos-10), 0);
454    unsigned UpperBound = std::min(ApproxPos+10, FileLen);
455
456    // If the computed lower bound is less than the query location, move it in.
457    if (SourceLineCache < SourceLineCacheStart+LowerBound &&
458        SourceLineCacheStart[LowerBound] < QueriedFilePos)
459      SourceLineCache = SourceLineCacheStart+LowerBound;
460
461    // If the computed upper bound is greater than the query location, move it.
462    if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
463        SourceLineCacheStart[UpperBound] >= QueriedFilePos)
464      SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
465  }
466
467  unsigned *Pos
468    = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
469  unsigned LineNo = Pos-SourceLineCacheStart;
470
471  LastLineNoFileIDQuery = LocInfo.first;
472  LastLineNoContentCache = Content;
473  LastLineNoFilePos = QueriedFilePos;
474  LastLineNoResult = LineNo;
475  return LineNo;
476}
477
478/// getSourceName - This method returns the name of the file or buffer that
479/// the SourceLocation specifies.  This can be modified with #line directives,
480/// etc.
481const char *SourceManager::getSourceName(SourceLocation Loc) const {
482  if (Loc.isInvalid()) return "";
483
484  const SrcMgr::ContentCache *C =
485  getSLocEntry(getFileID(getSpellingLoc(Loc))).getFile().getContentCache();
486
487  // To get the source name, first consult the FileEntry (if one exists) before
488  // the MemBuffer as this will avoid unnecessarily paging in the MemBuffer.
489  return C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
490}
491
492//===----------------------------------------------------------------------===//
493// Other miscellaneous methods.
494//===----------------------------------------------------------------------===//
495
496
497/// PrintStats - Print statistics to stderr.
498///
499void SourceManager::PrintStats() const {
500  llvm::cerr << "\n*** Source Manager Stats:\n";
501  llvm::cerr << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
502             << " mem buffers mapped, " << SLocEntryTable.size()
503             << " SLocEntry's allocated.\n";
504
505  unsigned NumLineNumsComputed = 0;
506  unsigned NumFileBytesMapped = 0;
507  for (std::set<ContentCache>::const_iterator I =
508       FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
509    NumLineNumsComputed += I->SourceLineCache != 0;
510    NumFileBytesMapped  += I->getSizeBytesMapped();
511  }
512
513  llvm::cerr << NumFileBytesMapped << " bytes of files mapped, "
514             << NumLineNumsComputed << " files with line #'s computed.\n";
515  llvm::cerr << "FileID scans: " << NumLinearScans << " linear, "
516             << NumBinaryProbes << " binary.\n";
517}
518
519//===----------------------------------------------------------------------===//
520// Serialization.
521//===----------------------------------------------------------------------===//
522
523void ContentCache::Emit(llvm::Serializer& S) const {
524  S.FlushRecord();
525  S.EmitPtr(this);
526
527  if (Entry) {
528    llvm::sys::Path Fname(Buffer->getBufferIdentifier());
529
530    if (Fname.isAbsolute())
531      S.EmitCStr(Fname.c_str());
532    else {
533      // Create an absolute path.
534      // FIXME: This will potentially contain ".." and "." in the path.
535      llvm::sys::Path path = llvm::sys::Path::GetCurrentDirectory();
536      path.appendComponent(Fname.c_str());
537      S.EmitCStr(path.c_str());
538    }
539  }
540  else {
541    const char* p = Buffer->getBufferStart();
542    const char* e = Buffer->getBufferEnd();
543
544    S.EmitInt(e-p);
545
546    for ( ; p != e; ++p)
547      S.EmitInt(*p);
548  }
549
550  S.FlushRecord();
551}
552
553void ContentCache::ReadToSourceManager(llvm::Deserializer& D,
554                                       SourceManager& SMgr,
555                                       FileManager* FMgr,
556                                       std::vector<char>& Buf) {
557  if (FMgr) {
558    llvm::SerializedPtrID PtrID = D.ReadPtrID();
559    D.ReadCStr(Buf,false);
560
561    // Create/fetch the FileEntry.
562    const char* start = &Buf[0];
563    const FileEntry* E = FMgr->getFile(start,start+Buf.size());
564
565    // FIXME: Ideally we want a lazy materialization of the ContentCache
566    //  anyway, because we don't want to read in source files unless this
567    //  is absolutely needed.
568    if (!E)
569      D.RegisterPtr(PtrID,NULL);
570    else
571      // Get the ContextCache object and register it with the deserializer.
572      D.RegisterPtr(PtrID, SMgr.getOrCreateContentCache(E));
573    return;
574  }
575
576  // Register the ContextCache object with the deserializer.
577  SMgr.MemBufferInfos.push_back(ContentCache());
578  ContentCache& Entry = const_cast<ContentCache&>(SMgr.MemBufferInfos.back());
579  D.RegisterPtr(&Entry);
580
581  // Create the buffer.
582  unsigned Size = D.ReadInt();
583  Entry.Buffer = MemoryBuffer::getNewUninitMemBuffer(Size);
584
585  // Read the contents of the buffer.
586  char* p = const_cast<char*>(Entry.Buffer->getBufferStart());
587  for (unsigned i = 0; i < Size ; ++i)
588    p[i] = D.ReadInt();
589}
590
591void SourceManager::Emit(llvm::Serializer& S) const {
592  S.EnterBlock();
593  S.EmitPtr(this);
594  S.EmitInt(MainFileID.getOpaqueValue());
595
596  // Emit: FileInfos.  Just emit the file name.
597  S.EnterBlock();
598
599  std::for_each(FileInfos.begin(),FileInfos.end(),
600                S.MakeEmitter<ContentCache>());
601
602  S.ExitBlock();
603
604  // Emit: MemBufferInfos
605  S.EnterBlock();
606
607  std::for_each(MemBufferInfos.begin(), MemBufferInfos.end(),
608                S.MakeEmitter<ContentCache>());
609
610  S.ExitBlock();
611
612  // FIXME: Emit SLocEntryTable.
613
614  S.ExitBlock();
615}
616
617SourceManager*
618SourceManager::CreateAndRegister(llvm::Deserializer& D, FileManager& FMgr){
619  SourceManager *M = new SourceManager();
620  D.RegisterPtr(M);
621
622  // Read: the FileID of the main source file of the translation unit.
623  M->MainFileID = FileID::get(D.ReadInt());
624
625  std::vector<char> Buf;
626
627  { // Read: FileInfos.
628    llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
629    while (!D.FinishedBlock(BLoc))
630    ContentCache::ReadToSourceManager(D,*M,&FMgr,Buf);
631  }
632
633  { // Read: MemBufferInfos.
634    llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
635    while (!D.FinishedBlock(BLoc))
636    ContentCache::ReadToSourceManager(D,*M,NULL,Buf);
637  }
638
639  // FIXME: Read SLocEntryTable.
640
641  return M;
642}
643