/builds/2mk6rsew/0/parcoach/parcoach/src/aSSA/SerializableWarning.cpp
Line | Count | Source |
1 | | #include "parcoach/SerializableWarning.h" |
2 | | |
3 | | #include "llvm/IR/Function.h" |
4 | | #include "llvm/Support/JSON.h" |
5 | | #include "llvm/Support/SourceMgr.h" |
6 | | |
7 | | using namespace llvm; |
8 | | |
9 | | namespace parcoach::serialization::sonar { |
10 | | |
11 | | namespace { |
12 | 3 | Twine createWarningMessage(Function const &F) { |
13 | 3 | return F.getName() + " may not be called by all MPI processes"; |
14 | 3 | } |
15 | | } // namespace |
16 | | |
17 | | Warning::Warning(parcoach::Warning const &W) |
18 | | : Message{W.Where.Filename.str(), |
19 | | {W.Where.Line}, |
20 | 3 | createWarningMessage(W.MissedFunction).str()} { |
21 | 3 | Conditionals.reserve(W.Conditionals.size()); |
22 | 3 | for (auto const &Cond : W.Conditionals) { |
23 | 3 | Conditionals.emplace_back( |
24 | 3 | Location{Cond.Filename.str(), |
25 | 3 | {Cond.Line}, |
26 | 3 | "because this condition depends on the rank"}); |
27 | 3 | } |
28 | 3 | } |
29 | | |
30 | 3 | void Database::append(WarningCollection const &Warnings) { |
31 | 3 | Issues.reserve(Issues.size() + Warnings.size()); |
32 | 3 | for (auto const &[_, W] : Warnings) { |
33 | 3 | Issues.emplace_back(W); |
34 | 3 | } |
35 | 3 | } |
36 | | |
37 | 6 | bool fromJSON(json::Value const &E, TextRange &R, json::Path P) { |
38 | 6 | json::ObjectMapper O(E, P); |
39 | 6 | return O && O.map("startLine", R.Line); |
40 | 6 | } |
41 | | |
42 | 6 | bool fromJSON(json::Value const &E, Location &L, json::Path P) { |
43 | 6 | json::ObjectMapper O(E, P); |
44 | 6 | return O && O.map("message", L.Message) && O.map("filePath", L.Filename) && |
45 | 6 | O.map("textRange", L.Range); |
46 | 6 | } |
47 | | |
48 | 6 | json::Value toJSON(TextRange const &R) { |
49 | 6 | return json::Object{ |
50 | 6 | {"startLine", R.Line}, |
51 | 6 | }; |
52 | 6 | } |
53 | | |
54 | 6 | json::Value toJSON(Location const &L) { |
55 | 6 | return json::Object{ |
56 | 6 | {"filePath", L.Filename}, |
57 | 6 | {"textRange", L.Range}, |
58 | 6 | {"message", L.Message}, |
59 | 6 | }; |
60 | 6 | } |
61 | | |
62 | 3 | bool fromJSON(json::Value const &E, Warning &W, json::Path P) { |
63 | 3 | json::ObjectMapper O(E, P); |
64 | 3 | return O && O.map("primaryLocation", W.Message) && |
65 | 3 | O.map("secondaryLocations", W.Conditionals); |
66 | 3 | } |
67 | | |
68 | 3 | json::Value toJSON(Warning const &W) { |
69 | 3 | return json::Object{ |
70 | | // matches SonarQube format at the moment. |
71 | 3 | {"engineId", "parcoach"}, {"ruleId", "mpiCollective"}, |
72 | 3 | {"severity", "MINOR"}, {"type", "BUG"}, |
73 | 3 | {"primaryLocation", W.Message}, {"secondaryLocations", W.Conditionals}, |
74 | 3 | }; |
75 | 3 | } |
76 | | |
77 | 2 | bool fromJSON(json::Value const &E, Database &DB, json::Path P) { |
78 | 2 | json::ObjectMapper O(E, P); |
79 | 2 | return O && O.map("issues", DB.Issues); |
80 | 2 | } |
81 | | |
82 | 2 | json::Value toJSON(Database const &DB) { |
83 | 2 | return json::Object{ |
84 | 2 | {"issues", DB.Issues}, |
85 | 2 | }; |
86 | 2 | } |
87 | | |
88 | 3 | Expected<Database> Database::load(StringRef Json) { |
89 | 3 | return json::parse<Database>(Json); |
90 | 3 | } |
91 | | |
92 | 2 | void Database::write(raw_fd_ostream &Os) const { |
93 | 2 | Os << formatv("{0:2}", json::Value(*this)); |
94 | 2 | } |
95 | | |
96 | | } // namespace parcoach::serialization::sonar |