zcov: / lib/Basic/SourceManager.cpp


Files: 1 Branches Taken: 72.1% 235 / 326
Generated: 2010-02-10 01:31 Branches Executed: 91.4% 298 / 326
Line Coverage: 90.4% 442 / 489


Programs: 2 Runs 3018


       1                 : //===--- SourceManager.cpp - Track and cache source files -----------------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : //  This file implements the SourceManager interface.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/Basic/SourceManager.h"
      15                 : #include "clang/Basic/SourceManagerInternals.h"
      16                 : #include "clang/Basic/FileManager.h"
      17                 : #include "llvm/Support/Compiler.h"
      18                 : #include "llvm/Support/MemoryBuffer.h"
      19                 : #include "llvm/Support/raw_ostream.h"
      20                 : #include "llvm/System/Path.h"
      21                 : #include <algorithm>
      22                 : using namespace clang;
      23                 : using namespace SrcMgr;
      24                 : using llvm::MemoryBuffer;
      25                 : 
      26                 : //===----------------------------------------------------------------------===//
      27                 : // SourceManager Helper Classes
      28                 : //===----------------------------------------------------------------------===//
      29                 : 
      30             5781: ContentCache::~ContentCache() {
                     5781: branch 0 taken
                     5781: branch 1 taken
                     5750: branch 3 taken
                       31: branch 4 taken
      31             5781:   delete Buffer;
      32             5781: }
      33                 : 
      34                 : /// getSizeBytesMapped - Returns the number of bytes actually mapped for
      35                 : ///  this ContentCache.  This can be 0 if the MemBuffer was not actually
      36                 : ///  instantiated.
      37                2: unsigned ContentCache::getSizeBytesMapped() const {
                        2: branch 0 taken
                        0: branch 1 not taken
      38                2:   return Buffer ? Buffer->getBufferSize() : 0;
      39                 : }
      40                 : 
      41                 : /// getSize - Returns the size of the content encapsulated by this ContentCache.
      42                 : ///  This can be the size of the source file or the size of an arbitrary
      43                 : ///  scratch buffer.  If the ContentCache encapsulates a source file, that
      44                 : ///  file is not lazily brought in from disk to satisfy this query.
      45             5761: unsigned ContentCache::getSize() const {
                     2837: branch 0 taken
                     2924: branch 1 taken
      46             5761:   return Buffer ? Buffer->getBufferSize() : Entry->getSize();
      47                 : }
      48                 : 
      49               99: void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B) {
                        0: branch 0 not taken
                       99: branch 1 taken
      50               99:   assert(B != Buffer);
      51                 :   
                       87: branch 0 taken
                       12: branch 1 taken
      52               99:   delete Buffer;
      53               99:   Buffer = B;
      54               99: }
      55                 : 
      56           331682: const llvm::MemoryBuffer *ContentCache::getBuffer(std::string *ErrorStr) const {
      57                 :   // Lazily create the Buffer for ContentCaches that wrap files.
                     2945: branch 0 taken
                   328737: branch 1 taken
                     2945: branch 2 taken
                        0: branch 3 not taken
      58           331682:   if (!Buffer && Entry) {
      59             2945:     Buffer = MemoryBuffer::getFile(Entry->getName(), ErrorStr,Entry->getSize());
      60                 : 
      61                 :     // If we were unable to open the file, then we are in an inconsistent
      62                 :     // situation where the content cache referenced a file which no longer
      63                 :     // exists. Most likely, we were using a stat cache with an invalid entry but
      64                 :     // the file could also have been removed during processing. Since we can't
      65                 :     // really deal with this situation, just create an empty buffer.
      66                 :     //
      67                 :     // FIXME: This is definitely not ideal, but our immediate clients can't
      68                 :     // currently handle returning a null entry here. Ideally we should detect
      69                 :     // that we are in an inconsistent situation and error out as quickly as
      70                 :     // possible.
                        0: branch 0 not taken
                     2945: branch 1 taken
      71             2945:     if (!Buffer) {
      72                0:       const llvm::StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
      73                0:       Buffer = MemoryBuffer::getNewMemBuffer(Entry->getSize(), "<invalid>");
      74                0:       char *Ptr = const_cast<char*>(Buffer->getBufferStart());
                        0: branch 1 not taken
                        0: branch 2 not taken
      75                0:       for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
      76                0:         Ptr[i] = FillStr[i % FillStr.size()];
      77                 :     }
      78                 :   }
      79           331682:   return Buffer;
      80                 : }
      81                 : 
      82             7713: unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) {
      83                 :   // Look up the filename in the string table, returning the pre-existing value
      84                 :   // if it exists.
      85                 :   llvm::StringMapEntry<unsigned> &Entry =
      86             7713:     FilenameIDs.GetOrCreateValue(Ptr, Ptr+Len, ~0U);
                     2610: branch 1 taken
                     5103: branch 2 taken
      87             7713:   if (Entry.getValue() != ~0U)
      88             2610:     return Entry.getValue();
      89                 : 
      90                 :   // Otherwise, assign this the next available ID.
      91             5103:   Entry.setValue(FilenamesByID.size());
      92             5103:   FilenamesByID.push_back(&Entry);
      93             5103:   return FilenamesByID.size()-1;
      94                 : }
      95                 : 
      96                 : /// AddLineNote - Add a line note to the line table that indicates that there
      97                 : /// is a #line at the specified FID/Offset location which changes the presumed
      98                 : /// location to LineNo/FilenameID.
      99                 : void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
     100               39:                                 unsigned LineNo, int FilenameID) {
     101               39:   std::vector<LineEntry> &Entries = LineEntries[FID];
     102                 : 
     103                 :   assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
                       33: branch 1 taken
                        6: branch 2 taken
                       33: branch 4 taken
                        0: branch 5 not taken
     104               39:          "Adding line entries out of order!");
     105                 : 
     106               39:   SrcMgr::CharacteristicKind Kind = SrcMgr::C_User;
     107               39:   unsigned IncludeOffset = 0;
     108                 : 
                       33: branch 1 taken
                        6: branch 2 taken
     109               39:   if (!Entries.empty()) {
     110                 :     // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember
     111                 :     // that we are still in "foo.h".
                       15: branch 0 taken
                       18: branch 1 taken
     112               33:     if (FilenameID == -1)
     113               15:       FilenameID = Entries.back().FilenameID;
     114                 : 
     115                 :     // If we are after a line marker that switched us to system header mode, or
     116                 :     // that set #include information, preserve it.
     117               33:     Kind = Entries.back().FileKind;
     118               33:     IncludeOffset = Entries.back().IncludeOffset;
     119                 :   }
     120                 : 
     121                 :   Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind,
     122               39:                                    IncludeOffset));
     123               39: }
     124                 : 
     125                 : /// AddLineNote This is the same as the previous version of AddLineNote, but is
     126                 : /// used for GNU line markers.  If EntryExit is 0, then this doesn't change the
     127                 : /// presumed #include stack.  If it is 1, this is a file entry, if it is 2 then
     128                 : /// this is a file exit.  FileKind specifies whether this is a system header or
     129                 : /// extern C system header.
     130                 : void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
     131                 :                                 unsigned LineNo, int FilenameID,
     132                 :                                 unsigned EntryExit,
     133             7580:                                 SrcMgr::CharacteristicKind FileKind) {
                        0: branch 0 not taken
                     7580: branch 1 taken
     134             7580:   assert(FilenameID != -1 && "Unspecified filename should use other accessor");
     135                 : 
     136             7580:   std::vector<LineEntry> &Entries = LineEntries[FID];
     137                 : 
     138                 :   assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
                     5092: branch 1 taken
                     2488: branch 2 taken
                     5092: branch 4 taken
                        0: branch 5 not taken
     139             7580:          "Adding line entries out of order!");
     140                 : 
     141             7580:   unsigned IncludeOffset = 0;
                     2559: branch 0 taken
                     5021: branch 1 taken
     142             7580:   if (EntryExit == 0) {  // No #include stack change.
                     2484: branch 1 taken
                       75: branch 2 taken
     143             2559:     IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
                     2514: branch 0 taken
                     2507: branch 1 taken
     144             5021:   } else if (EntryExit == 1) {
     145             2514:     IncludeOffset = Offset-1;
                     2507: branch 0 taken
                        0: branch 1 not taken
     146             2507:   } else if (EntryExit == 2) {
     147                 :     assert(!Entries.empty() && Entries.back().IncludeOffset &&
                     2507: branch 1 taken
                        0: branch 2 not taken
                     2507: branch 4 taken
                        0: branch 5 not taken
     148             2507:        "PPDirectives should have caught case when popping empty include stack");
     149                 : 
     150                 :     // Get the include loc of the last entries' include loc as our include loc.
     151             2507:     IncludeOffset = 0;
                     2507: branch 0 taken
                        0: branch 1 not taken
     152             2507:     if (const LineEntry *PrevEntry =
     153             2507:           FindNearestLineEntry(FID, Entries.back().IncludeOffset))
     154             2507:       IncludeOffset = PrevEntry->IncludeOffset;
     155                 :   }
     156                 : 
     157                 :   Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind,
     158             7580:                                    IncludeOffset));
     159             7580: }
     160                 : 
     161                 : 
     162                 : /// FindNearestLineEntry - Find the line entry nearest to FID that is before
     163                 : /// it.  If there is no line entry before Offset in FID, return null.
     164                 : const LineEntry *LineTableInfo::FindNearestLineEntry(unsigned FID,
     165             7146:                                                      unsigned Offset) {
     166             7146:   const std::vector<LineEntry> &Entries = LineEntries[FID];
                     7146: branch 1 taken
                        0: branch 2 not taken
     167             7146:   assert(!Entries.empty() && "No #line entries for this FID after all!");
     168                 : 
     169                 :   // It is very common for the query to be after the last #line, check this
     170                 :   // first.
                     4613: branch 1 taken
                     2533: branch 2 taken
     171             7146:   if (Entries.back().FileOffset <= Offset)
     172             4613:     return &Entries.back();
     173                 : 
     174                 :   // Do a binary search to find the maximal element that is still before Offset.
     175                 :   std::vector<LineEntry>::const_iterator I =
     176             2533:     std::upper_bound(Entries.begin(), Entries.end(), Offset);
                        2: branch 2 taken
                     2531: branch 3 taken
     177             2533:   if (I == Entries.begin()) return 0;
     178             2531:   return &*--I;
     179                 : }
     180                 : 
     181                 : /// \brief Add a new line entry that has already been encoded into
     182                 : /// the internal representation of the line table.
     183                 : void LineTableInfo::AddEntry(unsigned FID,
     184               49:                              const std::vector<LineEntry> &Entries) {
     185               49:   LineEntries[FID] = Entries;
     186               49: }
     187                 : 
     188                 : /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
     189                 : ///
     190             7616: unsigned SourceManager::getLineTableFilenameID(const char *Ptr, unsigned Len) {
                     2480: branch 0 taken
                     5136: branch 1 taken
     191             7616:   if (LineTable == 0)
     192             2480:     LineTable = new LineTableInfo();
     193             7616:   return LineTable->getLineTableFilenameID(Ptr, Len);
     194                 : }
     195                 : 
     196                 : 
     197                 : /// AddLineNote - Add a line note to the line table for the FileID and offset
     198                 : /// specified by Loc.  If FilenameID is -1, it is considered to be
     199                 : /// unspecified.
     200                 : void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
     201               39:                                 int FilenameID) {
     202               39:   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
     203                 : 
     204               39:   const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile();
     205                 : 
     206                 :   // Remember that this file has #line directives now if it doesn't already.
     207               39:   const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
     208                 : 
                        0: branch 0 not taken
                       39: branch 1 taken
     209               39:   if (LineTable == 0)
     210                0:     LineTable = new LineTableInfo();
     211               39:   LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID);
     212               39: }
     213                 : 
     214                 : /// AddLineNote - Add a GNU line marker to the line table.
     215                 : void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
     216                 :                                 int FilenameID, bool IsFileEntry,
     217                 :                                 bool IsFileExit, bool IsSystemHeader,
     218             7586:                                 bool IsExternCHeader) {
     219                 :   // If there is no filename and no flags, this is treated just like a #line,
     220                 :   // which does not change the flags of the previous line marker.
                        6: branch 0 taken
                     7580: branch 1 taken
     221             7586:   if (FilenameID == -1) {
     222                 :     assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader &&
                        6: branch 0 taken
                        0: branch 1 not taken
                        6: branch 2 taken
                        0: branch 3 not taken
                        6: branch 4 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        6: branch 7 taken
     223                6:            "Can't set flags without setting the filename!");
     224                6:     return AddLineNote(Loc, LineNo, FilenameID);
     225                 :   }
     226                 : 
     227             7580:   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
     228             7580:   const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile();
     229                 : 
     230                 :   // Remember that this file has #line directives now if it doesn't already.
     231             7580:   const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
     232                 : 
                        0: branch 0 not taken
                     7580: branch 1 taken
     233             7580:   if (LineTable == 0)
     234                0:     LineTable = new LineTableInfo();
     235                 : 
     236                 :   SrcMgr::CharacteristicKind FileKind;
                       95: branch 0 taken
                     7485: branch 1 taken
     237             7580:   if (IsExternCHeader)
     238               95:     FileKind = SrcMgr::C_ExternCSystem;
                     2493: branch 0 taken
                     4992: branch 1 taken
     239             7485:   else if (IsSystemHeader)
     240             2493:     FileKind = SrcMgr::C_System;
     241                 :   else
     242             4992:     FileKind = SrcMgr::C_User;
     243                 : 
     244             7580:   unsigned EntryExit = 0;
                     2514: branch 0 taken
                     5066: branch 1 taken
     245             7580:   if (IsFileEntry)
     246             2514:     EntryExit = 1;
                     2507: branch 0 taken
                     2559: branch 1 taken
     247             5066:   else if (IsFileExit)
     248             2507:     EntryExit = 2;
     249                 : 
     250                 :   LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID,
     251             7580:                          EntryExit, FileKind);
     252                 : }
     253                 : 
     254               92: LineTableInfo &SourceManager::getLineTable() {
                       48: branch 0 taken
                       44: branch 1 taken
     255               92:   if (LineTable == 0)
     256               48:     LineTable = new LineTableInfo();
     257               92:   return *LineTable;
     258                 : }
     259                 : 
     260                 : //===----------------------------------------------------------------------===//
     261                 : // Private 'Create' methods.
     262                 : //===----------------------------------------------------------------------===//
     263                 : 
     264             2582: SourceManager::~SourceManager() {
                     2525: branch 0 taken
                       57: branch 1 taken
                     2525: branch 4 taken
                     2525: branch 5 taken
     265             2582:   delete LineTable;
     266                 : 
     267                 :   // Delete FileEntry objects corresponding to content caches.  Since the actual
     268                 :   // content cache objects are bump pointer allocated, we just have to run the
     269                 :   // dtors, but we call the deallocate method for completeness.
                     2796: branch 1 taken
                     2582: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
     270             5378:   for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
     271             2796:     MemBufferInfos[i]->~ContentCache();
     272             2796:     ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
     273                 :   }
                     2985: branch 3 taken
                     2582: branch 4 taken
                        0: branch 8 not taken
                        0: branch 9 not taken
     274             5567:   for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
     275             2582:        I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
     276             2985:     I->second->~ContentCache();
     277             2985:     ContentCacheAlloc.Deallocate(I->second);
     278                 :   }
     279             2582: }
     280                 : 
     281             2585: void SourceManager::clearIDTables() {
     282             2585:   MainFileID = FileID();
     283             2585:   SLocEntryTable.clear();
     284             2585:   LastLineNoFileIDQuery = FileID();
     285             2585:   LastLineNoContentCache = 0;
     286             2585:   LastFileIDLookup = FileID();
     287                 : 
                        0: branch 0 not taken
                     2585: branch 1 taken
     288             2585:   if (LineTable)
     289                0:     LineTable->clear();
     290                 : 
     291                 :   // Use up FileID #0 as an invalid instantiation.
     292             2585:   NextOffset = 0;
     293             2585:   createInstantiationLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1);
     294             2585: }
     295                 : 
     296                 : /// getOrCreateContentCache - Create or return a cached ContentCache for the
     297                 : /// specified file.
     298                 : const ContentCache *
     299             3252: SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) {
                        0: branch 0 not taken
                     3252: branch 1 taken
     300             3252:   assert(FileEnt && "Didn't specify a file entry to use?");
     301                 : 
     302                 :   // Do we already have information about this file?
     303             3252:   ContentCache *&Entry = FileInfos[FileEnt];
                      264: branch 0 taken
                     2988: branch 1 taken
     304             3252:   if (Entry) return Entry;
     305                 : 
     306                 :   // Nope, create a new Cache entry.  Make sure it is at least 8-byte aligned
     307                 :   // so that FileInfo can use the low 3 bits of the pointer for its own
     308                 :   // nefarious purposes.
     309             2988:   unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
     310             2988:   EntryAlign = std::max(8U, EntryAlign);
     311             2988:   Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
                     2988: branch 1 taken
                        0: branch 2 not taken
     312             2988:   new (Entry) ContentCache(FileEnt);
     313             2988:   return Entry;
     314                 : }
     315                 : 
     316                 : 
     317                 : /// createMemBufferContentCache - Create a new ContentCache for the specified
     318                 : ///  memory buffer.  This does no caching.
     319                 : const ContentCache*
     320             2799: SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
     321                 :   // Add a new ContentCache to the MemBufferInfos list and return it.  Make sure
     322                 :   // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of
     323                 :   // the pointer for its own nefarious purposes.
     324             2799:   unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
     325             2799:   EntryAlign = std::max(8U, EntryAlign);
     326             2799:   ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
                     2799: branch 1 taken
                        0: branch 2 not taken
     327             2799:   new (Entry) ContentCache();
     328             2799:   MemBufferInfos.push_back(Entry);
     329             2799:   Entry->setBuffer(Buffer);
     330             2799:   return Entry;
     331                 : }
     332                 : 
     333                 : void SourceManager::PreallocateSLocEntries(ExternalSLocEntrySource *Source,
     334                 :                                            unsigned NumSLocEntries,
     335               48:                                            unsigned NextOffset) {
     336               48:   ExternalSLocEntries = Source;
     337               48:   this->NextOffset = NextOffset;
     338               48:   SLocEntryLoaded.resize(NumSLocEntries + 1);
     339               48:   SLocEntryLoaded[0] = true;
     340               48:   SLocEntryTable.resize(SLocEntryTable.size() + NumSLocEntries);
     341               48: }
     342                 : 
     343                0: void SourceManager::ClearPreallocatedSLocEntries() {
     344                0:   unsigned I = 0;
                        0: branch 1 not taken
                        0: branch 2 not taken
     345                0:   for (unsigned N = SLocEntryLoaded.size(); I != N; ++I)
                        0: branch 2 not taken
                        0: branch 3 not taken
     346                0:     if (!SLocEntryLoaded[I])
     347                0:       break;
     348                 : 
     349                 :   // We've already loaded all preallocated source location entries.
                        0: branch 1 not taken
                        0: branch 2 not taken
     350                0:   if (I == SLocEntryLoaded.size())
     351                0:     return;
     352                 : 
     353                 :   // Remove everything from location I onward.
     354                0:   SLocEntryTable.resize(I);
     355                0:   SLocEntryLoaded.clear();
     356                0:   ExternalSLocEntries = 0;
     357                 : }
     358                 : 
     359                 : 
     360                 : //===----------------------------------------------------------------------===//
     361                 : // Methods to create new FileID's and instantiations.
     362                 : //===----------------------------------------------------------------------===//
     363                 : 
     364                 : /// createFileID - Create a new fileID for the specified ContentCache and
     365                 : /// include position.  This works regardless of whether the ContentCache
     366                 : /// corresponds to a file or some other input source.
     367                 : FileID SourceManager::createFileID(const ContentCache *File,
     368                 :                                    SourceLocation IncludePos,
     369                 :                                    SrcMgr::CharacteristicKind FileCharacter,
     370                 :                                    unsigned PreallocatedID,
     371             5865:                                    unsigned Offset) {
                      104: branch 0 taken
                     5761: branch 1 taken
     372             5865:   if (PreallocatedID) {
     373                 :     // If we're filling in a preallocated ID, just load in the file
     374                 :     // entry and return.
     375                 :     assert(PreallocatedID < SLocEntryLoaded.size() &&
                      104: branch 1 taken
                        0: branch 2 not taken
     376              104:            "Preallocate ID out-of-range");
     377                 :     assert(!SLocEntryLoaded[PreallocatedID] &&
                      104: branch 2 taken
                        0: branch 3 not taken
     378              104:            "Source location entry already loaded");
                        0: branch 0 not taken
                      104: branch 1 taken
     379              104:     assert(Offset && "Preallocate source location cannot have zero offset");
     380                 :     SLocEntryTable[PreallocatedID]
     381              104:       = SLocEntry::get(Offset, FileInfo::get(IncludePos, File, FileCharacter));
     382              104:     SLocEntryLoaded[PreallocatedID] = true;
     383              104:     FileID FID = FileID::get(PreallocatedID);
     384              104:     return LastFileIDLookup = FID;
     385                 :   }
     386                 : 
     387                 :   SLocEntryTable.push_back(SLocEntry::get(NextOffset,
     388                 :                                           FileInfo::get(IncludePos, File,
     389             5761:                                                         FileCharacter)));
     390             5761:   unsigned FileSize = File->getSize();
                        0: branch 0 not taken
                     5761: branch 1 taken
     391             5761:   assert(NextOffset+FileSize+1 > NextOffset && "Ran out of source locations!");
     392             5761:   NextOffset += FileSize+1;
     393                 : 
     394                 :   // Set LastFileIDLookup to the newly created file.  The next getFileID call is
     395                 :   // almost guaranteed to be from that file.
     396             5761:   FileID FID = FileID::get(SLocEntryTable.size()-1);
     397             5761:   return LastFileIDLookup = FID;
     398                 : }
     399                 : 
     400                 : /// createInstantiationLoc - Return a new SourceLocation that encodes the fact
     401                 : /// that a token from SpellingLoc should actually be referenced from
     402                 : /// InstantiationLoc.
     403                 : SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc,
     404                 :                                                      SourceLocation ILocStart,
     405                 :                                                      SourceLocation ILocEnd,
     406                 :                                                      unsigned TokLength,
     407                 :                                                      unsigned PreallocatedID,
     408            57689:                                                      unsigned Offset) {
     409            57689:   InstantiationInfo II = InstantiationInfo::get(ILocStart,ILocEnd, SpellingLoc);
                       36: branch 0 taken
                    57653: branch 1 taken
     410            57689:   if (PreallocatedID) {
     411                 :     // If we're filling in a preallocated ID, just load in the
     412                 :     // instantiation entry and return.
     413                 :     assert(PreallocatedID < SLocEntryLoaded.size() &&
                       36: branch 1 taken
                        0: branch 2 not taken
     414               36:            "Preallocate ID out-of-range");
     415                 :     assert(!SLocEntryLoaded[PreallocatedID] &&
                       36: branch 2 taken
                        0: branch 3 not taken
     416               36:            "Source location entry already loaded");
                        0: branch 0 not taken
                       36: branch 1 taken
     417               36:     assert(Offset && "Preallocate source location cannot have zero offset");
     418               36:     SLocEntryTable[PreallocatedID] = SLocEntry::get(Offset, II);
     419               36:     SLocEntryLoaded[PreallocatedID] = true;
     420               36:     return SourceLocation::getMacroLoc(Offset);
     421                 :   }
     422            57653:   SLocEntryTable.push_back(SLocEntry::get(NextOffset, II));
                        0: branch 0 not taken
                    57653: branch 1 taken
     423            57653:   assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!");
     424            57653:   NextOffset += TokLength+1;
     425            57653:   return SourceLocation::getMacroLoc(NextOffset-(TokLength+1));
     426                 : }
     427                 : 
     428                 : const llvm::MemoryBuffer *
     429               87: SourceManager::getMemoryBufferForFile(const FileEntry *File) {
     430               87:   const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
                        0: branch 0 not taken
                       87: branch 1 taken
     431               87:   if (IR == 0)
     432                0:     return 0;
     433                 : 
     434               87:   return IR->getBuffer();
     435                 : }
     436                 : 
     437                 : bool SourceManager::overrideFileContents(const FileEntry *SourceFile,
     438               99:                                          const llvm::MemoryBuffer *Buffer) {
     439               99:   const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
                        0: branch 0 not taken
                       99: branch 1 taken
     440               99:   if (IR == 0)
     441                0:     return true;
     442                 : 
     443               99:   const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer);
     444               99:   return false;
     445                 : }
     446                 : 
     447                 : /// getBufferData - Return a pointer to the start and end of the source buffer
     448                 : /// data for the specified FileID.
     449                 : std::pair<const char*, const char*>
     450           139738: SourceManager::getBufferData(FileID FID) const {
     451           139738:   const llvm::MemoryBuffer *Buf = getBuffer(FID);
     452           139738:   return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
     453                 : }
     454                 : 
     455                 : 
     456                 : //===----------------------------------------------------------------------===//
     457                 : // SourceLocation manipulation methods.
     458                 : //===----------------------------------------------------------------------===//
     459                 : 
     460                 : /// getFileIDSlow - Return the FileID for a SourceLocation.  This is a very hot
     461                 : /// method that is used for all SourceManager queries that start with a
     462                 : /// SourceLocation object.  It is responsible for finding the entry in
     463                 : /// SLocEntryTable which contains the specified location.
     464                 : ///
     465            98712: FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
                        0: branch 0 not taken
                    98712: branch 1 taken
     466            98712:   assert(SLocOffset && "Invalid FileID");
     467                 : 
     468                 :   // After the first and second level caches, I see two common sorts of
     469                 :   // behavior: 1) a lot of searched FileID's are "near" the cached file location
     470                 :   // or are "near" the cached instantiation location.  2) others are just
     471                 :   // completely random and may be a very long way away.
     472                 :   //
     473                 :   // To handle this, we do a linear search for up to 8 steps to catch #1 quickly
     474                 :   // then we fall back to a less cache efficient, but more scalable, binary
     475                 :   // search to find the location.
     476                 : 
     477                 :   // See if this is near the file point - worst case we start scanning from the
     478                 :   // most newly created FileID.
     479            98712:   std::vector<SrcMgr::SLocEntry>::const_iterator I;
     480                 : 
                    47590: branch 2 taken
                    51122: branch 3 taken
     481            98712:   if (SLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
     482                 :     // Neither loc prunes our search.
     483            47590:     I = SLocEntryTable.end();
     484                 :   } else {
     485                 :     // Perhaps it is near the file point.
     486            51122:     I = SLocEntryTable.begin()+LastFileIDLookup.ID;
     487                 :   }
     488                 : 
     489                 :   // Find the FileID that contains this.  "I" is an iterator that points to a
     490                 :   // FileID whose offset is known to be larger than SLocOffset.
     491            98712:   unsigned NumProbes = 0;
     492           113034:   while (1) {
     493           211746:     --I;
                    77125: branch 0 taken
                   134621: branch 1 taken
     494           211746:     if (ExternalSLocEntries)
     495            77125:       getSLocEntry(FileID::get(I - SLocEntryTable.begin()));
                    82894: branch 2 taken
                   128852: branch 3 taken
     496           211746:     if (I->getOffset() <= SLocOffset) {
     497                 : #if 0
     498                 :       printf("lin %d -> %d [%s] %d %d\n", SLocOffset,
     499                 :              I-SLocEntryTable.begin(),
     500                 :              I->isInstantiation() ? "inst" : "file",
     501                 :              LastFileIDLookup.ID,  int(SLocEntryTable.end()-I));
     502                 : #endif
     503            82894:       FileID Res = FileID::get(I-SLocEntryTable.begin());
     504                 : 
     505                 :       // If this isn't an instantiation, remember it.  We have good locality
     506                 :       // across FileID lookups.
                    79596: branch 2 taken
                     3298: branch 3 taken
     507            82894:       if (!I->isInstantiation())
     508            79596:         LastFileIDLookup = Res;
     509            82894:       NumLinearScans += NumProbes+1;
     510            82894:       return Res;
     511                 :     }
                   113034: branch 0 taken
                    15818: branch 1 taken
     512           128852:     if (++NumProbes == 8)
     513            15818:       break;
     514                 :   }
     515                 : 
     516                 :   // Convert "I" back into an index.  We know that it is an entry whose index is
     517                 :   // larger than the offset we are looking for.
     518            15818:   unsigned GreaterIndex = I-SLocEntryTable.begin();
     519                 :   // LessIndex - This is the lower bound of the range that we're searching.
     520                 :   // We know that the offset corresponding to the FileID is is less than
     521                 :   // SLocOffset.
     522            15818:   unsigned LessIndex = 0;
     523            15818:   NumProbes = 0;
     524            96598:   while (1) {
     525           112416:     unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
     526           112416:     unsigned MidOffset = getSLocEntry(FileID::get(MiddleIndex)).getOffset();
     527                 : 
     528           112416:     ++NumProbes;
     529                 : 
     530                 :     // If the offset of the midpoint is too large, chop the high side of the
     531                 :     // range to the midpoint.
                    79579: branch 0 taken
                    32837: branch 1 taken
     532           112416:     if (MidOffset > SLocOffset) {
     533            79579:       GreaterIndex = MiddleIndex;
     534            79579:       continue;
     535                 :     }
     536                 : 
     537                 :     // If the middle index contains the value, succeed and return.
                    15818: branch 2 taken
                    17019: branch 3 taken
     538            32837:     if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
     539                 : #if 0
     540                 :       printf("bin %d -> %d [%s] %d %d\n", SLocOffset,
     541                 :              I-SLocEntryTable.begin(),
     542                 :              I->isInstantiation() ? "inst" : "file",
     543                 :              LastFileIDLookup.ID, int(SLocEntryTable.end()-I));
     544                 : #endif
     545            15818:       FileID Res = FileID::get(MiddleIndex);
     546                 : 
     547                 :       // If this isn't an instantiation, remember it.  We have good locality
     548                 :       // across FileID lookups.
                        6: branch 2 taken
                    15812: branch 3 taken
     549            15818:       if (!I->isInstantiation())
     550                6:         LastFileIDLookup = Res;
     551            15818:       NumBinaryProbes += NumProbes;
     552            15818:       return Res;
     553                 :     }
     554                 : 
     555                 :     // Otherwise, move the low-side up to the middle index.
     556            17019:     LessIndex = MiddleIndex;
     557                 :   }
     558                 : }
     559                 : 
     560                 : SourceLocation SourceManager::
     561               72: getInstantiationLocSlowCase(SourceLocation Loc) const {
                        4: branch 1 taken
                       68: branch 2 taken
     562               72:   do {
     563               72:     std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
     564                 :     Loc = getSLocEntry(LocInfo.first).getInstantiation()
     565               72:                    .getInstantiationLocStart();
     566               72:     Loc = Loc.getFileLocWithOffset(LocInfo.second);
     567                 :   } while (!Loc.isFileID());
     568                 : 
     569               68:   return Loc;
     570                 : }
     571                 : 
     572              592: SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const {
                        8: branch 1 taken
                      584: branch 2 taken
     573              592:   do {
     574              592:     std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
     575              592:     Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
     576              592:     Loc = Loc.getFileLocWithOffset(LocInfo.second);
     577                 :   } while (!Loc.isFileID());
     578              584:   return Loc;
     579                 : }
     580                 : 
     581                 : 
     582                 : std::pair<FileID, unsigned>
     583                 : SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
     584              525:                                                      unsigned Offset) const {
     585                 :   // If this is an instantiation record, walk through all the instantiation
     586                 :   // points.
     587              525:   FileID FID;
     588              525:   SourceLocation Loc;
                       35: branch 1 taken
                      525: branch 2 taken
     589              560:   do {
     590              560:     Loc = E->getInstantiation().getInstantiationLocStart();
     591                 : 
     592              560:     FID = getFileID(Loc);
     593              560:     E = &getSLocEntry(FID);
     594              560:     Offset += Loc.getOffset()-E->getOffset();
     595                 :   } while (!Loc.isFileID());
     596                 : 
     597              525:   return std::make_pair(FID, Offset);
     598                 : }
     599                 : 
     600                 : std::pair<FileID, unsigned>
     601                 : SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
     602             2171:                                                 unsigned Offset) const {
     603                 :   // If this is an instantiation record, walk through all the instantiation
     604                 :   // points.
     605             2171:   FileID FID;
     606             2171:   SourceLocation Loc;
                      996: branch 1 taken
                     2171: branch 2 taken
     607             3167:   do {
     608             3167:     Loc = E->getInstantiation().getSpellingLoc();
     609                 : 
     610             3167:     FID = getFileID(Loc);
     611             3167:     E = &getSLocEntry(FID);
     612             3167:     Offset += Loc.getOffset()-E->getOffset();
     613                 :   } while (!Loc.isFileID());
     614                 : 
     615             2171:   return std::make_pair(FID, Offset);
     616                 : }
     617                 : 
     618                 : /// getImmediateSpellingLoc - Given a SourceLocation object, return the
     619                 : /// spelling location referenced by the ID.  This is the first level down
     620                 : /// towards the place where the characters that make up the lexed token can be
     621                 : /// found.  This should not generally be used by clients.
     622               31: SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{
                        0: branch 1 not taken
                       31: branch 2 taken
     623               31:   if (Loc.isFileID()) return Loc;
     624               31:   std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
     625               31:   Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
     626               31:   return Loc.getFileLocWithOffset(LocInfo.second);
     627                 : }
     628                 : 
     629                 : 
     630                 : /// getImmediateInstantiationRange - Loc is required to be an instantiation
     631                 : /// location.  Return the start/end of the instantiation information.
     632                 : std::pair<SourceLocation,SourceLocation>
     633              228: SourceManager::getImmediateInstantiationRange(SourceLocation Loc) const {
                      228: branch 1 taken
                        0: branch 2 not taken
     634              228:   assert(Loc.isMacroID() && "Not an instantiation loc!");
     635              228:   const InstantiationInfo &II = getSLocEntry(getFileID(Loc)).getInstantiation();
     636              228:   return II.getInstantiationLocRange();
     637                 : }
     638                 : 
     639                 : /// getInstantiationRange - Given a SourceLocation object, return the
     640                 : /// range of tokens covered by the instantiation in the ultimate file.
     641                 : std::pair<SourceLocation,SourceLocation>
     642               99: SourceManager::getInstantiationRange(SourceLocation Loc) const {
                       11: branch 1 taken
                       88: branch 2 taken
     643               99:   if (Loc.isFileID()) return std::make_pair(Loc, Loc);
     644                 : 
     645                 :   std::pair<SourceLocation,SourceLocation> Res =
     646               88:     getImmediateInstantiationRange(Loc);
     647                 : 
     648                 :   // Fully resolve the start and end locations to their ultimate instantiation
     649                 :   // points.
                       30: branch 1 taken
                       88: branch 2 taken
     650              206:   while (!Res.first.isFileID())
     651               30:     Res.first = getImmediateInstantiationRange(Res.first).first;
                       30: branch 1 taken
                       88: branch 2 taken
     652              206:   while (!Res.second.isFileID())
     653               30:     Res.second = getImmediateInstantiationRange(Res.second).second;
     654               88:   return Res;
     655                 : }
     656                 : 
     657                 : 
     658                 : 
     659                 : //===----------------------------------------------------------------------===//
     660                 : // Queries about the code at a SourceLocation.
     661                 : //===----------------------------------------------------------------------===//
     662                 : 
     663                 : /// getCharacterData - Return a pointer to the start of the specified location
     664                 : /// in the appropriate MemoryBuffer.
     665           136419: const char *SourceManager::getCharacterData(SourceLocation SL) const {
     666                 :   // Note that this is a hot function in the getSpelling() path, which is
     667                 :   // heavily used by -E mode.
     668           136419:   std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL);
     669                 : 
     670                 :   // Note that calling 'getBuffer()' may lazily page in a source file.
     671                 :   return getSLocEntry(LocInfo.first).getFile().getContentCache()
     672           136419:               ->getBuffer()->getBufferStart() + LocInfo.second;
     673                 : }
     674                 : 
     675                 : 
     676                 : /// getColumnNumber - Return the column # for the specified file position.
     677                 : /// this is significantly cheaper to compute than the line number.
     678            13770: unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos) const {
     679            13770:   const char *Buf = getBuffer(FID)->getBufferStart();
     680                 : 
     681            13770:   unsigned LineStart = FilePos;
                   159178: branch 0 taken
                     1419: branch 1 taken
                   146827: branch 2 taken
                    12351: branch 3 taken
                   146827: branch 4 taken
                        0: branch 5 not taken
     682           174367:   while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
     683           146827:     --LineStart;
     684            13770:   return FilePos-LineStart+1;
     685                 : }
     686                 : 
     687                0: unsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc) const {
                        0: branch 1 not taken
                        0: branch 2 not taken
     688                0:   if (Loc.isInvalid()) return 0;
     689                0:   std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
     690                0:   return getColumnNumber(LocInfo.first, LocInfo.second);
     691                 : }
     692                 : 
     693             3637: unsigned SourceManager::getInstantiationColumnNumber(SourceLocation Loc) const {
                        0: branch 1 not taken
                     3637: branch 2 taken
     694             3637:   if (Loc.isInvalid()) return 0;
     695             3637:   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
     696             3637:   return getColumnNumber(LocInfo.first, LocInfo.second);
     697                 : }
     698                 : 
     699                 : 
     700                 : 
     701                 : static DISABLE_INLINE void ComputeLineNumbers(ContentCache* FI,
     702                 :                                               llvm::BumpPtrAllocator &Alloc);
     703             3989: static void ComputeLineNumbers(ContentCache* FI, llvm::BumpPtrAllocator &Alloc){
     704                 :   // Note that calling 'getBuffer()' may lazily page in the file.
     705             3989:   const MemoryBuffer *Buffer = FI->getBuffer();
     706                 : 
     707                 :   // Find the file offsets of all of the *physical* source lines.  This does
     708                 :   // not look at trigraphs, escaped newlines, or anything else tricky.
     709             3989:   std::vector<unsigned> LineOffsets;
     710                 : 
     711                 :   // Line #1 starts at char 0.
     712             3989:   LineOffsets.push_back(0);
     713                 : 
     714             3989:   const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
     715             3989:   const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
     716             3989:   unsigned Offs = 0;
     717           395031:   while (1) {
     718                 :     // Skip over the contents of the line.
     719                 :     // TODO: Vectorize this?  This is very performance sensitive for programs
     720                 :     // with lots of diagnostics and in -E mode.
     721           399020:     const unsigned char *NextBuf = (const unsigned char *)Buf;
                 11148829: branch 0 taken
                   381577: branch 1 taken
                 11148829: branch 2 taken
                        0: branch 3 not taken
                 11131386: branch 4 taken
                    17443: branch 5 taken
     722         11929426:     while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
     723         11131386:       ++NextBuf;
     724           399020:     Offs += NextBuf-Buf;
     725           399020:     Buf = NextBuf;
     726                 : 
                    17443: branch 0 taken
                   381577: branch 1 taken
                        0: branch 2 not taken
                    17443: branch 3 taken
     727           780597:     if (Buf[0] == '\n' || Buf[0] == '\r') {
     728                 :       // If this is \n\r or \r\n, skip both characters.
                   365105: branch 0 taken
                    16472: branch 1 taken
                        0: branch 2 not taken
                   365105: branch 3 taken
                        0: branch 4 not taken
                    16472: branch 5 taken
     729           381577:       if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
     730                0:         ++Offs, ++Buf;
     731           381577:       ++Offs, ++Buf;
     732           381577:       LineOffsets.push_back(Offs);
     733                 :     } else {
     734                 :       // Otherwise, this is a null.  If end of file, exit.
                    13454: branch 0 taken
                     3989: branch 1 taken
     735            17443:       if (Buf == End) break;
     736                 :       // Otherwise, skip the null.
     737            13454:       ++Offs, ++Buf;
     738                 :     }
     739                 :   }
     740                 : 
     741                 :   // Copy the offsets into the FileInfo structure.
     742             3989:   FI->NumLines = LineOffsets.size();
     743             3989:   FI->SourceLineCache = Alloc.Allocate<unsigned>(LineOffsets.size());
     744             3989:   std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
     745             3989: }
     746                 : 
     747                 : /// getLineNumber - Given a SourceLocation, return the spelling line number
     748                 : /// for the position indicated.  This requires building and caching a table of
     749                 : /// line offsets for the MemoryBuffer, so this is not cheap: use only when
     750                 : /// about to emit a diagnostic.
     751            37024: unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos) const {
     752                 :   ContentCache *Content;
                    32559: branch 1 taken
                     4465: branch 2 taken
     753            37024:   if (LastLineNoFileIDQuery == FID)
     754            32559:     Content = LastLineNoContentCache;
     755                 :   else
     756                 :     Content = const_cast<ContentCache*>(getSLocEntry(FID)
     757             4465:                                         .getFile().getContentCache());
     758                 : 
     759                 :   // If this is the first use of line information for this buffer, compute the
     760                 :   /// SourceLineCache for it on demand.
                     3964: branch 0 taken
                    33060: branch 1 taken
     761            37024:   if (Content->SourceLineCache == 0)
     762             3964:     ComputeLineNumbers(Content, ContentCacheAlloc);
     763                 : 
     764                 :   // Okay, we know we have a line number table.  Do a binary search to find the
     765                 :   // line number that this character position lands on.
     766            37024:   unsigned *SourceLineCache = Content->SourceLineCache;
     767            37024:   unsigned *SourceLineCacheStart = SourceLineCache;
     768            37024:   unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
     769                 : 
     770            37024:   unsigned QueriedFilePos = FilePos+1;
     771                 : 
     772                 :   // FIXME: I would like to be convinced that this code is worth being as
     773                 :   // complicated as it is, binary search isn't that slow.
     774                 :   //
     775                 :   // If it is worth being optimized, then in my opinion it could be more
     776                 :   // performant, simpler, and more obviously correct by just "galloping" outward
     777                 :   // from the queried file position. In fact, this could be incorporated into a
     778                 :   // generic algorithm such as lower_bound_with_hint.
     779                 :   //
     780                 :   // If someone gives me a test case where this matters, and I will do it! - DWD
     781                 : 
     782                 :   // If the previous query was to the same file, we know both the file pos from
     783                 :   // that query and the line number returned.  This allows us to narrow the
     784                 :   // search space from the entire file to something near the match.
                    32559: branch 1 taken
                     4465: branch 2 taken
     785            37024:   if (LastLineNoFileIDQuery == FID) {
                    19553: branch 0 taken
                    13006: branch 1 taken
     786            32559:     if (QueriedFilePos >= LastLineNoFilePos) {
     787                 :       // FIXME: Potential overflow?
     788            19553:       SourceLineCache = SourceLineCache+LastLineNoResult-1;
     789                 : 
     790                 :       // The query is likely to be nearby the previous one.  Here we check to
     791                 :       // see if it is within 5, 10 or 20 lines.  It can be far away in cases
     792                 :       // where big comment blocks and vertical whitespace eat up lines but
     793                 :       // contribute no tokens.
                    16933: branch 0 taken
                     2620: branch 1 taken
     794            19553:       if (SourceLineCache+5 < SourceLineCacheEnd) {
                    11824: branch 0 taken
                     5109: branch 1 taken
     795            16933:         if (SourceLineCache[5] > QueriedFilePos)
     796            11824:           SourceLineCacheEnd = SourceLineCache+5;
                     4973: branch 0 taken
                      136: branch 1 taken
     797             5109:         else if (SourceLineCache+10 < SourceLineCacheEnd) {
                     1693: branch 0 taken
                     3280: branch 1 taken
     798             4973:           if (SourceLineCache[10] > QueriedFilePos)
     799             1693:             SourceLineCacheEnd = SourceLineCache+10;
                     3111: branch 0 taken
                      169: branch 1 taken
     800             3280:           else if (SourceLineCache+20 < SourceLineCacheEnd) {
                      984: branch 0 taken
                     2127: branch 1 taken
     801             3111:             if (SourceLineCache[20] > QueriedFilePos)
     802              984:               SourceLineCacheEnd = SourceLineCache+20;
     803                 :           }
     804                 :         }
     805                 :       }
     806                 :     } else {
                    13005: branch 0 taken
                        1: branch 1 taken
     807            13006:       if (LastLineNoResult < Content->NumLines)
     808            13005:         SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
     809                 :     }
     810                 :   }
     811                 : 
     812                 :   // If the spread is large, do a "radix" test as our initial guess, based on
     813                 :   // the assumption that lines average to approximately the same length.
     814                 :   // NOTE: This is currently disabled, as it does not appear to be profitable in
     815                 :   // initial measurements.
     816                 :   if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
     817                 :     unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];
     818                 : 
     819                 :     // Take a stab at guessing where it is.
     820                 :     unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;
     821                 : 
     822                 :     // Check for -10 and +10 lines.
     823                 :     unsigned LowerBound = std::max(int(ApproxPos-10), 0);
     824                 :     unsigned UpperBound = std::min(ApproxPos+10, FileLen);
     825                 : 
     826                 :     // If the computed lower bound is less than the query location, move it in.
     827                 :     if (SourceLineCache < SourceLineCacheStart+LowerBound &&
     828                 :         SourceLineCacheStart[LowerBound] < QueriedFilePos)
     829                 :       SourceLineCache = SourceLineCacheStart+LowerBound;
     830                 : 
     831                 :     // If the computed upper bound is greater than the query location, move it.
     832                 :     if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
     833                 :         SourceLineCacheStart[UpperBound] >= QueriedFilePos)
     834                 :       SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
     835                 :   }
     836                 : 
     837                 :   unsigned *Pos
     838            37024:     = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
     839            37024:   unsigned LineNo = Pos-SourceLineCacheStart;
     840                 : 
     841            37024:   LastLineNoFileIDQuery = FID;
     842            37024:   LastLineNoContentCache = Content;
     843            37024:   LastLineNoFilePos = QueriedFilePos;
     844            37024:   LastLineNoResult = LineNo;
     845            37024:   return LineNo;
     846                 : }
     847                 : 
     848            22822: unsigned SourceManager::getInstantiationLineNumber(SourceLocation Loc) const {
                       18: branch 1 taken
                    22804: branch 2 taken
     849            22822:   if (Loc.isInvalid()) return 0;
     850            22804:   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
     851            22804:   return getLineNumber(LocInfo.first, LocInfo.second);
     852                 : }
     853                0: unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc) const {
                        0: branch 1 not taken
                        0: branch 2 not taken
     854                0:   if (Loc.isInvalid()) return 0;
     855                0:   std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
     856                0:   return getLineNumber(LocInfo.first, LocInfo.second);
     857                 : }
     858                 : 
     859                 : /// getFileCharacteristic - return the file characteristic of the specified
     860                 : /// source location, indicating whether this is a normal file, a system
     861                 : /// header, or an "implicit extern C" system header.
     862                 : ///
     863                 : /// This state can be modified with flags on GNU linemarker directives like:
     864                 : ///   # 4 "foo.h" 3
     865                 : /// which changes all source locations in the current file after that to be
     866                 : /// considered to be from a system header.
     867                 : SrcMgr::CharacteristicKind
     868             8443: SourceManager::getFileCharacteristic(SourceLocation Loc) const {
                     8443: branch 1 taken
                        0: branch 2 not taken
     869             8443:   assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!");
     870             8443:   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
     871             8443:   const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile();
     872                 : 
     873                 :   // If there are no #line directives in this file, just return the whole-file
     874                 :   // state.
                     8243: branch 1 taken
                      200: branch 2 taken
     875             8443:   if (!FI.hasLineDirectives())
     876             8243:     return FI.getFileCharacteristic();
     877                 : 
                        0: branch 0 not taken
                      200: branch 1 taken
     878              200:   assert(LineTable && "Can't have linetable entries without a LineTable!");
     879                 :   // See if there is a #line directive before the location.
     880                 :   const LineEntry *Entry =
     881              200:     LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second);
     882                 : 
     883                 :   // If this is before the first line marker, use the file characteristic.
                        0: branch 0 not taken
                      200: branch 1 taken
     884              200:   if (!Entry)
     885                0:     return FI.getFileCharacteristic();
     886                 : 
     887              200:   return Entry->FileKind;
     888                 : }
     889                 : 
     890                 : /// Return the filename or buffer identifier of the buffer the location is in.
     891                 : /// Note that this name does not respect #line directives.  Use getPresumedLoc
     892                 : /// for normal clients.
     893                1: const char *SourceManager::getBufferName(SourceLocation Loc) const {
                        0: branch 1 not taken
                        1: branch 2 taken
     894                1:   if (Loc.isInvalid()) return "<invalid loc>";
     895                 : 
     896                1:   return getBuffer(getFileID(Loc))->getBufferIdentifier();
     897                 : }
     898                 : 
     899                 : 
     900                 : /// getPresumedLoc - This method returns the "presumed" location of a
     901                 : /// SourceLocation specifies.  A "presumed location" can be modified by #line
     902                 : /// or GNU line marker directives.  This provides a view on the data that a
     903                 : /// user should see in diagnostics, for example.
     904                 : ///
     905                 : /// Note that a presumed location is always given as the instantiation point
     906                 : /// of an instantiation location, not at the spelling location.
     907             9388: PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
                       85: branch 1 taken
                     9303: branch 2 taken
     908             9388:   if (Loc.isInvalid()) return PresumedLoc();
     909                 : 
     910                 :   // Presumed locations are always for instantiation points.
     911             9303:   std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
     912                 : 
     913             9303:   const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile();
     914             9303:   const SrcMgr::ContentCache *C = FI.getContentCache();
     915                 : 
     916                 :   // To get the source name, first consult the FileEntry (if one exists)
     917                 :   // before the MemBuffer as this will avoid unnecessarily paging in the
     918                 :   // MemBuffer.
     919                 :   const char *Filename =
                     4500: branch 0 taken
                     4803: branch 1 taken
     920             9303:     C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
     921             9303:   unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second);
     922             9303:   unsigned ColNo  = getColumnNumber(LocInfo.first, LocInfo.second);
     923             9303:   SourceLocation IncludeLoc = FI.getIncludeLoc();
     924                 : 
     925                 :   // If we have #line directives in this file, update and overwrite the physical
     926                 :   // location info if appropriate.
                     4439: branch 1 taken
                     4864: branch 2 taken
     927             9303:   if (FI.hasLineDirectives()) {
                        0: branch 0 not taken
                     4439: branch 1 taken
     928             4439:     assert(LineTable && "Can't have linetable entries without a LineTable!");
     929                 :     // See if there is a #line directive before this.  If so, get it.
                     4437: branch 0 taken
                        2: branch 1 taken
     930             4439:     if (const LineEntry *Entry =
     931             4439:           LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second)) {
     932                 :       // If the LineEntry indicates a filename, use it.
                     4431: branch 0 taken
                        6: branch 1 taken
     933             4437:       if (Entry->FilenameID != -1)
     934             4431:         Filename = LineTable->getFilename(Entry->FilenameID);
     935                 : 
     936                 :       // Use the line number specified by the LineEntry.  This line number may
     937                 :       // be multiple lines down from the line entry.  Add the difference in
     938                 :       // physical line numbers from the query point and the line marker to the
     939                 :       // total.
     940             4437:       unsigned MarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset);
     941             4437:       LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
     942                 : 
     943                 :       // Note that column numbers are not molested by line markers.
     944                 : 
     945                 :       // Handle virtual #include manipulation.
                     2935: branch 0 taken
                     1502: branch 1 taken
     946             4437:       if (Entry->IncludeOffset) {
     947             2935:         IncludeLoc = getLocForStartOfFile(LocInfo.first);
     948             2935:         IncludeLoc = IncludeLoc.getFileLocWithOffset(Entry->IncludeOffset);
     949                 :       }
     950                 :     }
     951                 :   }
     952                 : 
     953             9303:   return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc);
     954                 : }
     955                 : 
     956                 : //===----------------------------------------------------------------------===//
     957                 : // Other miscellaneous methods.
     958                 : //===----------------------------------------------------------------------===//
     959                 : 
     960                 : /// \brief Get the source location for the given file:line:col triplet.
     961                 : ///
     962                 : /// If the source file is included multiple times, the source location will
     963                 : /// be based upon the first inclusion.
     964                 : SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
     965            12909:                                           unsigned Line, unsigned Col) const {
                        0: branch 0 not taken
                    12909: branch 1 taken
     966            12909:   assert(SourceFile && "Null source file!");
                    12909: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                    12909: branch 3 taken
     967            12909:   assert(Line && Col && "Line and column should start from 1!");
     968                 : 
     969            12909:   fileinfo_iterator FI = FileInfos.find(SourceFile);
                        0: branch 2 not taken
                    12909: branch 3 taken
     970            12909:   if (FI == FileInfos.end())
     971                0:     return SourceLocation();
     972            12909:   ContentCache *Content = FI->second;
     973                 : 
     974                 :   // If this is the first use of line information for this buffer, compute the
     975                 :   /// SourceLineCache for it on demand.
                       25: branch 0 taken
                    12884: branch 1 taken
     976            12909:   if (Content->SourceLineCache == 0)
     977               25:     ComputeLineNumbers(Content, ContentCacheAlloc);
     978                 : 
                        0: branch 0 not taken
                    12909: branch 1 taken
     979            12909:   if (Line > Content->NumLines)
     980                0:     return SourceLocation();
     981                 : 
     982            12909:   unsigned FilePos = Content->SourceLineCache[Line - 1];
     983            12909:   const char *Buf = Content->getBuffer()->getBufferStart() + FilePos;
     984            12909:   unsigned BufLength = Content->getBuffer()->getBufferEnd() - Buf;
     985            12909:   unsigned i = 0;
     986                 : 
     987                 :   // Check that the given column is valid.
                   559657: branch 0 taken
                        3: branch 1 taken
                   546751: branch 2 taken
                    12906: branch 3 taken
                   546751: branch 4 taken
                        0: branch 5 not taken
                   546751: branch 6 taken
                        0: branch 7 not taken
     988           572569:   while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r')
     989           546751:     ++i;
                        0: branch 0 not taken
                    12909: branch 1 taken
     990            12909:   if (i < Col-1)
     991                0:     return SourceLocation();
     992                 : 
     993                 :   // Find the first file ID that corresponds to the given file.
     994            12909:   FileID FirstFID;
     995                 : 
     996                 :   // First, check the main file ID, since it is common to look for a
     997                 :   // location in the main file.
                        6: branch 1 taken
                    12903: branch 2 taken
     998            12909:   if (!MainFileID.isInvalid()) {
     999                6:     const SLocEntry &MainSLoc = getSLocEntry(MainFileID);
                        6: branch 1 taken
                        0: branch 2 not taken
                        6: branch 5 taken
                        0: branch 6 not taken
                        6: branch 7 taken
                        0: branch 8 not taken
    1000                6:     if (MainSLoc.isFile() && MainSLoc.getFile().getContentCache() == Content)
    1001                6:       FirstFID = MainFileID;
    1002                 :   }
    1003                 : 
                    12903: branch 1 taken
                        6: branch 2 taken
    1004            12909:   if (FirstFID.isInvalid()) {
    1005                 :     // The location we're looking for isn't in the main file; look
    1006                 :     // through all of the source locations.
                    25806: branch 1 taken
                        0: branch 2 not taken
    1007            25806:     for (unsigned I = 0, N = sloc_entry_size(); I != N; ++I) {
    1008            25806:       const SLocEntry &SLoc = getSLocEntry(I);
                    12903: branch 1 taken
                    12903: branch 2 taken
                    12903: branch 5 taken
                        0: branch 6 not taken
                    12903: branch 7 taken
                    12903: branch 8 taken
    1009            25806:       if (SLoc.isFile() && SLoc.getFile().getContentCache() == Content) {
    1010            12903:         FirstFID = FileID::get(I);
    1011            12903:         break;
    1012                 :       }
    1013                 :     }
    1014                 :   }
    1015                 :     
                        0: branch 1 not taken
                    12909: branch 2 taken
    1016            12909:   if (FirstFID.isInvalid())
    1017                0:     return SourceLocation();
    1018                 : 
    1019            12909:   return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + Col - 1);
    1020                 : }
    1021                 : 
    1022                 : /// \brief Determines the order of 2 source locations in the translation unit.
    1023                 : ///
    1024                 : /// \returns true if LHS source location comes before RHS, false otherwise.
    1025                 : bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
    1026           127005:                                               SourceLocation RHS) const {
                   127005: branch 1 taken
                        0: branch 2 not taken
                   127005: branch 4 taken
                        0: branch 5 not taken
    1027           127005:   assert(LHS.isValid() && RHS.isValid() && "Passed invalid source location!");
                      107: branch 1 taken
                   126898: branch 2 taken
    1028           127005:   if (LHS == RHS)
    1029              107:     return false;
    1030                 : 
    1031           126898:   std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS);
    1032           126898:   std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS);
    1033                 : 
    1034                 :   // If the source locations are in the same file, just compare offsets.
                    88430: branch 1 taken
                    38468: branch 2 taken
    1035           126898:   if (LOffs.first == ROffs.first)
    1036            88430:     return LOffs.second < ROffs.second;
    1037                 : 
    1038                 :   // If we are comparing a source location with multiple locations in the same
    1039                 :   // file, we get a big win by caching the result.
    1040                 : 
                    38462: branch 1 taken
                        6: branch 2 taken
                    38462: branch 4 taken
                        0: branch 5 not taken
                    38462: branch 6 taken
                        6: branch 7 taken
    1041            38468:   if (LastLFIDForBeforeTUCheck == LOffs.first &&
    1042                 :       LastRFIDForBeforeTUCheck == ROffs.first)
    1043            38462:     return LastResForBeforeTUCheck;
    1044                 : 
    1045                6:   LastLFIDForBeforeTUCheck = LOffs.first;
    1046                6:   LastRFIDForBeforeTUCheck = ROffs.first;
    1047                 : 
    1048                 :   // "Traverse" the include/instantiation stacks of both locations and try to
    1049                 :   // find a common "ancestor".
    1050                 :   //
    1051                 :   // First we traverse the stack of the right location and check each level
    1052                 :   // against the level of the left location, while collecting all levels in a
    1053                 :   // "stack map".
    1054                 : 
    1055                6:   std::map<FileID, unsigned> ROffsMap;
    1056                6:   ROffsMap[ROffs.first] = ROffs.second;
    1057                 : 
    1058                0:   while (1) {
    1059                6:     SourceLocation UpperLoc;
    1060                6:     const SrcMgr::SLocEntry &Entry = getSLocEntry(ROffs.first);
                        0: branch 1 not taken
                        6: branch 2 taken
    1061                6:     if (Entry.isInstantiation())
    1062                0:       UpperLoc = Entry.getInstantiation().getInstantiationLocStart();
    1063                 :     else
    1064                6:       UpperLoc = Entry.getFile().getIncludeLoc();
    1065                 : 
                        0: branch 1 not taken
                        6: branch 2 taken
    1066                6:     if (UpperLoc.isInvalid())
    1067                6:       break; // We reached the top.
    1068                 : 
    1069                0:     ROffs = getDecomposedLoc(UpperLoc);
    1070                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
    1071                0:     if (LOffs.first == ROffs.first)
    1072                0:       return LastResForBeforeTUCheck = LOffs.second < ROffs.second;
    1073                 : 
    1074                0:     ROffsMap[ROffs.first] = ROffs.second;
    1075                 :   }
    1076                 : 
    1077                 :   // We didn't find a common ancestor. Now traverse the stack of the left
    1078                 :   // location, checking against the stack map of the right location.
    1079                 : 
    1080                0:   while (1) {
    1081                6:     SourceLocation UpperLoc;
    1082                6:     const SrcMgr::SLocEntry &Entry = getSLocEntry(LOffs.first);
                        0: branch 1 not taken
                        6: branch 2 taken
    1083                6:     if (Entry.isInstantiation())
    1084                0:       UpperLoc = Entry.getInstantiation().getInstantiationLocStart();
    1085                 :     else
    1086                6:       UpperLoc = Entry.getFile().getIncludeLoc();
    1087                 : 
                        0: branch 1 not taken
                        6: branch 2 taken
    1088                6:     if (UpperLoc.isInvalid())
    1089                6:       break; // We reached the top.
    1090                 : 
    1091                0:     LOffs = getDecomposedLoc(UpperLoc);
    1092                 : 
    1093                0:     std::map<FileID, unsigned>::iterator I = ROffsMap.find(LOffs.first);
                        0: branch 2 not taken
                        0: branch 3 not taken
    1094                0:     if (I != ROffsMap.end())
    1095                0:       return LastResForBeforeTUCheck = LOffs.second < I->second;
    1096                 :   }
    1097                 : 
    1098                 :   // There is no common ancestor, most probably because one location is in the
    1099                 :   // predefines buffer.
    1100                 :   //
    1101                 :   // FIXME: We should rearrange the external interface so this simply never
    1102                 :   // happens; it can't conceptually happen. Also see PR5662.
    1103                 : 
    1104                 :   // If exactly one location is a memory buffer, assume it preceeds the other.
    1105                6:   bool LIsMB = !getSLocEntry(LOffs.first).getFile().getContentCache()->Entry;
    1106                6:   bool RIsMB = !getSLocEntry(ROffs.first).getFile().getContentCache()->Entry;
                        6: branch 0 taken
                        0: branch 1 not taken
    1107                6:   if (LIsMB != RIsMB)
    1108                6:     return LastResForBeforeTUCheck = LIsMB;
    1109                 : 
    1110                 :   // Otherwise, just assume FileIDs were created in order.
    1111                0:   return LastResForBeforeTUCheck = (LOffs.first < ROffs.first);
    1112                 : }
    1113                 : 
    1114                 : /// PrintStats - Print statistics to stderr.
    1115                 : ///
    1116                2: void SourceManager::PrintStats() const {
    1117                2:   llvm::errs() << "\n*** Source Manager Stats:\n";
    1118                 :   llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
    1119                2:                << " mem buffers mapped.\n";
    1120                 :   llvm::errs() << SLocEntryTable.size() << " SLocEntry's allocated, "
    1121                2:                << NextOffset << "B of Sloc address space used.\n";
    1122                 : 
    1123                2:   unsigned NumLineNumsComputed = 0;
    1124                2:   unsigned NumFileBytesMapped = 0;
                        2: branch 4 taken
                        2: branch 5 taken
    1125                4:   for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){
    1126                2:     NumLineNumsComputed += I->second->SourceLineCache != 0;
    1127                2:     NumFileBytesMapped  += I->second->getSizeBytesMapped();
    1128                 :   }
    1129                 : 
    1130                 :   llvm::errs() << NumFileBytesMapped << " bytes of files mapped, "
    1131                2:                << NumLineNumsComputed << " files with line #'s computed.\n";
    1132                 :   llvm::errs() << "FileID scans: " << NumLinearScans << " linear, "
    1133                2:                << NumBinaryProbes << " binary.\n";
    1134                2: }
    1135                 : 
                       44: branch 0 taken
                       44: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 6 not taken
                       44: branch 7 taken
    1136               44: ExternalSLocEntrySource::~ExternalSLocEntrySource() { }

Generated: 2010-02-10 01:31 by zcov