brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · e39e4de Raw
137 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the adapter that maps diagnostics from llvm::SourceMgr10// to Clang's SourceManager.11//12//===----------------------------------------------------------------------===//13 14#include "clang/Basic/SourceMgrAdapter.h"15#include "clang/Basic/Diagnostic.h"16 17using namespace clang;18 19void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag,20                                  void *Context) {21  static_cast<SourceMgrAdapter *>(Context)->handleDiag(Diag);22}23 24SourceMgrAdapter::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 33SourceMgrAdapter::~SourceMgrAdapter() {}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()) {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 = FileIDMapping70                      .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.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