1//===-- DiagnosticsYaml.h -- Serialiazation for Diagnosticss ---*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file defines the structure of a YAML document for serializing
12/// diagnostics.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CLANG_TOOLING_DIAGNOSTICSYAML_H
17#define LLVM_CLANG_TOOLING_DIAGNOSTICSYAML_H
18
19#include "clang/Tooling/Core/Diagnostic.h"
20#include "clang/Tooling/ReplacementsYaml.h"
21#include "llvm/Support/YAMLTraits.h"
22#include <string>
23
24LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Diagnostic)
25
26namespace llvm {
27namespace yaml {
28
29template <> struct MappingTraits<clang::tooling::Diagnostic> {
30  /// \brief Helper to (de)serialize a Diagnostic since we don't have direct
31  /// access to its data members.
32  class NormalizedDiagnostic {
33  public:
34    NormalizedDiagnostic(const IO &)
35        : DiagLevel(clang::tooling::Diagnostic::Level::Warning) {}
36
37    NormalizedDiagnostic(const IO &, const clang::tooling::Diagnostic &D)
38        : DiagnosticName(D.DiagnosticName), Message(D.Message), Fix(D.Fix),
39          Notes(D.Notes), DiagLevel(D.DiagLevel),
40          BuildDirectory(D.BuildDirectory) {}
41
42    clang::tooling::Diagnostic denormalize(const IO &) {
43      return clang::tooling::Diagnostic(DiagnosticName, Message, Fix, Notes,
44                                        DiagLevel, BuildDirectory);
45    }
46
47    std::string DiagnosticName;
48    clang::tooling::DiagnosticMessage Message;
49    llvm::StringMap<clang::tooling::Replacements> Fix;
50    SmallVector<clang::tooling::DiagnosticMessage, 1> Notes;
51    clang::tooling::Diagnostic::Level DiagLevel;
52    std::string BuildDirectory;
53  };
54
55  static void mapping(IO &Io, clang::tooling::Diagnostic &D) {
56    MappingNormalization<NormalizedDiagnostic, clang::tooling::Diagnostic> Keys(
57        Io, D);
58    Io.mapRequired("DiagnosticName", Keys->DiagnosticName);
59    Io.mapRequired("Message", Keys->Message.Message);
60    Io.mapRequired("FileOffset", Keys->Message.FileOffset);
61    Io.mapRequired("FilePath", Keys->Message.FilePath);
62
63    // FIXME: Export properly all the different fields.
64
65    std::vector<clang::tooling::Replacement> Fixes;
66    for (auto &Replacements : Keys->Fix) {
67      for (auto &Replacement : Replacements.second) {
68        Fixes.push_back(Replacement);
69      }
70    }
71    Io.mapRequired("Replacements", Fixes);
72    for (auto &Fix : Fixes) {
73      llvm::Error Err = Keys->Fix[Fix.getFilePath()].add(Fix);
74      if (Err) {
75        // FIXME: Implement better conflict handling.
76        llvm::errs() << "Fix conflicts with existing fix: "
77                     << llvm::toString(std::move(Err)) << "\n";
78      }
79    }
80  }
81};
82
83/// \brief Specialized MappingTraits to describe how a
84/// TranslationUnitDiagnostics is (de)serialized.
85template <> struct MappingTraits<clang::tooling::TranslationUnitDiagnostics> {
86  static void mapping(IO &Io, clang::tooling::TranslationUnitDiagnostics &Doc) {
87    Io.mapRequired("MainSourceFile", Doc.MainSourceFile);
88    Io.mapRequired("Diagnostics", Doc.Diagnostics);
89  }
90};
91} // end namespace yaml
92} // end namespace llvm
93
94#endif // LLVM_CLANG_TOOLING_DIAGNOSTICSYAML_H
95