SourceManager.cpp revision 48002c89578eaeb008a0bb5a10d8216e61906459
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- SourceManager.cpp - Track and cache source files -----------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file implements the SourceManager interface.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/SourceManager.h"
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/FileManager.h"
165e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner#include "llvm/Support/Compiler.h"
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/MemoryBuffer.h"
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/System/Path.h"
1978d85f53b093867bbb0123f016956178eea7343eTed Kremenek#include "llvm/Bitcode/Serialize.h"
2078d85f53b093867bbb0123f016956178eea7343eTed Kremenek#include "llvm/Bitcode/Deserialize.h"
21665dd4a40e0e38657f7bf26c2e3490304e5c7510Ted Kremenek#include "llvm/Support/Streams.h"
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <algorithm>
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace SrcMgr;
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::MemoryBuffer;
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2778d85f53b093867bbb0123f016956178eea7343eTed KremenekContentCache::~ContentCache() {
2878d85f53b093867bbb0123f016956178eea7343eTed Kremenek  delete Buffer;
2978d85f53b093867bbb0123f016956178eea7343eTed Kremenek  delete [] SourceLineCache;
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getFileInfo - Create or return a cached FileInfo for the specified file.
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
3478d85f53b093867bbb0123f016956178eea7343eTed Kremenekconst ContentCache* SourceManager::getContentCache(const FileEntry *FileEnt) {
3578d85f53b093867bbb0123f016956178eea7343eTed Kremenek
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert(FileEnt && "Didn't specify a file entry to use?");
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Do we already have information about this file?
3878d85f53b093867bbb0123f016956178eea7343eTed Kremenek  std::set<ContentCache>::iterator I =
3978d85f53b093867bbb0123f016956178eea7343eTed Kremenek    FileInfos.lower_bound(ContentCache(FileEnt));
4078d85f53b093867bbb0123f016956178eea7343eTed Kremenek
4178d85f53b093867bbb0123f016956178eea7343eTed Kremenek  if (I != FileInfos.end() && I->Entry == FileEnt)
425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return &*I;
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Nope, get information.
453c1f7b615c03e55f8aaee14a5793c917c050b373Chris Lattner  const MemoryBuffer *File =
4635de512b9cb22a234a771b417507f71a2bbb5a94Chris Lattner    MemoryBuffer::getFile(FileEnt->getName(), 0, FileEnt->getSize());
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (File == 0)
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 0;
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5078d85f53b093867bbb0123f016956178eea7343eTed Kremenek  ContentCache& Entry = const_cast<ContentCache&>(*FileInfos.insert(I,FileEnt));
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5278d85f53b093867bbb0123f016956178eea7343eTed Kremenek  Entry.Buffer = File;
5378d85f53b093867bbb0123f016956178eea7343eTed Kremenek  Entry.SourceLineCache = 0;
5478d85f53b093867bbb0123f016956178eea7343eTed Kremenek  Entry.NumLines = 0;
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return &Entry;
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
59d1c0eee9aa30926839184b657b9e21be4a2ebdb8Ted Kremenek/// createMemBufferContentCache - Create a new ContentCache for the specified
60d1c0eee9aa30926839184b657b9e21be4a2ebdb8Ted Kremenek///  memory buffer.  This does no caching.
6178d85f53b093867bbb0123f016956178eea7343eTed Kremenekconst ContentCache*
6278d85f53b093867bbb0123f016956178eea7343eTed KremenekSourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
630d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek  // Add a new ContentCache to the MemBufferInfos list and return it.  We
640d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek  // must default construct the object first that the instance actually
650d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek  // stored within MemBufferInfos actually owns the Buffer, and not any
660d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek  // temporary we would use in the call to "push_back".
6778d85f53b093867bbb0123f016956178eea7343eTed Kremenek  MemBufferInfos.push_back(ContentCache());
6878d85f53b093867bbb0123f016956178eea7343eTed Kremenek  ContentCache& Entry = const_cast<ContentCache&>(MemBufferInfos.back());
6978d85f53b093867bbb0123f016956178eea7343eTed Kremenek  Entry.Buffer = Buffer;
7078d85f53b093867bbb0123f016956178eea7343eTed Kremenek  return &Entry;
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7448002c89578eaeb008a0bb5a10d8216e61906459Nico Weber/// createFileID - Create a new fileID for the specified ContentCache and
750d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek/// include position.  This works regardless of whether the ContentCache
760d892d8bfddd4916cc4f3467e1184a623d0716daTed Kremenek/// corresponds to a file or some other input source.
7778d85f53b093867bbb0123f016956178eea7343eTed Kremenekunsigned SourceManager::createFileID(const ContentCache *File,
787bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber                                     SourceLocation IncludePos,
790b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner                                     SrcMgr::Characteristic_t FileCharacter) {
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If FileEnt is really large (e.g. it's a large .i file), we may not be able
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // to fit an arbitrary position in the file in the FilePos field.  To handle
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // this, we create one FileID for each chunk of the file that fits in a
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FilePos field.
8478d85f53b093867bbb0123f016956178eea7343eTed Kremenek  unsigned FileSize = File->Buffer->getBufferSize();
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
860b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, FileCharacter));
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           "Ran out of file ID's!");
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return FileIDs.size();
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Create one FileID for each chunk of the file.
935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned Result = FileIDs.size()+1;
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned ChunkNo = 0;
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  while (1) {
977bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber    FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File,
980b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner                                      FileCharacter));
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break;
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    FileSize -= (1 << SourceLocation::FilePosBits);
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         "Ran out of file ID's!");
1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return Result;
1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getInstantiationLoc - Return a new SourceLocation that encodes the fact
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// that a token from physloc PhysLoc should actually be referenced from
1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// InstantiationLoc.
11231bb8be680ee2facf7fbb3c6c87b9bbd20248328Chris LattnerSourceLocation SourceManager::getInstantiationLoc(SourceLocation PhysLoc,
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                                  SourceLocation InstantLoc) {
114abca2bba54197256f2830f757218cfbea2ed9cd1Chris Lattner  // The specified source location may be a mapped location, due to a macro
115abca2bba54197256f2830f757218cfbea2ed9cd1Chris Lattner  // instantiation or #line directive.  Strip off this information to find out
116abca2bba54197256f2830f757218cfbea2ed9cd1Chris Lattner  // where the characters are actually located.
11731bb8be680ee2facf7fbb3c6c87b9bbd20248328Chris Lattner  PhysLoc = getPhysicalLoc(PhysLoc);
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Resolve InstantLoc down to a real logical location.
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  InstantLoc = getLogicalLoc(InstantLoc);
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12231bb8be680ee2facf7fbb3c6c87b9bbd20248328Chris Lattner
12331bb8be680ee2facf7fbb3c6c87b9bbd20248328Chris Lattner  // If the last macro id is close to the currently requested location, try to
124991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner  // reuse it.  This implements a small cache.
125991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner  for (int i = MacroIDs.size()-1, e = MacroIDs.size()-6; i >= 0 && i != e; --i){
126991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner    MacroIDInfo &LastOne = MacroIDs[i];
127d1623a81992a24abbfcd5520b32a0dd90857b8a8Chris Lattner
128991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner    // The instanitation point and source physloc have to exactly match to reuse
129991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner    // (for now).  We could allow "nearby" instantiations in the future.
13018807d2bfb9282a35b921b4feeda09ffaa110e6bChris Lattner    if (LastOne.getVirtualLoc() != InstantLoc ||
131991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner        LastOne.getPhysicalLoc().getFileID() != PhysLoc.getFileID())
132991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner      continue;
133991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner
134991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner    // Check to see if the physloc of the token came from near enough to reuse.
135991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner    int PhysDelta = PhysLoc.getRawFilePos() -
136991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner                    LastOne.getPhysicalLoc().getRawFilePos();
137991ae518e915bbdef5710b2965adee032a04f5a5Chris Lattner    if (SourceLocation::isValidMacroPhysOffs(PhysDelta))
138f8484542bbd9f3445b22fe8d240a1eac790cd8caChris Lattner      return SourceLocation::getMacroLoc(i, PhysDelta);
13931bb8be680ee2facf7fbb3c6c87b9bbd20248328Chris Lattner  }
14031bb8be680ee2facf7fbb3c6c87b9bbd20248328Chris Lattner
14145011cf25e756477766231373111aa80b607ebedChris Lattner
1429dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner  MacroIDs.push_back(MacroIDInfo::get(InstantLoc, PhysLoc));
143f8484542bbd9f3445b22fe8d240a1eac790cd8caChris Lattner  return SourceLocation::getMacroLoc(MacroIDs.size()-1, 0);
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1468a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner/// getBufferData - Return a pointer to the start and end of the character
1478a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner/// data for the specified FileID.
1488a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattnerstd::pair<const char*, const char*>
1498a12c2777cccdf629b89745b6ecc89a8c1641e4eChris LattnerSourceManager::getBufferData(unsigned FileID) const {
1508a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  const llvm::MemoryBuffer *Buf = getBuffer(FileID);
1518a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
1528a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner}
1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getCharacterData - Return a pointer to the start of the specified location
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// in the appropriate MemoryBuffer.
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerconst char *SourceManager::getCharacterData(SourceLocation SL) const {
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Note that this is a hot function in the getSpelling() path, which is
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // heavily used by -E mode.
1609dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner  SL = getPhysicalLoc(SL);
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
16278d85f53b093867bbb0123f016956178eea7343eTed Kremenek  return getContentCache(SL.getFileID())->Buffer->getBufferStart() +
1639dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner         getFullFilePos(SL);
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1679dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner/// getColumnNumber - Return the column # for the specified file position.
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// this is significantly cheaper to compute than the line number.  This returns
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// zero if the column number isn't known.
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerunsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned FileID = Loc.getFileID();
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (FileID == 0) return 0;
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1749dc1f530c086d2c16f8cba758b0f59a5bf41323aChris Lattner  unsigned FilePos = getFullFilePos(Loc);
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const MemoryBuffer *Buffer = getBuffer(FileID);
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const char *Buf = Buffer->getBufferStart();
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned LineStart = FilePos;
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    --LineStart;
1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return FilePos-LineStart+1;
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getSourceName - This method returns the name of the file or buffer that
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// the SourceLocation specifies.  This can be modified with #line directives,
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// etc.
1878b6ca8866f09fd8e018a329a0749d2dcf11b146aChris Lattnerconst char *SourceManager::getSourceName(SourceLocation Loc) const {
1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned FileID = Loc.getFileID();
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (FileID == 0) return "";
19078d85f53b093867bbb0123f016956178eea7343eTed Kremenek  return getContentCache(FileID)->Buffer->getBufferIdentifier();
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
19378d85f53b093867bbb0123f016956178eea7343eTed Kremenekstatic void ComputeLineNumbers(ContentCache* FI) DISABLE_INLINE;
19478d85f53b093867bbb0123f016956178eea7343eTed Kremenekstatic void ComputeLineNumbers(ContentCache* FI) {
1955e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  const MemoryBuffer *Buffer = FI->Buffer;
1965e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
1975e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  // Find the file offsets of all of the *physical* source lines.  This does
1985e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  // not look at trigraphs, escaped newlines, or anything else tricky.
1995e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  std::vector<unsigned> LineOffsets;
2005e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
2015e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  // Line #1 starts at char 0.
2025e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  LineOffsets.push_back(0);
2035e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
2045e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
2055e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
2065e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  unsigned Offs = 0;
2075e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  while (1) {
2085e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    // Skip over the contents of the line.
2095e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    // TODO: Vectorize this?  This is very performance sensitive for programs
2105e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    // with lots of diagnostics and in -E mode.
2115e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    const unsigned char *NextBuf = (const unsigned char *)Buf;
2125e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
2135e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      ++NextBuf;
2145e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    Offs += NextBuf-Buf;
2155e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    Buf = NextBuf;
2165e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
2175e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    if (Buf[0] == '\n' || Buf[0] == '\r') {
2185e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      // If this is \n\r or \r\n, skip both characters.
2195e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
2205e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner        ++Offs, ++Buf;
2215e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      ++Offs, ++Buf;
2225e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      LineOffsets.push_back(Offs);
2235e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    } else {
2245e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      // Otherwise, this is a null.  If end of file, exit.
2255e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      if (Buf == End) break;
2265e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      // Otherwise, skip the null.
2275e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      ++Offs, ++Buf;
2285e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    }
2295e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  }
2305e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
2315e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  // Copy the offsets into the FileInfo structure.
2325e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  FI->NumLines = LineOffsets.size();
2335e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  FI->SourceLineCache = new unsigned[LineOffsets.size()];
2345e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
2355e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner}
2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getLineNumber - Given a SourceLocation, return the physical line number
2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// for the position indicated.  This requires building and caching a table of
2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// line offsets for the MemoryBuffer, so this is not cheap: use only when
2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// about to emit a diagnostic.
2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerunsigned SourceManager::getLineNumber(SourceLocation Loc) {
2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned FileID = Loc.getFileID();
2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (FileID == 0) return 0;
24478d85f53b093867bbb0123f016956178eea7343eTed Kremenek
24578d85f53b093867bbb0123f016956178eea7343eTed Kremenek  ContentCache* Content;
2465e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
2475e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  if (LastLineNoFileIDQuery == FileID)
24878d85f53b093867bbb0123f016956178eea7343eTed Kremenek    Content = LastLineNoContentCache;
2495e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  else
25078d85f53b093867bbb0123f016956178eea7343eTed Kremenek    Content = const_cast<ContentCache*>(getContentCache(FileID));
2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // If this is the first use of line information for this buffer, compute the
2535e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  /// SourceLineCache for it on demand.
25478d85f53b093867bbb0123f016956178eea7343eTed Kremenek  if (Content->SourceLineCache == 0)
25578d85f53b093867bbb0123f016956178eea7343eTed Kremenek    ComputeLineNumbers(Content);
2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Okay, we know we have a line number table.  Do a binary search to find the
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // line number that this character position lands on.
25978d85f53b093867bbb0123f016956178eea7343eTed Kremenek  unsigned *SourceLineCache = Content->SourceLineCache;
2605e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  unsigned *SourceLineCacheStart = SourceLineCache;
26178d85f53b093867bbb0123f016956178eea7343eTed Kremenek  unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
2625e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
2635e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  unsigned QueriedFilePos = getFullFilePos(Loc)+1;
2645e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
2655e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  // If the previous query was to the same file, we know both the file pos from
2665e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  // that query and the line number returned.  This allows us to narrow the
2675e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  // search space from the entire file to something near the match.
2685e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  if (LastLineNoFileIDQuery == FileID) {
2695e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    if (QueriedFilePos >= LastLineNoFilePos) {
2705e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      SourceLineCache = SourceLineCache+LastLineNoResult-1;
2715e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
2725e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      // The query is likely to be nearby the previous one.  Here we check to
2735e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      // see if it is within 5, 10 or 20 lines.  It can be far away in cases
2745e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      // where big comment blocks and vertical whitespace eat up lines but
2755e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      // contribute no tokens.
2765e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      if (SourceLineCache+5 < SourceLineCacheEnd) {
2775e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner        if (SourceLineCache[5] > QueriedFilePos)
2785e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner          SourceLineCacheEnd = SourceLineCache+5;
2795e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner        else if (SourceLineCache+10 < SourceLineCacheEnd) {
2805e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner          if (SourceLineCache[10] > QueriedFilePos)
2815e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner            SourceLineCacheEnd = SourceLineCache+10;
2825e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner          else if (SourceLineCache+20 < SourceLineCacheEnd) {
2835e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner            if (SourceLineCache[20] > QueriedFilePos)
2845e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner              SourceLineCacheEnd = SourceLineCache+20;
2855e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner          }
2865e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner        }
2875e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      }
2885e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    } else {
2895e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner      SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
2905e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner    }
2915e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  }
2925e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
2931cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner  // If the spread is large, do a "radix" test as our initial guess, based on
2941cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner  // the assumption that lines average to approximately the same length.
2951cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner  // NOTE: This is currently disabled, as it does not appear to be profitable in
2961cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner  // initial measurements.
2971cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner  if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
29878d85f53b093867bbb0123f016956178eea7343eTed Kremenek    unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];
2991cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner
3001cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner    // Take a stab at guessing where it is.
30178d85f53b093867bbb0123f016956178eea7343eTed Kremenek    unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;
3021cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner
3031cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner    // Check for -10 and +10 lines.
3041cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner    unsigned LowerBound = std::max(int(ApproxPos-10), 0);
3051cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner    unsigned UpperBound = std::min(ApproxPos+10, FileLen);
3061cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner
3071cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner    // If the computed lower bound is less than the query location, move it in.
3081cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner    if (SourceLineCache < SourceLineCacheStart+LowerBound &&
3091cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner        SourceLineCacheStart[LowerBound] < QueriedFilePos)
3101cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner      SourceLineCache = SourceLineCacheStart+LowerBound;
3111cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner
3121cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner    // If the computed upper bound is greater than the query location, move it.
3131cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner    if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
3141cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner        SourceLineCacheStart[UpperBound] >= QueriedFilePos)
3151cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner      SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
3161cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner  }
3171cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner
3181cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner  unsigned *Pos
3191cf12bfa80825cce46be35a0a2b54f281b0b51dbChris Lattner    = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
3205e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  unsigned LineNo = Pos-SourceLineCacheStart;
3215e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner
3225e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  LastLineNoFileIDQuery = FileID;
32378d85f53b093867bbb0123f016956178eea7343eTed Kremenek  LastLineNoContentCache = Content;
3245e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  LastLineNoFilePos = QueriedFilePos;
3255e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  LastLineNoResult = LineNo;
3265e36a7a89da5d69ece23fc8228624a053f75c645Chris Lattner  return LineNo;
3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// PrintStats - Print statistics to stderr.
3305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
3315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid SourceManager::PrintStats() const {
332665dd4a40e0e38657f7bf26c2e3490304e5c7510Ted Kremenek  llvm::cerr << "\n*** Source Manager Stats:\n";
333665dd4a40e0e38657f7bf26c2e3490304e5c7510Ted Kremenek  llvm::cerr << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
334665dd4a40e0e38657f7bf26c2e3490304e5c7510Ted Kremenek             << " mem buffers mapped, " << FileIDs.size()
335665dd4a40e0e38657f7bf26c2e3490304e5c7510Ted Kremenek             << " file ID's allocated.\n";
336665dd4a40e0e38657f7bf26c2e3490304e5c7510Ted Kremenek  llvm::cerr << "  " << FileIDs.size() << " normal buffer FileID's, "
337665dd4a40e0e38657f7bf26c2e3490304e5c7510Ted Kremenek             << MacroIDs.size() << " macro expansion FileID's.\n";
3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumLineNumsComputed = 0;
3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumFileBytesMapped = 0;
34178d85f53b093867bbb0123f016956178eea7343eTed Kremenek  for (std::set<ContentCache>::const_iterator I =
3425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer       FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
34378d85f53b093867bbb0123f016956178eea7343eTed Kremenek    NumLineNumsComputed += I->SourceLineCache != 0;
34478d85f53b093867bbb0123f016956178eea7343eTed Kremenek    NumFileBytesMapped  += I->Buffer->getBufferSize();
3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
34678d85f53b093867bbb0123f016956178eea7343eTed Kremenek
347665dd4a40e0e38657f7bf26c2e3490304e5c7510Ted Kremenek  llvm::cerr << NumFileBytesMapped << " bytes of files mapped, "
348665dd4a40e0e38657f7bf26c2e3490304e5c7510Ted Kremenek             << NumLineNumsComputed << " files with line #'s computed.\n";
3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
350e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek
351e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek//===----------------------------------------------------------------------===//
352e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek// Serialization.
353e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek//===----------------------------------------------------------------------===//
354099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
355099b4747042352f69184481a48508b599a8d3f73Ted Kremenekvoid ContentCache::Emit(llvm::Serializer& S) const {
356e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek  S.FlushRecord();
357e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek  S.EmitPtr(this);
358e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek
35982dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek  if (Entry) {
36082dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek    llvm::sys::Path Fname(Buffer->getBufferIdentifier());
36182dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek
36282dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek    if (Fname.isAbsolute())
36382dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek      S.EmitCStr(Fname.c_str());
36482dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek    else {
36582dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek      // Create an absolute path.
36682dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek      // FIXME: This will potentially contain ".." and "." in the path.
36782dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek      llvm::sys::Path path = llvm::sys::Path::GetCurrentDirectory();
36882dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek      path.appendComponent(Fname.c_str());
36982dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek      S.EmitCStr(path.c_str());
37082dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek    }
37182dfaf7c0ccbbde43f701b12367dbf22265dcb4eTed Kremenek  }
372099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  else {
373e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek    const char* p = Buffer->getBufferStart();
374e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek    const char* e = Buffer->getBufferEnd();
375e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek
376099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    S.EmitInt(e-p);
377099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
378e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek    for ( ; p != e; ++p)
379099b4747042352f69184481a48508b599a8d3f73Ted Kremenek      S.EmitInt(*p);
380099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  }
381099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
382099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.FlushRecord();
383099b4747042352f69184481a48508b599a8d3f73Ted Kremenek}
384e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek
385099b4747042352f69184481a48508b599a8d3f73Ted Kremenekvoid ContentCache::ReadToSourceManager(llvm::Deserializer& D,
386099b4747042352f69184481a48508b599a8d3f73Ted Kremenek                                       SourceManager& SMgr,
387099b4747042352f69184481a48508b599a8d3f73Ted Kremenek                                       FileManager* FMgr,
388099b4747042352f69184481a48508b599a8d3f73Ted Kremenek                                       std::vector<char>& Buf) {
389099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  if (FMgr) {
390099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    llvm::SerializedPtrID PtrID = D.ReadPtrID();
391099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    D.ReadCStr(Buf,false);
392099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
393099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    // Create/fetch the FileEntry.
394099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    const char* start = &Buf[0];
395099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    const FileEntry* E = FMgr->getFile(start,start+Buf.size());
396099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
397db9c22917e411c924dae593d71e64fd616fd3a12Ted Kremenek    // FIXME: Ideally we want a lazy materialization of the ContentCache
398db9c22917e411c924dae593d71e64fd616fd3a12Ted Kremenek    //  anyway, because we don't want to read in source files unless this
399db9c22917e411c924dae593d71e64fd616fd3a12Ted Kremenek    //  is absolutely needed.
400db9c22917e411c924dae593d71e64fd616fd3a12Ted Kremenek    if (!E)
401db9c22917e411c924dae593d71e64fd616fd3a12Ted Kremenek      D.RegisterPtr(PtrID,NULL);
40248002c89578eaeb008a0bb5a10d8216e61906459Nico Weber    else
403db9c22917e411c924dae593d71e64fd616fd3a12Ted Kremenek      // Get the ContextCache object and register it with the deserializer.
404db9c22917e411c924dae593d71e64fd616fd3a12Ted Kremenek      D.RegisterPtr(PtrID,SMgr.getContentCache(E));
405e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek  }
406099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  else {
407099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    // Register the ContextCache object with the deserializer.
408099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    SMgr.MemBufferInfos.push_back(ContentCache());
40948002c89578eaeb008a0bb5a10d8216e61906459Nico Weber    ContentCache& Entry = const_cast<ContentCache&>(SMgr.MemBufferInfos.back());
410099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    D.RegisterPtr(&Entry);
411099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
412099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    // Create the buffer.
413099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    unsigned Size = D.ReadInt();
414099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    Entry.Buffer = MemoryBuffer::getNewUninitMemBuffer(Size);
415099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
416099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    // Read the contents of the buffer.
417099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    char* p = const_cast<char*>(Entry.Buffer->getBufferStart());
418099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    for (unsigned i = 0; i < Size ; ++i)
419099b4747042352f69184481a48508b599a8d3f73Ted Kremenek      p[i] = D.ReadInt();
420099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  }
421099b4747042352f69184481a48508b599a8d3f73Ted Kremenek}
422099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
423099b4747042352f69184481a48508b599a8d3f73Ted Kremenekvoid FileIDInfo::Emit(llvm::Serializer& S) const {
424099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.Emit(IncludeLoc);
425099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.EmitInt(ChunkNo);
426099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.EmitPtr(Content);
427099b4747042352f69184481a48508b599a8d3f73Ted Kremenek}
428099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
429099b4747042352f69184481a48508b599a8d3f73Ted KremenekFileIDInfo FileIDInfo::ReadVal(llvm::Deserializer& D) {
430099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  FileIDInfo I;
431099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  I.IncludeLoc = SourceLocation::ReadVal(D);
432099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  I.ChunkNo = D.ReadInt();
433099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  D.ReadPtr(I.Content,false);
434099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  return I;
435099b4747042352f69184481a48508b599a8d3f73Ted Kremenek}
436099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
437099b4747042352f69184481a48508b599a8d3f73Ted Kremenekvoid MacroIDInfo::Emit(llvm::Serializer& S) const {
438099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.Emit(VirtualLoc);
439099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.Emit(PhysicalLoc);
440099b4747042352f69184481a48508b599a8d3f73Ted Kremenek}
441099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
442099b4747042352f69184481a48508b599a8d3f73Ted KremenekMacroIDInfo MacroIDInfo::ReadVal(llvm::Deserializer& D) {
443099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  MacroIDInfo I;
444099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  I.VirtualLoc = SourceLocation::ReadVal(D);
445099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  I.PhysicalLoc = SourceLocation::ReadVal(D);
446099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  return I;
447e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek}
448e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek
449099b4747042352f69184481a48508b599a8d3f73Ted Kremenekvoid SourceManager::Emit(llvm::Serializer& S) const {
4501f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek  S.EnterBlock();
4511f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek  S.EmitPtr(this);
45276edd0e4ae0592a7225d50d0bad6732ac64dca2aTed Kremenek  S.EmitInt(MainFileID);
4531f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek
454099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  // Emit: FileInfos.  Just emit the file name.
455099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.EnterBlock();
456099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
457099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  std::for_each(FileInfos.begin(),FileInfos.end(),
458099b4747042352f69184481a48508b599a8d3f73Ted Kremenek                S.MakeEmitter<ContentCache>());
459e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek
460099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.ExitBlock();
461e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek
462099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  // Emit: MemBufferInfos
463099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.EnterBlock();
464099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
465099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  std::for_each(MemBufferInfos.begin(), MemBufferInfos.end(),
466099b4747042352f69184481a48508b599a8d3f73Ted Kremenek                S.MakeEmitter<ContentCache>());
467099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
468099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.ExitBlock();
469099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
47048002c89578eaeb008a0bb5a10d8216e61906459Nico Weber  // Emit: FileIDs
471099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.EmitInt(FileIDs.size());
472099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  std::for_each(FileIDs.begin(), FileIDs.end(), S.MakeEmitter<FileIDInfo>());
473099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
474099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  // Emit: MacroIDs
475099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  S.EmitInt(MacroIDs.size());
476099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  std::for_each(MacroIDs.begin(), MacroIDs.end(), S.MakeEmitter<MacroIDInfo>());
4771f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek
4781f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek  S.ExitBlock();
479e21272fbdbfbf5bf3461d3e9b42279f4d47caa42Ted Kremenek}
480099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
4811f94100e53a7d45cea706c09ac0f35cf723a8d83Ted KremenekSourceManager*
4821f94100e53a7d45cea706c09ac0f35cf723a8d83Ted KremenekSourceManager::CreateAndRegister(llvm::Deserializer& D, FileManager& FMgr){
4831f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek  SourceManager *M = new SourceManager();
4841f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek  D.RegisterPtr(M);
4851f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek
48676edd0e4ae0592a7225d50d0bad6732ac64dca2aTed Kremenek  // Read: the FileID of the main source file of the translation unit.
48776edd0e4ae0592a7225d50d0bad6732ac64dca2aTed Kremenek  M->MainFileID = D.ReadInt();
48876edd0e4ae0592a7225d50d0bad6732ac64dca2aTed Kremenek
489099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  std::vector<char> Buf;
490099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
491099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  { // Read: FileInfos.
492099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
493099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    while (!D.FinishedBlock(BLoc))
4941f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek    ContentCache::ReadToSourceManager(D,*M,&FMgr,Buf);
495099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  }
496099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
497099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  { // Read: MemBufferInfos.
498099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
499099b4747042352f69184481a48508b599a8d3f73Ted Kremenek    while (!D.FinishedBlock(BLoc))
5001f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek    ContentCache::ReadToSourceManager(D,*M,NULL,Buf);
501099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  }
502099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
503099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  // Read: FileIDs.
504099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  unsigned Size = D.ReadInt();
5051f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek  M->FileIDs.reserve(Size);
506099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  for (; Size > 0 ; --Size)
5071f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek    M->FileIDs.push_back(FileIDInfo::ReadVal(D));
508099b4747042352f69184481a48508b599a8d3f73Ted Kremenek
509099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  // Read: MacroIDs.
510099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  Size = D.ReadInt();
5111f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek  M->MacroIDs.reserve(Size);
512099b4747042352f69184481a48508b599a8d3f73Ted Kremenek  for (; Size > 0 ; --Size)
5131f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek    M->MacroIDs.push_back(MacroIDInfo::ReadVal(D));
5141f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek
5151f94100e53a7d45cea706c09ac0f35cf723a8d83Ted Kremenek  return M;
5161f2c7d110de6d3c568ab3841a31d76b9148393acTed Kremenek}
517