diff options
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Basic/SourceManager.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Basic/SourceManager.cpp | 177 |
1 files changed, 112 insertions, 65 deletions
diff --git a/gnu/llvm/tools/clang/lib/Basic/SourceManager.cpp b/gnu/llvm/tools/clang/lib/Basic/SourceManager.cpp index 0a51985614c..efa6ad2493b 100644 --- a/gnu/llvm/tools/clang/lib/Basic/SourceManager.cpp +++ b/gnu/llvm/tools/clang/lib/Basic/SourceManager.cpp @@ -105,9 +105,9 @@ llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, if (Buffer.getPointer() || !ContentsEntry) { if (Invalid) *Invalid = isBufferInvalid(); - + return Buffer.getPointer(); - } + } bool isVolatile = SM.userFilesAreVolatile() && !IsSystemFile; auto BufferOrError = @@ -141,7 +141,7 @@ llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, << ContentsEntry->getName() << BufferOrError.getError().message(); Buffer.setInt(Buffer.getInt() | InvalidFlag); - + if (Invalid) *Invalid = true; return Buffer.getPointer(); } @@ -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") @@ -185,10 +187,10 @@ llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, << InvalidBOM << ContentsEntry->getName(); Buffer.setInt(Buffer.getInt() | InvalidFlag); } - + if (Invalid) *Invalid = isBufferInvalid(); - + return Buffer.getPointer(); } @@ -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, @@ -659,7 +672,7 @@ StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { bool MyInvalid = false; const SLocEntry &SLoc = getSLocEntry(FID, &MyInvalid); if (!SLoc.isFile() || MyInvalid) { - if (Invalid) + if (Invalid) *Invalid = true; return "<<<<<INVALID SOURCE LOCATION>>>>>"; } @@ -671,7 +684,7 @@ StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { if (MyInvalid) return "<<<<<INVALID SOURCE LOCATION>>>>>"; - + return Buf->getBuffer(); } @@ -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. @@ -757,7 +770,7 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { unsigned MidOffset = getLocalSLocEntry(MiddleIndex, &Invalid).getOffset(); if (Invalid) return FileID::get(0); - + ++NumProbes; // If the offset of the midpoint is too large, chop the high side of the @@ -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; } @@ -1083,7 +1104,7 @@ const char *SourceManager::getCharacterData(SourceLocation SL, if (CharDataInvalid || !Entry.isFile()) { if (Invalid) *Invalid = true; - + return "<<<<INVALID BUFFER>>>>"; } llvm::MemoryBuffer *Buffer = Entry.getFile().getContentCache()->getBuffer( @@ -1268,7 +1289,7 @@ FoundSpecialChar: /// for the position indicated. This requires building and caching a table of /// line offsets for the MemoryBuffer, so this is not cheap: use only when /// about to emit a diagnostic. -unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos, +unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos, bool *Invalid) const { if (FID.isInvalid()) { if (Invalid) @@ -1287,10 +1308,10 @@ unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos, *Invalid = true; return 1; } - + Content = const_cast<ContentCache*>(Entry.getFile().getContentCache()); } - + // If this is the first use of line information for this buffer, compute the /// SourceLineCache for it on demand. if (!Content->SourceLineCache) { @@ -1362,7 +1383,7 @@ unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos, return LineNo; } -unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc, +unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc, bool *Invalid) const { if (isInvalid(Loc, Invalid)) return 0; std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc); @@ -1397,7 +1418,7 @@ SourceManager::getFileCharacteristic(SourceLocation Loc) const { const SLocEntry &SEntry = getSLocEntry(LocInfo.first, &Invalid); if (Invalid || !SEntry.isFile()) return C_User; - + const SrcMgr::FileInfo &FI = SEntry.getFile(); // If there are no #line directives in this file, just return the whole-file @@ -1445,7 +1466,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid); if (Invalid || !Entry.isFile()) return PresumedLoc(); - + const SrcMgr::FileInfo &FI = Entry.getFile(); const SrcMgr::ContentCache *C = FI.getContentCache(); @@ -1464,7 +1485,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, unsigned ColNo = getColumnNumber(LocInfo.first, LocInfo.second, &Invalid); if (Invalid) return PresumedLoc(); - + SourceLocation IncludeLoc = FI.getIncludeLoc(); // If we have #line directives in this file, update and overwrite the physical @@ -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. @@ -1600,7 +1621,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid); if (Invalid) return FileID(); - + if (MainSLoc.isFile()) { const ContentCache *MainContentCache = MainSLoc.getFile().getContentCache(); @@ -1637,8 +1658,8 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid); if (Invalid) return FileID(); - - if (SLoc.isFile() && + + if (SLoc.isFile() && SLoc.getFile().getContentCache() && SLoc.getFile().getContentCache()->OrigEntry == SourceFile) { FirstFID = FileID::get(I); @@ -1649,7 +1670,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { if (FirstFID.isInvalid()) { for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) { const SLocEntry &SLoc = getLoadedSLocEntry(I); - if (SLoc.isFile() && + if (SLoc.isFile() && SLoc.getFile().getContentCache() && SLoc.getFile().getContentCache()->OrigEntry == SourceFile) { FirstFID = FileID::get(-int(I) - 2); @@ -1660,7 +1681,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { } // If we haven't found what we want yet, try again, but this time stat() - // each of the files in case the files have changed since we originally + // each of the files in case the files have changed since we originally // parsed the file. if (FirstFID.isInvalid() && (SourceFileName || @@ -1673,13 +1694,13 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { const SLocEntry &SLoc = getSLocEntry(IFileID, &Invalid); if (Invalid) return FileID(); - - if (SLoc.isFile()) { - const ContentCache *FileContentCache + + if (SLoc.isFile()) { + const ContentCache *FileContentCache = SLoc.getFile().getContentCache(); const FileEntry *Entry = FileContentCache ? FileContentCache->OrigEntry : nullptr; - if (Entry && + if (Entry && *SourceFileName == llvm::sys::path::filename(Entry->getName())) { if (Optional<llvm::sys::fs::UniqueID> EntryUID = getActualFileUID(Entry)) { @@ -1691,14 +1712,14 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { } } } - } + } } - + (void) SourceFile; 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. @@ -1927,7 +1948,7 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const { assert(!MacroArgsCache->empty()); MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset); --I; - + unsigned MacroArgBeginOffs = I->first; SourceLocation MacroArgExpandedLoc = I->second; if (MacroArgExpandedLoc.isValid()) @@ -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, @@ -2130,7 +2151,7 @@ void SourceManager::PrintStats() const { << " loaded SLocEntries allocated, " << MaxLoadedOffset - CurrentLoadedOffset << "B of Sloc address space used.\n"; - + unsigned NumLineNumsComputed = 0; unsigned NumFileBytesMapped = 0; for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){ @@ -2210,7 +2231,7 @@ ExternalSLocEntrySource::~ExternalSLocEntrySource() = default; SourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const { size_t malloc_bytes = 0; size_t mmap_bytes = 0; - + for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) if (size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped()) switch (MemBufferInfos[i]->getMemoryBufferKind()) { @@ -2221,7 +2242,7 @@ SourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const { malloc_bytes += sized_mapped; break; } - + return MemoryBufferSizes(malloc_bytes, mmap_bytes); } @@ -2231,9 +2252,35 @@ size_t SourceManager::getDataStructureSizes() const { + llvm::capacity_in_bytes(LoadedSLocEntryTable) + llvm::capacity_in_bytes(SLocEntryLoaded) + llvm::capacity_in_bytes(FileInfos); - + if (OverriddenFilesInfo) size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles); 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); +} |
