73 lines · cpp
1//===--- Diagnostic.cpp - Framework for clang diagnostics tools ----------===//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// Implements classes to support/store diagnostics refactoring.10//11//===----------------------------------------------------------------------===//12 13#include "clang/Tooling/Core/Diagnostic.h"14#include "clang/Basic/SourceLocation.h"15#include "clang/Basic/SourceManager.h"16#include "llvm/ADT/STLExtras.h"17 18namespace clang {19namespace tooling {20 21DiagnosticMessage::DiagnosticMessage(llvm::StringRef Message)22 : Message(Message), FileOffset(0) {}23 24DiagnosticMessage::DiagnosticMessage(llvm::StringRef Message,25 const SourceManager &Sources,26 SourceLocation Loc)27 : Message(Message), FileOffset(0) {28 assert(Loc.isValid() && Loc.isFileID());29 FilePath = std::string(Sources.getFilename(Loc));30 31 // Don't store offset in the scratch space. It doesn't tell anything to the32 // user. Moreover, it depends on the history of macro expansions and thus33 // prevents deduplication of warnings in headers.34 if (!FilePath.empty())35 FileOffset = Sources.getFileOffset(Loc);36}37 38FileByteRange::FileByteRange(39 const SourceManager &Sources, CharSourceRange Range)40 : FileOffset(0), Length(0) {41 FilePath = std::string(Sources.getFilename(Range.getBegin()));42 if (!FilePath.empty()) {43 FileOffset = Sources.getFileOffset(Range.getBegin());44 Length = Sources.getFileOffset(Range.getEnd()) - FileOffset;45 }46}47 48Diagnostic::Diagnostic(llvm::StringRef DiagnosticName,49 Diagnostic::Level DiagLevel, StringRef BuildDirectory)50 : DiagnosticName(DiagnosticName), DiagLevel(DiagLevel),51 BuildDirectory(BuildDirectory) {}52 53Diagnostic::Diagnostic(llvm::StringRef DiagnosticName,54 const DiagnosticMessage &Message,55 const SmallVector<DiagnosticMessage, 1> &Notes,56 Level DiagLevel, llvm::StringRef BuildDirectory)57 : DiagnosticName(DiagnosticName), Message(Message), Notes(Notes),58 DiagLevel(DiagLevel), BuildDirectory(BuildDirectory) {}59 60const llvm::StringMap<Replacements> *selectFirstFix(const Diagnostic& D) {61 if (!D.Message.Fix.empty())62 return &D.Message.Fix;63 auto Iter = llvm::find_if(D.Notes, [](const tooling::DiagnosticMessage &D) {64 return !D.Fix.empty();65 });66 if (Iter != D.Notes.end())67 return &Iter->Fix;68 return nullptr;69}70 71} // end namespace tooling72} // end namespace clang73