summaryrefslogtreecommitdiff
path: root/lib/Basic/SourceManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Basic/SourceManager.cpp')
-rw-r--r--lib/Basic/SourceManager.cpp113
1 files changed, 80 insertions, 33 deletions
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index 0a51985614c80..ae76817826e11 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -170,8 +170,10 @@ llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr)
.StartsWith("\xFE\xFF", "UTF-16 (BE)")
.StartsWith("\xFF\xFE", "UTF-16 (LE)")
- .StartsWith("\x00\x00\xFE\xFF", "UTF-32 (BE)")
- .StartsWith("\xFF\xFE\x00\x00", "UTF-32 (LE)")
+ .StartsWith(llvm::StringLiteral::withInnerNUL("\x00\x00\xFE\xFF"),
+ "UTF-32 (BE)")
+ .StartsWith(llvm::StringLiteral::withInnerNUL("\xFF\xFE\x00\x00"),
+ "UTF-32 (LE)")
.StartsWith("\x2B\x2F\x76", "UTF-7")
.StartsWith("\xF7\x64\x4C", "UTF-1")
.StartsWith("\xDD\x73\x66\x73", "UTF-EBCDIC")
@@ -258,7 +260,7 @@ const LineEntry *LineTableInfo::FindNearestLineEntry(FileID FID,
return &*--I;
}
-/// \brief Add a new line entry that has already been encoded into
+/// Add a new line entry that has already been encoded into
/// the internal representation of the line table.
void LineTableInfo::AddEntry(FileID FID,
const std::vector<LineEntry> &Entries) {
@@ -466,7 +468,7 @@ SourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries,
return std::make_pair(-ID - 1, CurrentLoadedOffset);
}
-/// \brief As part of recovering from missing or changed content, produce a
+/// As part of recovering from missing or changed content, produce a
/// fake, non-empty buffer.
llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
if (!FakeBufferForRecovery)
@@ -476,7 +478,7 @@ llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
return FakeBufferForRecovery.get();
}
-/// \brief As part of recovering from missing or changed content, produce a
+/// As part of recovering from missing or changed content, produce a
/// fake content cache.
const SrcMgr::ContentCache *
SourceManager::getFakeContentCacheForRecovery() const {
@@ -488,7 +490,7 @@ SourceManager::getFakeContentCacheForRecovery() const {
return FakeContentCacheForRecovery.get();
}
-/// \brief Returns the previous in-order FileID or an invalid FileID if there
+/// Returns the previous in-order FileID or an invalid FileID if there
/// is no previous one.
FileID SourceManager::getPreviousFileID(FileID FID) const {
if (FID.isInvalid())
@@ -508,7 +510,7 @@ FileID SourceManager::getPreviousFileID(FileID FID) const {
return FileID::get(ID-1);
}
-/// \brief Returns the next in-order FileID or an invalid FileID if there is
+/// Returns the next in-order FileID or an invalid FileID if there is
/// no next one.
FileID SourceManager::getNextFileID(FileID FID) const {
if (FID.isInvalid())
@@ -577,13 +579,24 @@ SourceManager::createExpansionLoc(SourceLocation SpellingLoc,
SourceLocation ExpansionLocStart,
SourceLocation ExpansionLocEnd,
unsigned TokLength,
+ bool ExpansionIsTokenRange,
int LoadedID,
unsigned LoadedOffset) {
- ExpansionInfo Info = ExpansionInfo::create(SpellingLoc, ExpansionLocStart,
- ExpansionLocEnd);
+ ExpansionInfo Info = ExpansionInfo::create(
+ SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange);
return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
}
+SourceLocation SourceManager::createTokenSplitLoc(SourceLocation Spelling,
+ SourceLocation TokenStart,
+ SourceLocation TokenEnd) {
+ assert(getFileID(TokenStart) == getFileID(TokenEnd) &&
+ "token spans multiple files");
+ return createExpansionLocImpl(
+ ExpansionInfo::createForTokenSplit(Spelling, TokenStart, TokenEnd),
+ TokenEnd.getOffset() - TokenStart.getOffset());
+}
+
SourceLocation
SourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
unsigned TokLength,
@@ -679,7 +692,7 @@ StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
// SourceLocation manipulation methods.
//===----------------------------------------------------------------------===//
-/// \brief Return the FileID for a SourceLocation.
+/// Return the FileID for a SourceLocation.
///
/// This is the cache-miss path of getFileID. Not as hot as that function, but
/// still very important. It is responsible for finding the entry in the
@@ -695,7 +708,7 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
return getFileIDLoaded(SLocOffset);
}
-/// \brief Return the FileID for a SourceLocation with a low offset.
+/// Return the FileID for a SourceLocation with a low offset.
///
/// This function knows that the SourceLocation is in a local buffer, not a
/// loaded one.
@@ -786,7 +799,7 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const {
}
}
-/// \brief Return the FileID for a SourceLocation with a high offset.
+/// Return the FileID for a SourceLocation with a high offset.
///
/// This function knows that the SourceLocation is in a loaded buffer, not a
/// local one.
@@ -893,7 +906,7 @@ SourceLocation SourceManager::getFileLocSlowCase(SourceLocation Loc) const {
if (isMacroArgExpansion(Loc))
Loc = getImmediateSpellingLoc(Loc);
else
- Loc = getImmediateExpansionRange(Loc).first;
+ Loc = getImmediateExpansionRange(Loc).getBegin();
} while (!Loc.isFileID());
return Loc;
}
@@ -948,28 +961,36 @@ SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{
/// getImmediateExpansionRange - Loc is required to be an expansion location.
/// Return the start/end of the expansion information.
-std::pair<SourceLocation,SourceLocation>
+CharSourceRange
SourceManager::getImmediateExpansionRange(SourceLocation Loc) const {
assert(Loc.isMacroID() && "Not a macro expansion loc!");
const ExpansionInfo &Expansion = getSLocEntry(getFileID(Loc)).getExpansion();
return Expansion.getExpansionLocRange();
}
+SourceLocation SourceManager::getTopMacroCallerLoc(SourceLocation Loc) const {
+ while (isMacroArgExpansion(Loc))
+ Loc = getImmediateSpellingLoc(Loc);
+ return Loc;
+}
+
/// getExpansionRange - Given a SourceLocation object, return the range of
/// tokens covered by the expansion in the ultimate file.
-std::pair<SourceLocation,SourceLocation>
-SourceManager::getExpansionRange(SourceLocation Loc) const {
- if (Loc.isFileID()) return std::make_pair(Loc, Loc);
+CharSourceRange SourceManager::getExpansionRange(SourceLocation Loc) const {
+ if (Loc.isFileID())
+ return CharSourceRange(SourceRange(Loc, Loc), true);
- std::pair<SourceLocation,SourceLocation> Res =
- getImmediateExpansionRange(Loc);
+ CharSourceRange Res = getImmediateExpansionRange(Loc);
// Fully resolve the start and end locations to their ultimate expansion
// points.
- while (!Res.first.isFileID())
- Res.first = getImmediateExpansionRange(Res.first).first;
- while (!Res.second.isFileID())
- Res.second = getImmediateExpansionRange(Res.second).second;
+ while (!Res.getBegin().isFileID())
+ Res.setBegin(getImmediateExpansionRange(Res.getBegin()).getBegin());
+ while (!Res.getEnd().isFileID()) {
+ CharSourceRange EndRange = getImmediateExpansionRange(Res.getEnd());
+ Res.setEnd(EndRange.getEnd());
+ Res.setTokenRange(EndRange.isTokenRange());
+ }
return Res;
}
@@ -1498,7 +1519,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc,
return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc);
}
-/// \brief Returns whether the PresumedLoc for a given SourceLocation is
+/// Returns whether the PresumedLoc for a given SourceLocation is
/// in the main file.
///
/// This computes the "presumed" location for a SourceLocation, then checks
@@ -1528,7 +1549,7 @@ bool SourceManager::isInMainFile(SourceLocation Loc) const {
return FI.getIncludeLoc().isInvalid();
}
-/// \brief The size of the SLocEntry that \p FID represents.
+/// The size of the SLocEntry that \p FID represents.
unsigned SourceManager::getFileIDSize(FileID FID) const {
bool Invalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
@@ -1551,7 +1572,7 @@ unsigned SourceManager::getFileIDSize(FileID FID) const {
// Other miscellaneous methods.
//===----------------------------------------------------------------------===//
-/// \brief Retrieve the inode for the given file entry, if possible.
+/// Retrieve the inode for the given file entry, if possible.
///
/// This routine involves a system call, and therefore should only be used
/// in non-performance-critical code.
@@ -1567,7 +1588,7 @@ getActualFileUID(const FileEntry *File) {
return ID;
}
-/// \brief Get the source location for the given file:line:col triplet.
+/// Get the source location for the given file:line:col triplet.
///
/// If the source file is included multiple times, the source location will
/// be based upon an arbitrary inclusion.
@@ -1581,7 +1602,7 @@ SourceLocation SourceManager::translateFileLineCol(const FileEntry *SourceFile,
return translateLineCol(FirstFID, Line, Col);
}
-/// \brief Get the FileID for the given file.
+/// Get the FileID for the given file.
///
/// If the source file is included multiple times, the FileID will be the
/// first inclusion.
@@ -1698,7 +1719,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
return FirstFID;
}
-/// \brief Get the source location in \arg FID for the given line:col.
+/// Get the source location in \arg FID for the given line:col.
/// Returns null location if \arg FID is not a file SLocEntry.
SourceLocation SourceManager::translateLineCol(FileID FID,
unsigned Line,
@@ -1759,7 +1780,7 @@ SourceLocation SourceManager::translateLineCol(FileID FID,
return FileLoc.getLocWithOffset(FilePos + i);
}
-/// \brief Compute a map of macro argument chunks to their expanded source
+/// Compute a map of macro argument chunks to their expanded source
/// location. Chunks that are not part of a macro argument will map to an
/// invalid source location. e.g. if a file contains one macro argument at
/// offset 100 with length 10, this is how the map will be formed:
@@ -1879,7 +1900,7 @@ void SourceManager::associateFileChunkWithMacroArgExp(
// 0 -> SourceLocation()
// 100 -> Expanded loc #1
// 110 -> SourceLocation()
- // and we found a new macro FileID that lexed from offet 105 with length 3,
+ // and we found a new macro FileID that lexed from offset 105 with length 3,
// the new map will be:
// 0 -> SourceLocation()
// 100 -> Expanded loc #1
@@ -1898,7 +1919,7 @@ void SourceManager::associateFileChunkWithMacroArgExp(
MacroArgsCache[EndOffs] = EndOffsMappedLoc;
}
-/// \brief If \arg Loc points inside a function macro argument, the returned
+/// If \arg Loc points inside a function macro argument, the returned
/// location will be the macro location in which the argument was expanded.
/// If a macro argument is used multiple times, the expanded location will
/// be at the first expansion of the argument.
@@ -2007,7 +2028,7 @@ InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID,
return IBTUCacheOverflow;
}
-/// \brief Determines the order of 2 source locations in the translation unit.
+/// Determines the order of 2 source locations in the translation unit.
///
/// \returns true if LHS source location comes before RHS, false otherwise.
bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
@@ -2237,3 +2258,29 @@ size_t SourceManager::getDataStructureSizes() const {
return size;
}
+
+SourceManagerForFile::SourceManagerForFile(StringRef FileName,
+ StringRef Content) {
+ // This is referenced by `FileMgr` and will be released by `FileMgr` when it
+ // is deleted.
+ IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
+ new vfs::InMemoryFileSystem);
+ InMemoryFileSystem->addFile(
+ FileName, 0,
+ llvm::MemoryBuffer::getMemBuffer(Content, FileName,
+ /*RequiresNullTerminator=*/false));
+ // This is passed to `SM` as reference, so the pointer has to be referenced
+ // in `Environment` so that `FileMgr` can out-live this function scope.
+ FileMgr =
+ llvm::make_unique<FileManager>(FileSystemOptions(), InMemoryFileSystem);
+ // This is passed to `SM` as reference, so the pointer has to be referenced
+ // by `Environment` due to the same reason above.
+ Diagnostics = llvm::make_unique<DiagnosticsEngine>(
+ IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
+ new DiagnosticOptions);
+ SourceMgr = llvm::make_unique<SourceManager>(*Diagnostics, *FileMgr);
+ FileID ID = SourceMgr->createFileID(FileMgr->getFile(FileName),
+ SourceLocation(), clang::SrcMgr::C_User);
+ assert(ID.isValid());
+ SourceMgr->setMainFileID(ID);
+}