| //===--- SourceManager.cpp - Track and cache source files -----------------===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | //  This file implements the SourceManager interface. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "clang/Basic/SourceManager.h" | 
 | #include "clang/Basic/SourceManagerInternals.h" | 
 | #include "clang/Basic/FileManager.h" | 
 | #include "llvm/Support/Compiler.h" | 
 | #include "llvm/Support/MemoryBuffer.h" | 
 | #include "llvm/Support/raw_ostream.h" | 
 | #include "llvm/System/Path.h" | 
 | #include <algorithm> | 
 | using namespace clang; | 
 | using namespace SrcMgr; | 
 | using llvm::MemoryBuffer; | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // SourceManager Helper Classes | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | ContentCache::~ContentCache() { | 
 |   delete Buffer; | 
 | } | 
 |  | 
 | /// getSizeBytesMapped - Returns the number of bytes actually mapped for | 
 | ///  this ContentCache.  This can be 0 if the MemBuffer was not actually | 
 | ///  instantiated. | 
 | unsigned ContentCache::getSizeBytesMapped() const { | 
 |   return Buffer ? Buffer->getBufferSize() : 0; | 
 | } | 
 |  | 
 | /// getSize - Returns the size of the content encapsulated by this ContentCache. | 
 | ///  This can be the size of the source file or the size of an arbitrary | 
 | ///  scratch buffer.  If the ContentCache encapsulates a source file, that | 
 | ///  file is not lazily brought in from disk to satisfy this query unless it | 
 | ///  needs to be truncated due to a truncateAt() call. | 
 | unsigned ContentCache::getSize() const { | 
 |   return Buffer ? Buffer->getBufferSize() : Entry->getSize(); | 
 | } | 
 |  | 
 | const llvm::MemoryBuffer *ContentCache::getBuffer() const { | 
 |   // Lazily create the Buffer for ContentCaches that wrap files. | 
 |   if (!Buffer && Entry) { | 
 |     // FIXME: Should we support a way to not have to do this check over | 
 |     //   and over if we cannot open the file? | 
 |     Buffer = MemoryBuffer::getFile(Entry->getName(), 0, Entry->getSize()); | 
 |     if (isTruncated()) | 
 |       const_cast<ContentCache *>(this)->truncateAt(TruncateAtLine,  | 
 |                                                    TruncateAtColumn); | 
 |   } | 
 |   return Buffer; | 
 | } | 
 |  | 
 | void ContentCache::truncateAt(unsigned Line, unsigned Column) { | 
 |   TruncateAtLine = Line; | 
 |   TruncateAtColumn = Column; | 
 |    | 
 |   if (!isTruncated() || !Buffer) | 
 |     return; | 
 |    | 
 |   // Find the byte position of the truncation point. | 
 |   const char *Position = Buffer->getBufferStart(); | 
 |   for (unsigned Line = 1; Line < TruncateAtLine; ++Line) { | 
 |     for (; *Position; ++Position) { | 
 |       if (*Position != '\r' && *Position != '\n') | 
 |         continue; | 
 |        | 
 |       // Eat \r\n or \n\r as a single line. | 
 |       if ((Position[1] == '\r' || Position[1] == '\n') && | 
 |           Position[0] != Position[1]) | 
 |         ++Position; | 
 |       ++Position; | 
 |       break; | 
 |     } | 
 |   } | 
 |    | 
 |   for (unsigned Column = 1; Column < TruncateAtColumn; ++Column, ++Position) { | 
 |     if (!*Position) | 
 |       break; | 
 |      | 
 |     if (*Position == '\t') | 
 |       Column += 7; | 
 |   } | 
 |    | 
 |   // Truncate the buffer. | 
 |   if (Position != Buffer->getBufferEnd()) { | 
 |     MemoryBuffer *TruncatedBuffer  | 
 |       = MemoryBuffer::getMemBufferCopy(Buffer->getBufferStart(), Position,  | 
 |                                        Buffer->getBufferIdentifier()); | 
 |     delete Buffer; | 
 |     Buffer = TruncatedBuffer; | 
 |   } | 
 | } | 
 |  | 
 | unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) { | 
 |   // Look up the filename in the string table, returning the pre-existing value | 
 |   // if it exists. | 
 |   llvm::StringMapEntry<unsigned> &Entry = | 
 |     FilenameIDs.GetOrCreateValue(Ptr, Ptr+Len, ~0U); | 
 |   if (Entry.getValue() != ~0U) | 
 |     return Entry.getValue(); | 
 |  | 
 |   // Otherwise, assign this the next available ID. | 
 |   Entry.setValue(FilenamesByID.size()); | 
 |   FilenamesByID.push_back(&Entry); | 
 |   return FilenamesByID.size()-1; | 
 | } | 
 |  | 
 | /// AddLineNote - Add a line note to the line table that indicates that there | 
 | /// is a #line at the specified FID/Offset location which changes the presumed | 
 | /// location to LineNo/FilenameID. | 
 | void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset, | 
 |                                 unsigned LineNo, int FilenameID) { | 
 |   std::vector<LineEntry> &Entries = LineEntries[FID]; | 
 |  | 
 |   assert((Entries.empty() || Entries.back().FileOffset < Offset) && | 
 |          "Adding line entries out of order!"); | 
 |  | 
 |   SrcMgr::CharacteristicKind Kind = SrcMgr::C_User; | 
 |   unsigned IncludeOffset = 0; | 
 |  | 
 |   if (!Entries.empty()) { | 
 |     // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember | 
 |     // that we are still in "foo.h". | 
 |     if (FilenameID == -1) | 
 |       FilenameID = Entries.back().FilenameID; | 
 |  | 
 |     // If we are after a line marker that switched us to system header mode, or | 
 |     // that set #include information, preserve it. | 
 |     Kind = Entries.back().FileKind; | 
 |     IncludeOffset = Entries.back().IncludeOffset; | 
 |   } | 
 |  | 
 |   Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind, | 
 |                                    IncludeOffset)); | 
 | } | 
 |  | 
 | /// AddLineNote This is the same as the previous version of AddLineNote, but is | 
 | /// used for GNU line markers.  If EntryExit is 0, then this doesn't change the | 
 | /// presumed #include stack.  If it is 1, this is a file entry, if it is 2 then | 
 | /// this is a file exit.  FileKind specifies whether this is a system header or | 
 | /// extern C system header. | 
 | void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset, | 
 |                                 unsigned LineNo, int FilenameID, | 
 |                                 unsigned EntryExit, | 
 |                                 SrcMgr::CharacteristicKind FileKind) { | 
 |   assert(FilenameID != -1 && "Unspecified filename should use other accessor"); | 
 |  | 
 |   std::vector<LineEntry> &Entries = LineEntries[FID]; | 
 |  | 
 |   assert((Entries.empty() || Entries.back().FileOffset < Offset) && | 
 |          "Adding line entries out of order!"); | 
 |  | 
 |   unsigned IncludeOffset = 0; | 
 |   if (EntryExit == 0) {  // No #include stack change. | 
 |     IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset; | 
 |   } else if (EntryExit == 1) { | 
 |     IncludeOffset = Offset-1; | 
 |   } else if (EntryExit == 2) { | 
 |     assert(!Entries.empty() && Entries.back().IncludeOffset && | 
 |        "PPDirectives should have caught case when popping empty include stack"); | 
 |  | 
 |     // Get the include loc of the last entries' include loc as our include loc. | 
 |     IncludeOffset = 0; | 
 |     if (const LineEntry *PrevEntry = | 
 |           FindNearestLineEntry(FID, Entries.back().IncludeOffset)) | 
 |       IncludeOffset = PrevEntry->IncludeOffset; | 
 |   } | 
 |  | 
 |   Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind, | 
 |                                    IncludeOffset)); | 
 | } | 
 |  | 
 |  | 
 | /// FindNearestLineEntry - Find the line entry nearest to FID that is before | 
 | /// it.  If there is no line entry before Offset in FID, return null. | 
 | const LineEntry *LineTableInfo::FindNearestLineEntry(unsigned FID, | 
 |                                                      unsigned Offset) { | 
 |   const std::vector<LineEntry> &Entries = LineEntries[FID]; | 
 |   assert(!Entries.empty() && "No #line entries for this FID after all!"); | 
 |  | 
 |   // It is very common for the query to be after the last #line, check this | 
 |   // first. | 
 |   if (Entries.back().FileOffset <= Offset) | 
 |     return &Entries.back(); | 
 |  | 
 |   // Do a binary search to find the maximal element that is still before Offset. | 
 |   std::vector<LineEntry>::const_iterator I = | 
 |     std::upper_bound(Entries.begin(), Entries.end(), Offset); | 
 |   if (I == Entries.begin()) return 0; | 
 |   return &*--I; | 
 | } | 
 |  | 
 | /// \brief Add a new line entry that has already been encoded into | 
 | /// the internal representation of the line table. | 
 | void LineTableInfo::AddEntry(unsigned FID, | 
 |                              const std::vector<LineEntry> &Entries) { | 
 |   LineEntries[FID] = Entries; | 
 | } | 
 |  | 
 | /// getLineTableFilenameID - Return the uniqued ID for the specified filename. | 
 | /// | 
 | unsigned SourceManager::getLineTableFilenameID(const char *Ptr, unsigned Len) { | 
 |   if (LineTable == 0) | 
 |     LineTable = new LineTableInfo(); | 
 |   return LineTable->getLineTableFilenameID(Ptr, Len); | 
 | } | 
 |  | 
 |  | 
 | /// AddLineNote - Add a line note to the line table for the FileID and offset | 
 | /// specified by Loc.  If FilenameID is -1, it is considered to be | 
 | /// unspecified. | 
 | void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, | 
 |                                 int FilenameID) { | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc); | 
 |  | 
 |   const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile(); | 
 |  | 
 |   // Remember that this file has #line directives now if it doesn't already. | 
 |   const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives(); | 
 |  | 
 |   if (LineTable == 0) | 
 |     LineTable = new LineTableInfo(); | 
 |   LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID); | 
 | } | 
 |  | 
 | /// AddLineNote - Add a GNU line marker to the line table. | 
 | void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, | 
 |                                 int FilenameID, bool IsFileEntry, | 
 |                                 bool IsFileExit, bool IsSystemHeader, | 
 |                                 bool IsExternCHeader) { | 
 |   // If there is no filename and no flags, this is treated just like a #line, | 
 |   // which does not change the flags of the previous line marker. | 
 |   if (FilenameID == -1) { | 
 |     assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader && | 
 |            "Can't set flags without setting the filename!"); | 
 |     return AddLineNote(Loc, LineNo, FilenameID); | 
 |   } | 
 |  | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc); | 
 |   const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile(); | 
 |  | 
 |   // Remember that this file has #line directives now if it doesn't already. | 
 |   const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives(); | 
 |  | 
 |   if (LineTable == 0) | 
 |     LineTable = new LineTableInfo(); | 
 |  | 
 |   SrcMgr::CharacteristicKind FileKind; | 
 |   if (IsExternCHeader) | 
 |     FileKind = SrcMgr::C_ExternCSystem; | 
 |   else if (IsSystemHeader) | 
 |     FileKind = SrcMgr::C_System; | 
 |   else | 
 |     FileKind = SrcMgr::C_User; | 
 |  | 
 |   unsigned EntryExit = 0; | 
 |   if (IsFileEntry) | 
 |     EntryExit = 1; | 
 |   else if (IsFileExit) | 
 |     EntryExit = 2; | 
 |  | 
 |   LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID, | 
 |                          EntryExit, FileKind); | 
 | } | 
 |  | 
 | LineTableInfo &SourceManager::getLineTable() { | 
 |   if (LineTable == 0) | 
 |     LineTable = new LineTableInfo(); | 
 |   return *LineTable; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Private 'Create' methods. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | SourceManager::~SourceManager() { | 
 |   delete LineTable; | 
 |  | 
 |   // Delete FileEntry objects corresponding to content caches.  Since the actual | 
 |   // content cache objects are bump pointer allocated, we just have to run the | 
 |   // dtors, but we call the deallocate method for completeness. | 
 |   for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) { | 
 |     MemBufferInfos[i]->~ContentCache(); | 
 |     ContentCacheAlloc.Deallocate(MemBufferInfos[i]); | 
 |   } | 
 |   for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator | 
 |        I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) { | 
 |     I->second->~ContentCache(); | 
 |     ContentCacheAlloc.Deallocate(I->second); | 
 |   } | 
 | } | 
 |  | 
 | void SourceManager::clearIDTables() { | 
 |   MainFileID = FileID(); | 
 |   SLocEntryTable.clear(); | 
 |   LastLineNoFileIDQuery = FileID(); | 
 |   LastLineNoContentCache = 0; | 
 |   LastFileIDLookup = FileID(); | 
 |  | 
 |   if (LineTable) | 
 |     LineTable->clear(); | 
 |  | 
 |   // Use up FileID #0 as an invalid instantiation. | 
 |   NextOffset = 0; | 
 |   createInstantiationLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1); | 
 | } | 
 |  | 
 | /// getOrCreateContentCache - Create or return a cached ContentCache for the | 
 | /// specified file. | 
 | const ContentCache * | 
 | SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) { | 
 |   assert(FileEnt && "Didn't specify a file entry to use?"); | 
 |  | 
 |   // Do we already have information about this file? | 
 |   ContentCache *&Entry = FileInfos[FileEnt]; | 
 |   if (Entry) return Entry; | 
 |  | 
 |   // Nope, create a new Cache entry.  Make sure it is at least 8-byte aligned | 
 |   // so that FileInfo can use the low 3 bits of the pointer for its own | 
 |   // nefarious purposes. | 
 |   unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment; | 
 |   EntryAlign = std::max(8U, EntryAlign); | 
 |   Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign); | 
 |   new (Entry) ContentCache(FileEnt); | 
 |    | 
 |   if (FileEnt == TruncateFile) { | 
 |     // If we had queued up a file truncation request, perform the truncation | 
 |     // now. | 
 |     Entry->truncateAt(TruncateAtLine, TruncateAtColumn); | 
 |     TruncateFile = 0; | 
 |     TruncateAtLine = 0; | 
 |     TruncateAtColumn = 0; | 
 |   } | 
 |    | 
 |   return Entry; | 
 | } | 
 |  | 
 |  | 
 | /// createMemBufferContentCache - Create a new ContentCache for the specified | 
 | ///  memory buffer.  This does no caching. | 
 | const ContentCache* | 
 | SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { | 
 |   // Add a new ContentCache to the MemBufferInfos list and return it.  Make sure | 
 |   // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of | 
 |   // the pointer for its own nefarious purposes. | 
 |   unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment; | 
 |   EntryAlign = std::max(8U, EntryAlign); | 
 |   ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign); | 
 |   new (Entry) ContentCache(); | 
 |   MemBufferInfos.push_back(Entry); | 
 |   Entry->setBuffer(Buffer); | 
 |   return Entry; | 
 | } | 
 |  | 
 | void SourceManager::PreallocateSLocEntries(ExternalSLocEntrySource *Source, | 
 |                                            unsigned NumSLocEntries, | 
 |                                            unsigned NextOffset) { | 
 |   ExternalSLocEntries = Source; | 
 |   this->NextOffset = NextOffset; | 
 |   SLocEntryLoaded.resize(NumSLocEntries + 1); | 
 |   SLocEntryLoaded[0] = true; | 
 |   SLocEntryTable.resize(SLocEntryTable.size() + NumSLocEntries); | 
 | } | 
 |  | 
 | void SourceManager::ClearPreallocatedSLocEntries() { | 
 |   unsigned I = 0; | 
 |   for (unsigned N = SLocEntryLoaded.size(); I != N; ++I) | 
 |     if (!SLocEntryLoaded[I]) | 
 |       break; | 
 |  | 
 |   // We've already loaded all preallocated source location entries. | 
 |   if (I == SLocEntryLoaded.size()) | 
 |     return; | 
 |  | 
 |   // Remove everything from location I onward. | 
 |   SLocEntryTable.resize(I); | 
 |   SLocEntryLoaded.clear(); | 
 |   ExternalSLocEntries = 0; | 
 | } | 
 |  | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Methods to create new FileID's and instantiations. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | /// createFileID - Create a new fileID for the specified ContentCache and | 
 | /// include position.  This works regardless of whether the ContentCache | 
 | /// corresponds to a file or some other input source. | 
 | FileID SourceManager::createFileID(const ContentCache *File, | 
 |                                    SourceLocation IncludePos, | 
 |                                    SrcMgr::CharacteristicKind FileCharacter, | 
 |                                    unsigned PreallocatedID, | 
 |                                    unsigned Offset) { | 
 |   if (PreallocatedID) { | 
 |     // If we're filling in a preallocated ID, just load in the file | 
 |     // entry and return. | 
 |     assert(PreallocatedID < SLocEntryLoaded.size() && | 
 |            "Preallocate ID out-of-range"); | 
 |     assert(!SLocEntryLoaded[PreallocatedID] && | 
 |            "Source location entry already loaded"); | 
 |     assert(Offset && "Preallocate source location cannot have zero offset"); | 
 |     SLocEntryTable[PreallocatedID] | 
 |       = SLocEntry::get(Offset, FileInfo::get(IncludePos, File, FileCharacter)); | 
 |     SLocEntryLoaded[PreallocatedID] = true; | 
 |     FileID FID = FileID::get(PreallocatedID); | 
 |     if (File->FirstFID.isInvalid()) | 
 |       File->FirstFID = FID; | 
 |     return LastFileIDLookup = FID; | 
 |   } | 
 |  | 
 |   SLocEntryTable.push_back(SLocEntry::get(NextOffset, | 
 |                                           FileInfo::get(IncludePos, File, | 
 |                                                         FileCharacter))); | 
 |   unsigned FileSize = File->getSize(); | 
 |   assert(NextOffset+FileSize+1 > NextOffset && "Ran out of source locations!"); | 
 |   NextOffset += FileSize+1; | 
 |  | 
 |   // Set LastFileIDLookup to the newly created file.  The next getFileID call is | 
 |   // almost guaranteed to be from that file. | 
 |   FileID FID = FileID::get(SLocEntryTable.size()-1); | 
 |   if (File->FirstFID.isInvalid()) | 
 |     File->FirstFID = FID; | 
 |   return LastFileIDLookup = FID; | 
 | } | 
 |  | 
 | /// createInstantiationLoc - Return a new SourceLocation that encodes the fact | 
 | /// that a token from SpellingLoc should actually be referenced from | 
 | /// InstantiationLoc. | 
 | SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc, | 
 |                                                      SourceLocation ILocStart, | 
 |                                                      SourceLocation ILocEnd, | 
 |                                                      unsigned TokLength, | 
 |                                                      unsigned PreallocatedID, | 
 |                                                      unsigned Offset) { | 
 |   InstantiationInfo II = InstantiationInfo::get(ILocStart,ILocEnd, SpellingLoc); | 
 |   if (PreallocatedID) { | 
 |     // If we're filling in a preallocated ID, just load in the | 
 |     // instantiation entry and return. | 
 |     assert(PreallocatedID < SLocEntryLoaded.size() && | 
 |            "Preallocate ID out-of-range"); | 
 |     assert(!SLocEntryLoaded[PreallocatedID] && | 
 |            "Source location entry already loaded"); | 
 |     assert(Offset && "Preallocate source location cannot have zero offset"); | 
 |     SLocEntryTable[PreallocatedID] = SLocEntry::get(Offset, II); | 
 |     SLocEntryLoaded[PreallocatedID] = true; | 
 |     return SourceLocation::getMacroLoc(Offset); | 
 |   } | 
 |   SLocEntryTable.push_back(SLocEntry::get(NextOffset, II)); | 
 |   assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!"); | 
 |   NextOffset += TokLength+1; | 
 |   return SourceLocation::getMacroLoc(NextOffset-(TokLength+1)); | 
 | } | 
 |  | 
 | /// getBufferData - Return a pointer to the start and end of the source buffer | 
 | /// data for the specified FileID. | 
 | std::pair<const char*, const char*> | 
 | SourceManager::getBufferData(FileID FID) const { | 
 |   const llvm::MemoryBuffer *Buf = getBuffer(FID); | 
 |   return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd()); | 
 | } | 
 |  | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // SourceLocation manipulation methods. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | /// getFileIDSlow - Return the FileID for a SourceLocation.  This is a very hot | 
 | /// method that is used for all SourceManager queries that start with a | 
 | /// SourceLocation object.  It is responsible for finding the entry in | 
 | /// SLocEntryTable which contains the specified location. | 
 | /// | 
 | FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const { | 
 |   assert(SLocOffset && "Invalid FileID"); | 
 |  | 
 |   // After the first and second level caches, I see two common sorts of | 
 |   // behavior: 1) a lot of searched FileID's are "near" the cached file location | 
 |   // or are "near" the cached instantiation location.  2) others are just | 
 |   // completely random and may be a very long way away. | 
 |   // | 
 |   // To handle this, we do a linear search for up to 8 steps to catch #1 quickly | 
 |   // then we fall back to a less cache efficient, but more scalable, binary | 
 |   // search to find the location. | 
 |  | 
 |   // See if this is near the file point - worst case we start scanning from the | 
 |   // most newly created FileID. | 
 |   std::vector<SrcMgr::SLocEntry>::const_iterator I; | 
 |  | 
 |   if (SLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) { | 
 |     // Neither loc prunes our search. | 
 |     I = SLocEntryTable.end(); | 
 |   } else { | 
 |     // Perhaps it is near the file point. | 
 |     I = SLocEntryTable.begin()+LastFileIDLookup.ID; | 
 |   } | 
 |  | 
 |   // Find the FileID that contains this.  "I" is an iterator that points to a | 
 |   // FileID whose offset is known to be larger than SLocOffset. | 
 |   unsigned NumProbes = 0; | 
 |   while (1) { | 
 |     --I; | 
 |     if (ExternalSLocEntries) | 
 |       getSLocEntry(FileID::get(I - SLocEntryTable.begin())); | 
 |     if (I->getOffset() <= SLocOffset) { | 
 | #if 0 | 
 |       printf("lin %d -> %d [%s] %d %d\n", SLocOffset, | 
 |              I-SLocEntryTable.begin(), | 
 |              I->isInstantiation() ? "inst" : "file", | 
 |              LastFileIDLookup.ID,  int(SLocEntryTable.end()-I)); | 
 | #endif | 
 |       FileID Res = FileID::get(I-SLocEntryTable.begin()); | 
 |  | 
 |       // If this isn't an instantiation, remember it.  We have good locality | 
 |       // across FileID lookups. | 
 |       if (!I->isInstantiation()) | 
 |         LastFileIDLookup = Res; | 
 |       NumLinearScans += NumProbes+1; | 
 |       return Res; | 
 |     } | 
 |     if (++NumProbes == 8) | 
 |       break; | 
 |   } | 
 |  | 
 |   // Convert "I" back into an index.  We know that it is an entry whose index is | 
 |   // larger than the offset we are looking for. | 
 |   unsigned GreaterIndex = I-SLocEntryTable.begin(); | 
 |   // LessIndex - This is the lower bound of the range that we're searching. | 
 |   // We know that the offset corresponding to the FileID is is less than | 
 |   // SLocOffset. | 
 |   unsigned LessIndex = 0; | 
 |   NumProbes = 0; | 
 |   while (1) { | 
 |     unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; | 
 |     unsigned MidOffset = getSLocEntry(FileID::get(MiddleIndex)).getOffset(); | 
 |  | 
 |     ++NumProbes; | 
 |  | 
 |     // If the offset of the midpoint is too large, chop the high side of the | 
 |     // range to the midpoint. | 
 |     if (MidOffset > SLocOffset) { | 
 |       GreaterIndex = MiddleIndex; | 
 |       continue; | 
 |     } | 
 |  | 
 |     // If the middle index contains the value, succeed and return. | 
 |     if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) { | 
 | #if 0 | 
 |       printf("bin %d -> %d [%s] %d %d\n", SLocOffset, | 
 |              I-SLocEntryTable.begin(), | 
 |              I->isInstantiation() ? "inst" : "file", | 
 |              LastFileIDLookup.ID, int(SLocEntryTable.end()-I)); | 
 | #endif | 
 |       FileID Res = FileID::get(MiddleIndex); | 
 |  | 
 |       // If this isn't an instantiation, remember it.  We have good locality | 
 |       // across FileID lookups. | 
 |       if (!I->isInstantiation()) | 
 |         LastFileIDLookup = Res; | 
 |       NumBinaryProbes += NumProbes; | 
 |       return Res; | 
 |     } | 
 |  | 
 |     // Otherwise, move the low-side up to the middle index. | 
 |     LessIndex = MiddleIndex; | 
 |   } | 
 | } | 
 |  | 
 | SourceLocation SourceManager:: | 
 | getInstantiationLocSlowCase(SourceLocation Loc) const { | 
 |   do { | 
 |     std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc); | 
 |     Loc = getSLocEntry(LocInfo.first).getInstantiation() | 
 |                    .getInstantiationLocStart(); | 
 |     Loc = Loc.getFileLocWithOffset(LocInfo.second); | 
 |   } while (!Loc.isFileID()); | 
 |  | 
 |   return Loc; | 
 | } | 
 |  | 
 | SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const { | 
 |   do { | 
 |     std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc); | 
 |     Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc(); | 
 |     Loc = Loc.getFileLocWithOffset(LocInfo.second); | 
 |   } while (!Loc.isFileID()); | 
 |   return Loc; | 
 | } | 
 |  | 
 |  | 
 | std::pair<FileID, unsigned> | 
 | SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, | 
 |                                                      unsigned Offset) const { | 
 |   // If this is an instantiation record, walk through all the instantiation | 
 |   // points. | 
 |   FileID FID; | 
 |   SourceLocation Loc; | 
 |   do { | 
 |     Loc = E->getInstantiation().getInstantiationLocStart(); | 
 |  | 
 |     FID = getFileID(Loc); | 
 |     E = &getSLocEntry(FID); | 
 |     Offset += Loc.getOffset()-E->getOffset(); | 
 |   } while (!Loc.isFileID()); | 
 |  | 
 |   return std::make_pair(FID, Offset); | 
 | } | 
 |  | 
 | std::pair<FileID, unsigned> | 
 | SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, | 
 |                                                 unsigned Offset) const { | 
 |   // If this is an instantiation record, walk through all the instantiation | 
 |   // points. | 
 |   FileID FID; | 
 |   SourceLocation Loc; | 
 |   do { | 
 |     Loc = E->getInstantiation().getSpellingLoc(); | 
 |  | 
 |     FID = getFileID(Loc); | 
 |     E = &getSLocEntry(FID); | 
 |     Offset += Loc.getOffset()-E->getOffset(); | 
 |   } while (!Loc.isFileID()); | 
 |  | 
 |   return std::make_pair(FID, Offset); | 
 | } | 
 |  | 
 | /// getImmediateSpellingLoc - Given a SourceLocation object, return the | 
 | /// spelling location referenced by the ID.  This is the first level down | 
 | /// towards the place where the characters that make up the lexed token can be | 
 | /// found.  This should not generally be used by clients. | 
 | SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{ | 
 |   if (Loc.isFileID()) return Loc; | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc); | 
 |   Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc(); | 
 |   return Loc.getFileLocWithOffset(LocInfo.second); | 
 | } | 
 |  | 
 |  | 
 | /// getImmediateInstantiationRange - Loc is required to be an instantiation | 
 | /// location.  Return the start/end of the instantiation information. | 
 | std::pair<SourceLocation,SourceLocation> | 
 | SourceManager::getImmediateInstantiationRange(SourceLocation Loc) const { | 
 |   assert(Loc.isMacroID() && "Not an instantiation loc!"); | 
 |   const InstantiationInfo &II = getSLocEntry(getFileID(Loc)).getInstantiation(); | 
 |   return II.getInstantiationLocRange(); | 
 | } | 
 |  | 
 | /// getInstantiationRange - Given a SourceLocation object, return the | 
 | /// range of tokens covered by the instantiation in the ultimate file. | 
 | std::pair<SourceLocation,SourceLocation> | 
 | SourceManager::getInstantiationRange(SourceLocation Loc) const { | 
 |   if (Loc.isFileID()) return std::make_pair(Loc, Loc); | 
 |  | 
 |   std::pair<SourceLocation,SourceLocation> Res = | 
 |     getImmediateInstantiationRange(Loc); | 
 |  | 
 |   // Fully resolve the start and end locations to their ultimate instantiation | 
 |   // points. | 
 |   while (!Res.first.isFileID()) | 
 |     Res.first = getImmediateInstantiationRange(Res.first).first; | 
 |   while (!Res.second.isFileID()) | 
 |     Res.second = getImmediateInstantiationRange(Res.second).second; | 
 |   return Res; | 
 | } | 
 |  | 
 |  | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Queries about the code at a SourceLocation. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | /// getCharacterData - Return a pointer to the start of the specified location | 
 | /// in the appropriate MemoryBuffer. | 
 | const char *SourceManager::getCharacterData(SourceLocation SL) const { | 
 |   // Note that this is a hot function in the getSpelling() path, which is | 
 |   // heavily used by -E mode. | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL); | 
 |  | 
 |   // Note that calling 'getBuffer()' may lazily page in a source file. | 
 |   return getSLocEntry(LocInfo.first).getFile().getContentCache() | 
 |               ->getBuffer()->getBufferStart() + LocInfo.second; | 
 | } | 
 |  | 
 |  | 
 | /// getColumnNumber - Return the column # for the specified file position. | 
 | /// this is significantly cheaper to compute than the line number. | 
 | unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos) const { | 
 |   const char *Buf = getBuffer(FID)->getBufferStart(); | 
 |  | 
 |   unsigned LineStart = FilePos; | 
 |   while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r') | 
 |     --LineStart; | 
 |   return FilePos-LineStart+1; | 
 | } | 
 |  | 
 | unsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc) const { | 
 |   if (Loc.isInvalid()) return 0; | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc); | 
 |   return getColumnNumber(LocInfo.first, LocInfo.second); | 
 | } | 
 |  | 
 | unsigned SourceManager::getInstantiationColumnNumber(SourceLocation Loc) const { | 
 |   if (Loc.isInvalid()) return 0; | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc); | 
 |   return getColumnNumber(LocInfo.first, LocInfo.second); | 
 | } | 
 |  | 
 |  | 
 |  | 
 | static DISABLE_INLINE void ComputeLineNumbers(ContentCache* FI, | 
 |                                               llvm::BumpPtrAllocator &Alloc); | 
 | static void ComputeLineNumbers(ContentCache* FI, llvm::BumpPtrAllocator &Alloc){ | 
 |   // Note that calling 'getBuffer()' may lazily page in the file. | 
 |   const MemoryBuffer *Buffer = FI->getBuffer(); | 
 |  | 
 |   // Find the file offsets of all of the *physical* source lines.  This does | 
 |   // not look at trigraphs, escaped newlines, or anything else tricky. | 
 |   std::vector<unsigned> LineOffsets; | 
 |  | 
 |   // Line #1 starts at char 0. | 
 |   LineOffsets.push_back(0); | 
 |  | 
 |   const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart(); | 
 |   const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd(); | 
 |   unsigned Offs = 0; | 
 |   while (1) { | 
 |     // Skip over the contents of the line. | 
 |     // TODO: Vectorize this?  This is very performance sensitive for programs | 
 |     // with lots of diagnostics and in -E mode. | 
 |     const unsigned char *NextBuf = (const unsigned char *)Buf; | 
 |     while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0') | 
 |       ++NextBuf; | 
 |     Offs += NextBuf-Buf; | 
 |     Buf = NextBuf; | 
 |  | 
 |     if (Buf[0] == '\n' || Buf[0] == '\r') { | 
 |       // If this is \n\r or \r\n, skip both characters. | 
 |       if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1]) | 
 |         ++Offs, ++Buf; | 
 |       ++Offs, ++Buf; | 
 |       LineOffsets.push_back(Offs); | 
 |     } else { | 
 |       // Otherwise, this is a null.  If end of file, exit. | 
 |       if (Buf == End) break; | 
 |       // Otherwise, skip the null. | 
 |       ++Offs, ++Buf; | 
 |     } | 
 |   } | 
 |  | 
 |   // Copy the offsets into the FileInfo structure. | 
 |   FI->NumLines = LineOffsets.size(); | 
 |   FI->SourceLineCache = Alloc.Allocate<unsigned>(LineOffsets.size()); | 
 |   std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache); | 
 | } | 
 |  | 
 | /// getLineNumber - Given a SourceLocation, return the spelling line number | 
 | /// for the position indicated.  This requires building and caching a table of | 
 | /// line offsets for the MemoryBuffer, so this is not cheap: use only when | 
 | /// about to emit a diagnostic. | 
 | unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos) const { | 
 |   ContentCache *Content; | 
 |   if (LastLineNoFileIDQuery == FID) | 
 |     Content = LastLineNoContentCache; | 
 |   else | 
 |     Content = const_cast<ContentCache*>(getSLocEntry(FID) | 
 |                                         .getFile().getContentCache()); | 
 |  | 
 |   // If this is the first use of line information for this buffer, compute the | 
 |   /// SourceLineCache for it on demand. | 
 |   if (Content->SourceLineCache == 0) | 
 |     ComputeLineNumbers(Content, ContentCacheAlloc); | 
 |  | 
 |   // Okay, we know we have a line number table.  Do a binary search to find the | 
 |   // line number that this character position lands on. | 
 |   unsigned *SourceLineCache = Content->SourceLineCache; | 
 |   unsigned *SourceLineCacheStart = SourceLineCache; | 
 |   unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines; | 
 |  | 
 |   unsigned QueriedFilePos = FilePos+1; | 
 |  | 
 |   // FIXME: I would like to be convinced that this code is worth being as | 
 |   // complicated as it is, binary search isn't that slow. | 
 |   // | 
 |   // If it is worth being optimized, then in my opinion it could be more | 
 |   // performant, simpler, and more obviously correct by just "galloping" outward | 
 |   // from the queried file position. In fact, this could be incorporated into a | 
 |   // generic algorithm such as lower_bound_with_hint. | 
 |   // | 
 |   // If someone gives me a test case where this matters, and I will do it! - DWD | 
 |  | 
 |   // If the previous query was to the same file, we know both the file pos from | 
 |   // that query and the line number returned.  This allows us to narrow the | 
 |   // search space from the entire file to something near the match. | 
 |   if (LastLineNoFileIDQuery == FID) { | 
 |     if (QueriedFilePos >= LastLineNoFilePos) { | 
 |       // FIXME: Potential overflow? | 
 |       SourceLineCache = SourceLineCache+LastLineNoResult-1; | 
 |  | 
 |       // The query is likely to be nearby the previous one.  Here we check to | 
 |       // see if it is within 5, 10 or 20 lines.  It can be far away in cases | 
 |       // where big comment blocks and vertical whitespace eat up lines but | 
 |       // contribute no tokens. | 
 |       if (SourceLineCache+5 < SourceLineCacheEnd) { | 
 |         if (SourceLineCache[5] > QueriedFilePos) | 
 |           SourceLineCacheEnd = SourceLineCache+5; | 
 |         else if (SourceLineCache+10 < SourceLineCacheEnd) { | 
 |           if (SourceLineCache[10] > QueriedFilePos) | 
 |             SourceLineCacheEnd = SourceLineCache+10; | 
 |           else if (SourceLineCache+20 < SourceLineCacheEnd) { | 
 |             if (SourceLineCache[20] > QueriedFilePos) | 
 |               SourceLineCacheEnd = SourceLineCache+20; | 
 |           } | 
 |         } | 
 |       } | 
 |     } else { | 
 |       if (LastLineNoResult < Content->NumLines) | 
 |         SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1; | 
 |     } | 
 |   } | 
 |  | 
 |   // If the spread is large, do a "radix" test as our initial guess, based on | 
 |   // the assumption that lines average to approximately the same length. | 
 |   // NOTE: This is currently disabled, as it does not appear to be profitable in | 
 |   // initial measurements. | 
 |   if (0 && SourceLineCacheEnd-SourceLineCache > 20) { | 
 |     unsigned FileLen = Content->SourceLineCache[Content->NumLines-1]; | 
 |  | 
 |     // Take a stab at guessing where it is. | 
 |     unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen; | 
 |  | 
 |     // Check for -10 and +10 lines. | 
 |     unsigned LowerBound = std::max(int(ApproxPos-10), 0); | 
 |     unsigned UpperBound = std::min(ApproxPos+10, FileLen); | 
 |  | 
 |     // If the computed lower bound is less than the query location, move it in. | 
 |     if (SourceLineCache < SourceLineCacheStart+LowerBound && | 
 |         SourceLineCacheStart[LowerBound] < QueriedFilePos) | 
 |       SourceLineCache = SourceLineCacheStart+LowerBound; | 
 |  | 
 |     // If the computed upper bound is greater than the query location, move it. | 
 |     if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound && | 
 |         SourceLineCacheStart[UpperBound] >= QueriedFilePos) | 
 |       SourceLineCacheEnd = SourceLineCacheStart+UpperBound; | 
 |   } | 
 |  | 
 |   unsigned *Pos | 
 |     = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos); | 
 |   unsigned LineNo = Pos-SourceLineCacheStart; | 
 |  | 
 |   LastLineNoFileIDQuery = FID; | 
 |   LastLineNoContentCache = Content; | 
 |   LastLineNoFilePos = QueriedFilePos; | 
 |   LastLineNoResult = LineNo; | 
 |   return LineNo; | 
 | } | 
 |  | 
 | unsigned SourceManager::getInstantiationLineNumber(SourceLocation Loc) const { | 
 |   if (Loc.isInvalid()) return 0; | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc); | 
 |   return getLineNumber(LocInfo.first, LocInfo.second); | 
 | } | 
 | unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc) const { | 
 |   if (Loc.isInvalid()) return 0; | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc); | 
 |   return getLineNumber(LocInfo.first, LocInfo.second); | 
 | } | 
 |  | 
 | /// getFileCharacteristic - return the file characteristic of the specified | 
 | /// source location, indicating whether this is a normal file, a system | 
 | /// header, or an "implicit extern C" system header. | 
 | /// | 
 | /// This state can be modified with flags on GNU linemarker directives like: | 
 | ///   # 4 "foo.h" 3 | 
 | /// which changes all source locations in the current file after that to be | 
 | /// considered to be from a system header. | 
 | SrcMgr::CharacteristicKind | 
 | SourceManager::getFileCharacteristic(SourceLocation Loc) const { | 
 |   assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!"); | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc); | 
 |   const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile(); | 
 |  | 
 |   // If there are no #line directives in this file, just return the whole-file | 
 |   // state. | 
 |   if (!FI.hasLineDirectives()) | 
 |     return FI.getFileCharacteristic(); | 
 |  | 
 |   assert(LineTable && "Can't have linetable entries without a LineTable!"); | 
 |   // See if there is a #line directive before the location. | 
 |   const LineEntry *Entry = | 
 |     LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second); | 
 |  | 
 |   // If this is before the first line marker, use the file characteristic. | 
 |   if (!Entry) | 
 |     return FI.getFileCharacteristic(); | 
 |  | 
 |   return Entry->FileKind; | 
 | } | 
 |  | 
 | /// Return the filename or buffer identifier of the buffer the location is in. | 
 | /// Note that this name does not respect #line directives.  Use getPresumedLoc | 
 | /// for normal clients. | 
 | const char *SourceManager::getBufferName(SourceLocation Loc) const { | 
 |   if (Loc.isInvalid()) return "<invalid loc>"; | 
 |  | 
 |   return getBuffer(getFileID(Loc))->getBufferIdentifier(); | 
 | } | 
 |  | 
 |  | 
 | /// getPresumedLoc - This method returns the "presumed" location of a | 
 | /// SourceLocation specifies.  A "presumed location" can be modified by #line | 
 | /// or GNU line marker directives.  This provides a view on the data that a | 
 | /// user should see in diagnostics, for example. | 
 | /// | 
 | /// Note that a presumed location is always given as the instantiation point | 
 | /// of an instantiation location, not at the spelling location. | 
 | PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const { | 
 |   if (Loc.isInvalid()) return PresumedLoc(); | 
 |  | 
 |   // Presumed locations are always for instantiation points. | 
 |   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc); | 
 |  | 
 |   const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile(); | 
 |   const SrcMgr::ContentCache *C = FI.getContentCache(); | 
 |  | 
 |   // To get the source name, first consult the FileEntry (if one exists) | 
 |   // before the MemBuffer as this will avoid unnecessarily paging in the | 
 |   // MemBuffer. | 
 |   const char *Filename = | 
 |     C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier(); | 
 |   unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second); | 
 |   unsigned ColNo  = getColumnNumber(LocInfo.first, LocInfo.second); | 
 |   SourceLocation IncludeLoc = FI.getIncludeLoc(); | 
 |  | 
 |   // If we have #line directives in this file, update and overwrite the physical | 
 |   // location info if appropriate. | 
 |   if (FI.hasLineDirectives()) { | 
 |     assert(LineTable && "Can't have linetable entries without a LineTable!"); | 
 |     // See if there is a #line directive before this.  If so, get it. | 
 |     if (const LineEntry *Entry = | 
 |           LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second)) { | 
 |       // If the LineEntry indicates a filename, use it. | 
 |       if (Entry->FilenameID != -1) | 
 |         Filename = LineTable->getFilename(Entry->FilenameID); | 
 |  | 
 |       // Use the line number specified by the LineEntry.  This line number may | 
 |       // be multiple lines down from the line entry.  Add the difference in | 
 |       // physical line numbers from the query point and the line marker to the | 
 |       // total. | 
 |       unsigned MarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset); | 
 |       LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1); | 
 |  | 
 |       // Note that column numbers are not molested by line markers. | 
 |  | 
 |       // Handle virtual #include manipulation. | 
 |       if (Entry->IncludeOffset) { | 
 |         IncludeLoc = getLocForStartOfFile(LocInfo.first); | 
 |         IncludeLoc = IncludeLoc.getFileLocWithOffset(Entry->IncludeOffset); | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc); | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Other miscellaneous methods. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | /// \brief Get the source location for the given file:line:col triplet. | 
 | /// | 
 | /// If the source file is included multiple times, the source location will | 
 | /// be based upon the first inclusion. | 
 | SourceLocation SourceManager::getLocation(const FileEntry *SourceFile, | 
 |                                           unsigned Line, unsigned Col) const { | 
 |   assert(SourceFile && "Null source file!"); | 
 |   assert(Line && Col && "Line and column should start from 1!"); | 
 |  | 
 |   fileinfo_iterator FI = FileInfos.find(SourceFile); | 
 |   if (FI == FileInfos.end()) | 
 |     return SourceLocation(); | 
 |   ContentCache *Content = FI->second; | 
 |  | 
 |   // If this is the first use of line information for this buffer, compute the | 
 |   /// SourceLineCache for it on demand. | 
 |   if (Content->SourceLineCache == 0) | 
 |     ComputeLineNumbers(Content, ContentCacheAlloc); | 
 |  | 
 |   if (Line > Content->NumLines) | 
 |     return SourceLocation(); | 
 |  | 
 |   unsigned FilePos = Content->SourceLineCache[Line - 1]; | 
 |   const char *Buf = Content->getBuffer()->getBufferStart() + FilePos; | 
 |   unsigned BufLength = Content->getBuffer()->getBufferEnd() - Buf; | 
 |   unsigned i = 0; | 
 |  | 
 |   // Check that the given column is valid. | 
 |   while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r') | 
 |     ++i; | 
 |   if (i < Col-1) | 
 |     return SourceLocation(); | 
 |  | 
 |   return getLocForStartOfFile(Content->FirstFID). | 
 |             getFileLocWithOffset(FilePos + Col - 1); | 
 | } | 
 |  | 
 | /// \brief Determines the order of 2 source locations in the translation unit. | 
 | /// | 
 | /// \returns true if LHS source location comes before RHS, false otherwise. | 
 | bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, | 
 |                                               SourceLocation RHS) const { | 
 |   assert(LHS.isValid() && RHS.isValid() && "Passed invalid source location!"); | 
 |   if (LHS == RHS) | 
 |     return false; | 
 |  | 
 |   std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS); | 
 |   std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS); | 
 |  | 
 |   // If the source locations are in the same file, just compare offsets. | 
 |   if (LOffs.first == ROffs.first) | 
 |     return LOffs.second < ROffs.second; | 
 |  | 
 |   // If we are comparing a source location with multiple locations in the same | 
 |   // file, we get a big win by caching the result. | 
 |  | 
 |   if (LastLFIDForBeforeTUCheck == LOffs.first && | 
 |       LastRFIDForBeforeTUCheck == ROffs.first) | 
 |     return LastResForBeforeTUCheck; | 
 |  | 
 |   LastLFIDForBeforeTUCheck = LOffs.first; | 
 |   LastRFIDForBeforeTUCheck = ROffs.first; | 
 |  | 
 |   // "Traverse" the include/instantiation stacks of both locations and try to | 
 |   // find a common "ancestor". | 
 |   // | 
 |   // First we traverse the stack of the right location and check each level | 
 |   // against the level of the left location, while collecting all levels in a | 
 |   // "stack map". | 
 |  | 
 |   std::map<FileID, unsigned> ROffsMap; | 
 |   ROffsMap[ROffs.first] = ROffs.second; | 
 |  | 
 |   while (1) { | 
 |     SourceLocation UpperLoc; | 
 |     const SrcMgr::SLocEntry &Entry = getSLocEntry(ROffs.first); | 
 |     if (Entry.isInstantiation()) | 
 |       UpperLoc = Entry.getInstantiation().getInstantiationLocStart(); | 
 |     else | 
 |       UpperLoc = Entry.getFile().getIncludeLoc(); | 
 |  | 
 |     if (UpperLoc.isInvalid()) | 
 |       break; // We reached the top. | 
 |  | 
 |     ROffs = getDecomposedLoc(UpperLoc); | 
 |  | 
 |     if (LOffs.first == ROffs.first) | 
 |       return LastResForBeforeTUCheck = LOffs.second < ROffs.second; | 
 |  | 
 |     ROffsMap[ROffs.first] = ROffs.second; | 
 |   } | 
 |  | 
 |   // We didn't find a common ancestor. Now traverse the stack of the left | 
 |   // location, checking against the stack map of the right location. | 
 |  | 
 |   while (1) { | 
 |     SourceLocation UpperLoc; | 
 |     const SrcMgr::SLocEntry &Entry = getSLocEntry(LOffs.first); | 
 |     if (Entry.isInstantiation()) | 
 |       UpperLoc = Entry.getInstantiation().getInstantiationLocStart(); | 
 |     else | 
 |       UpperLoc = Entry.getFile().getIncludeLoc(); | 
 |  | 
 |     if (UpperLoc.isInvalid()) | 
 |       break; // We reached the top. | 
 |  | 
 |     LOffs = getDecomposedLoc(UpperLoc); | 
 |  | 
 |     std::map<FileID, unsigned>::iterator I = ROffsMap.find(LOffs.first); | 
 |     if (I != ROffsMap.end()) | 
 |       return LastResForBeforeTUCheck = LOffs.second < I->second; | 
 |   } | 
 |  | 
 |   // No common ancestor. | 
 |   // Now we are getting into murky waters. Most probably this is because one | 
 |   // location is in the predefines buffer. | 
 |  | 
 |   const FileEntry *LEntry = | 
 |     getSLocEntry(LOffs.first).getFile().getContentCache()->Entry; | 
 |   const FileEntry *REntry = | 
 |     getSLocEntry(ROffs.first).getFile().getContentCache()->Entry; | 
 |  | 
 |   // If the locations are in two memory buffers we give up, we can't answer | 
 |   // which one should be considered first. | 
 |   // FIXME: Should there be a way to "include" memory buffers in the translation | 
 |   // unit ? | 
 |   assert((LEntry != 0 || REntry != 0) && "Locations in memory buffers."); | 
 |   (void) REntry; | 
 |  | 
 |   // Consider the memory buffer as coming before the file in the translation | 
 |   // unit. | 
 |   if (LEntry == 0) | 
 |     return LastResForBeforeTUCheck = true; | 
 |   else { | 
 |     assert(REntry == 0 && "Locations in not #included files ?"); | 
 |     return LastResForBeforeTUCheck = false; | 
 |   } | 
 | } | 
 |  | 
 | void SourceManager::truncateFileAt(const FileEntry *Entry, unsigned Line,  | 
 |                                    unsigned Column) { | 
 |   llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator FI | 
 |      = FileInfos.find(Entry); | 
 |   if (FI != FileInfos.end()) { | 
 |     FI->second->truncateAt(Line, Column); | 
 |     return; | 
 |   } | 
 |    | 
 |   // We cannot perform the truncation until we actually see the file, so | 
 |   // save the truncation information. | 
 |   assert(TruncateFile == 0 && "Can't queue up multiple file truncations!"); | 
 |   TruncateFile = Entry; | 
 |   TruncateAtLine = Line; | 
 |   TruncateAtColumn = Column; | 
 | } | 
 |  | 
 | /// \brief Determine whether this file was truncated. | 
 | bool SourceManager::isTruncatedFile(FileID FID) const { | 
 |   return getSLocEntry(FID).getFile().getContentCache()->isTruncated(); | 
 | } | 
 |  | 
 | /// PrintStats - Print statistics to stderr. | 
 | /// | 
 | void SourceManager::PrintStats() const { | 
 |   llvm::errs() << "\n*** Source Manager Stats:\n"; | 
 |   llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size() | 
 |                << " mem buffers mapped.\n"; | 
 |   llvm::errs() << SLocEntryTable.size() << " SLocEntry's allocated, " | 
 |                << NextOffset << "B of Sloc address space used.\n"; | 
 |  | 
 |   unsigned NumLineNumsComputed = 0; | 
 |   unsigned NumFileBytesMapped = 0; | 
 |   for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){ | 
 |     NumLineNumsComputed += I->second->SourceLineCache != 0; | 
 |     NumFileBytesMapped  += I->second->getSizeBytesMapped(); | 
 |   } | 
 |  | 
 |   llvm::errs() << NumFileBytesMapped << " bytes of files mapped, " | 
 |                << NumLineNumsComputed << " files with line #'s computed.\n"; | 
 |   llvm::errs() << "FileID scans: " << NumLinearScans << " linear, " | 
 |                << NumBinaryProbes << " binary.\n"; | 
 | } | 
 |  | 
 | ExternalSLocEntrySource::~ExternalSLocEntrySource() { } |