aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-18 20:30:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-19 21:23:40 +0000
commitbdbe302c3396ceb4dd89d1214485439598f05368 (patch)
treeccf66c6349b23061ed5e9645c21f15fbe718da8b /contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp
parente7a1904fe1ced461b2a31f03b6592ae6564a243a (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp b/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp
new file mode 100644
index 000000000000..e39e4de9d42d
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp
@@ -0,0 +1,136 @@
+//=== SourceMgrAdapter.cpp - SourceMgr to SourceManager Adapter -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the adapter that maps diagnostics from llvm::SourceMgr
+// to Clang's SourceManager.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/SourceMgrAdapter.h"
+#include "clang/Basic/Diagnostic.h"
+
+using namespace clang;
+
+void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag,
+ void *Context) {
+ static_cast<SourceMgrAdapter *>(Context)->handleDiag(Diag);
+}
+
+SourceMgrAdapter::SourceMgrAdapter(SourceManager &SM,
+ DiagnosticsEngine &Diagnostics,
+ unsigned ErrorDiagID, unsigned WarningDiagID,
+ unsigned NoteDiagID,
+ OptionalFileEntryRef DefaultFile)
+ : SrcMgr(SM), Diagnostics(Diagnostics), ErrorDiagID(ErrorDiagID),
+ WarningDiagID(WarningDiagID), NoteDiagID(NoteDiagID),
+ DefaultFile(DefaultFile) {}
+
+SourceMgrAdapter::~SourceMgrAdapter() {}
+
+SourceLocation SourceMgrAdapter::mapLocation(const llvm::SourceMgr &LLVMSrcMgr,
+ llvm::SMLoc Loc) {
+ // Map invalid locations.
+ if (!Loc.isValid())
+ return SourceLocation();
+
+ // Find the buffer containing the location.
+ unsigned BufferID = LLVMSrcMgr.FindBufferContainingLoc(Loc);
+ if (!BufferID)
+ return SourceLocation();
+
+ // If we haven't seen this buffer before, copy it over.
+ auto Buffer = LLVMSrcMgr.getMemoryBuffer(BufferID);
+ auto KnownBuffer = FileIDMapping.find(std::make_pair(&LLVMSrcMgr, BufferID));
+ if (KnownBuffer == FileIDMapping.end()) {
+ FileID FileID;
+ if (DefaultFile) {
+ // Map to the default file.
+ FileID = SrcMgr.getOrCreateFileID(*DefaultFile, SrcMgr::C_User);
+
+ // Only do this once.
+ DefaultFile = std::nullopt;
+ } else {
+ // Make a copy of the memory buffer.
+ StringRef bufferName = Buffer->getBufferIdentifier();
+ auto bufferCopy = std::unique_ptr<llvm::MemoryBuffer>(
+ llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(),
+ bufferName));
+
+ // Add this memory buffer to the Clang source manager.
+ FileID = SrcMgr.createFileID(std::move(bufferCopy));
+ }
+
+ // Save the mapping.
+ KnownBuffer = FileIDMapping
+ .insert(std::make_pair(
+ std::make_pair(&LLVMSrcMgr, BufferID), FileID))
+ .first;
+ }
+
+ // Translate the offset into the file.
+ unsigned Offset = Loc.getPointer() - Buffer->getBufferStart();
+ return SrcMgr.getLocForStartOfFile(KnownBuffer->second)
+ .getLocWithOffset(Offset);
+}
+
+SourceRange SourceMgrAdapter::mapRange(const llvm::SourceMgr &LLVMSrcMgr,
+ llvm::SMRange Range) {
+ if (!Range.isValid())
+ return SourceRange();
+
+ SourceLocation Start = mapLocation(LLVMSrcMgr, Range.Start);
+ SourceLocation End = mapLocation(LLVMSrcMgr, Range.End);
+ return SourceRange(Start, End);
+}
+
+void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag) {
+ // Map the location.
+ SourceLocation Loc;
+ if (auto *LLVMSrcMgr = Diag.getSourceMgr())
+ Loc = mapLocation(*LLVMSrcMgr, Diag.getLoc());
+
+ // Extract the message.
+ StringRef Message = Diag.getMessage();
+
+ // Map the diagnostic kind.
+ unsigned DiagID;
+ switch (Diag.getKind()) {
+ case llvm::SourceMgr::DK_Error:
+ DiagID = ErrorDiagID;
+ break;
+
+ case llvm::SourceMgr::DK_Warning:
+ DiagID = WarningDiagID;
+ break;
+
+ case llvm::SourceMgr::DK_Remark:
+ llvm_unreachable("remarks not implemented");
+
+ case llvm::SourceMgr::DK_Note:
+ DiagID = NoteDiagID;
+ break;
+ }
+
+ // Report the diagnostic.
+ DiagnosticBuilder Builder = Diagnostics.Report(Loc, DiagID) << Message;
+
+ if (auto *LLVMSrcMgr = Diag.getSourceMgr()) {
+ // Translate ranges.
+ SourceLocation StartOfLine = Loc.getLocWithOffset(-Diag.getColumnNo());
+ for (auto Range : Diag.getRanges()) {
+ Builder << SourceRange(StartOfLine.getLocWithOffset(Range.first),
+ StartOfLine.getLocWithOffset(Range.second));
+ }
+
+ // Translate Fix-Its.
+ for (const llvm::SMFixIt &FixIt : Diag.getFixIts()) {
+ CharSourceRange Range(mapRange(*LLVMSrcMgr, FixIt.getRange()), false);
+ Builder << FixItHint::CreateReplacement(Range, FixIt.getText());
+ }
+ }
+}