diff options
Diffstat (limited to 'lib/Basic/SourceManager.cpp')
-rw-r--r-- | lib/Basic/SourceManager.cpp | 113 |
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); +} |