SourceLoc ClangDiagnosticConsumer::resolveSourceLocation( const clang::SourceManager &clangSrcMgr, clang::SourceLocation clangLoc) { SourceManager &swiftSrcMgr = ImporterImpl.SwiftContext.SourceMgr; SourceLoc loc; clangLoc = clangSrcMgr.getFileLoc(clangLoc); auto decomposedLoc = clangSrcMgr.getDecomposedLoc(clangLoc); if (decomposedLoc.first.isInvalid()) return loc; auto buffer = clangSrcMgr.getBuffer(decomposedLoc.first); unsigned mirrorID; auto mirrorIter = mirroredBuffers.find(buffer); if (mirrorIter != mirroredBuffers.end()) { mirrorID = mirrorIter->second; } else { std::unique_ptr<llvm::MemoryBuffer> mirrorBuffer{ llvm::MemoryBuffer::getMemBuffer(buffer->getBuffer(), buffer->getBufferIdentifier(), /*nullTerminated=*/true) }; mirrorID = swiftSrcMgr.addNewSourceBuffer(std::move(mirrorBuffer)); mirroredBuffers[buffer] = mirrorID; } loc = swiftSrcMgr.getLocForOffset(mirrorID, decomposedLoc.second); auto presumedLoc = clangSrcMgr.getPresumedLoc(clangLoc); if (!presumedLoc.getFilename()) return loc; if (presumedLoc.getLine() == 0) return SourceLoc(); unsigned bufferLineNumber = clangSrcMgr.getLineNumber(decomposedLoc.first, decomposedLoc.second); StringRef presumedFile = presumedLoc.getFilename(); SourceLoc startOfLine = loc.getAdvancedLoc(-presumedLoc.getColumn() + 1); bool isNewVirtualFile = swiftSrcMgr.openVirtualFile(startOfLine, presumedFile, presumedLoc.getLine() - bufferLineNumber); if (isNewVirtualFile) { SourceLoc endOfLine = findEndOfLine(swiftSrcMgr, loc, mirrorID); swiftSrcMgr.closeVirtualFile(endOfLine); } using SourceManagerRef = llvm::IntrusiveRefCntPtr<const clang::SourceManager>; auto iter = std::lower_bound(sourceManagersWithDiagnostics.begin(), sourceManagersWithDiagnostics.end(), &clangSrcMgr, [](const SourceManagerRef &inArray, const clang::SourceManager *toInsert) { return std::less<const clang::SourceManager *>()(inArray.get(), toInsert); }); if (iter->get() != &clangSrcMgr) sourceManagersWithDiagnostics.insert(iter, &clangSrcMgr); return loc; }
std::string locationToString(clang::SourceLocation loc, clang::SourceManager& sm) { clang::PresumedLoc fixed = sm.getPresumedLoc(loc); if (!fixed.isValid()) return "???"; return (llvm::Twine(fixed.getFilename()) + ":" + llvm::Twine(fixed.getLine())).str(); }