clang 22.0.0git
SourceMgrAdapter.cpp
Go to the documentation of this file.
1//=== SourceMgrAdapter.cpp - SourceMgr to SourceManager Adapter -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the adapter that maps diagnostics from llvm::SourceMgr
10// to Clang's SourceManager.
11//
12//===----------------------------------------------------------------------===//
13
16
17using namespace clang;
18
19void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag,
20 void *Context) {
21 static_cast<SourceMgrAdapter *>(Context)->handleDiag(Diag);
22}
23
25 DiagnosticsEngine &Diagnostics,
26 unsigned ErrorDiagID, unsigned WarningDiagID,
27 unsigned NoteDiagID,
28 OptionalFileEntryRef DefaultFile)
29 : SrcMgr(SM), Diagnostics(Diagnostics), ErrorDiagID(ErrorDiagID),
30 WarningDiagID(WarningDiagID), NoteDiagID(NoteDiagID),
31 DefaultFile(DefaultFile) {}
32
34
35SourceLocation SourceMgrAdapter::mapLocation(const llvm::SourceMgr &LLVMSrcMgr,
36 llvm::SMLoc Loc) {
37 // Map invalid locations.
38 if (!Loc.isValid())
39 return SourceLocation();
40
41 // Find the buffer containing the location.
42 unsigned BufferID = LLVMSrcMgr.FindBufferContainingLoc(Loc);
43 if (!BufferID)
44 return SourceLocation();
45
46 // If we haven't seen this buffer before, copy it over.
47 auto Buffer = LLVMSrcMgr.getMemoryBuffer(BufferID);
48 auto KnownBuffer = FileIDMapping.find(std::make_pair(&LLVMSrcMgr, BufferID));
49 if (KnownBuffer == FileIDMapping.end()) {
51 if (DefaultFile) {
52 // Map to the default file.
53 FileID = SrcMgr.getOrCreateFileID(*DefaultFile, SrcMgr::C_User);
54
55 // Only do this once.
56 DefaultFile = std::nullopt;
57 } else {
58 // Make a copy of the memory buffer.
59 StringRef bufferName = Buffer->getBufferIdentifier();
60 auto bufferCopy = std::unique_ptr<llvm::MemoryBuffer>(
61 llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(),
62 bufferName));
63
64 // Add this memory buffer to the Clang source manager.
65 FileID = SrcMgr.createFileID(std::move(bufferCopy));
66 }
67
68 // Save the mapping.
69 KnownBuffer = FileIDMapping
70 .insert(std::make_pair(
71 std::make_pair(&LLVMSrcMgr, BufferID), FileID))
72 .first;
73 }
74
75 // Translate the offset into the file.
76 unsigned Offset = Loc.getPointer() - Buffer->getBufferStart();
77 return SrcMgr.getLocForStartOfFile(KnownBuffer->second)
78 .getLocWithOffset(Offset);
79}
80
81SourceRange SourceMgrAdapter::mapRange(const llvm::SourceMgr &LLVMSrcMgr,
82 llvm::SMRange Range) {
83 if (!Range.isValid())
84 return SourceRange();
85
86 SourceLocation Start = mapLocation(LLVMSrcMgr, Range.Start);
87 SourceLocation End = mapLocation(LLVMSrcMgr, Range.End);
88 return SourceRange(Start, End);
89}
90
91void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag) {
92 // Map the location.
94 if (auto *LLVMSrcMgr = Diag.getSourceMgr())
95 Loc = mapLocation(*LLVMSrcMgr, Diag.getLoc());
96
97 // Extract the message.
98 StringRef Message = Diag.getMessage();
99
100 // Map the diagnostic kind.
101 unsigned DiagID;
102 switch (Diag.getKind()) {
103 case llvm::SourceMgr::DK_Error:
104 DiagID = ErrorDiagID;
105 break;
106
107 case llvm::SourceMgr::DK_Warning:
108 DiagID = WarningDiagID;
109 break;
110
111 case llvm::SourceMgr::DK_Remark:
112 llvm_unreachable("remarks not implemented");
113
114 case llvm::SourceMgr::DK_Note:
115 DiagID = NoteDiagID;
116 break;
117 }
118
119 // Report the diagnostic.
120 DiagnosticBuilder Builder = Diagnostics.Report(Loc, DiagID) << Message;
121
122 if (auto *LLVMSrcMgr = Diag.getSourceMgr()) {
123 // Translate ranges.
124 SourceLocation StartOfLine = Loc.getLocWithOffset(-Diag.getColumnNo());
125 for (auto Range : Diag.getRanges()) {
126 Builder << SourceRange(StartOfLine.getLocWithOffset(Range.first),
127 StartOfLine.getLocWithOffset(Range.second));
128 }
129
130 // Translate Fix-Its.
131 for (const llvm::SMFixIt &FixIt : Diag.getFixIts()) {
132 CharSourceRange Range(mapRange(*LLVMSrcMgr, FixIt.getRange()), false);
133 Builder << FixItHint::CreateReplacement(Range, FixIt.getText());
134 }
135 }
136}
Defines the Diagnostic-related interfaces.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
#define SM(sm)
Represents a character-granular source range.
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:231
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition Diagnostic.h:139
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
SourceLocation mapLocation(const llvm::SourceMgr &LLVMSrcMgr, llvm::SMLoc Loc)
Map a source location in the given LLVM source manager to its corresponding location in the Clang sou...
SourceRange mapRange(const llvm::SourceMgr &LLVMSrcMgr, llvm::SMRange Range)
Map a source range in the given LLVM source manager to its corresponding range in the Clang source ma...
SourceMgrAdapter(SourceManager &SM, DiagnosticsEngine &Diagnostics, unsigned ErrorDiagID, unsigned WarningDiagID, unsigned NoteDiagID, OptionalFileEntryRef DefaultFile=std::nullopt)
Create a new SourceMgr adaptor that maps to the given source manager and diagnostics engine.
A trivial tuple used to represent a source range.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
Definition FileEntry.h:208