SourceMgrAdapter.cpp [plain text]
#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 &srcMgr,
DiagnosticsEngine &diag,
unsigned errorDiagID,
unsigned warningDiagID,
unsigned noteDiagID,
const FileEntry *defaultFile)
: SrcMgr(srcMgr), Diag(diag), ErrorDiagID(errorDiagID),
WarningDiagID(warningDiagID), NoteDiagID(noteDiagID),
DefaultFile(defaultFile) { }
SourceMgrAdapter::~SourceMgrAdapter() { }
SourceLocation SourceMgrAdapter::mapLocation(const llvm::SourceMgr &llvmSrcMgr,
llvm::SMLoc loc) {
if (!loc.isValid())
return SourceLocation();
unsigned bufferID = llvmSrcMgr.FindBufferContainingLoc(loc);
if (!bufferID)
return SourceLocation();
auto buffer = llvmSrcMgr.getMemoryBuffer(bufferID);
auto knownBuffer = FileIDMapping.find(std::make_pair(&llvmSrcMgr, bufferID));
if (knownBuffer == FileIDMapping.end()) {
FileID fileID;
if (DefaultFile) {
fileID = SrcMgr.createFileID(DefaultFile, SourceLocation(),
SrcMgr::C_User);
DefaultFile = nullptr;
} else {
StringRef bufferName = buffer->getBufferIdentifier();
auto bufferCopy
= std::unique_ptr<llvm::MemoryBuffer>(
llvm::MemoryBuffer::getMemBufferCopy(buffer->getBuffer(),
bufferName));
fileID = SrcMgr.createFileID(std::move(bufferCopy));
}
knownBuffer = FileIDMapping.insert(
std::make_pair(std::make_pair(&llvmSrcMgr, bufferID),
fileID)).first;
}
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) {
SourceLocation loc;
if (auto *llvmSrcMgr = diag.getSourceMgr())
loc = mapLocation(*llvmSrcMgr, diag.getLoc());
StringRef message = diag.getMessage();
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_Note:
diagID = NoteDiagID;
break;
}
DiagnosticBuilder builder = Diag.Report(loc, diagID) << message;
if (auto *llvmSrcMgr = diag.getSourceMgr()) {
SourceLocation startOfLine = loc.getLocWithOffset(-diag.getColumnNo());
for (auto range : diag.getRanges()) {
builder << SourceRange(startOfLine.getLocWithOffset(range.first),
startOfLine.getLocWithOffset(range.second));
}
for (const llvm::SMFixIt &fixIt : diag.getFixIts()) {
CharSourceRange range(mapRange(*llvmSrcMgr, fixIt.getRange()), false);
builder << FixItHint::CreateReplacement(range, fixIt.getText());
}
}
}