1193326Sed//===--- SourceManager.cpp - Track and cache source files -----------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file implements the SourceManager interface.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "clang/Basic/SourceManager.h"
15205219Srdivacky#include "clang/Basic/Diagnostic.h"
16193326Sed#include "clang/Basic/FileManager.h"
17252723Sdim#include "clang/Basic/SourceManagerInternals.h"
18218893Sdim#include "llvm/ADT/Optional.h"
19226890Sdim#include "llvm/ADT/STLExtras.h"
20252723Sdim#include "llvm/ADT/StringSwitch.h"
21252723Sdim#include "llvm/Support/Capacity.h"
22193326Sed#include "llvm/Support/Compiler.h"
23193326Sed#include "llvm/Support/MemoryBuffer.h"
24252723Sdim#include "llvm/Support/Path.h"
25198092Srdivacky#include "llvm/Support/raw_ostream.h"
26193326Sed#include <algorithm>
27252723Sdim#include <cstring>
28205219Srdivacky#include <string>
29218893Sdim#include <sys/stat.h>
30205219Srdivacky
31193326Sedusing namespace clang;
32193326Sedusing namespace SrcMgr;
33193326Sedusing llvm::MemoryBuffer;
34193326Sed
35193326Sed//===----------------------------------------------------------------------===//
36193326Sed// SourceManager Helper Classes
37193326Sed//===----------------------------------------------------------------------===//
38193326Sed
39193326SedContentCache::~ContentCache() {
40212904Sdim  if (shouldFreeBuffer())
41212904Sdim    delete Buffer.getPointer();
42193326Sed}
43193326Sed
44226890Sdim/// getSizeBytesMapped - Returns the number of bytes actually mapped for this
45226890Sdim/// ContentCache. This can be 0 if the MemBuffer was not actually expanded.
46193326Sedunsigned ContentCache::getSizeBytesMapped() const {
47205408Srdivacky  return Buffer.getPointer() ? Buffer.getPointer()->getBufferSize() : 0;
48193326Sed}
49193326Sed
50221345Sdim/// Returns the kind of memory used to back the memory buffer for
51221345Sdim/// this content cache.  This is used for performance analysis.
52221345Sdimllvm::MemoryBuffer::BufferKind ContentCache::getMemoryBufferKind() const {
53221345Sdim  assert(Buffer.getPointer());
54221345Sdim
55221345Sdim  // Should be unreachable, but keep for sanity.
56221345Sdim  if (!Buffer.getPointer())
57221345Sdim    return llvm::MemoryBuffer::MemoryBuffer_Malloc;
58221345Sdim
59221345Sdim  const llvm::MemoryBuffer *buf = Buffer.getPointer();
60221345Sdim  return buf->getBufferKind();
61221345Sdim}
62221345Sdim
63193326Sed/// getSize - Returns the size of the content encapsulated by this ContentCache.
64193326Sed///  This can be the size of the source file or the size of an arbitrary
65193326Sed///  scratch buffer.  If the ContentCache encapsulates a source file, that
66200583Srdivacky///  file is not lazily brought in from disk to satisfy this query.
67193326Sedunsigned ContentCache::getSize() const {
68205408Srdivacky  return Buffer.getPointer() ? (unsigned) Buffer.getPointer()->getBufferSize()
69221345Sdim                             : (unsigned) ContentsEntry->getSize();
70193326Sed}
71193326Sed
72212904Sdimvoid ContentCache::replaceBuffer(const llvm::MemoryBuffer *B,
73212904Sdim                                 bool DoNotFree) {
74245431Sdim  if (B && B == Buffer.getPointer()) {
75235633Sdim    assert(0 && "Replacing with the same buffer");
76235633Sdim    Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
77235633Sdim    return;
78235633Sdim  }
79200583Srdivacky
80212904Sdim  if (shouldFreeBuffer())
81212904Sdim    delete Buffer.getPointer();
82205408Srdivacky  Buffer.setPointer(B);
83212904Sdim  Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
84200583Srdivacky}
85200583Srdivacky
86226890Sdimconst llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
87207619Srdivacky                                                  const SourceManager &SM,
88207619Srdivacky                                                  SourceLocation Loc,
89205219Srdivacky                                                  bool *Invalid) const {
90218893Sdim  // Lazily create the Buffer for ContentCaches that wrap files.  If we already
91221345Sdim  // computed it, just return what we have.
92221345Sdim  if (Buffer.getPointer() || ContentsEntry == 0) {
93218893Sdim    if (Invalid)
94218893Sdim      *Invalid = isBufferInvalid();
95205408Srdivacky
96218893Sdim    return Buffer.getPointer();
97218893Sdim  }
98206084Srdivacky
99218893Sdim  std::string ErrorStr;
100245431Sdim  bool isVolatile = SM.userFilesAreVolatile() && !IsSystemFile;
101245431Sdim  Buffer.setPointer(SM.getFileManager().getBufferForFile(ContentsEntry,
102245431Sdim                                                         &ErrorStr,
103245431Sdim                                                         isVolatile));
104206084Srdivacky
105218893Sdim  // If we were unable to open the file, then we are in an inconsistent
106218893Sdim  // situation where the content cache referenced a file which no longer
107218893Sdim  // exists. Most likely, we were using a stat cache with an invalid entry but
108218893Sdim  // the file could also have been removed during processing. Since we can't
109218893Sdim  // really deal with this situation, just create an empty buffer.
110218893Sdim  //
111218893Sdim  // FIXME: This is definitely not ideal, but our immediate clients can't
112218893Sdim  // currently handle returning a null entry here. Ideally we should detect
113218893Sdim  // that we are in an inconsistent situation and error out as quickly as
114218893Sdim  // possible.
115218893Sdim  if (!Buffer.getPointer()) {
116226890Sdim    const StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
117221345Sdim    Buffer.setPointer(MemoryBuffer::getNewMemBuffer(ContentsEntry->getSize(),
118218893Sdim                                                    "<invalid>"));
119218893Sdim    char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart());
120221345Sdim    for (unsigned i = 0, e = ContentsEntry->getSize(); i != e; ++i)
121218893Sdim      Ptr[i] = FillStr[i % FillStr.size()];
122207619Srdivacky
123218893Sdim    if (Diag.isDiagnosticInFlight())
124218893Sdim      Diag.SetDelayedDiagnostic(diag::err_cannot_open_file,
125221345Sdim                                ContentsEntry->getName(), ErrorStr);
126218893Sdim    else
127218893Sdim      Diag.Report(Loc, diag::err_cannot_open_file)
128221345Sdim        << ContentsEntry->getName() << ErrorStr;
129206084Srdivacky
130218893Sdim    Buffer.setInt(Buffer.getInt() | InvalidFlag);
131207619Srdivacky
132218893Sdim    if (Invalid) *Invalid = true;
133218893Sdim    return Buffer.getPointer();
134198092Srdivacky  }
135205219Srdivacky
136218893Sdim  // Check that the file's size is the same as in the file entry (which may
137218893Sdim  // have come from a stat cache).
138221345Sdim  if (getRawBuffer()->getBufferSize() != (size_t)ContentsEntry->getSize()) {
139218893Sdim    if (Diag.isDiagnosticInFlight())
140218893Sdim      Diag.SetDelayedDiagnostic(diag::err_file_modified,
141221345Sdim                                ContentsEntry->getName());
142218893Sdim    else
143218893Sdim      Diag.Report(Loc, diag::err_file_modified)
144221345Sdim        << ContentsEntry->getName();
145218893Sdim
146218893Sdim    Buffer.setInt(Buffer.getInt() | InvalidFlag);
147218893Sdim    if (Invalid) *Invalid = true;
148218893Sdim    return Buffer.getPointer();
149218893Sdim  }
150221345Sdim
151218893Sdim  // If the buffer is valid, check to see if it has a UTF Byte Order Mark
152221345Sdim  // (BOM).  We only support UTF-8 with and without a BOM right now.  See
153218893Sdim  // http://en.wikipedia.org/wiki/Byte_order_mark for more information.
154226890Sdim  StringRef BufStr = Buffer.getPointer()->getBuffer();
155221345Sdim  const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr)
156218893Sdim    .StartsWith("\xFE\xFF", "UTF-16 (BE)")
157218893Sdim    .StartsWith("\xFF\xFE", "UTF-16 (LE)")
158218893Sdim    .StartsWith("\x00\x00\xFE\xFF", "UTF-32 (BE)")
159218893Sdim    .StartsWith("\xFF\xFE\x00\x00", "UTF-32 (LE)")
160218893Sdim    .StartsWith("\x2B\x2F\x76", "UTF-7")
161218893Sdim    .StartsWith("\xF7\x64\x4C", "UTF-1")
162218893Sdim    .StartsWith("\xDD\x73\x66\x73", "UTF-EBCDIC")
163218893Sdim    .StartsWith("\x0E\xFE\xFF", "SDSU")
164218893Sdim    .StartsWith("\xFB\xEE\x28", "BOCU-1")
165218893Sdim    .StartsWith("\x84\x31\x95\x33", "GB-18030")
166218893Sdim    .Default(0);
167218893Sdim
168221345Sdim  if (InvalidBOM) {
169218893Sdim    Diag.Report(Loc, diag::err_unsupported_bom)
170221345Sdim      << InvalidBOM << ContentsEntry->getName();
171218893Sdim    Buffer.setInt(Buffer.getInt() | InvalidFlag);
172218893Sdim  }
173218893Sdim
174205408Srdivacky  if (Invalid)
175212904Sdim    *Invalid = isBufferInvalid();
176205408Srdivacky
177205408Srdivacky  return Buffer.getPointer();
178198092Srdivacky}
179198092Srdivacky
180226890Sdimunsigned LineTableInfo::getLineTableFilenameID(StringRef Name) {
181193326Sed  // Look up the filename in the string table, returning the pre-existing value
182193326Sed  // if it exists.
183198092Srdivacky  llvm::StringMapEntry<unsigned> &Entry =
184224145Sdim    FilenameIDs.GetOrCreateValue(Name, ~0U);
185193326Sed  if (Entry.getValue() != ~0U)
186193326Sed    return Entry.getValue();
187198092Srdivacky
188193326Sed  // Otherwise, assign this the next available ID.
189193326Sed  Entry.setValue(FilenamesByID.size());
190193326Sed  FilenamesByID.push_back(&Entry);
191193326Sed  return FilenamesByID.size()-1;
192193326Sed}
193193326Sed
194193326Sed/// AddLineNote - Add a line note to the line table that indicates that there
195245431Sdim/// is a \#line at the specified FID/Offset location which changes the presumed
196193326Sed/// location to LineNo/FilenameID.
197245431Sdimvoid LineTableInfo::AddLineNote(FileID FID, unsigned Offset,
198193326Sed                                unsigned LineNo, int FilenameID) {
199193326Sed  std::vector<LineEntry> &Entries = LineEntries[FID];
200198092Srdivacky
201193326Sed  assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
202193326Sed         "Adding line entries out of order!");
203198092Srdivacky
204193326Sed  SrcMgr::CharacteristicKind Kind = SrcMgr::C_User;
205193326Sed  unsigned IncludeOffset = 0;
206198092Srdivacky
207193326Sed  if (!Entries.empty()) {
208193326Sed    // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember
209193326Sed    // that we are still in "foo.h".
210193326Sed    if (FilenameID == -1)
211193326Sed      FilenameID = Entries.back().FilenameID;
212198092Srdivacky
213193326Sed    // If we are after a line marker that switched us to system header mode, or
214193326Sed    // that set #include information, preserve it.
215193326Sed    Kind = Entries.back().FileKind;
216193326Sed    IncludeOffset = Entries.back().IncludeOffset;
217193326Sed  }
218198092Srdivacky
219193326Sed  Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind,
220193326Sed                                   IncludeOffset));
221193326Sed}
222193326Sed
223193326Sed/// AddLineNote This is the same as the previous version of AddLineNote, but is
224193326Sed/// used for GNU line markers.  If EntryExit is 0, then this doesn't change the
225245431Sdim/// presumed \#include stack.  If it is 1, this is a file entry, if it is 2 then
226193326Sed/// this is a file exit.  FileKind specifies whether this is a system header or
227193326Sed/// extern C system header.
228245431Sdimvoid LineTableInfo::AddLineNote(FileID FID, unsigned Offset,
229193326Sed                                unsigned LineNo, int FilenameID,
230193326Sed                                unsigned EntryExit,
231193326Sed                                SrcMgr::CharacteristicKind FileKind) {
232193326Sed  assert(FilenameID != -1 && "Unspecified filename should use other accessor");
233198092Srdivacky
234193326Sed  std::vector<LineEntry> &Entries = LineEntries[FID];
235198092Srdivacky
236193326Sed  assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
237193326Sed         "Adding line entries out of order!");
238193326Sed
239193326Sed  unsigned IncludeOffset = 0;
240193326Sed  if (EntryExit == 0) {  // No #include stack change.
241193326Sed    IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
242193326Sed  } else if (EntryExit == 1) {
243193326Sed    IncludeOffset = Offset-1;
244193326Sed  } else if (EntryExit == 2) {
245193326Sed    assert(!Entries.empty() && Entries.back().IncludeOffset &&
246193326Sed       "PPDirectives should have caught case when popping empty include stack");
247198092Srdivacky
248193326Sed    // Get the include loc of the last entries' include loc as our include loc.
249193326Sed    IncludeOffset = 0;
250193326Sed    if (const LineEntry *PrevEntry =
251193326Sed          FindNearestLineEntry(FID, Entries.back().IncludeOffset))
252193326Sed      IncludeOffset = PrevEntry->IncludeOffset;
253193326Sed  }
254198092Srdivacky
255193326Sed  Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind,
256193326Sed                                   IncludeOffset));
257193326Sed}
258193326Sed
259193326Sed
260193326Sed/// FindNearestLineEntry - Find the line entry nearest to FID that is before
261193326Sed/// it.  If there is no line entry before Offset in FID, return null.
262245431Sdimconst LineEntry *LineTableInfo::FindNearestLineEntry(FileID FID,
263193326Sed                                                     unsigned Offset) {
264193326Sed  const std::vector<LineEntry> &Entries = LineEntries[FID];
265193326Sed  assert(!Entries.empty() && "No #line entries for this FID after all!");
266193326Sed
267193326Sed  // It is very common for the query to be after the last #line, check this
268193326Sed  // first.
269193326Sed  if (Entries.back().FileOffset <= Offset)
270193326Sed    return &Entries.back();
271193326Sed
272193326Sed  // Do a binary search to find the maximal element that is still before Offset.
273193326Sed  std::vector<LineEntry>::const_iterator I =
274193326Sed    std::upper_bound(Entries.begin(), Entries.end(), Offset);
275193326Sed  if (I == Entries.begin()) return 0;
276193326Sed  return &*--I;
277193326Sed}
278193326Sed
279193326Sed/// \brief Add a new line entry that has already been encoded into
280193326Sed/// the internal representation of the line table.
281245431Sdimvoid LineTableInfo::AddEntry(FileID FID,
282193326Sed                             const std::vector<LineEntry> &Entries) {
283193326Sed  LineEntries[FID] = Entries;
284193326Sed}
285193326Sed
286193326Sed/// getLineTableFilenameID - Return the uniqued ID for the specified filename.
287198092Srdivacky///
288226890Sdimunsigned SourceManager::getLineTableFilenameID(StringRef Name) {
289193326Sed  if (LineTable == 0)
290193326Sed    LineTable = new LineTableInfo();
291224145Sdim  return LineTable->getLineTableFilenameID(Name);
292193326Sed}
293193326Sed
294193326Sed
295193326Sed/// AddLineNote - Add a line note to the line table for the FileID and offset
296193326Sed/// specified by Loc.  If FilenameID is -1, it is considered to be
297193326Sed/// unspecified.
298193326Sedvoid SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
299193326Sed                                int FilenameID) {
300226890Sdim  std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
301198092Srdivacky
302221345Sdim  bool Invalid = false;
303221345Sdim  const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
304221345Sdim  if (!Entry.isFile() || Invalid)
305221345Sdim    return;
306221345Sdim
307221345Sdim  const SrcMgr::FileInfo &FileInfo = Entry.getFile();
308193326Sed
309193326Sed  // Remember that this file has #line directives now if it doesn't already.
310193326Sed  const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
311198092Srdivacky
312193326Sed  if (LineTable == 0)
313193326Sed    LineTable = new LineTableInfo();
314245431Sdim  LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID);
315193326Sed}
316193326Sed
317193326Sed/// AddLineNote - Add a GNU line marker to the line table.
318193326Sedvoid SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
319193326Sed                                int FilenameID, bool IsFileEntry,
320193326Sed                                bool IsFileExit, bool IsSystemHeader,
321193326Sed                                bool IsExternCHeader) {
322193326Sed  // If there is no filename and no flags, this is treated just like a #line,
323193326Sed  // which does not change the flags of the previous line marker.
324193326Sed  if (FilenameID == -1) {
325193326Sed    assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader &&
326193326Sed           "Can't set flags without setting the filename!");
327193326Sed    return AddLineNote(Loc, LineNo, FilenameID);
328193326Sed  }
329198092Srdivacky
330226890Sdim  std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
331198092Srdivacky
332221345Sdim  bool Invalid = false;
333221345Sdim  const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
334221345Sdim  if (!Entry.isFile() || Invalid)
335221345Sdim    return;
336221345Sdim
337221345Sdim  const SrcMgr::FileInfo &FileInfo = Entry.getFile();
338221345Sdim
339193326Sed  // Remember that this file has #line directives now if it doesn't already.
340193326Sed  const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
341198092Srdivacky
342193326Sed  if (LineTable == 0)
343193326Sed    LineTable = new LineTableInfo();
344198092Srdivacky
345193326Sed  SrcMgr::CharacteristicKind FileKind;
346193326Sed  if (IsExternCHeader)
347193326Sed    FileKind = SrcMgr::C_ExternCSystem;
348193326Sed  else if (IsSystemHeader)
349193326Sed    FileKind = SrcMgr::C_System;
350193326Sed  else
351193326Sed    FileKind = SrcMgr::C_User;
352198092Srdivacky
353193326Sed  unsigned EntryExit = 0;
354193326Sed  if (IsFileEntry)
355193326Sed    EntryExit = 1;
356193326Sed  else if (IsFileExit)
357193326Sed    EntryExit = 2;
358198092Srdivacky
359245431Sdim  LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
360193326Sed                         EntryExit, FileKind);
361193326Sed}
362193326Sed
363193326SedLineTableInfo &SourceManager::getLineTable() {
364193326Sed  if (LineTable == 0)
365193326Sed    LineTable = new LineTableInfo();
366193326Sed  return *LineTable;
367193326Sed}
368193326Sed
369193326Sed//===----------------------------------------------------------------------===//
370193326Sed// Private 'Create' methods.
371193326Sed//===----------------------------------------------------------------------===//
372193326Sed
373245431SdimSourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr,
374245431Sdim                             bool UserFilesAreVolatile)
375221345Sdim  : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true),
376245431Sdim    UserFilesAreVolatile(UserFilesAreVolatile),
377218893Sdim    ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
378235633Sdim    NumBinaryProbes(0), FakeBufferForRecovery(0),
379235633Sdim    FakeContentCacheForRecovery(0) {
380218893Sdim  clearIDTables();
381218893Sdim  Diag.setSourceManager(this);
382218893Sdim}
383218893Sdim
384193326SedSourceManager::~SourceManager() {
385193326Sed  delete LineTable;
386198092Srdivacky
387193326Sed  // Delete FileEntry objects corresponding to content caches.  Since the actual
388193326Sed  // content cache objects are bump pointer allocated, we just have to run the
389193326Sed  // dtors, but we call the deallocate method for completeness.
390193326Sed  for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
391235633Sdim    if (MemBufferInfos[i]) {
392235633Sdim      MemBufferInfos[i]->~ContentCache();
393235633Sdim      ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
394235633Sdim    }
395193326Sed  }
396193326Sed  for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
397193326Sed       I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
398235633Sdim    if (I->second) {
399235633Sdim      I->second->~ContentCache();
400235633Sdim      ContentCacheAlloc.Deallocate(I->second);
401235633Sdim    }
402193326Sed  }
403221345Sdim
404221345Sdim  delete FakeBufferForRecovery;
405235633Sdim  delete FakeContentCacheForRecovery;
406226890Sdim
407226890Sdim  for (llvm::DenseMap<FileID, MacroArgsMap *>::iterator
408226890Sdim         I = MacroArgsCacheMap.begin(),E = MacroArgsCacheMap.end(); I!=E; ++I) {
409226890Sdim    delete I->second;
410226890Sdim  }
411193326Sed}
412193326Sed
413193326Sedvoid SourceManager::clearIDTables() {
414193326Sed  MainFileID = FileID();
415226890Sdim  LocalSLocEntryTable.clear();
416226890Sdim  LoadedSLocEntryTable.clear();
417226890Sdim  SLocEntryLoaded.clear();
418193326Sed  LastLineNoFileIDQuery = FileID();
419193326Sed  LastLineNoContentCache = 0;
420193326Sed  LastFileIDLookup = FileID();
421198092Srdivacky
422193326Sed  if (LineTable)
423193326Sed    LineTable->clear();
424198092Srdivacky
425226890Sdim  // Use up FileID #0 as an invalid expansion.
426226890Sdim  NextLocalOffset = 0;
427226890Sdim  CurrentLoadedOffset = MaxLoadedOffset;
428226890Sdim  createExpansionLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1);
429193326Sed}
430193326Sed
431193326Sed/// getOrCreateContentCache - Create or return a cached ContentCache for the
432193326Sed/// specified file.
433193326Sedconst ContentCache *
434245431SdimSourceManager::getOrCreateContentCache(const FileEntry *FileEnt,
435245431Sdim                                       bool isSystemFile) {
436193326Sed  assert(FileEnt && "Didn't specify a file entry to use?");
437198092Srdivacky
438193326Sed  // Do we already have information about this file?
439193326Sed  ContentCache *&Entry = FileInfos[FileEnt];
440193326Sed  if (Entry) return Entry;
441198092Srdivacky
442193326Sed  // Nope, create a new Cache entry.  Make sure it is at least 8-byte aligned
443193326Sed  // so that FileInfo can use the low 3 bits of the pointer for its own
444193326Sed  // nefarious purposes.
445193326Sed  unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
446193326Sed  EntryAlign = std::max(8U, EntryAlign);
447193326Sed  Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
448221345Sdim
449245431Sdim  if (OverriddenFilesInfo) {
450245431Sdim    // If the file contents are overridden with contents from another file,
451245431Sdim    // pass that file to ContentCache.
452245431Sdim    llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
453245431Sdim        overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
454245431Sdim    if (overI == OverriddenFilesInfo->OverriddenFiles.end())
455245431Sdim      new (Entry) ContentCache(FileEnt);
456245431Sdim    else
457245431Sdim      new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt
458245431Sdim                                                              : overI->second,
459245431Sdim                               overI->second);
460245431Sdim  } else {
461221345Sdim    new (Entry) ContentCache(FileEnt);
462245431Sdim  }
463221345Sdim
464245431Sdim  Entry->IsSystemFile = isSystemFile;
465245431Sdim
466193326Sed  return Entry;
467193326Sed}
468193326Sed
469193326Sed
470193326Sed/// createMemBufferContentCache - Create a new ContentCache for the specified
471193326Sed///  memory buffer.  This does no caching.
472193326Sedconst ContentCache*
473193326SedSourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
474193326Sed  // Add a new ContentCache to the MemBufferInfos list and return it.  Make sure
475193326Sed  // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of
476193326Sed  // the pointer for its own nefarious purposes.
477193326Sed  unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
478193326Sed  EntryAlign = std::max(8U, EntryAlign);
479193326Sed  ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
480193326Sed  new (Entry) ContentCache();
481193326Sed  MemBufferInfos.push_back(Entry);
482193326Sed  Entry->setBuffer(Buffer);
483193326Sed  return Entry;
484193326Sed}
485193326Sed
486235633Sdimconst SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index,
487235633Sdim                                                      bool *Invalid) const {
488235633Sdim  assert(!SLocEntryLoaded[Index]);
489235633Sdim  if (ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
490235633Sdim    if (Invalid)
491235633Sdim      *Invalid = true;
492235633Sdim    // If the file of the SLocEntry changed we could still have loaded it.
493235633Sdim    if (!SLocEntryLoaded[Index]) {
494235633Sdim      // Try to recover; create a SLocEntry so the rest of clang can handle it.
495235633Sdim      LoadedSLocEntryTable[Index] = SLocEntry::get(0,
496235633Sdim                                 FileInfo::get(SourceLocation(),
497235633Sdim                                               getFakeContentCacheForRecovery(),
498235633Sdim                                               SrcMgr::C_User));
499235633Sdim    }
500235633Sdim  }
501235633Sdim
502235633Sdim  return LoadedSLocEntryTable[Index];
503235633Sdim}
504235633Sdim
505226890Sdimstd::pair<int, unsigned>
506226890SdimSourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries,
507226890Sdim                                         unsigned TotalSize) {
508226890Sdim  assert(ExternalSLocEntries && "Don't have an external sloc source");
509226890Sdim  LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
510226890Sdim  SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
511226890Sdim  CurrentLoadedOffset -= TotalSize;
512226890Sdim  assert(CurrentLoadedOffset >= NextLocalOffset && "Out of source locations");
513226890Sdim  int ID = LoadedSLocEntryTable.size();
514226890Sdim  return std::make_pair(-ID - 1, CurrentLoadedOffset);
515193326Sed}
516193326Sed
517221345Sdim/// \brief As part of recovering from missing or changed content, produce a
518221345Sdim/// fake, non-empty buffer.
519221345Sdimconst llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
520221345Sdim  if (!FakeBufferForRecovery)
521221345Sdim    FakeBufferForRecovery
522221345Sdim      = llvm::MemoryBuffer::getMemBuffer("<<<INVALID BUFFER>>");
523221345Sdim
524221345Sdim  return FakeBufferForRecovery;
525221345Sdim}
526193326Sed
527235633Sdim/// \brief As part of recovering from missing or changed content, produce a
528235633Sdim/// fake content cache.
529235633Sdimconst SrcMgr::ContentCache *
530235633SdimSourceManager::getFakeContentCacheForRecovery() const {
531235633Sdim  if (!FakeContentCacheForRecovery) {
532235633Sdim    FakeContentCacheForRecovery = new ContentCache();
533235633Sdim    FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(),
534235633Sdim                                               /*DoNotFree=*/true);
535235633Sdim  }
536235633Sdim  return FakeContentCacheForRecovery;
537235633Sdim}
538235633Sdim
539263509Sdim/// \brief Returns the previous in-order FileID or an invalid FileID if there
540263509Sdim/// is no previous one.
541263509SdimFileID SourceManager::getPreviousFileID(FileID FID) const {
542263509Sdim  if (FID.isInvalid())
543263509Sdim    return FileID();
544263509Sdim
545263509Sdim  int ID = FID.ID;
546263509Sdim  if (ID == -1)
547263509Sdim    return FileID();
548263509Sdim
549263509Sdim  if (ID > 0) {
550263509Sdim    if (ID-1 == 0)
551263509Sdim      return FileID();
552263509Sdim  } else if (unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
553263509Sdim    return FileID();
554263509Sdim  }
555263509Sdim
556263509Sdim  return FileID::get(ID-1);
557263509Sdim}
558263509Sdim
559263509Sdim/// \brief Returns the next in-order FileID or an invalid FileID if there is
560263509Sdim/// no next one.
561263509SdimFileID SourceManager::getNextFileID(FileID FID) const {
562263509Sdim  if (FID.isInvalid())
563263509Sdim    return FileID();
564263509Sdim
565263509Sdim  int ID = FID.ID;
566263509Sdim  if (ID > 0) {
567263509Sdim    if (unsigned(ID+1) >= local_sloc_entry_size())
568263509Sdim      return FileID();
569263509Sdim  } else if (ID+1 >= -1) {
570263509Sdim    return FileID();
571263509Sdim  }
572263509Sdim
573263509Sdim  return FileID::get(ID+1);
574263509Sdim}
575263509Sdim
576193326Sed//===----------------------------------------------------------------------===//
577226890Sdim// Methods to create new FileID's and macro expansions.
578193326Sed//===----------------------------------------------------------------------===//
579193326Sed
580212904Sdim/// createFileID - Create a new FileID for the specified ContentCache and
581193326Sed/// include position.  This works regardless of whether the ContentCache
582193326Sed/// corresponds to a file or some other input source.
583193326SedFileID SourceManager::createFileID(const ContentCache *File,
584193326Sed                                   SourceLocation IncludePos,
585193326Sed                                   SrcMgr::CharacteristicKind FileCharacter,
586226890Sdim                                   int LoadedID, unsigned LoadedOffset) {
587226890Sdim  if (LoadedID < 0) {
588226890Sdim    assert(LoadedID != -1 && "Loading sentinel FileID");
589226890Sdim    unsigned Index = unsigned(-LoadedID) - 2;
590226890Sdim    assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
591226890Sdim    assert(!SLocEntryLoaded[Index] && "FileID already loaded");
592226890Sdim    LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset,
593226890Sdim        FileInfo::get(IncludePos, File, FileCharacter));
594226890Sdim    SLocEntryLoaded[Index] = true;
595226890Sdim    return FileID::get(LoadedID);
596193326Sed  }
597226890Sdim  LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset,
598226890Sdim                                               FileInfo::get(IncludePos, File,
599226890Sdim                                                             FileCharacter)));
600193326Sed  unsigned FileSize = File->getSize();
601226890Sdim  assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
602226890Sdim         NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
603226890Sdim         "Ran out of source locations!");
604226890Sdim  // We do a +1 here because we want a SourceLocation that means "the end of the
605226890Sdim  // file", e.g. for the "no newline at the end of the file" diagnostic.
606226890Sdim  NextLocalOffset += FileSize + 1;
607198092Srdivacky
608193326Sed  // Set LastFileIDLookup to the newly created file.  The next getFileID call is
609193326Sed  // almost guaranteed to be from that file.
610226890Sdim  FileID FID = FileID::get(LocalSLocEntryTable.size()-1);
611194711Sed  return LastFileIDLookup = FID;
612193326Sed}
613193326Sed
614224145SdimSourceLocation
615226890SdimSourceManager::createMacroArgExpansionLoc(SourceLocation SpellingLoc,
616226890Sdim                                          SourceLocation ExpansionLoc,
617226890Sdim                                          unsigned TokLength) {
618226890Sdim  ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc,
619226890Sdim                                                        ExpansionLoc);
620226890Sdim  return createExpansionLocImpl(Info, TokLength);
621224145Sdim}
622224145Sdim
623226890SdimSourceLocation
624226890SdimSourceManager::createExpansionLoc(SourceLocation SpellingLoc,
625226890Sdim                                  SourceLocation ExpansionLocStart,
626226890Sdim                                  SourceLocation ExpansionLocEnd,
627226890Sdim                                  unsigned TokLength,
628226890Sdim                                  int LoadedID,
629226890Sdim                                  unsigned LoadedOffset) {
630226890Sdim  ExpansionInfo Info = ExpansionInfo::create(SpellingLoc, ExpansionLocStart,
631226890Sdim                                             ExpansionLocEnd);
632226890Sdim  return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
633224145Sdim}
634224145Sdim
635224145SdimSourceLocation
636226890SdimSourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
637226890Sdim                                      unsigned TokLength,
638226890Sdim                                      int LoadedID,
639226890Sdim                                      unsigned LoadedOffset) {
640226890Sdim  if (LoadedID < 0) {
641226890Sdim    assert(LoadedID != -1 && "Loading sentinel FileID");
642226890Sdim    unsigned Index = unsigned(-LoadedID) - 2;
643226890Sdim    assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
644226890Sdim    assert(!SLocEntryLoaded[Index] && "FileID already loaded");
645226890Sdim    LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
646226890Sdim    SLocEntryLoaded[Index] = true;
647226890Sdim    return SourceLocation::getMacroLoc(LoadedOffset);
648193326Sed  }
649226890Sdim  LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
650226890Sdim  assert(NextLocalOffset + TokLength + 1 > NextLocalOffset &&
651226890Sdim         NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset &&
652226890Sdim         "Ran out of source locations!");
653226890Sdim  // See createFileID for that +1.
654226890Sdim  NextLocalOffset += TokLength + 1;
655226890Sdim  return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
656193326Sed}
657193326Sed
658200583Srdivackyconst llvm::MemoryBuffer *
659205219SrdivackySourceManager::getMemoryBufferForFile(const FileEntry *File,
660205219Srdivacky                                      bool *Invalid) {
661200583Srdivacky  const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
662205219Srdivacky  assert(IR && "getOrCreateContentCache() cannot return NULL");
663207619Srdivacky  return IR->getBuffer(Diag, *this, SourceLocation(), Invalid);
664200583Srdivacky}
665200583Srdivacky
666218893Sdimvoid SourceManager::overrideFileContents(const FileEntry *SourceFile,
667212904Sdim                                         const llvm::MemoryBuffer *Buffer,
668212904Sdim                                         bool DoNotFree) {
669200583Srdivacky  const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
670218893Sdim  assert(IR && "getOrCreateContentCache() cannot return NULL");
671200583Srdivacky
672212904Sdim  const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer, DoNotFree);
673235633Sdim  const_cast<SrcMgr::ContentCache *>(IR)->BufferOverridden = true;
674245431Sdim
675245431Sdim  getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
676200583Srdivacky}
677200583Srdivacky
678221345Sdimvoid SourceManager::overrideFileContents(const FileEntry *SourceFile,
679221345Sdim                                         const FileEntry *NewFile) {
680221345Sdim  assert(SourceFile->getSize() == NewFile->getSize() &&
681221345Sdim         "Different sizes, use the FileManager to create a virtual file with "
682221345Sdim         "the correct size");
683221345Sdim  assert(FileInfos.count(SourceFile) == 0 &&
684221345Sdim         "This function should be called at the initialization stage, before "
685221345Sdim         "any parsing occurs.");
686245431Sdim  getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
687221345Sdim}
688221345Sdim
689245431Sdimvoid SourceManager::disableFileContentsOverride(const FileEntry *File) {
690245431Sdim  if (!isFileOverridden(File))
691245431Sdim    return;
692245431Sdim
693245431Sdim  const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
694245431Sdim  const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(0);
695245431Sdim  const_cast<SrcMgr::ContentCache *>(IR)->ContentsEntry = IR->OrigEntry;
696245431Sdim
697245431Sdim  assert(OverriddenFilesInfo);
698245431Sdim  OverriddenFilesInfo->OverriddenFiles.erase(File);
699245431Sdim  OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File);
700245431Sdim}
701245431Sdim
702226890SdimStringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
703205408Srdivacky  bool MyInvalid = false;
704226890Sdim  const SLocEntry &SLoc = getSLocEntry(FID, &MyInvalid);
705221345Sdim  if (!SLoc.isFile() || MyInvalid) {
706218893Sdim    if (Invalid)
707218893Sdim      *Invalid = true;
708218893Sdim    return "<<<<<INVALID SOURCE LOCATION>>>>>";
709218893Sdim  }
710218893Sdim
711218893Sdim  const llvm::MemoryBuffer *Buf
712218893Sdim    = SLoc.getFile().getContentCache()->getBuffer(Diag, *this, SourceLocation(),
713218893Sdim                                                  &MyInvalid);
714205219Srdivacky  if (Invalid)
715205408Srdivacky    *Invalid = MyInvalid;
716205408Srdivacky
717205408Srdivacky  if (MyInvalid)
718218893Sdim    return "<<<<<INVALID SOURCE LOCATION>>>>>";
719205219Srdivacky
720205219Srdivacky  return Buf->getBuffer();
721193326Sed}
722193326Sed
723193326Sed//===----------------------------------------------------------------------===//
724193326Sed// SourceLocation manipulation methods.
725193326Sed//===----------------------------------------------------------------------===//
726193326Sed
727226890Sdim/// \brief Return the FileID for a SourceLocation.
728193326Sed///
729226890Sdim/// This is the cache-miss path of getFileID. Not as hot as that function, but
730226890Sdim/// still very important. It is responsible for finding the entry in the
731226890Sdim/// SLocEntry tables that contains the specified location.
732193326SedFileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
733221345Sdim  if (!SLocOffset)
734221345Sdim    return FileID::get(0);
735198092Srdivacky
736226890Sdim  // Now it is time to search for the correct file. See where the SLocOffset
737226890Sdim  // sits in the global view and consult local or loaded buffers for it.
738226890Sdim  if (SLocOffset < NextLocalOffset)
739226890Sdim    return getFileIDLocal(SLocOffset);
740226890Sdim  return getFileIDLoaded(SLocOffset);
741226890Sdim}
742226890Sdim
743226890Sdim/// \brief Return the FileID for a SourceLocation with a low offset.
744226890Sdim///
745226890Sdim/// This function knows that the SourceLocation is in a local buffer, not a
746226890Sdim/// loaded one.
747226890SdimFileID SourceManager::getFileIDLocal(unsigned SLocOffset) const {
748226890Sdim  assert(SLocOffset < NextLocalOffset && "Bad function choice");
749226890Sdim
750193326Sed  // After the first and second level caches, I see two common sorts of
751226890Sdim  // behavior: 1) a lot of searched FileID's are "near" the cached file
752226890Sdim  // location or are "near" the cached expansion location. 2) others are just
753193326Sed  // completely random and may be a very long way away.
754193326Sed  //
755193326Sed  // To handle this, we do a linear search for up to 8 steps to catch #1 quickly
756193326Sed  // then we fall back to a less cache efficient, but more scalable, binary
757193326Sed  // search to find the location.
758198092Srdivacky
759193326Sed  // See if this is near the file point - worst case we start scanning from the
760193326Sed  // most newly created FileID.
761252723Sdim  const SrcMgr::SLocEntry *I;
762198092Srdivacky
763226890Sdim  if (LastFileIDLookup.ID < 0 ||
764226890Sdim      LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
765193326Sed    // Neither loc prunes our search.
766226890Sdim    I = LocalSLocEntryTable.end();
767193326Sed  } else {
768193326Sed    // Perhaps it is near the file point.
769226890Sdim    I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID;
770193326Sed  }
771193326Sed
772193326Sed  // Find the FileID that contains this.  "I" is an iterator that points to a
773193326Sed  // FileID whose offset is known to be larger than SLocOffset.
774193326Sed  unsigned NumProbes = 0;
775193326Sed  while (1) {
776193326Sed    --I;
777193326Sed    if (I->getOffset() <= SLocOffset) {
778226890Sdim      FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin()));
779193326Sed
780226890Sdim      // If this isn't an expansion, remember it.  We have good locality across
781226890Sdim      // FileID lookups.
782226890Sdim      if (!I->isExpansion())
783193326Sed        LastFileIDLookup = Res;
784193326Sed      NumLinearScans += NumProbes+1;
785193326Sed      return Res;
786193326Sed    }
787193326Sed    if (++NumProbes == 8)
788193326Sed      break;
789193326Sed  }
790198092Srdivacky
791193326Sed  // Convert "I" back into an index.  We know that it is an entry whose index is
792193326Sed  // larger than the offset we are looking for.
793226890Sdim  unsigned GreaterIndex = I - LocalSLocEntryTable.begin();
794193326Sed  // LessIndex - This is the lower bound of the range that we're searching.
795193326Sed  // We know that the offset corresponding to the FileID is is less than
796193326Sed  // SLocOffset.
797193326Sed  unsigned LessIndex = 0;
798193326Sed  NumProbes = 0;
799193326Sed  while (1) {
800221345Sdim    bool Invalid = false;
801193326Sed    unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
802226890Sdim    unsigned MidOffset = getLocalSLocEntry(MiddleIndex, &Invalid).getOffset();
803221345Sdim    if (Invalid)
804221345Sdim      return FileID::get(0);
805221345Sdim
806193326Sed    ++NumProbes;
807198092Srdivacky
808193326Sed    // If the offset of the midpoint is too large, chop the high side of the
809193326Sed    // range to the midpoint.
810193326Sed    if (MidOffset > SLocOffset) {
811193326Sed      GreaterIndex = MiddleIndex;
812193326Sed      continue;
813193326Sed    }
814198092Srdivacky
815193326Sed    // If the middle index contains the value, succeed and return.
816226890Sdim    // FIXME: This could be made faster by using a function that's aware of
817226890Sdim    // being in the local area.
818193326Sed    if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
819193326Sed      FileID Res = FileID::get(MiddleIndex);
820193326Sed
821226890Sdim      // If this isn't a macro expansion, remember it.  We have good locality
822193326Sed      // across FileID lookups.
823226890Sdim      if (!LocalSLocEntryTable[MiddleIndex].isExpansion())
824193326Sed        LastFileIDLookup = Res;
825193326Sed      NumBinaryProbes += NumProbes;
826193326Sed      return Res;
827193326Sed    }
828198092Srdivacky
829193326Sed    // Otherwise, move the low-side up to the middle index.
830193326Sed    LessIndex = MiddleIndex;
831193326Sed  }
832193326Sed}
833193326Sed
834226890Sdim/// \brief Return the FileID for a SourceLocation with a high offset.
835226890Sdim///
836226890Sdim/// This function knows that the SourceLocation is in a loaded buffer, not a
837226890Sdim/// local one.
838226890SdimFileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const {
839226890Sdim  // Sanity checking, otherwise a bug may lead to hanging in release build.
840235633Sdim  if (SLocOffset < CurrentLoadedOffset) {
841235633Sdim    assert(0 && "Invalid SLocOffset or bad function choice");
842226890Sdim    return FileID();
843235633Sdim  }
844226890Sdim
845226890Sdim  // Essentially the same as the local case, but the loaded array is sorted
846226890Sdim  // in the other direction.
847226890Sdim
848226890Sdim  // First do a linear scan from the last lookup position, if possible.
849226890Sdim  unsigned I;
850226890Sdim  int LastID = LastFileIDLookup.ID;
851226890Sdim  if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset)
852226890Sdim    I = 0;
853226890Sdim  else
854226890Sdim    I = (-LastID - 2) + 1;
855226890Sdim
856226890Sdim  unsigned NumProbes;
857226890Sdim  for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) {
858226890Sdim    // Make sure the entry is loaded!
859226890Sdim    const SrcMgr::SLocEntry &E = getLoadedSLocEntry(I);
860226890Sdim    if (E.getOffset() <= SLocOffset) {
861226890Sdim      FileID Res = FileID::get(-int(I) - 2);
862226890Sdim
863226890Sdim      if (!E.isExpansion())
864226890Sdim        LastFileIDLookup = Res;
865226890Sdim      NumLinearScans += NumProbes + 1;
866226890Sdim      return Res;
867226890Sdim    }
868226890Sdim  }
869226890Sdim
870226890Sdim  // Linear scan failed. Do the binary search. Note the reverse sorting of the
871226890Sdim  // table: GreaterIndex is the one where the offset is greater, which is
872226890Sdim  // actually a lower index!
873226890Sdim  unsigned GreaterIndex = I;
874226890Sdim  unsigned LessIndex = LoadedSLocEntryTable.size();
875226890Sdim  NumProbes = 0;
876226890Sdim  while (1) {
877226890Sdim    ++NumProbes;
878226890Sdim    unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;
879226890Sdim    const SrcMgr::SLocEntry &E = getLoadedSLocEntry(MiddleIndex);
880252723Sdim    if (E.getOffset() == 0)
881252723Sdim      return FileID(); // invalid entry.
882226890Sdim
883226890Sdim    ++NumProbes;
884226890Sdim
885226890Sdim    if (E.getOffset() > SLocOffset) {
886252723Sdim      // Sanity checking, otherwise a bug may lead to hanging in release build.
887252723Sdim      if (GreaterIndex == MiddleIndex) {
888252723Sdim        assert(0 && "binary search missed the entry");
889252723Sdim        return FileID();
890252723Sdim      }
891226890Sdim      GreaterIndex = MiddleIndex;
892226890Sdim      continue;
893226890Sdim    }
894226890Sdim
895226890Sdim    if (isOffsetInFileID(FileID::get(-int(MiddleIndex) - 2), SLocOffset)) {
896226890Sdim      FileID Res = FileID::get(-int(MiddleIndex) - 2);
897226890Sdim      if (!E.isExpansion())
898226890Sdim        LastFileIDLookup = Res;
899226890Sdim      NumBinaryProbes += NumProbes;
900226890Sdim      return Res;
901226890Sdim    }
902226890Sdim
903252723Sdim    // Sanity checking, otherwise a bug may lead to hanging in release build.
904252723Sdim    if (LessIndex == MiddleIndex) {
905252723Sdim      assert(0 && "binary search missed the entry");
906252723Sdim      return FileID();
907252723Sdim    }
908226890Sdim    LessIndex = MiddleIndex;
909226890Sdim  }
910226890Sdim}
911226890Sdim
912193326SedSourceLocation SourceManager::
913226890SdimgetExpansionLocSlowCase(SourceLocation Loc) const {
914193326Sed  do {
915203955Srdivacky    // Note: If Loc indicates an offset into a token that came from a macro
916203955Srdivacky    // expansion (e.g. the 5th character of the token) we do not want to add
917226890Sdim    // this offset when going to the expansion location.  The expansion
918203955Srdivacky    // location is the macro invocation, which the offset has nothing to do
919203955Srdivacky    // with.  This is unlike when we get the spelling loc, because the offset
920203955Srdivacky    // directly correspond to the token whose spelling we're inspecting.
921226890Sdim    Loc = getSLocEntry(getFileID(Loc)).getExpansion().getExpansionLocStart();
922193326Sed  } while (!Loc.isFileID());
923193326Sed
924193326Sed  return Loc;
925193326Sed}
926193326Sed
927193326SedSourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const {
928193326Sed  do {
929193326Sed    std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
930226890Sdim    Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc();
931226890Sdim    Loc = Loc.getLocWithOffset(LocInfo.second);
932193326Sed  } while (!Loc.isFileID());
933193326Sed  return Loc;
934193326Sed}
935193326Sed
936226890SdimSourceLocation SourceManager::getFileLocSlowCase(SourceLocation Loc) const {
937226890Sdim  do {
938226890Sdim    if (isMacroArgExpansion(Loc))
939226890Sdim      Loc = getImmediateSpellingLoc(Loc);
940226890Sdim    else
941226890Sdim      Loc = getImmediateExpansionRange(Loc).first;
942226890Sdim  } while (!Loc.isFileID());
943226890Sdim  return Loc;
944226890Sdim}
945193326Sed
946226890Sdim
947193326Sedstd::pair<FileID, unsigned>
948226890SdimSourceManager::getDecomposedExpansionLocSlowCase(
949224145Sdim                                             const SrcMgr::SLocEntry *E) const {
950226890Sdim  // If this is an expansion record, walk through all the expansion points.
951193326Sed  FileID FID;
952193326Sed  SourceLocation Loc;
953224145Sdim  unsigned Offset;
954193326Sed  do {
955226890Sdim    Loc = E->getExpansion().getExpansionLocStart();
956198092Srdivacky
957193326Sed    FID = getFileID(Loc);
958193326Sed    E = &getSLocEntry(FID);
959224145Sdim    Offset = Loc.getOffset()-E->getOffset();
960193326Sed  } while (!Loc.isFileID());
961198092Srdivacky
962193326Sed  return std::make_pair(FID, Offset);
963193326Sed}
964193326Sed
965193326Sedstd::pair<FileID, unsigned>
966193326SedSourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
967193326Sed                                                unsigned Offset) const {
968226890Sdim  // If this is an expansion record, walk through all the expansion points.
969193326Sed  FileID FID;
970193326Sed  SourceLocation Loc;
971193326Sed  do {
972226890Sdim    Loc = E->getExpansion().getSpellingLoc();
973226890Sdim    Loc = Loc.getLocWithOffset(Offset);
974198092Srdivacky
975193326Sed    FID = getFileID(Loc);
976193326Sed    E = &getSLocEntry(FID);
977226890Sdim    Offset = Loc.getOffset()-E->getOffset();
978193326Sed  } while (!Loc.isFileID());
979198092Srdivacky
980193326Sed  return std::make_pair(FID, Offset);
981193326Sed}
982193326Sed
983193326Sed/// getImmediateSpellingLoc - Given a SourceLocation object, return the
984193326Sed/// spelling location referenced by the ID.  This is the first level down
985193326Sed/// towards the place where the characters that make up the lexed token can be
986193326Sed/// found.  This should not generally be used by clients.
987193326SedSourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{
988193326Sed  if (Loc.isFileID()) return Loc;
989193326Sed  std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
990226890Sdim  Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc();
991226890Sdim  return Loc.getLocWithOffset(LocInfo.second);
992193326Sed}
993193326Sed
994193326Sed
995226890Sdim/// getImmediateExpansionRange - Loc is required to be an expansion location.
996226890Sdim/// Return the start/end of the expansion information.
997193326Sedstd::pair<SourceLocation,SourceLocation>
998226890SdimSourceManager::getImmediateExpansionRange(SourceLocation Loc) const {
999226890Sdim  assert(Loc.isMacroID() && "Not a macro expansion loc!");
1000226890Sdim  const ExpansionInfo &Expansion = getSLocEntry(getFileID(Loc)).getExpansion();
1001226890Sdim  return Expansion.getExpansionLocRange();
1002193326Sed}
1003193326Sed
1004226890Sdim/// getExpansionRange - Given a SourceLocation object, return the range of
1005226890Sdim/// tokens covered by the expansion in the ultimate file.
1006193326Sedstd::pair<SourceLocation,SourceLocation>
1007226890SdimSourceManager::getExpansionRange(SourceLocation Loc) const {
1008193326Sed  if (Loc.isFileID()) return std::make_pair(Loc, Loc);
1009198092Srdivacky
1010193326Sed  std::pair<SourceLocation,SourceLocation> Res =
1011226890Sdim    getImmediateExpansionRange(Loc);
1012198092Srdivacky
1013226890Sdim  // Fully resolve the start and end locations to their ultimate expansion
1014193326Sed  // points.
1015193326Sed  while (!Res.first.isFileID())
1016226890Sdim    Res.first = getImmediateExpansionRange(Res.first).first;
1017193326Sed  while (!Res.second.isFileID())
1018226890Sdim    Res.second = getImmediateExpansionRange(Res.second).second;
1019193326Sed  return Res;
1020193326Sed}
1021193326Sed
1022226890Sdimbool SourceManager::isMacroArgExpansion(SourceLocation Loc) const {
1023224145Sdim  if (!Loc.isMacroID()) return false;
1024193326Sed
1025224145Sdim  FileID FID = getFileID(Loc);
1026252723Sdim  const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion();
1027226890Sdim  return Expansion.isMacroArgExpansion();
1028224145Sdim}
1029193326Sed
1030252723Sdimbool SourceManager::isMacroBodyExpansion(SourceLocation Loc) const {
1031252723Sdim  if (!Loc.isMacroID()) return false;
1032224145Sdim
1033252723Sdim  FileID FID = getFileID(Loc);
1034252723Sdim  const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion();
1035252723Sdim  return Expansion.isMacroBodyExpansion();
1036252723Sdim}
1037252723Sdim
1038263509Sdimbool SourceManager::isAtStartOfImmediateMacroExpansion(SourceLocation Loc,
1039263509Sdim                                             SourceLocation *MacroBegin) const {
1040263509Sdim  assert(Loc.isValid() && Loc.isMacroID() && "Expected a valid macro loc");
1041252723Sdim
1042263509Sdim  std::pair<FileID, unsigned> DecompLoc = getDecomposedLoc(Loc);
1043263509Sdim  if (DecompLoc.second > 0)
1044263509Sdim    return false; // Does not point at the start of expansion range.
1045263509Sdim
1046263509Sdim  bool Invalid = false;
1047263509Sdim  const SrcMgr::ExpansionInfo &ExpInfo =
1048263509Sdim      getSLocEntry(DecompLoc.first, &Invalid).getExpansion();
1049263509Sdim  if (Invalid)
1050263509Sdim    return false;
1051263509Sdim  SourceLocation ExpLoc = ExpInfo.getExpansionLocStart();
1052263509Sdim
1053263509Sdim  if (ExpInfo.isMacroArgExpansion()) {
1054263509Sdim    // For macro argument expansions, check if the previous FileID is part of
1055263509Sdim    // the same argument expansion, in which case this Loc is not at the
1056263509Sdim    // beginning of the expansion.
1057263509Sdim    FileID PrevFID = getPreviousFileID(DecompLoc.first);
1058263509Sdim    if (!PrevFID.isInvalid()) {
1059263509Sdim      const SrcMgr::SLocEntry &PrevEntry = getSLocEntry(PrevFID, &Invalid);
1060263509Sdim      if (Invalid)
1061263509Sdim        return false;
1062263509Sdim      if (PrevEntry.isExpansion() &&
1063263509Sdim          PrevEntry.getExpansion().getExpansionLocStart() == ExpLoc)
1064263509Sdim        return false;
1065263509Sdim    }
1066263509Sdim  }
1067263509Sdim
1068263509Sdim  if (MacroBegin)
1069263509Sdim    *MacroBegin = ExpLoc;
1070263509Sdim  return true;
1071263509Sdim}
1072263509Sdim
1073263509Sdimbool SourceManager::isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
1074263509Sdim                                               SourceLocation *MacroEnd) const {
1075263509Sdim  assert(Loc.isValid() && Loc.isMacroID() && "Expected a valid macro loc");
1076263509Sdim
1077263509Sdim  FileID FID = getFileID(Loc);
1078263509Sdim  SourceLocation NextLoc = Loc.getLocWithOffset(1);
1079263509Sdim  if (isInFileID(NextLoc, FID))
1080263509Sdim    return false; // Does not point at the end of expansion range.
1081263509Sdim
1082263509Sdim  bool Invalid = false;
1083263509Sdim  const SrcMgr::ExpansionInfo &ExpInfo =
1084263509Sdim      getSLocEntry(FID, &Invalid).getExpansion();
1085263509Sdim  if (Invalid)
1086263509Sdim    return false;
1087263509Sdim
1088263509Sdim  if (ExpInfo.isMacroArgExpansion()) {
1089263509Sdim    // For macro argument expansions, check if the next FileID is part of the
1090263509Sdim    // same argument expansion, in which case this Loc is not at the end of the
1091263509Sdim    // expansion.
1092263509Sdim    FileID NextFID = getNextFileID(FID);
1093263509Sdim    if (!NextFID.isInvalid()) {
1094263509Sdim      const SrcMgr::SLocEntry &NextEntry = getSLocEntry(NextFID, &Invalid);
1095263509Sdim      if (Invalid)
1096263509Sdim        return false;
1097263509Sdim      if (NextEntry.isExpansion() &&
1098263509Sdim          NextEntry.getExpansion().getExpansionLocStart() ==
1099263509Sdim              ExpInfo.getExpansionLocStart())
1100263509Sdim        return false;
1101263509Sdim    }
1102263509Sdim  }
1103263509Sdim
1104263509Sdim  if (MacroEnd)
1105263509Sdim    *MacroEnd = ExpInfo.getExpansionLocEnd();
1106263509Sdim  return true;
1107263509Sdim}
1108263509Sdim
1109263509Sdim
1110193326Sed//===----------------------------------------------------------------------===//
1111193326Sed// Queries about the code at a SourceLocation.
1112193326Sed//===----------------------------------------------------------------------===//
1113193326Sed
1114193326Sed/// getCharacterData - Return a pointer to the start of the specified location
1115193326Sed/// in the appropriate MemoryBuffer.
1116205219Srdivackyconst char *SourceManager::getCharacterData(SourceLocation SL,
1117205219Srdivacky                                            bool *Invalid) const {
1118193326Sed  // Note that this is a hot function in the getSpelling() path, which is
1119193326Sed  // heavily used by -E mode.
1120193326Sed  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL);
1121198092Srdivacky
1122193326Sed  // Note that calling 'getBuffer()' may lazily page in a source file.
1123205219Srdivacky  bool CharDataInvalid = false;
1124221345Sdim  const SLocEntry &Entry = getSLocEntry(LocInfo.first, &CharDataInvalid);
1125221345Sdim  if (CharDataInvalid || !Entry.isFile()) {
1126221345Sdim    if (Invalid)
1127221345Sdim      *Invalid = true;
1128221345Sdim
1129221345Sdim    return "<<<<INVALID BUFFER>>>>";
1130221345Sdim  }
1131205219Srdivacky  const llvm::MemoryBuffer *Buffer
1132221345Sdim    = Entry.getFile().getContentCache()
1133221345Sdim                  ->getBuffer(Diag, *this, SourceLocation(), &CharDataInvalid);
1134205219Srdivacky  if (Invalid)
1135205219Srdivacky    *Invalid = CharDataInvalid;
1136205219Srdivacky  return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
1137193326Sed}
1138193326Sed
1139193326Sed
1140193326Sed/// getColumnNumber - Return the column # for the specified file position.
1141193326Sed/// this is significantly cheaper to compute than the line number.
1142205219Srdivackyunsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
1143205219Srdivacky                                        bool *Invalid) const {
1144205219Srdivacky  bool MyInvalid = false;
1145235633Sdim  const llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid);
1146205219Srdivacky  if (Invalid)
1147205219Srdivacky    *Invalid = MyInvalid;
1148198092Srdivacky
1149205219Srdivacky  if (MyInvalid)
1150205219Srdivacky    return 1;
1151205219Srdivacky
1152245431Sdim  // It is okay to request a position just past the end of the buffer.
1153245431Sdim  if (FilePos > MemBuf->getBufferSize()) {
1154235633Sdim    if (Invalid)
1155245431Sdim      *Invalid = true;
1156235633Sdim    return 1;
1157235633Sdim  }
1158235633Sdim
1159245431Sdim  // See if we just calculated the line number for this FilePos and can use
1160245431Sdim  // that to lookup the start of the line instead of searching for it.
1161245431Sdim  if (LastLineNoFileIDQuery == FID &&
1162252723Sdim      LastLineNoContentCache->SourceLineCache != 0 &&
1163252723Sdim      LastLineNoResult < LastLineNoContentCache->NumLines) {
1164245431Sdim    unsigned *SourceLineCache = LastLineNoContentCache->SourceLineCache;
1165245431Sdim    unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
1166245431Sdim    unsigned LineEnd = SourceLineCache[LastLineNoResult];
1167245431Sdim    if (FilePos >= LineStart && FilePos < LineEnd)
1168245431Sdim      return FilePos - LineStart + 1;
1169245431Sdim  }
1170245431Sdim
1171235633Sdim  const char *Buf = MemBuf->getBufferStart();
1172193326Sed  unsigned LineStart = FilePos;
1173193326Sed  while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
1174193326Sed    --LineStart;
1175193326Sed  return FilePos-LineStart+1;
1176193326Sed}
1177193326Sed
1178218893Sdim// isInvalid - Return the result of calling loc.isInvalid(), and
1179218893Sdim// if Invalid is not null, set its value to same.
1180218893Sdimstatic bool isInvalid(SourceLocation Loc, bool *Invalid) {
1181218893Sdim  bool MyInvalid = Loc.isInvalid();
1182218893Sdim  if (Invalid)
1183218893Sdim    *Invalid = MyInvalid;
1184218893Sdim  return MyInvalid;
1185218893Sdim}
1186218893Sdim
1187205219Srdivackyunsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc,
1188205219Srdivacky                                                bool *Invalid) const {
1189218893Sdim  if (isInvalid(Loc, Invalid)) return 0;
1190193326Sed  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
1191205219Srdivacky  return getColumnNumber(LocInfo.first, LocInfo.second, Invalid);
1192193326Sed}
1193193326Sed
1194226890Sdimunsigned SourceManager::getExpansionColumnNumber(SourceLocation Loc,
1195226890Sdim                                                 bool *Invalid) const {
1196218893Sdim  if (isInvalid(Loc, Invalid)) return 0;
1197226890Sdim  std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1198205219Srdivacky  return getColumnNumber(LocInfo.first, LocInfo.second, Invalid);
1199193326Sed}
1200193326Sed
1201219077Sdimunsigned SourceManager::getPresumedColumnNumber(SourceLocation Loc,
1202219077Sdim                                                bool *Invalid) const {
1203219077Sdim  if (isInvalid(Loc, Invalid)) return 0;
1204219077Sdim  return getPresumedLoc(Loc).getColumn();
1205219077Sdim}
1206219077Sdim
1207235633Sdim#ifdef __SSE2__
1208235633Sdim#include <emmintrin.h>
1209235633Sdim#endif
1210235633Sdim
1211218893Sdimstatic LLVM_ATTRIBUTE_NOINLINE void
1212226890SdimComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI,
1213207619Srdivacky                   llvm::BumpPtrAllocator &Alloc,
1214207619Srdivacky                   const SourceManager &SM, bool &Invalid);
1215226890Sdimstatic void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI,
1216207619Srdivacky                               llvm::BumpPtrAllocator &Alloc,
1217207619Srdivacky                               const SourceManager &SM, bool &Invalid) {
1218193326Sed  // Note that calling 'getBuffer()' may lazily page in the file.
1219207619Srdivacky  const MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(),
1220207619Srdivacky                                             &Invalid);
1221205219Srdivacky  if (Invalid)
1222205219Srdivacky    return;
1223198092Srdivacky
1224193326Sed  // Find the file offsets of all of the *physical* source lines.  This does
1225193326Sed  // not look at trigraphs, escaped newlines, or anything else tricky.
1226226890Sdim  SmallVector<unsigned, 256> LineOffsets;
1227198092Srdivacky
1228193326Sed  // Line #1 starts at char 0.
1229193326Sed  LineOffsets.push_back(0);
1230198092Srdivacky
1231193326Sed  const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
1232193326Sed  const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
1233193326Sed  unsigned Offs = 0;
1234193326Sed  while (1) {
1235193326Sed    // Skip over the contents of the line.
1236193326Sed    const unsigned char *NextBuf = (const unsigned char *)Buf;
1237235633Sdim
1238235633Sdim#ifdef __SSE2__
1239235633Sdim    // Try to skip to the next newline using SSE instructions. This is very
1240235633Sdim    // performance sensitive for programs with lots of diagnostics and in -E
1241235633Sdim    // mode.
1242235633Sdim    __m128i CRs = _mm_set1_epi8('\r');
1243235633Sdim    __m128i LFs = _mm_set1_epi8('\n');
1244235633Sdim
1245235633Sdim    // First fix up the alignment to 16 bytes.
1246235633Sdim    while (((uintptr_t)NextBuf & 0xF) != 0) {
1247235633Sdim      if (*NextBuf == '\n' || *NextBuf == '\r' || *NextBuf == '\0')
1248235633Sdim        goto FoundSpecialChar;
1249235633Sdim      ++NextBuf;
1250235633Sdim    }
1251235633Sdim
1252235633Sdim    // Scan 16 byte chunks for '\r' and '\n'. Ignore '\0'.
1253235633Sdim    while (NextBuf+16 <= End) {
1254245431Sdim      const __m128i Chunk = *(const __m128i*)NextBuf;
1255235633Sdim      __m128i Cmp = _mm_or_si128(_mm_cmpeq_epi8(Chunk, CRs),
1256235633Sdim                                 _mm_cmpeq_epi8(Chunk, LFs));
1257235633Sdim      unsigned Mask = _mm_movemask_epi8(Cmp);
1258235633Sdim
1259235633Sdim      // If we found a newline, adjust the pointer and jump to the handling code.
1260235633Sdim      if (Mask != 0) {
1261263509Sdim        NextBuf += llvm::countTrailingZeros(Mask);
1262235633Sdim        goto FoundSpecialChar;
1263235633Sdim      }
1264235633Sdim      NextBuf += 16;
1265235633Sdim    }
1266235633Sdim#endif
1267235633Sdim
1268193326Sed    while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
1269193326Sed      ++NextBuf;
1270235633Sdim
1271235633Sdim#ifdef __SSE2__
1272235633SdimFoundSpecialChar:
1273235633Sdim#endif
1274193326Sed    Offs += NextBuf-Buf;
1275193326Sed    Buf = NextBuf;
1276198092Srdivacky
1277193326Sed    if (Buf[0] == '\n' || Buf[0] == '\r') {
1278193326Sed      // If this is \n\r or \r\n, skip both characters.
1279193326Sed      if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
1280193326Sed        ++Offs, ++Buf;
1281193326Sed      ++Offs, ++Buf;
1282193326Sed      LineOffsets.push_back(Offs);
1283193326Sed    } else {
1284193326Sed      // Otherwise, this is a null.  If end of file, exit.
1285193326Sed      if (Buf == End) break;
1286193326Sed      // Otherwise, skip the null.
1287193326Sed      ++Offs, ++Buf;
1288193326Sed    }
1289193326Sed  }
1290198092Srdivacky
1291193326Sed  // Copy the offsets into the FileInfo structure.
1292193326Sed  FI->NumLines = LineOffsets.size();
1293193326Sed  FI->SourceLineCache = Alloc.Allocate<unsigned>(LineOffsets.size());
1294193326Sed  std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
1295193326Sed}
1296193326Sed
1297193326Sed/// getLineNumber - Given a SourceLocation, return the spelling line number
1298193326Sed/// for the position indicated.  This requires building and caching a table of
1299193326Sed/// line offsets for the MemoryBuffer, so this is not cheap: use only when
1300193326Sed/// about to emit a diagnostic.
1301205219Srdivackyunsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos,
1302205219Srdivacky                                      bool *Invalid) const {
1303223017Sdim  if (FID.isInvalid()) {
1304223017Sdim    if (Invalid)
1305223017Sdim      *Invalid = true;
1306223017Sdim    return 1;
1307223017Sdim  }
1308223017Sdim
1309193326Sed  ContentCache *Content;
1310193326Sed  if (LastLineNoFileIDQuery == FID)
1311193326Sed    Content = LastLineNoContentCache;
1312221345Sdim  else {
1313221345Sdim    bool MyInvalid = false;
1314221345Sdim    const SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
1315221345Sdim    if (MyInvalid || !Entry.isFile()) {
1316221345Sdim      if (Invalid)
1317221345Sdim        *Invalid = true;
1318221345Sdim      return 1;
1319221345Sdim    }
1320221345Sdim
1321221345Sdim    Content = const_cast<ContentCache*>(Entry.getFile().getContentCache());
1322221345Sdim  }
1323221345Sdim
1324193326Sed  // If this is the first use of line information for this buffer, compute the
1325193326Sed  /// SourceLineCache for it on demand.
1326205219Srdivacky  if (Content->SourceLineCache == 0) {
1327205219Srdivacky    bool MyInvalid = false;
1328207619Srdivacky    ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid);
1329205219Srdivacky    if (Invalid)
1330205219Srdivacky      *Invalid = MyInvalid;
1331205219Srdivacky    if (MyInvalid)
1332205219Srdivacky      return 1;
1333205219Srdivacky  } else if (Invalid)
1334205219Srdivacky    *Invalid = false;
1335193326Sed
1336193326Sed  // Okay, we know we have a line number table.  Do a binary search to find the
1337193326Sed  // line number that this character position lands on.
1338193326Sed  unsigned *SourceLineCache = Content->SourceLineCache;
1339193326Sed  unsigned *SourceLineCacheStart = SourceLineCache;
1340193326Sed  unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
1341198092Srdivacky
1342193326Sed  unsigned QueriedFilePos = FilePos+1;
1343193326Sed
1344193326Sed  // FIXME: I would like to be convinced that this code is worth being as
1345198092Srdivacky  // complicated as it is, binary search isn't that slow.
1346193326Sed  //
1347193326Sed  // If it is worth being optimized, then in my opinion it could be more
1348193326Sed  // performant, simpler, and more obviously correct by just "galloping" outward
1349193326Sed  // from the queried file position. In fact, this could be incorporated into a
1350193326Sed  // generic algorithm such as lower_bound_with_hint.
1351193326Sed  //
1352193326Sed  // If someone gives me a test case where this matters, and I will do it! - DWD
1353193326Sed
1354193326Sed  // If the previous query was to the same file, we know both the file pos from
1355193326Sed  // that query and the line number returned.  This allows us to narrow the
1356193326Sed  // search space from the entire file to something near the match.
1357193326Sed  if (LastLineNoFileIDQuery == FID) {
1358193326Sed    if (QueriedFilePos >= LastLineNoFilePos) {
1359193326Sed      // FIXME: Potential overflow?
1360193326Sed      SourceLineCache = SourceLineCache+LastLineNoResult-1;
1361198092Srdivacky
1362193326Sed      // The query is likely to be nearby the previous one.  Here we check to
1363193326Sed      // see if it is within 5, 10 or 20 lines.  It can be far away in cases
1364193326Sed      // where big comment blocks and vertical whitespace eat up lines but
1365193326Sed      // contribute no tokens.
1366193326Sed      if (SourceLineCache+5 < SourceLineCacheEnd) {
1367193326Sed        if (SourceLineCache[5] > QueriedFilePos)
1368193326Sed          SourceLineCacheEnd = SourceLineCache+5;
1369193326Sed        else if (SourceLineCache+10 < SourceLineCacheEnd) {
1370193326Sed          if (SourceLineCache[10] > QueriedFilePos)
1371193326Sed            SourceLineCacheEnd = SourceLineCache+10;
1372193326Sed          else if (SourceLineCache+20 < SourceLineCacheEnd) {
1373193326Sed            if (SourceLineCache[20] > QueriedFilePos)
1374193326Sed              SourceLineCacheEnd = SourceLineCache+20;
1375193326Sed          }
1376193326Sed        }
1377193326Sed      }
1378193326Sed    } else {
1379193326Sed      if (LastLineNoResult < Content->NumLines)
1380193326Sed        SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
1381193326Sed    }
1382193326Sed  }
1383198092Srdivacky
1384193326Sed  // If the spread is large, do a "radix" test as our initial guess, based on
1385193326Sed  // the assumption that lines average to approximately the same length.
1386193326Sed  // NOTE: This is currently disabled, as it does not appear to be profitable in
1387193326Sed  // initial measurements.
1388193326Sed  if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
1389193326Sed    unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];
1390198092Srdivacky
1391193326Sed    // Take a stab at guessing where it is.
1392193326Sed    unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;
1393198092Srdivacky
1394193326Sed    // Check for -10 and +10 lines.
1395193326Sed    unsigned LowerBound = std::max(int(ApproxPos-10), 0);
1396193326Sed    unsigned UpperBound = std::min(ApproxPos+10, FileLen);
1397193326Sed
1398193326Sed    // If the computed lower bound is less than the query location, move it in.
1399193326Sed    if (SourceLineCache < SourceLineCacheStart+LowerBound &&
1400193326Sed        SourceLineCacheStart[LowerBound] < QueriedFilePos)
1401193326Sed      SourceLineCache = SourceLineCacheStart+LowerBound;
1402198092Srdivacky
1403193326Sed    // If the computed upper bound is greater than the query location, move it.
1404193326Sed    if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
1405193326Sed        SourceLineCacheStart[UpperBound] >= QueriedFilePos)
1406193326Sed      SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
1407193326Sed  }
1408198092Srdivacky
1409193326Sed  unsigned *Pos
1410193326Sed    = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
1411193326Sed  unsigned LineNo = Pos-SourceLineCacheStart;
1412198092Srdivacky
1413193326Sed  LastLineNoFileIDQuery = FID;
1414193326Sed  LastLineNoContentCache = Content;
1415193326Sed  LastLineNoFilePos = QueriedFilePos;
1416193326Sed  LastLineNoResult = LineNo;
1417193326Sed  return LineNo;
1418193326Sed}
1419193326Sed
1420219077Sdimunsigned SourceManager::getSpellingLineNumber(SourceLocation Loc,
1421219077Sdim                                              bool *Invalid) const {
1422219077Sdim  if (isInvalid(Loc, Invalid)) return 0;
1423219077Sdim  std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
1424219077Sdim  return getLineNumber(LocInfo.first, LocInfo.second);
1425219077Sdim}
1426226890Sdimunsigned SourceManager::getExpansionLineNumber(SourceLocation Loc,
1427226890Sdim                                               bool *Invalid) const {
1428218893Sdim  if (isInvalid(Loc, Invalid)) return 0;
1429226890Sdim  std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1430193326Sed  return getLineNumber(LocInfo.first, LocInfo.second);
1431193326Sed}
1432219077Sdimunsigned SourceManager::getPresumedLineNumber(SourceLocation Loc,
1433205219Srdivacky                                              bool *Invalid) const {
1434218893Sdim  if (isInvalid(Loc, Invalid)) return 0;
1435219077Sdim  return getPresumedLoc(Loc).getLine();
1436193326Sed}
1437193326Sed
1438193326Sed/// getFileCharacteristic - return the file characteristic of the specified
1439198092Srdivacky/// source location, indicating whether this is a normal file, a system
1440193326Sed/// header, or an "implicit extern C" system header.
1441193326Sed///
1442193326Sed/// This state can be modified with flags on GNU linemarker directives like:
1443193326Sed///   # 4 "foo.h" 3
1444193326Sed/// which changes all source locations in the current file after that to be
1445193326Sed/// considered to be from a system header.
1446198092SrdivackySrcMgr::CharacteristicKind
1447193326SedSourceManager::getFileCharacteristic(SourceLocation Loc) const {
1448193326Sed  assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!");
1449226890Sdim  std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1450221345Sdim  bool Invalid = false;
1451221345Sdim  const SLocEntry &SEntry = getSLocEntry(LocInfo.first, &Invalid);
1452221345Sdim  if (Invalid || !SEntry.isFile())
1453221345Sdim    return C_User;
1454221345Sdim
1455221345Sdim  const SrcMgr::FileInfo &FI = SEntry.getFile();
1456193326Sed
1457193326Sed  // If there are no #line directives in this file, just return the whole-file
1458193326Sed  // state.
1459193326Sed  if (!FI.hasLineDirectives())
1460193326Sed    return FI.getFileCharacteristic();
1461198092Srdivacky
1462193326Sed  assert(LineTable && "Can't have linetable entries without a LineTable!");
1463193326Sed  // See if there is a #line directive before the location.
1464193326Sed  const LineEntry *Entry =
1465245431Sdim    LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second);
1466198092Srdivacky
1467193326Sed  // If this is before the first line marker, use the file characteristic.
1468193326Sed  if (!Entry)
1469193326Sed    return FI.getFileCharacteristic();
1470193326Sed
1471193326Sed  return Entry->FileKind;
1472193326Sed}
1473193326Sed
1474193326Sed/// Return the filename or buffer identifier of the buffer the location is in.
1475245431Sdim/// Note that this name does not respect \#line directives.  Use getPresumedLoc
1476193326Sed/// for normal clients.
1477205219Srdivackyconst char *SourceManager::getBufferName(SourceLocation Loc,
1478205219Srdivacky                                         bool *Invalid) const {
1479218893Sdim  if (isInvalid(Loc, Invalid)) return "<invalid loc>";
1480198092Srdivacky
1481205219Srdivacky  return getBuffer(getFileID(Loc), Invalid)->getBufferIdentifier();
1482193326Sed}
1483193326Sed
1484193326Sed
1485193326Sed/// getPresumedLoc - This method returns the "presumed" location of a
1486245431Sdim/// SourceLocation specifies.  A "presumed location" can be modified by \#line
1487193326Sed/// or GNU line marker directives.  This provides a view on the data that a
1488193326Sed/// user should see in diagnostics, for example.
1489193326Sed///
1490226890Sdim/// Note that a presumed location is always given as the expansion point of an
1491226890Sdim/// expansion location, not at the spelling location.
1492252723SdimPresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc,
1493252723Sdim                                          bool UseLineDirectives) const {
1494193326Sed  if (Loc.isInvalid()) return PresumedLoc();
1495198092Srdivacky
1496226890Sdim  // Presumed locations are always for expansion points.
1497226890Sdim  std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1498198092Srdivacky
1499221345Sdim  bool Invalid = false;
1500221345Sdim  const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
1501221345Sdim  if (Invalid || !Entry.isFile())
1502221345Sdim    return PresumedLoc();
1503221345Sdim
1504221345Sdim  const SrcMgr::FileInfo &FI = Entry.getFile();
1505193326Sed  const SrcMgr::ContentCache *C = FI.getContentCache();
1506198092Srdivacky
1507193326Sed  // To get the source name, first consult the FileEntry (if one exists)
1508193326Sed  // before the MemBuffer as this will avoid unnecessarily paging in the
1509193326Sed  // MemBuffer.
1510207619Srdivacky  const char *Filename;
1511221345Sdim  if (C->OrigEntry)
1512221345Sdim    Filename = C->OrigEntry->getName();
1513207619Srdivacky  else
1514207619Srdivacky    Filename = C->getBuffer(Diag, *this)->getBufferIdentifier();
1515221345Sdim
1516218893Sdim  unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second, &Invalid);
1517218893Sdim  if (Invalid)
1518218893Sdim    return PresumedLoc();
1519218893Sdim  unsigned ColNo  = getColumnNumber(LocInfo.first, LocInfo.second, &Invalid);
1520218893Sdim  if (Invalid)
1521218893Sdim    return PresumedLoc();
1522218893Sdim
1523193326Sed  SourceLocation IncludeLoc = FI.getIncludeLoc();
1524198092Srdivacky
1525193326Sed  // If we have #line directives in this file, update and overwrite the physical
1526193326Sed  // location info if appropriate.
1527252723Sdim  if (UseLineDirectives && FI.hasLineDirectives()) {
1528193326Sed    assert(LineTable && "Can't have linetable entries without a LineTable!");
1529193326Sed    // See if there is a #line directive before this.  If so, get it.
1530193326Sed    if (const LineEntry *Entry =
1531245431Sdim          LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second)) {
1532193326Sed      // If the LineEntry indicates a filename, use it.
1533193326Sed      if (Entry->FilenameID != -1)
1534193326Sed        Filename = LineTable->getFilename(Entry->FilenameID);
1535193326Sed
1536193326Sed      // Use the line number specified by the LineEntry.  This line number may
1537193326Sed      // be multiple lines down from the line entry.  Add the difference in
1538193326Sed      // physical line numbers from the query point and the line marker to the
1539193326Sed      // total.
1540193326Sed      unsigned MarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset);
1541193326Sed      LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
1542198092Srdivacky
1543193326Sed      // Note that column numbers are not molested by line markers.
1544198092Srdivacky
1545193326Sed      // Handle virtual #include manipulation.
1546193326Sed      if (Entry->IncludeOffset) {
1547193326Sed        IncludeLoc = getLocForStartOfFile(LocInfo.first);
1548226890Sdim        IncludeLoc = IncludeLoc.getLocWithOffset(Entry->IncludeOffset);
1549193326Sed      }
1550193326Sed    }
1551193326Sed  }
1552193326Sed
1553193326Sed  return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc);
1554193326Sed}
1555193326Sed
1556263509Sdim/// \brief Returns whether the PresumedLoc for a given SourceLocation is
1557263509Sdim/// in the main file.
1558263509Sdim///
1559263509Sdim/// This computes the "presumed" location for a SourceLocation, then checks
1560263509Sdim/// whether it came from a file other than the main file. This is different
1561263509Sdim/// from isWrittenInMainFile() because it takes line marker directives into
1562263509Sdim/// account.
1563263509Sdimbool SourceManager::isInMainFile(SourceLocation Loc) const {
1564263509Sdim  if (Loc.isInvalid()) return false;
1565263509Sdim
1566263509Sdim  // Presumed locations are always for expansion points.
1567263509Sdim  std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1568263509Sdim
1569263509Sdim  bool Invalid = false;
1570263509Sdim  const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
1571263509Sdim  if (Invalid || !Entry.isFile())
1572263509Sdim    return false;
1573263509Sdim
1574263509Sdim  const SrcMgr::FileInfo &FI = Entry.getFile();
1575263509Sdim
1576263509Sdim  // Check if there is a line directive for this location.
1577263509Sdim  if (FI.hasLineDirectives())
1578263509Sdim    if (const LineEntry *Entry =
1579263509Sdim            LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second))
1580263509Sdim      if (Entry->IncludeOffset)
1581263509Sdim        return false;
1582263509Sdim
1583263509Sdim  return FI.getIncludeLoc().isInvalid();
1584263509Sdim}
1585263509Sdim
1586226890Sdim/// \brief The size of the SLocEnty that \arg FID represents.
1587226890Sdimunsigned SourceManager::getFileIDSize(FileID FID) const {
1588226890Sdim  bool Invalid = false;
1589226890Sdim  const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
1590226890Sdim  if (Invalid)
1591226890Sdim    return 0;
1592226890Sdim
1593226890Sdim  int ID = FID.ID;
1594226890Sdim  unsigned NextOffset;
1595226890Sdim  if ((ID > 0 && unsigned(ID+1) == local_sloc_entry_size()))
1596226890Sdim    NextOffset = getNextLocalOffset();
1597226890Sdim  else if (ID+1 == -1)
1598226890Sdim    NextOffset = MaxLoadedOffset;
1599226890Sdim  else
1600226890Sdim    NextOffset = getSLocEntry(FileID::get(ID+1)).getOffset();
1601226890Sdim
1602226890Sdim  return NextOffset - Entry.getOffset() - 1;
1603226890Sdim}
1604226890Sdim
1605193326Sed//===----------------------------------------------------------------------===//
1606193326Sed// Other miscellaneous methods.
1607193326Sed//===----------------------------------------------------------------------===//
1608193326Sed
1609218893Sdim/// \brief Retrieve the inode for the given file entry, if possible.
1610218893Sdim///
1611218893Sdim/// This routine involves a system call, and therefore should only be used
1612218893Sdim/// in non-performance-critical code.
1613263509Sdimstatic Optional<llvm::sys::fs::UniqueID>
1614263509SdimgetActualFileUID(const FileEntry *File) {
1615218893Sdim  if (!File)
1616252723Sdim    return None;
1617263509Sdim
1618263509Sdim  llvm::sys::fs::UniqueID ID;
1619263509Sdim  if (llvm::sys::fs::getUniqueID(File->getName(), ID))
1620252723Sdim    return None;
1621263509Sdim
1622263509Sdim  return ID;
1623218893Sdim}
1624218893Sdim
1625194613Sed/// \brief Get the source location for the given file:line:col triplet.
1626194613Sed///
1627194613Sed/// If the source file is included multiple times, the source location will
1628226890Sdim/// be based upon an arbitrary inclusion.
1629226890SdimSourceLocation SourceManager::translateFileLineCol(const FileEntry *SourceFile,
1630226890Sdim                                                  unsigned Line,
1631226890Sdim                                                  unsigned Col) const {
1632194613Sed  assert(SourceFile && "Null source file!");
1633194613Sed  assert(Line && Col && "Line and column should start from 1!");
1634193326Sed
1635226890Sdim  FileID FirstFID = translateFile(SourceFile);
1636226890Sdim  return translateLineCol(FirstFID, Line, Col);
1637226890Sdim}
1638226890Sdim
1639226890Sdim/// \brief Get the FileID for the given file.
1640226890Sdim///
1641226890Sdim/// If the source file is included multiple times, the FileID will be the
1642226890Sdim/// first inclusion.
1643226890SdimFileID SourceManager::translateFile(const FileEntry *SourceFile) const {
1644226890Sdim  assert(SourceFile && "Null source file!");
1645226890Sdim
1646200583Srdivacky  // Find the first file ID that corresponds to the given file.
1647200583Srdivacky  FileID FirstFID;
1648200583Srdivacky
1649200583Srdivacky  // First, check the main file ID, since it is common to look for a
1650200583Srdivacky  // location in the main file.
1651263509Sdim  Optional<llvm::sys::fs::UniqueID> SourceFileUID;
1652252723Sdim  Optional<StringRef> SourceFileName;
1653200583Srdivacky  if (!MainFileID.isInvalid()) {
1654221345Sdim    bool Invalid = false;
1655221345Sdim    const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid);
1656221345Sdim    if (Invalid)
1657226890Sdim      return FileID();
1658221345Sdim
1659218893Sdim    if (MainSLoc.isFile()) {
1660218893Sdim      const ContentCache *MainContentCache
1661218893Sdim        = MainSLoc.getFile().getContentCache();
1662218893Sdim      if (!MainContentCache) {
1663218893Sdim        // Can't do anything
1664221345Sdim      } else if (MainContentCache->OrigEntry == SourceFile) {
1665218893Sdim        FirstFID = MainFileID;
1666218893Sdim      } else {
1667218893Sdim        // Fall back: check whether we have the same base name and inode
1668218893Sdim        // as the main file.
1669221345Sdim        const FileEntry *MainFile = MainContentCache->OrigEntry;
1670218893Sdim        SourceFileName = llvm::sys::path::filename(SourceFile->getName());
1671218893Sdim        if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) {
1672263509Sdim          SourceFileUID = getActualFileUID(SourceFile);
1673263509Sdim          if (SourceFileUID) {
1674263509Sdim            if (Optional<llvm::sys::fs::UniqueID> MainFileUID =
1675263509Sdim                    getActualFileUID(MainFile)) {
1676263509Sdim              if (*SourceFileUID == *MainFileUID) {
1677218893Sdim                FirstFID = MainFileID;
1678218893Sdim                SourceFile = MainFile;
1679218893Sdim              }
1680218893Sdim            }
1681218893Sdim          }
1682218893Sdim        }
1683218893Sdim      }
1684218893Sdim    }
1685200583Srdivacky  }
1686200583Srdivacky
1687200583Srdivacky  if (FirstFID.isInvalid()) {
1688200583Srdivacky    // The location we're looking for isn't in the main file; look
1689226890Sdim    // through all of the local source locations.
1690226890Sdim    for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) {
1691221345Sdim      bool Invalid = false;
1692226890Sdim      const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid);
1693221345Sdim      if (Invalid)
1694226890Sdim        return FileID();
1695221345Sdim
1696218893Sdim      if (SLoc.isFile() &&
1697218893Sdim          SLoc.getFile().getContentCache() &&
1698221345Sdim          SLoc.getFile().getContentCache()->OrigEntry == SourceFile) {
1699200583Srdivacky        FirstFID = FileID::get(I);
1700200583Srdivacky        break;
1701200583Srdivacky      }
1702200583Srdivacky    }
1703226890Sdim    // If that still didn't help, try the modules.
1704226890Sdim    if (FirstFID.isInvalid()) {
1705226890Sdim      for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) {
1706226890Sdim        const SLocEntry &SLoc = getLoadedSLocEntry(I);
1707226890Sdim        if (SLoc.isFile() &&
1708226890Sdim            SLoc.getFile().getContentCache() &&
1709226890Sdim            SLoc.getFile().getContentCache()->OrigEntry == SourceFile) {
1710226890Sdim          FirstFID = FileID::get(-int(I) - 2);
1711226890Sdim          break;
1712226890Sdim        }
1713226890Sdim      }
1714226890Sdim    }
1715200583Srdivacky  }
1716218893Sdim
1717218893Sdim  // If we haven't found what we want yet, try again, but this time stat()
1718218893Sdim  // each of the files in case the files have changed since we originally
1719263509Sdim  // parsed the file.
1720218893Sdim  if (FirstFID.isInvalid() &&
1721263509Sdim      (SourceFileName ||
1722218893Sdim       (SourceFileName = llvm::sys::path::filename(SourceFile->getName()))) &&
1723263509Sdim      (SourceFileUID || (SourceFileUID = getActualFileUID(SourceFile)))) {
1724221345Sdim    bool Invalid = false;
1725226890Sdim    for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) {
1726226890Sdim      FileID IFileID;
1727226890Sdim      IFileID.ID = I;
1728226890Sdim      const SLocEntry &SLoc = getSLocEntry(IFileID, &Invalid);
1729221345Sdim      if (Invalid)
1730226890Sdim        return FileID();
1731221345Sdim
1732218893Sdim      if (SLoc.isFile()) {
1733218893Sdim        const ContentCache *FileContentCache
1734218893Sdim          = SLoc.getFile().getContentCache();
1735221345Sdim      const FileEntry *Entry =FileContentCache? FileContentCache->OrigEntry : 0;
1736218893Sdim        if (Entry &&
1737218893Sdim            *SourceFileName == llvm::sys::path::filename(Entry->getName())) {
1738263509Sdim          if (Optional<llvm::sys::fs::UniqueID> EntryUID =
1739263509Sdim                  getActualFileUID(Entry)) {
1740263509Sdim            if (*SourceFileUID == *EntryUID) {
1741218893Sdim              FirstFID = FileID::get(I);
1742218893Sdim              SourceFile = Entry;
1743218893Sdim              break;
1744218893Sdim            }
1745218893Sdim          }
1746218893Sdim        }
1747218893Sdim      }
1748218893Sdim    }
1749218893Sdim  }
1750226890Sdim
1751245431Sdim  (void) SourceFile;
1752226890Sdim  return FirstFID;
1753226890Sdim}
1754226890Sdim
1755226890Sdim/// \brief Get the source location in \arg FID for the given line:col.
1756226890Sdim/// Returns null location if \arg FID is not a file SLocEntry.
1757226890SdimSourceLocation SourceManager::translateLineCol(FileID FID,
1758226890Sdim                                               unsigned Line,
1759226890Sdim                                               unsigned Col) const {
1760263509Sdim  // Lines are used as a one-based index into a zero-based array. This assert
1761263509Sdim  // checks for possible buffer underruns.
1762263509Sdim  assert(Line != 0 && "Passed a zero-based line");
1763263509Sdim
1764226890Sdim  if (FID.isInvalid())
1765200583Srdivacky    return SourceLocation();
1766200583Srdivacky
1767226890Sdim  bool Invalid = false;
1768226890Sdim  const SLocEntry &Entry = getSLocEntry(FID, &Invalid);
1769226890Sdim  if (Invalid)
1770226890Sdim    return SourceLocation();
1771263509Sdim
1772226890Sdim  if (!Entry.isFile())
1773226890Sdim    return SourceLocation();
1774226890Sdim
1775226890Sdim  SourceLocation FileLoc = SourceLocation::getFileLoc(Entry.getOffset());
1776226890Sdim
1777218893Sdim  if (Line == 1 && Col == 1)
1778226890Sdim    return FileLoc;
1779218893Sdim
1780218893Sdim  ContentCache *Content
1781226890Sdim    = const_cast<ContentCache *>(Entry.getFile().getContentCache());
1782218893Sdim  if (!Content)
1783218893Sdim    return SourceLocation();
1784263509Sdim
1785218893Sdim  // If this is the first use of line information for this buffer, compute the
1786226890Sdim  // SourceLineCache for it on demand.
1787218893Sdim  if (Content->SourceLineCache == 0) {
1788218893Sdim    bool MyInvalid = false;
1789218893Sdim    ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid);
1790218893Sdim    if (MyInvalid)
1791218893Sdim      return SourceLocation();
1792218893Sdim  }
1793218893Sdim
1794204643Srdivacky  if (Line > Content->NumLines) {
1795207619Srdivacky    unsigned Size = Content->getBuffer(Diag, *this)->getBufferSize();
1796204643Srdivacky    if (Size > 0)
1797204643Srdivacky      --Size;
1798226890Sdim    return FileLoc.getLocWithOffset(Size);
1799204643Srdivacky  }
1800204643Srdivacky
1801235633Sdim  const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
1802204643Srdivacky  unsigned FilePos = Content->SourceLineCache[Line - 1];
1803235633Sdim  const char *Buf = Buffer->getBufferStart() + FilePos;
1804235633Sdim  unsigned BufLength = Buffer->getBufferSize() - FilePos;
1805226890Sdim  if (BufLength == 0)
1806226890Sdim    return FileLoc.getLocWithOffset(FilePos);
1807226890Sdim
1808204643Srdivacky  unsigned i = 0;
1809204643Srdivacky
1810204643Srdivacky  // Check that the given column is valid.
1811204643Srdivacky  while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r')
1812204643Srdivacky    ++i;
1813263509Sdim  return FileLoc.getLocWithOffset(FilePos + i);
1814194613Sed}
1815194613Sed
1816226890Sdim/// \brief Compute a map of macro argument chunks to their expanded source
1817226890Sdim/// location. Chunks that are not part of a macro argument will map to an
1818226890Sdim/// invalid source location. e.g. if a file contains one macro argument at
1819226890Sdim/// offset 100 with length 10, this is how the map will be formed:
1820226890Sdim///     0   -> SourceLocation()
1821226890Sdim///     100 -> Expanded macro arg location
1822226890Sdim///     110 -> SourceLocation()
1823226890Sdimvoid SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr,
1824226890Sdim                                          FileID FID) const {
1825226890Sdim  assert(!FID.isInvalid());
1826226890Sdim  assert(!CachePtr);
1827226890Sdim
1828226890Sdim  CachePtr = new MacroArgsMap();
1829226890Sdim  MacroArgsMap &MacroArgsCache = *CachePtr;
1830226890Sdim  // Initially no macro argument chunk is present.
1831226890Sdim  MacroArgsCache.insert(std::make_pair(0, SourceLocation()));
1832226890Sdim
1833226890Sdim  int ID = FID.ID;
1834226890Sdim  while (1) {
1835226890Sdim    ++ID;
1836226890Sdim    // Stop if there are no more FileIDs to check.
1837226890Sdim    if (ID > 0) {
1838226890Sdim      if (unsigned(ID) >= local_sloc_entry_size())
1839226890Sdim        return;
1840226890Sdim    } else if (ID == -1) {
1841226890Sdim      return;
1842226890Sdim    }
1843226890Sdim
1844263509Sdim    bool Invalid = false;
1845263509Sdim    const SrcMgr::SLocEntry &Entry = getSLocEntryByID(ID, &Invalid);
1846263509Sdim    if (Invalid)
1847263509Sdim      return;
1848226890Sdim    if (Entry.isFile()) {
1849226890Sdim      SourceLocation IncludeLoc = Entry.getFile().getIncludeLoc();
1850226890Sdim      if (IncludeLoc.isInvalid())
1851226890Sdim        continue;
1852226890Sdim      if (!isInFileID(IncludeLoc, FID))
1853226890Sdim        return; // No more files/macros that may be "contained" in this file.
1854226890Sdim
1855226890Sdim      // Skip the files/macros of the #include'd file, we only care about macros
1856226890Sdim      // that lexed macro arguments from our file.
1857226890Sdim      if (Entry.getFile().NumCreatedFIDs)
1858226890Sdim        ID += Entry.getFile().NumCreatedFIDs - 1/*because of next ++ID*/;
1859226890Sdim      continue;
1860226890Sdim    }
1861226890Sdim
1862235633Sdim    const ExpansionInfo &ExpInfo = Entry.getExpansion();
1863235633Sdim
1864235633Sdim    if (ExpInfo.getExpansionLocStart().isFileID()) {
1865235633Sdim      if (!isInFileID(ExpInfo.getExpansionLocStart(), FID))
1866235633Sdim        return; // No more files/macros that may be "contained" in this file.
1867235633Sdim    }
1868235633Sdim
1869235633Sdim    if (!ExpInfo.isMacroArgExpansion())
1870226890Sdim      continue;
1871235633Sdim
1872245431Sdim    associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1873245431Sdim                                 ExpInfo.getSpellingLoc(),
1874245431Sdim                                 SourceLocation::getMacroLoc(Entry.getOffset()),
1875245431Sdim                                 getFileIDSize(FileID::get(ID)));
1876245431Sdim  }
1877245431Sdim}
1878245431Sdim
1879245431Sdimvoid SourceManager::associateFileChunkWithMacroArgExp(
1880245431Sdim                                         MacroArgsMap &MacroArgsCache,
1881245431Sdim                                         FileID FID,
1882245431Sdim                                         SourceLocation SpellLoc,
1883245431Sdim                                         SourceLocation ExpansionLoc,
1884245431Sdim                                         unsigned ExpansionLength) const {
1885245431Sdim  if (!SpellLoc.isFileID()) {
1886245431Sdim    unsigned SpellBeginOffs = SpellLoc.getOffset();
1887245431Sdim    unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength;
1888245431Sdim
1889245431Sdim    // The spelling range for this macro argument expansion can span multiple
1890245431Sdim    // consecutive FileID entries. Go through each entry contained in the
1891245431Sdim    // spelling range and if one is itself a macro argument expansion, recurse
1892245431Sdim    // and associate the file chunk that it represents.
1893245431Sdim
1894245431Sdim    FileID SpellFID; // Current FileID in the spelling range.
1895245431Sdim    unsigned SpellRelativeOffs;
1896245431Sdim    llvm::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc);
1897245431Sdim    while (1) {
1898245431Sdim      const SLocEntry &Entry = getSLocEntry(SpellFID);
1899245431Sdim      unsigned SpellFIDBeginOffs = Entry.getOffset();
1900245431Sdim      unsigned SpellFIDSize = getFileIDSize(SpellFID);
1901245431Sdim      unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
1902245431Sdim      const ExpansionInfo &Info = Entry.getExpansion();
1903245431Sdim      if (Info.isMacroArgExpansion()) {
1904245431Sdim        unsigned CurrSpellLength;
1905245431Sdim        if (SpellFIDEndOffs < SpellEndOffs)
1906245431Sdim          CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
1907245431Sdim        else
1908245431Sdim          CurrSpellLength = ExpansionLength;
1909245431Sdim        associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1910245431Sdim                      Info.getSpellingLoc().getLocWithOffset(SpellRelativeOffs),
1911245431Sdim                      ExpansionLoc, CurrSpellLength);
1912245431Sdim      }
1913245431Sdim
1914245431Sdim      if (SpellFIDEndOffs >= SpellEndOffs)
1915245431Sdim        return; // we covered all FileID entries in the spelling range.
1916245431Sdim
1917245431Sdim      // Move to the next FileID entry in the spelling range.
1918245431Sdim      unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
1919245431Sdim      ExpansionLoc = ExpansionLoc.getLocWithOffset(advance);
1920245431Sdim      ExpansionLength -= advance;
1921245431Sdim      ++SpellFID.ID;
1922245431Sdim      SpellRelativeOffs = 0;
1923235633Sdim    }
1924235633Sdim
1925245431Sdim  }
1926226890Sdim
1927245431Sdim  assert(SpellLoc.isFileID());
1928226890Sdim
1929245431Sdim  unsigned BeginOffs;
1930245431Sdim  if (!isInFileID(SpellLoc, FID, &BeginOffs))
1931245431Sdim    return;
1932245431Sdim
1933245431Sdim  unsigned EndOffs = BeginOffs + ExpansionLength;
1934245431Sdim
1935245431Sdim  // Add a new chunk for this macro argument. A previous macro argument chunk
1936245431Sdim  // may have been lexed again, so e.g. if the map is
1937245431Sdim  //     0   -> SourceLocation()
1938245431Sdim  //     100 -> Expanded loc #1
1939245431Sdim  //     110 -> SourceLocation()
1940245431Sdim  // and we found a new macro FileID that lexed from offet 105 with length 3,
1941245431Sdim  // the new map will be:
1942245431Sdim  //     0   -> SourceLocation()
1943245431Sdim  //     100 -> Expanded loc #1
1944245431Sdim  //     105 -> Expanded loc #2
1945245431Sdim  //     108 -> Expanded loc #1
1946245431Sdim  //     110 -> SourceLocation()
1947245431Sdim  //
1948245431Sdim  // Since re-lexed macro chunks will always be the same size or less of
1949245431Sdim  // previous chunks, we only need to find where the ending of the new macro
1950245431Sdim  // chunk is mapped to and update the map with new begin/end mappings.
1951245431Sdim
1952245431Sdim  MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
1953245431Sdim  --I;
1954245431Sdim  SourceLocation EndOffsMappedLoc = I->second;
1955245431Sdim  MacroArgsCache[BeginOffs] = ExpansionLoc;
1956245431Sdim  MacroArgsCache[EndOffs] = EndOffsMappedLoc;
1957226890Sdim}
1958226890Sdim
1959226890Sdim/// \brief If \arg Loc points inside a function macro argument, the returned
1960226890Sdim/// location will be the macro location in which the argument was expanded.
1961226890Sdim/// If a macro argument is used multiple times, the expanded location will
1962226890Sdim/// be at the first expansion of the argument.
1963226890Sdim/// e.g.
1964226890Sdim///   MY_MACRO(foo);
1965226890Sdim///             ^
1966226890Sdim/// Passing a file location pointing at 'foo', will yield a macro location
1967226890Sdim/// where 'foo' was expanded into.
1968226890SdimSourceLocation
1969226890SdimSourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const {
1970226890Sdim  if (Loc.isInvalid() || !Loc.isFileID())
1971226890Sdim    return Loc;
1972226890Sdim
1973226890Sdim  FileID FID;
1974226890Sdim  unsigned Offset;
1975226890Sdim  llvm::tie(FID, Offset) = getDecomposedLoc(Loc);
1976226890Sdim  if (FID.isInvalid())
1977226890Sdim    return Loc;
1978226890Sdim
1979226890Sdim  MacroArgsMap *&MacroArgsCache = MacroArgsCacheMap[FID];
1980226890Sdim  if (!MacroArgsCache)
1981226890Sdim    computeMacroArgsCache(MacroArgsCache, FID);
1982226890Sdim
1983226890Sdim  assert(!MacroArgsCache->empty());
1984226890Sdim  MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset);
1985226890Sdim  --I;
1986226890Sdim
1987226890Sdim  unsigned MacroArgBeginOffs = I->first;
1988226890Sdim  SourceLocation MacroArgExpandedLoc = I->second;
1989226890Sdim  if (MacroArgExpandedLoc.isValid())
1990226890Sdim    return MacroArgExpandedLoc.getLocWithOffset(Offset - MacroArgBeginOffs);
1991226890Sdim
1992226890Sdim  return Loc;
1993226890Sdim}
1994226890Sdim
1995252723Sdimstd::pair<FileID, unsigned>
1996252723SdimSourceManager::getDecomposedIncludedLoc(FileID FID) const {
1997263509Sdim  if (FID.isInvalid())
1998263509Sdim    return std::make_pair(FileID(), 0);
1999263509Sdim
2000252723Sdim  // Uses IncludedLocMap to retrieve/cache the decomposed loc.
2001252723Sdim
2002252723Sdim  typedef std::pair<FileID, unsigned> DecompTy;
2003252723Sdim  typedef llvm::DenseMap<FileID, DecompTy> MapTy;
2004252723Sdim  std::pair<MapTy::iterator, bool>
2005252723Sdim    InsertOp = IncludedLocMap.insert(std::make_pair(FID, DecompTy()));
2006252723Sdim  DecompTy &DecompLoc = InsertOp.first->second;
2007252723Sdim  if (!InsertOp.second)
2008252723Sdim    return DecompLoc; // already in map.
2009252723Sdim
2010252723Sdim  SourceLocation UpperLoc;
2011263509Sdim  bool Invalid = false;
2012263509Sdim  const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
2013263509Sdim  if (!Invalid) {
2014263509Sdim    if (Entry.isExpansion())
2015263509Sdim      UpperLoc = Entry.getExpansion().getExpansionLocStart();
2016263509Sdim    else
2017263509Sdim      UpperLoc = Entry.getFile().getIncludeLoc();
2018263509Sdim  }
2019252723Sdim
2020252723Sdim  if (UpperLoc.isValid())
2021252723Sdim    DecompLoc = getDecomposedLoc(UpperLoc);
2022252723Sdim
2023252723Sdim  return DecompLoc;
2024252723Sdim}
2025252723Sdim
2026226890Sdim/// Given a decomposed source location, move it up the include/expansion stack
2027226890Sdim/// to the parent source location.  If this is possible, return the decomposed
2028226890Sdim/// version of the parent in Loc and return false.  If Loc is the top-level
2029226890Sdim/// entry, return true and don't modify it.
2030208600Srdivackystatic bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc,
2031208600Srdivacky                                   const SourceManager &SM) {
2032252723Sdim  std::pair<FileID, unsigned> UpperLoc = SM.getDecomposedIncludedLoc(Loc.first);
2033252723Sdim  if (UpperLoc.first.isInvalid())
2034208600Srdivacky    return true; // We reached the top.
2035252723Sdim
2036252723Sdim  Loc = UpperLoc;
2037208600Srdivacky  return false;
2038208600Srdivacky}
2039208600Srdivacky
2040252723Sdim/// Return the cache entry for comparing the given file IDs
2041252723Sdim/// for isBeforeInTranslationUnit.
2042252723SdimInBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID,
2043252723Sdim                                                            FileID RFID) const {
2044252723Sdim  // This is a magic number for limiting the cache size.  It was experimentally
2045252723Sdim  // derived from a small Objective-C project (where the cache filled
2046252723Sdim  // out to ~250 items).  We can make it larger if necessary.
2047252723Sdim  enum { MagicCacheSize = 300 };
2048252723Sdim  IsBeforeInTUCacheKey Key(LFID, RFID);
2049252723Sdim
2050252723Sdim  // If the cache size isn't too large, do a lookup and if necessary default
2051252723Sdim  // construct an entry.  We can then return it to the caller for direct
2052252723Sdim  // use.  When they update the value, the cache will get automatically
2053252723Sdim  // updated as well.
2054252723Sdim  if (IBTUCache.size() < MagicCacheSize)
2055252723Sdim    return IBTUCache[Key];
2056252723Sdim
2057252723Sdim  // Otherwise, do a lookup that will not construct a new value.
2058252723Sdim  InBeforeInTUCache::iterator I = IBTUCache.find(Key);
2059252723Sdim  if (I != IBTUCache.end())
2060252723Sdim    return I->second;
2061252723Sdim
2062252723Sdim  // Fall back to the overflow value.
2063252723Sdim  return IBTUCacheOverflow;
2064252723Sdim}
2065252723Sdim
2066195099Sed/// \brief Determines the order of 2 source locations in the translation unit.
2067195099Sed///
2068195099Sed/// \returns true if LHS source location comes before RHS, false otherwise.
2069195099Sedbool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
2070195099Sed                                              SourceLocation RHS) const {
2071195099Sed  assert(LHS.isValid() && RHS.isValid() && "Passed invalid source location!");
2072195099Sed  if (LHS == RHS)
2073195099Sed    return false;
2074198092Srdivacky
2075195099Sed  std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS);
2076195099Sed  std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS);
2077198092Srdivacky
2078263509Sdim  // getDecomposedLoc may have failed to return a valid FileID because, e.g. it
2079263509Sdim  // is a serialized one referring to a file that was removed after we loaded
2080263509Sdim  // the PCH.
2081263509Sdim  if (LOffs.first.isInvalid() || ROffs.first.isInvalid())
2082263509Sdim    return LOffs.first.isInvalid() && !ROffs.first.isInvalid();
2083263509Sdim
2084195099Sed  // If the source locations are in the same file, just compare offsets.
2085195099Sed  if (LOffs.first == ROffs.first)
2086195099Sed    return LOffs.second < ROffs.second;
2087194613Sed
2088195099Sed  // If we are comparing a source location with multiple locations in the same
2089195099Sed  // file, we get a big win by caching the result.
2090252723Sdim  InBeforeInTUCacheEntry &IsBeforeInTUCache =
2091252723Sdim    getInBeforeInTUCache(LOffs.first, ROffs.first);
2092252723Sdim
2093252723Sdim  // If we are comparing a source location with multiple locations in the same
2094252723Sdim  // file, we get a big win by caching the result.
2095208600Srdivacky  if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first))
2096208600Srdivacky    return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second);
2097198092Srdivacky
2098208600Srdivacky  // Okay, we missed in the cache, start updating the cache for this query.
2099226890Sdim  IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first,
2100226890Sdim                          /*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID);
2101198092Srdivacky
2102226890Sdim  // We need to find the common ancestor. The only way of doing this is to
2103226890Sdim  // build the complete include chain for one and then walking up the chain
2104226890Sdim  // of the other looking for a match.
2105226890Sdim  // We use a map from FileID to Offset to store the chain. Easier than writing
2106226890Sdim  // a custom set hash info that only depends on the first part of a pair.
2107252723Sdim  typedef llvm::SmallDenseMap<FileID, unsigned, 16> LocSet;
2108226890Sdim  LocSet LChain;
2109208600Srdivacky  do {
2110226890Sdim    LChain.insert(LOffs);
2111226890Sdim    // We catch the case where LOffs is in a file included by ROffs and
2112226890Sdim    // quit early. The other way round unfortunately remains suboptimal.
2113226890Sdim  } while (LOffs.first != ROffs.first && !MoveUpIncludeHierarchy(LOffs, *this));
2114226890Sdim  LocSet::iterator I;
2115226890Sdim  while((I = LChain.find(ROffs.first)) == LChain.end()) {
2116226890Sdim    if (MoveUpIncludeHierarchy(ROffs, *this))
2117226890Sdim      break; // Met at topmost file.
2118226890Sdim  }
2119226890Sdim  if (I != LChain.end())
2120226890Sdim    LOffs = *I;
2121195099Sed
2122208600Srdivacky  // If we exited because we found a nearest common ancestor, compare the
2123208600Srdivacky  // locations within the common file and cache them.
2124208600Srdivacky  if (LOffs.first == ROffs.first) {
2125208600Srdivacky    IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
2126208600Srdivacky    return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second);
2127195099Sed  }
2128195099Sed
2129226890Sdim  // This can happen if a location is in a built-ins buffer.
2130226890Sdim  // But see PR5662.
2131226890Sdim  // Clear the lookup cache, it depends on a common location.
2132226890Sdim  IsBeforeInTUCache.clear();
2133226890Sdim  bool LIsBuiltins = strcmp("<built-in>",
2134226890Sdim                            getBuffer(LOffs.first)->getBufferIdentifier()) == 0;
2135226890Sdim  bool RIsBuiltins = strcmp("<built-in>",
2136226890Sdim                            getBuffer(ROffs.first)->getBufferIdentifier()) == 0;
2137226890Sdim  // built-in is before non-built-in
2138226890Sdim  if (LIsBuiltins != RIsBuiltins)
2139226890Sdim    return LIsBuiltins;
2140226890Sdim  assert(LIsBuiltins && RIsBuiltins &&
2141226890Sdim         "Non-built-in locations must be rooted in the main file");
2142226890Sdim  // Both are in built-in buffers, but from different files. We just claim that
2143226890Sdim  // lower IDs come first.
2144208600Srdivacky  return LOffs.first < ROffs.first;
2145195099Sed}
2146195099Sed
2147193326Sedvoid SourceManager::PrintStats() const {
2148198092Srdivacky  llvm::errs() << "\n*** Source Manager Stats:\n";
2149198092Srdivacky  llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
2150198092Srdivacky               << " mem buffers mapped.\n";
2151226890Sdim  llvm::errs() << LocalSLocEntryTable.size() << " local SLocEntry's allocated ("
2152226890Sdim               << llvm::capacity_in_bytes(LocalSLocEntryTable)
2153224145Sdim               << " bytes of capacity), "
2154226890Sdim               << NextLocalOffset << "B of Sloc address space used.\n";
2155226890Sdim  llvm::errs() << LoadedSLocEntryTable.size()
2156226890Sdim               << " loaded SLocEntries allocated, "
2157226890Sdim               << MaxLoadedOffset - CurrentLoadedOffset
2158226890Sdim               << "B of Sloc address space used.\n";
2159226890Sdim
2160193326Sed  unsigned NumLineNumsComputed = 0;
2161193326Sed  unsigned NumFileBytesMapped = 0;
2162193326Sed  for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){
2163193326Sed    NumLineNumsComputed += I->second->SourceLineCache != 0;
2164193326Sed    NumFileBytesMapped  += I->second->getSizeBytesMapped();
2165193326Sed  }
2166226890Sdim  unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
2167198092Srdivacky
2168198092Srdivacky  llvm::errs() << NumFileBytesMapped << " bytes of files mapped, "
2169226890Sdim               << NumLineNumsComputed << " files with line #'s computed, "
2170226890Sdim               << NumMacroArgsComputed << " files with macro args computed.\n";
2171198092Srdivacky  llvm::errs() << "FileID scans: " << NumLinearScans << " linear, "
2172198092Srdivacky               << NumBinaryProbes << " binary.\n";
2173193326Sed}
2174193326Sed
2175193326SedExternalSLocEntrySource::~ExternalSLocEntrySource() { }
2176221345Sdim
2177221345Sdim/// Return the amount of memory used by memory buffers, breaking down
2178221345Sdim/// by heap-backed versus mmap'ed memory.
2179221345SdimSourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const {
2180221345Sdim  size_t malloc_bytes = 0;
2181221345Sdim  size_t mmap_bytes = 0;
2182221345Sdim
2183221345Sdim  for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i)
2184221345Sdim    if (size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped())
2185221345Sdim      switch (MemBufferInfos[i]->getMemoryBufferKind()) {
2186221345Sdim        case llvm::MemoryBuffer::MemoryBuffer_MMap:
2187221345Sdim          mmap_bytes += sized_mapped;
2188221345Sdim          break;
2189221345Sdim        case llvm::MemoryBuffer::MemoryBuffer_Malloc:
2190221345Sdim          malloc_bytes += sized_mapped;
2191221345Sdim          break;
2192221345Sdim      }
2193221345Sdim
2194221345Sdim  return MemoryBufferSizes(malloc_bytes, mmap_bytes);
2195221345Sdim}
2196221345Sdim
2197226890Sdimsize_t SourceManager::getDataStructureSizes() const {
2198245431Sdim  size_t size = llvm::capacity_in_bytes(MemBufferInfos)
2199226890Sdim    + llvm::capacity_in_bytes(LocalSLocEntryTable)
2200226890Sdim    + llvm::capacity_in_bytes(LoadedSLocEntryTable)
2201226890Sdim    + llvm::capacity_in_bytes(SLocEntryLoaded)
2202245431Sdim    + llvm::capacity_in_bytes(FileInfos);
2203245431Sdim
2204245431Sdim  if (OverriddenFilesInfo)
2205245431Sdim    size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
2206245431Sdim
2207245431Sdim  return size;
2208226890Sdim}
2209