diff options
Diffstat (limited to 'lib/Basic/SourceManager.cpp')
| -rw-r--r-- | lib/Basic/SourceManager.cpp | 96 | 
1 files changed, 63 insertions, 33 deletions
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index cef091c5983b..9ec247429945 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -71,7 +71,7 @@ unsigned ContentCache::getSize() const {  void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B,                                   bool DoNotFree) { -  if (B == Buffer.getPointer()) { +  if (B && B == Buffer.getPointer()) {      assert(0 && "Replacing with the same buffer");      Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);      return; @@ -97,7 +97,10 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,    }        std::string ErrorStr; -  Buffer.setPointer(SM.getFileManager().getBufferForFile(ContentsEntry, &ErrorStr)); +  bool isVolatile = SM.userFilesAreVolatile() && !IsSystemFile; +  Buffer.setPointer(SM.getFileManager().getBufferForFile(ContentsEntry, +                                                         &ErrorStr, +                                                         isVolatile));    // If we were unable to open the file, then we are in an inconsistent    // situation where the content cache referenced a file which no longer @@ -189,9 +192,9 @@ unsigned LineTableInfo::getLineTableFilenameID(StringRef Name) {  }  /// 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 +/// is a \#line at the specified FID/Offset location which changes the presumed  /// location to LineNo/FilenameID. -void LineTableInfo::AddLineNote(int FID, unsigned Offset, +void LineTableInfo::AddLineNote(FileID FID, unsigned Offset,                                  unsigned LineNo, int FilenameID) {    std::vector<LineEntry> &Entries = LineEntries[FID]; @@ -219,10 +222,10 @@ void LineTableInfo::AddLineNote(int FID, unsigned Offset,  /// 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 +/// 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(int FID, unsigned Offset, +void LineTableInfo::AddLineNote(FileID FID, unsigned Offset,                                  unsigned LineNo, int FilenameID,                                  unsigned EntryExit,                                  SrcMgr::CharacteristicKind FileKind) { @@ -256,7 +259,7 @@ void LineTableInfo::AddLineNote(int FID, unsigned Offset,  /// 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(int FID, +const LineEntry *LineTableInfo::FindNearestLineEntry(FileID FID,                                                       unsigned Offset) {    const std::vector<LineEntry> &Entries = LineEntries[FID];    assert(!Entries.empty() && "No #line entries for this FID after all!"); @@ -275,7 +278,7 @@ const LineEntry *LineTableInfo::FindNearestLineEntry(int FID,  /// \brief Add a new line entry that has already been encoded into  /// the internal representation of the line table. -void LineTableInfo::AddEntry(int FID, +void LineTableInfo::AddEntry(FileID FID,                               const std::vector<LineEntry> &Entries) {    LineEntries[FID] = Entries;  } @@ -308,7 +311,7 @@ void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,    if (LineTable == 0)      LineTable = new LineTableInfo(); -  LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID); +  LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID);  }  /// AddLineNote - Add a GNU line marker to the line table. @@ -353,7 +356,7 @@ void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,    else if (IsFileExit)      EntryExit = 2; -  LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID, +  LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,                           EntryExit, FileKind);  } @@ -367,8 +370,10 @@ LineTableInfo &SourceManager::getLineTable() {  // Private 'Create' methods.  //===----------------------------------------------------------------------===// -SourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr) +SourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, +                             bool UserFilesAreVolatile)    : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true), +    UserFilesAreVolatile(UserFilesAreVolatile),      ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),      NumBinaryProbes(0), FakeBufferForRecovery(0),      FakeContentCacheForRecovery(0) { @@ -426,7 +431,8 @@ void SourceManager::clearIDTables() {  /// getOrCreateContentCache - Create or return a cached ContentCache for the  /// specified file.  const ContentCache * -SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) { +SourceManager::getOrCreateContentCache(const FileEntry *FileEnt, +                                       bool isSystemFile) {    assert(FileEnt && "Didn't specify a file entry to use?");    // Do we already have information about this file? @@ -440,16 +446,22 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) {    EntryAlign = std::max(8U, EntryAlign);    Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign); -  // If the file contents are overridden with contents from another file, -  // pass that file to ContentCache. -  llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator -      overI = OverriddenFiles.find(FileEnt); -  if (overI == OverriddenFiles.end()) +  if (OverriddenFilesInfo) { +    // If the file contents are overridden with contents from another file, +    // pass that file to ContentCache. +    llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator +        overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt); +    if (overI == OverriddenFilesInfo->OverriddenFiles.end()) +      new (Entry) ContentCache(FileEnt); +    else +      new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt +                                                              : overI->second, +                               overI->second); +  } else {      new (Entry) ContentCache(FileEnt); -  else -    new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt -                                                            : overI->second, -                             overI->second); +  } + +  Entry->IsSystemFile = isSystemFile;    return Entry;  } @@ -622,6 +634,8 @@ void SourceManager::overrideFileContents(const FileEntry *SourceFile,    const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer, DoNotFree);    const_cast<SrcMgr::ContentCache *>(IR)->BufferOverridden = true; + +  getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);  }  void SourceManager::overrideFileContents(const FileEntry *SourceFile, @@ -632,7 +646,20 @@ void SourceManager::overrideFileContents(const FileEntry *SourceFile,    assert(FileInfos.count(SourceFile) == 0 &&           "This function should be called at the initialization stage, before "           "any parsing occurs."); -  OverriddenFiles[SourceFile] = NewFile; +  getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile; +} + +void SourceManager::disableFileContentsOverride(const FileEntry *File) { +  if (!isFileOverridden(File)) +    return; + +  const SrcMgr::ContentCache *IR = getOrCreateContentCache(File); +  const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(0); +  const_cast<SrcMgr::ContentCache *>(IR)->ContentsEntry = IR->OrigEntry; + +  assert(OverriddenFilesInfo); +  OverriddenFilesInfo->OverriddenFiles.erase(File); +  OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File);  }  StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { @@ -995,9 +1022,10 @@ unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,    if (MyInvalid)      return 1; -  if (FilePos >= MemBuf->getBufferSize()) { +  // It is okay to request a position just past the end of the buffer. +  if (FilePos > MemBuf->getBufferSize()) {      if (Invalid) -      *Invalid = MyInvalid; +      *Invalid = true;      return 1;    } @@ -1295,7 +1323,7 @@ SourceManager::getFileCharacteristic(SourceLocation Loc) const {    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); +    LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second);    // If this is before the first line marker, use the file characteristic.    if (!Entry) @@ -1305,7 +1333,7 @@ SourceManager::getFileCharacteristic(SourceLocation Loc) const {  }  /// Return the filename or buffer identifier of the buffer the location is in. -/// Note that this name does not respect #line directives.  Use getPresumedLoc +/// Note that this name does not respect \#line directives.  Use getPresumedLoc  /// for normal clients.  const char *SourceManager::getBufferName(SourceLocation Loc,                                            bool *Invalid) const { @@ -1316,7 +1344,7 @@ const char *SourceManager::getBufferName(SourceLocation Loc,  /// getPresumedLoc - This method returns the "presumed" location of a -/// SourceLocation specifies.  A "presumed location" can be modified by #line +/// 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.  /// @@ -1360,7 +1388,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {      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)) { +          LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second)) {        // If the LineEntry indicates a filename, use it.        if (Entry->FilenameID != -1)          Filename = LineTable->getFilename(Entry->FilenameID); @@ -1834,8 +1862,6 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,    return LOffs.first < ROffs.first;  } -/// PrintStats - Print statistics to stderr. -///  void SourceManager::PrintStats() const {    llvm::errs() << "\n*** Source Manager Stats:\n";    llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size() @@ -1887,10 +1913,14 @@ SourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const {  }  size_t SourceManager::getDataStructureSizes() const { -  return llvm::capacity_in_bytes(MemBufferInfos) +  size_t size = llvm::capacity_in_bytes(MemBufferInfos)      + llvm::capacity_in_bytes(LocalSLocEntryTable)      + llvm::capacity_in_bytes(LoadedSLocEntryTable)      + llvm::capacity_in_bytes(SLocEntryLoaded) -    + llvm::capacity_in_bytes(FileInfos) -    + llvm::capacity_in_bytes(OverriddenFiles); +    + llvm::capacity_in_bytes(FileInfos); +   +  if (OverriddenFilesInfo) +    size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles); + +  return size;  }  | 
