diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp | 138 |
1 files changed, 57 insertions, 81 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp index 380ca373e69b..3936afab21a4 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp @@ -73,11 +73,11 @@ void ContentCache::replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree) { Buffer.setInt(DoNotFree? DoNotFreeFlag : 0); return; } - + if (shouldFreeBuffer()) delete Buffer.getPointer(); Buffer.setPointer(B); - Buffer.setInt(DoNotFree? DoNotFreeFlag : 0); + Buffer.setInt((B && DoNotFree) ? DoNotFreeFlag : 0); } llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, @@ -183,48 +183,22 @@ unsigned LineTableInfo::getLineTableFilenameID(StringRef Name) { return IterBool.first->second; } -/// AddLineNote - Add a line note to the line table that indicates that there -/// is a \#line at the specified FID/Offset location which changes the presumed -/// location to LineNo/FilenameID. -void LineTableInfo::AddLineNote(FileID FID, unsigned Offset, - unsigned LineNo, int FilenameID) { - std::vector<LineEntry> &Entries = LineEntries[FID]; - - assert((Entries.empty() || Entries.back().FileOffset < Offset) && - "Adding line entries out of order!"); - - SrcMgr::CharacteristicKind Kind = SrcMgr::C_User; - unsigned IncludeOffset = 0; - - if (!Entries.empty()) { - // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember - // that we are still in "foo.h". - if (FilenameID == -1) - FilenameID = Entries.back().FilenameID; - - // If we are after a line marker that switched us to system header mode, or - // that set #include information, preserve it. - Kind = Entries.back().FileKind; - IncludeOffset = Entries.back().IncludeOffset; - } - - Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind, - IncludeOffset)); -} - -/// AddLineNote This is the same as the previous version of AddLineNote, but is -/// used for GNU line markers. If EntryExit is 0, then this doesn't change the -/// presumed \#include stack. If it is 1, this is a file entry, if it is 2 then -/// this is a file exit. FileKind specifies whether this is a system header or -/// extern C system header. -void LineTableInfo::AddLineNote(FileID FID, unsigned Offset, - unsigned LineNo, int FilenameID, - unsigned EntryExit, +/// Add a line note to the line table that indicates that there is a \#line or +/// GNU line marker at the specified FID/Offset location which changes the +/// presumed location to LineNo/FilenameID. If EntryExit is 0, then this doesn't +/// change the presumed \#include stack. If it is 1, this is a file entry, if +/// it is 2 then this is a file exit. FileKind specifies whether this is a +/// system header or extern C system header. +void LineTableInfo::AddLineNote(FileID FID, unsigned Offset, unsigned LineNo, + int FilenameID, unsigned EntryExit, SrcMgr::CharacteristicKind FileKind) { - assert(FilenameID != -1 && "Unspecified filename should use other accessor"); - std::vector<LineEntry> &Entries = LineEntries[FID]; + // An unspecified FilenameID means use the last filename if available, or the + // main source file otherwise. + if (FilenameID == -1 && !Entries.empty()) + FilenameID = Entries.back().FilenameID; + assert((Entries.empty() || Entries.back().FileOffset < Offset) && "Adding line entries out of order!"); @@ -281,47 +255,20 @@ unsigned SourceManager::getLineTableFilenameID(StringRef Name) { return getLineTable().getLineTableFilenameID(Name); } - /// AddLineNote - Add a line note to the line table for the FileID and offset /// specified by Loc. If FilenameID is -1, it is considered to be /// unspecified. void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, - int FilenameID) { - std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); - - bool Invalid = false; - const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid); - if (!Entry.isFile() || Invalid) - return; - - const SrcMgr::FileInfo &FileInfo = Entry.getFile(); - - // Remember that this file has #line directives now if it doesn't already. - const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives(); - - getLineTable().AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID); -} - -/// AddLineNote - Add a GNU line marker to the line table. -void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, bool IsFileEntry, - bool IsFileExit, bool IsSystemHeader, - bool IsExternCHeader) { - // If there is no filename and no flags, this is treated just like a #line, - // which does not change the flags of the previous line marker. - if (FilenameID == -1) { - assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader && - "Can't set flags without setting the filename!"); - return AddLineNote(Loc, LineNo, FilenameID); - } - + bool IsFileExit, + SrcMgr::CharacteristicKind FileKind) { std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc); bool Invalid = false; const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid); if (!Entry.isFile() || Invalid) return; - + const SrcMgr::FileInfo &FileInfo = Entry.getFile(); // Remember that this file has #line directives now if it doesn't already. @@ -329,14 +276,6 @@ void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, (void) getLineTable(); - SrcMgr::CharacteristicKind FileKind; - if (IsExternCHeader) - FileKind = SrcMgr::C_ExternCSystem; - else if (IsSystemHeader) - FileKind = SrcMgr::C_System; - else - FileKind = SrcMgr::C_User; - unsigned EntryExit = 0; if (IsFileEntry) EntryExit = 1; @@ -406,6 +345,34 @@ void SourceManager::clearIDTables() { createExpansionLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1); } +void SourceManager::initializeForReplay(const SourceManager &Old) { + assert(MainFileID.isInvalid() && "expected uninitialized SourceManager"); + + auto CloneContentCache = [&](const ContentCache *Cache) -> ContentCache * { + auto *Clone = new (ContentCacheAlloc.Allocate<ContentCache>()) ContentCache; + Clone->OrigEntry = Cache->OrigEntry; + Clone->ContentsEntry = Cache->ContentsEntry; + Clone->BufferOverridden = Cache->BufferOverridden; + Clone->IsSystemFile = Cache->IsSystemFile; + Clone->IsTransient = Cache->IsTransient; + Clone->replaceBuffer(Cache->getRawBuffer(), /*DoNotFree*/true); + return Clone; + }; + + // Ensure all SLocEntries are loaded from the external source. + for (unsigned I = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I) + if (!Old.SLocEntryLoaded[I]) + Old.loadSLocEntry(I, nullptr); + + // Inherit any content cache data from the old source manager. + for (auto &FileInfo : Old.FileInfos) { + SrcMgr::ContentCache *&Slot = FileInfos[FileInfo.first]; + if (Slot) + continue; + Slot = CloneContentCache(FileInfo.second); + } +} + /// getOrCreateContentCache - Create or return a cached ContentCache for the /// specified file. const ContentCache * @@ -1136,6 +1103,7 @@ unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, return 1; } + const char *Buf = MemBuf->getBufferStart(); // See if we just calculated the line number for this FilePos and can use // that to lookup the start of the line instead of searching for it. if (LastLineNoFileIDQuery == FID && @@ -1144,11 +1112,19 @@ unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, unsigned *SourceLineCache = LastLineNoContentCache->SourceLineCache; unsigned LineStart = SourceLineCache[LastLineNoResult - 1]; unsigned LineEnd = SourceLineCache[LastLineNoResult]; - if (FilePos >= LineStart && FilePos < LineEnd) + if (FilePos >= LineStart && FilePos < LineEnd) { + // LineEnd is the LineStart of the next line. + // A line ends with separator LF or CR+LF on Windows. + // FilePos might point to the last separator, + // but we need a column number at most 1 + the last column. + if (FilePos + 1 == LineEnd && FilePos > LineStart) { + if (Buf[FilePos - 1] == '\r' || Buf[FilePos - 1] == '\n') + --FilePos; + } return FilePos - LineStart + 1; + } } - const char *Buf = MemBuf->getBufferStart(); unsigned LineStart = FilePos; while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r') --LineStart; |
