Index: include/clang/Tooling/Core/Diagnostic.h =================================================================== --- include/clang/Tooling/Core/Diagnostic.h +++ include/clang/Tooling/Core/Diagnostic.h @@ -47,6 +47,18 @@ llvm::StringMap Fix; }; +/// Represents a single source ranges to be associated with a diagnostic. +struct DiagnosticAssociatedRange { + DiagnosticAssociatedRange() = default; + + DiagnosticAssociatedRange(const SourceManager &Sources, + CharSourceRange Range); + + std::string FilePath; + unsigned FileOffset; + unsigned Length; +}; + /// Represents the diagnostic with the level of severity and possible /// fixes to be applied. struct Diagnostic { @@ -62,7 +74,8 @@ Diagnostic(llvm::StringRef DiagnosticName, const DiagnosticMessage &Message, const SmallVector &Notes, Level DiagLevel, - llvm::StringRef BuildDirectory); + llvm::StringRef BuildDirectory, + const SmallVector &Ranges); /// Name identifying the Diagnostic. std::string DiagnosticName; @@ -84,6 +97,10 @@ /// /// Note: it is empty in unittest. std::string BuildDirectory; + + /// Extra source ranges associated with the diagnostic (in addition to the + /// location of the Message above). + SmallVector Ranges; }; /// Collection of Diagnostics generated from a single translation unit. Index: include/clang/Tooling/DiagnosticsYaml.h =================================================================== --- include/clang/Tooling/DiagnosticsYaml.h +++ include/clang/Tooling/DiagnosticsYaml.h @@ -20,12 +20,21 @@ #include "llvm/Support/YAMLTraits.h" #include +LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::DiagnosticAssociatedRange) LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Diagnostic) LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::DiagnosticMessage) namespace llvm { namespace yaml { +template <> struct MappingTraits { + static void mapping(IO &Io, clang::tooling::DiagnosticAssociatedRange &R) { + Io.mapRequired("FilePath", R.FilePath); + Io.mapRequired("FileOffset", R.FileOffset); + Io.mapRequired("Length", R.Length); + } +}; + template <> struct MappingTraits { static void mapping(IO &Io, clang::tooling::DiagnosticMessage &M) { Io.mapRequired("Message", M.Message); @@ -58,11 +67,12 @@ NormalizedDiagnostic(const IO &, const clang::tooling::Diagnostic &D) : DiagnosticName(D.DiagnosticName), Message(D.Message), Notes(D.Notes), - DiagLevel(D.DiagLevel), BuildDirectory(D.BuildDirectory) {} + DiagLevel(D.DiagLevel), BuildDirectory(D.BuildDirectory), + Ranges(D.Ranges) {} clang::tooling::Diagnostic denormalize(const IO &) { return clang::tooling::Diagnostic(DiagnosticName, Message, Notes, - DiagLevel, BuildDirectory); + DiagLevel, BuildDirectory, Ranges); } std::string DiagnosticName; @@ -71,6 +81,7 @@ SmallVector Notes; clang::tooling::Diagnostic::Level DiagLevel; std::string BuildDirectory; + SmallVector Ranges; }; static void mapping(IO &Io, clang::tooling::Diagnostic &D) { @@ -79,6 +90,7 @@ Io.mapRequired("DiagnosticName", Keys->DiagnosticName); Io.mapRequired("DiagnosticMessage", Keys->Message); Io.mapOptional("Notes", Keys->Notes); + Io.mapOptional("Ranges", Keys->Ranges); // FIXME: Export properly all the different fields. } Index: lib/Tooling/Core/Diagnostic.cpp =================================================================== --- lib/Tooling/Core/Diagnostic.cpp +++ lib/Tooling/Core/Diagnostic.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/Core/Diagnostic.h" +#include "third_party/llvm/llvm-project/clang/include/clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/STLExtras.h" @@ -34,6 +35,16 @@ FileOffset = Sources.getFileOffset(Loc); } +DiagnosticAssociatedRange::DiagnosticAssociatedRange( + const SourceManager &Sources, CharSourceRange Range) + : FileOffset(0), Length(0) { + FilePath = std::string(Sources.getFilename(Range.getBegin())); + if (!FilePath.empty()) { + FileOffset = Sources.getFileOffset(Range.getBegin()); + Length = Sources.getFileOffset(Range.getEnd()) - FileOffset; + } +} + Diagnostic::Diagnostic(llvm::StringRef DiagnosticName, Diagnostic::Level DiagLevel, StringRef BuildDirectory) : DiagnosticName(DiagnosticName), DiagLevel(DiagLevel), @@ -42,9 +53,10 @@ Diagnostic::Diagnostic(llvm::StringRef DiagnosticName, const DiagnosticMessage &Message, const SmallVector &Notes, - Level DiagLevel, llvm::StringRef BuildDirectory) + Level DiagLevel, llvm::StringRef BuildDirectory, + const SmallVector &Ranges) : DiagnosticName(DiagnosticName), Message(Message), Notes(Notes), - DiagLevel(DiagLevel), BuildDirectory(BuildDirectory) {} + DiagLevel(DiagLevel), BuildDirectory(BuildDirectory), Ranges(Ranges) {} const llvm::StringMap *selectFirstFix(const Diagnostic& D) { if (!D.Message.Fix.empty())