aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp138
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;