Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp
35232 views
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
14
#include "clang/Basic/SourceMgrAdapter.h"
15
#include "clang/Basic/Diagnostic.h"
16
17
using namespace clang;
18
19
void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag,
20
void *Context) {
21
static_cast<SourceMgrAdapter *>(Context)->handleDiag(Diag);
22
}
23
24
SourceMgrAdapter::SourceMgrAdapter(SourceManager &SM,
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
33
SourceMgrAdapter::~SourceMgrAdapter() {}
34
35
SourceLocation 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()) {
50
FileID FileID;
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
81
SourceRange 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
91
void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag) {
92
// Map the location.
93
SourceLocation Loc;
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
}
137
138