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 cef091c..9ec2474 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; } |