Path: blob/main/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp
35232 views
//=== SourceMgrAdapter.cpp - SourceMgr to SourceManager Adapter -----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the adapter that maps diagnostics from llvm::SourceMgr9// to Clang's SourceManager.10//11//===----------------------------------------------------------------------===//1213#include "clang/Basic/SourceMgrAdapter.h"14#include "clang/Basic/Diagnostic.h"1516using namespace clang;1718void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag,19void *Context) {20static_cast<SourceMgrAdapter *>(Context)->handleDiag(Diag);21}2223SourceMgrAdapter::SourceMgrAdapter(SourceManager &SM,24DiagnosticsEngine &Diagnostics,25unsigned ErrorDiagID, unsigned WarningDiagID,26unsigned NoteDiagID,27OptionalFileEntryRef DefaultFile)28: SrcMgr(SM), Diagnostics(Diagnostics), ErrorDiagID(ErrorDiagID),29WarningDiagID(WarningDiagID), NoteDiagID(NoteDiagID),30DefaultFile(DefaultFile) {}3132SourceMgrAdapter::~SourceMgrAdapter() {}3334SourceLocation SourceMgrAdapter::mapLocation(const llvm::SourceMgr &LLVMSrcMgr,35llvm::SMLoc Loc) {36// Map invalid locations.37if (!Loc.isValid())38return SourceLocation();3940// Find the buffer containing the location.41unsigned BufferID = LLVMSrcMgr.FindBufferContainingLoc(Loc);42if (!BufferID)43return SourceLocation();4445// If we haven't seen this buffer before, copy it over.46auto Buffer = LLVMSrcMgr.getMemoryBuffer(BufferID);47auto KnownBuffer = FileIDMapping.find(std::make_pair(&LLVMSrcMgr, BufferID));48if (KnownBuffer == FileIDMapping.end()) {49FileID FileID;50if (DefaultFile) {51// Map to the default file.52FileID = SrcMgr.getOrCreateFileID(*DefaultFile, SrcMgr::C_User);5354// Only do this once.55DefaultFile = std::nullopt;56} else {57// Make a copy of the memory buffer.58StringRef bufferName = Buffer->getBufferIdentifier();59auto bufferCopy = std::unique_ptr<llvm::MemoryBuffer>(60llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(),61bufferName));6263// Add this memory buffer to the Clang source manager.64FileID = SrcMgr.createFileID(std::move(bufferCopy));65}6667// Save the mapping.68KnownBuffer = FileIDMapping69.insert(std::make_pair(70std::make_pair(&LLVMSrcMgr, BufferID), FileID))71.first;72}7374// Translate the offset into the file.75unsigned Offset = Loc.getPointer() - Buffer->getBufferStart();76return SrcMgr.getLocForStartOfFile(KnownBuffer->second)77.getLocWithOffset(Offset);78}7980SourceRange SourceMgrAdapter::mapRange(const llvm::SourceMgr &LLVMSrcMgr,81llvm::SMRange Range) {82if (!Range.isValid())83return SourceRange();8485SourceLocation Start = mapLocation(LLVMSrcMgr, Range.Start);86SourceLocation End = mapLocation(LLVMSrcMgr, Range.End);87return SourceRange(Start, End);88}8990void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag) {91// Map the location.92SourceLocation Loc;93if (auto *LLVMSrcMgr = Diag.getSourceMgr())94Loc = mapLocation(*LLVMSrcMgr, Diag.getLoc());9596// Extract the message.97StringRef Message = Diag.getMessage();9899// Map the diagnostic kind.100unsigned DiagID;101switch (Diag.getKind()) {102case llvm::SourceMgr::DK_Error:103DiagID = ErrorDiagID;104break;105106case llvm::SourceMgr::DK_Warning:107DiagID = WarningDiagID;108break;109110case llvm::SourceMgr::DK_Remark:111llvm_unreachable("remarks not implemented");112113case llvm::SourceMgr::DK_Note:114DiagID = NoteDiagID;115break;116}117118// Report the diagnostic.119DiagnosticBuilder Builder = Diagnostics.Report(Loc, DiagID) << Message;120121if (auto *LLVMSrcMgr = Diag.getSourceMgr()) {122// Translate ranges.123SourceLocation StartOfLine = Loc.getLocWithOffset(-Diag.getColumnNo());124for (auto Range : Diag.getRanges()) {125Builder << SourceRange(StartOfLine.getLocWithOffset(Range.first),126StartOfLine.getLocWithOffset(Range.second));127}128129// Translate Fix-Its.130for (const llvm::SMFixIt &FixIt : Diag.getFixIts()) {131CharSourceRange Range(mapRange(*LLVMSrcMgr, FixIt.getRange()), false);132Builder << FixItHint::CreateReplacement(Range, FixIt.getText());133}134}135}136137138