xref: /llvm-project/clang/lib/Basic/SourceManager.cpp (revision 4fa23625abb476ac89b84d06ee2a45ef822eaf15)
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 // 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 
37 ContentCache::~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.
45 unsigned 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.
53 unsigned ContentCache::getSize() const {
54   return Entry ? Entry->getSize() : Buffer->getBufferSize();
55 }
56 
57 const 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.
75 const ContentCache *
76 SourceManager::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.
106 const ContentCache*
107 SourceManager::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.
125 FileID 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.
143 SourceLocation 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.
164 std::pair<const char*, const char*>
165 SourceManager::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 ///
180 FileID 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 
273 std::pair<FileID, unsigned>
274 SourceManager::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 
291 std::pair<FileID, unsigned>
292 SourceManager::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.
310 const 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.
324 unsigned 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 
339 static void ComputeLineNumbers(ContentCache* FI) DISABLE_INLINE;
340 static 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.
388 unsigned 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.
481 const 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 ///
499 void 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 
523 void 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 
553 void 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 
591 void 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 
617 SourceManager*
618 SourceManager::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