This relands #165277 by reverting #169397. This also relands the corresponding Bazel port by reverting #169410. The original revert was due to a report of a broken build, which was later resolved by fully clearing the build directory.
118 lines
4.6 KiB
C++
118 lines
4.6 KiB
C++
//===--- StandaloneDiagnostic.h - Serializable Diagnostic ------------- ---===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/Frontend/StandaloneDiagnostic.h"
|
|
#include "clang/Lex/Lexer.h"
|
|
|
|
namespace clang {
|
|
|
|
StandaloneDiagnostic::SourceOffsetRange::SourceOffsetRange(
|
|
CharSourceRange Range, const SourceManager &SrcMgr,
|
|
const LangOptions &LangOpts) {
|
|
const auto FileRange = Lexer::makeFileCharRange(Range, SrcMgr, LangOpts);
|
|
Begin = SrcMgr.getFileOffset(FileRange.getBegin());
|
|
End = SrcMgr.getFileOffset(FileRange.getEnd());
|
|
}
|
|
|
|
StandaloneDiagnostic::StandaloneFixIt::StandaloneFixIt(
|
|
const SourceManager &SrcMgr, const LangOptions &LangOpts,
|
|
const FixItHint &FixIt)
|
|
: RemoveRange(FixIt.RemoveRange, SrcMgr, LangOpts),
|
|
InsertFromRange(FixIt.InsertFromRange, SrcMgr, LangOpts),
|
|
CodeToInsert(FixIt.CodeToInsert),
|
|
BeforePreviousInsertions(FixIt.BeforePreviousInsertions) {}
|
|
|
|
StandaloneDiagnostic::StandaloneDiagnostic(const LangOptions &LangOpts,
|
|
const StoredDiagnostic &InDiag)
|
|
: Level(InDiag.getLevel()), ID(InDiag.getID()),
|
|
Message(InDiag.getMessage()) {
|
|
const FullSourceLoc &FullLoc = InDiag.getLocation();
|
|
// This is not an invalid diagnostic; invalid SourceLocations are used to
|
|
// represent diagnostics without a specific SourceLocation.
|
|
if (FullLoc.isInvalid())
|
|
return;
|
|
|
|
const auto &SrcMgr = FullLoc.getManager();
|
|
FileKind = SrcMgr.getFileCharacteristic(static_cast<SourceLocation>(FullLoc));
|
|
const auto FileLoc = SrcMgr.getFileLoc(static_cast<SourceLocation>(FullLoc));
|
|
FileOffset = SrcMgr.getFileOffset(FileLoc);
|
|
Filename = SrcMgr.getFilename(FileLoc);
|
|
assert(!Filename.empty() && "diagnostic with location has no source file?");
|
|
|
|
Ranges.reserve(InDiag.getRanges().size());
|
|
for (const auto &Range : InDiag.getRanges())
|
|
Ranges.emplace_back(Range, SrcMgr, LangOpts);
|
|
|
|
FixIts.reserve(InDiag.getFixIts().size());
|
|
for (const auto &FixIt : InDiag.getFixIts())
|
|
FixIts.emplace_back(SrcMgr, LangOpts, FixIt);
|
|
}
|
|
|
|
StoredDiagnostic
|
|
translateStandaloneDiag(FileManager &FileMgr, SourceManager &SrcMgr,
|
|
const StandaloneDiagnostic &StandaloneDiag,
|
|
llvm::StringMap<SourceLocation> &SrcLocCache) {
|
|
const auto FileRef = FileMgr.getOptionalFileRef(StandaloneDiag.Filename);
|
|
if (!FileRef)
|
|
return StoredDiagnostic(StandaloneDiag.Level, StandaloneDiag.ID,
|
|
StandaloneDiag.Message);
|
|
|
|
// Try to get FileLoc from cache first
|
|
SourceLocation FileLoc;
|
|
auto It = SrcLocCache.find(StandaloneDiag.Filename);
|
|
if (It != SrcLocCache.end()) {
|
|
FileLoc = It->getValue();
|
|
}
|
|
|
|
// Cache miss - compute and cache the location
|
|
if (FileLoc.isInvalid()) {
|
|
const auto FileID =
|
|
SrcMgr.getOrCreateFileID(*FileRef, StandaloneDiag.FileKind);
|
|
FileLoc = SrcMgr.getLocForStartOfFile(FileID);
|
|
|
|
if (FileLoc.isInvalid())
|
|
return StoredDiagnostic(StandaloneDiag.Level, StandaloneDiag.ID,
|
|
StandaloneDiag.Message);
|
|
|
|
SrcLocCache[StandaloneDiag.Filename] = FileLoc;
|
|
}
|
|
|
|
const auto DiagLoc = FileLoc.getLocWithOffset(StandaloneDiag.FileOffset);
|
|
const FullSourceLoc Loc(DiagLoc, SrcMgr);
|
|
|
|
auto ConvertOffsetRange =
|
|
[&](const StandaloneDiagnostic::SourceOffsetRange &Range) {
|
|
return CharSourceRange(
|
|
SourceRange(FileLoc.getLocWithOffset(Range.Begin),
|
|
FileLoc.getLocWithOffset(Range.End)),
|
|
/*IsTokenRange*/ false);
|
|
};
|
|
|
|
SmallVector<CharSourceRange, 4> TranslatedRanges;
|
|
TranslatedRanges.reserve(StandaloneDiag.Ranges.size());
|
|
transform(StandaloneDiag.Ranges, std::back_inserter(TranslatedRanges),
|
|
ConvertOffsetRange);
|
|
|
|
SmallVector<FixItHint, 2> TranslatedFixIts;
|
|
TranslatedFixIts.reserve(StandaloneDiag.FixIts.size());
|
|
for (const auto &FixIt : StandaloneDiag.FixIts) {
|
|
FixItHint TranslatedFixIt;
|
|
TranslatedFixIt.CodeToInsert = FixIt.CodeToInsert;
|
|
TranslatedFixIt.RemoveRange = ConvertOffsetRange(FixIt.RemoveRange);
|
|
TranslatedFixIt.InsertFromRange = ConvertOffsetRange(FixIt.InsertFromRange);
|
|
TranslatedFixIt.BeforePreviousInsertions = FixIt.BeforePreviousInsertions;
|
|
TranslatedFixIts.push_back(std::move(TranslatedFixIt));
|
|
}
|
|
|
|
return StoredDiagnostic(StandaloneDiag.Level, StandaloneDiag.ID,
|
|
StandaloneDiag.Message, Loc, TranslatedRanges,
|
|
TranslatedFixIts);
|
|
}
|
|
|
|
} // namespace clang
|