brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · 4f19c91 Raw
118 lines · cpp
1//===--- StandaloneDiagnostic.h - Serializable Diagnostic ------------- ---===//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#include "clang/Frontend/StandaloneDiagnostic.h"10#include "clang/Lex/Lexer.h"11 12namespace clang {13 14StandaloneDiagnostic::SourceOffsetRange::SourceOffsetRange(15    CharSourceRange Range, const SourceManager &SrcMgr,16    const LangOptions &LangOpts) {17  const auto FileRange = Lexer::makeFileCharRange(Range, SrcMgr, LangOpts);18  Begin = SrcMgr.getFileOffset(FileRange.getBegin());19  End = SrcMgr.getFileOffset(FileRange.getEnd());20}21 22StandaloneDiagnostic::StandaloneFixIt::StandaloneFixIt(23    const SourceManager &SrcMgr, const LangOptions &LangOpts,24    const FixItHint &FixIt)25    : RemoveRange(FixIt.RemoveRange, SrcMgr, LangOpts),26      InsertFromRange(FixIt.InsertFromRange, SrcMgr, LangOpts),27      CodeToInsert(FixIt.CodeToInsert),28      BeforePreviousInsertions(FixIt.BeforePreviousInsertions) {}29 30StandaloneDiagnostic::StandaloneDiagnostic(const LangOptions &LangOpts,31                                           const StoredDiagnostic &InDiag)32    : Level(InDiag.getLevel()), ID(InDiag.getID()),33      Message(InDiag.getMessage()) {34  const FullSourceLoc &FullLoc = InDiag.getLocation();35  // This is not an invalid diagnostic; invalid SourceLocations are used to36  // represent diagnostics without a specific SourceLocation.37  if (FullLoc.isInvalid())38    return;39 40  const auto &SrcMgr = FullLoc.getManager();41  FileKind = SrcMgr.getFileCharacteristic(static_cast<SourceLocation>(FullLoc));42  const auto FileLoc = SrcMgr.getFileLoc(static_cast<SourceLocation>(FullLoc));43  FileOffset = SrcMgr.getFileOffset(FileLoc);44  Filename = SrcMgr.getFilename(FileLoc);45  assert(!Filename.empty() && "diagnostic with location has no source file?");46 47  Ranges.reserve(InDiag.getRanges().size());48  for (const auto &Range : InDiag.getRanges())49    Ranges.emplace_back(Range, SrcMgr, LangOpts);50 51  FixIts.reserve(InDiag.getFixIts().size());52  for (const auto &FixIt : InDiag.getFixIts())53    FixIts.emplace_back(SrcMgr, LangOpts, FixIt);54}55 56StoredDiagnostic57translateStandaloneDiag(FileManager &FileMgr, SourceManager &SrcMgr,58                        const StandaloneDiagnostic &StandaloneDiag,59                        llvm::StringMap<SourceLocation> &SrcLocCache) {60  const auto FileRef = FileMgr.getOptionalFileRef(StandaloneDiag.Filename);61  if (!FileRef)62    return StoredDiagnostic(StandaloneDiag.Level, StandaloneDiag.ID,63                            StandaloneDiag.Message);64 65  // Try to get FileLoc from cache first66  SourceLocation FileLoc;67  auto It = SrcLocCache.find(StandaloneDiag.Filename);68  if (It != SrcLocCache.end()) {69    FileLoc = It->getValue();70  }71 72  // Cache miss - compute and cache the location73  if (FileLoc.isInvalid()) {74    const auto FileID =75        SrcMgr.getOrCreateFileID(*FileRef, StandaloneDiag.FileKind);76    FileLoc = SrcMgr.getLocForStartOfFile(FileID);77 78    if (FileLoc.isInvalid())79      return StoredDiagnostic(StandaloneDiag.Level, StandaloneDiag.ID,80                              StandaloneDiag.Message);81 82    SrcLocCache[StandaloneDiag.Filename] = FileLoc;83  }84 85  const auto DiagLoc = FileLoc.getLocWithOffset(StandaloneDiag.FileOffset);86  const FullSourceLoc Loc(DiagLoc, SrcMgr);87 88  auto ConvertOffsetRange =89      [&](const StandaloneDiagnostic::SourceOffsetRange &Range) {90        return CharSourceRange(91            SourceRange(FileLoc.getLocWithOffset(Range.Begin),92                        FileLoc.getLocWithOffset(Range.End)),93            /*IsTokenRange*/ false);94      };95 96  SmallVector<CharSourceRange, 4> TranslatedRanges;97  TranslatedRanges.reserve(StandaloneDiag.Ranges.size());98  transform(StandaloneDiag.Ranges, std::back_inserter(TranslatedRanges),99            ConvertOffsetRange);100 101  SmallVector<FixItHint, 2> TranslatedFixIts;102  TranslatedFixIts.reserve(StandaloneDiag.FixIts.size());103  for (const auto &FixIt : StandaloneDiag.FixIts) {104    FixItHint TranslatedFixIt;105    TranslatedFixIt.CodeToInsert = FixIt.CodeToInsert;106    TranslatedFixIt.RemoveRange = ConvertOffsetRange(FixIt.RemoveRange);107    TranslatedFixIt.InsertFromRange = ConvertOffsetRange(FixIt.InsertFromRange);108    TranslatedFixIt.BeforePreviousInsertions = FixIt.BeforePreviousInsertions;109    TranslatedFixIts.push_back(std::move(TranslatedFixIt));110  }111 112  return StoredDiagnostic(StandaloneDiag.Level, StandaloneDiag.ID,113                          StandaloneDiag.Message, Loc, TranslatedRanges,114                          TranslatedFixIts);115}116 117} // namespace clang118