]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / lib / StaticAnalyzer / Core / PlistDiagnostics.cpp
1 //===--- PlistDiagnostics.cpp - Plist Diagnostics for Paths -----*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file defines the PlistDiagnostics object.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "clang/Basic/FileManager.h"
14 #include "clang/Basic/PlistSupport.h"
15 #include "clang/Basic/SourceManager.h"
16 #include "clang/Basic/Version.h"
17 #include "clang/Lex/Preprocessor.h"
18 #include "clang/Lex/TokenConcatenation.h"
19 #include "clang/Rewrite/Core/HTMLRewrite.h"
20 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
21 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
22 #include "clang/StaticAnalyzer/Core/IssueHash.h"
23 #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
24 #include "llvm/ADT/Statistic.h"
25 #include "llvm/ADT/SmallPtrSet.h"
26 #include "llvm/ADT/SmallVector.h"
27 #include "llvm/Support/Casting.h"
28
29 using namespace clang;
30 using namespace ento;
31 using namespace markup;
32
33 //===----------------------------------------------------------------------===//
34 // Declarations of helper classes and functions for emitting bug reports in
35 // plist format.
36 //===----------------------------------------------------------------------===//
37
38 namespace {
39   class PlistDiagnostics : public PathDiagnosticConsumer {
40     const std::string OutputFile;
41     const Preprocessor &PP;
42     AnalyzerOptions &AnOpts;
43     const bool SupportsCrossFileDiagnostics;
44   public:
45     PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
46                      const std::string& prefix,
47                      const Preprocessor &PP,
48                      bool supportsMultipleFiles);
49
50     ~PlistDiagnostics() override {}
51
52     void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
53                               FilesMade *filesMade) override;
54
55     StringRef getName() const override {
56       return "PlistDiagnostics";
57     }
58
59     PathGenerationScheme getGenerationScheme() const override {
60       return Extensive;
61     }
62     bool supportsLogicalOpControlFlow() const override { return true; }
63     bool supportsCrossFileDiagnostics() const override {
64       return SupportsCrossFileDiagnostics;
65     }
66   };
67 } // end anonymous namespace
68
69 namespace {
70
71 /// A helper class for emitting a single report.
72 class PlistPrinter {
73   const FIDMap& FM;
74   AnalyzerOptions &AnOpts;
75   const Preprocessor &PP;
76   llvm::SmallVector<const PathDiagnosticMacroPiece *, 0> MacroPieces;
77
78 public:
79   PlistPrinter(const FIDMap& FM, AnalyzerOptions &AnOpts,
80                const Preprocessor &PP)
81     : FM(FM), AnOpts(AnOpts), PP(PP) {
82   }
83
84   void ReportDiag(raw_ostream &o, const PathDiagnosticPiece& P) {
85     ReportPiece(o, P, /*indent*/ 4, /*depth*/ 0, /*includeControlFlow*/ true);
86
87     // Don't emit a warning about an unused private field.
88     (void)AnOpts;
89   }
90
91   /// Print the expansions of the collected macro pieces.
92   ///
93   /// Each time ReportDiag is called on a PathDiagnosticMacroPiece (or, if one
94   /// is found through a call piece, etc), it's subpieces are reported, and the
95   /// piece itself is collected. Call this function after the entire bugpath
96   /// was reported.
97   void ReportMacroExpansions(raw_ostream &o, unsigned indent);
98
99 private:
100   void ReportPiece(raw_ostream &o, const PathDiagnosticPiece &P,
101                    unsigned indent, unsigned depth, bool includeControlFlow,
102                    bool isKeyEvent = false) {
103     switch (P.getKind()) {
104       case PathDiagnosticPiece::ControlFlow:
105         if (includeControlFlow)
106           ReportControlFlow(o, cast<PathDiagnosticControlFlowPiece>(P), indent);
107         break;
108       case PathDiagnosticPiece::Call:
109         ReportCall(o, cast<PathDiagnosticCallPiece>(P), indent,
110                    depth);
111         break;
112       case PathDiagnosticPiece::Event:
113         ReportEvent(o, cast<PathDiagnosticEventPiece>(P), indent, depth,
114                     isKeyEvent);
115         break;
116       case PathDiagnosticPiece::Macro:
117         ReportMacroSubPieces(o, cast<PathDiagnosticMacroPiece>(P), indent,
118                              depth);
119         break;
120       case PathDiagnosticPiece::Note:
121         ReportNote(o, cast<PathDiagnosticNotePiece>(P), indent);
122         break;
123       case PathDiagnosticPiece::PopUp:
124         ReportPopUp(o, cast<PathDiagnosticPopUpPiece>(P), indent);
125         break;
126     }
127   }
128
129   void EmitRanges(raw_ostream &o, const ArrayRef<SourceRange> Ranges,
130                   unsigned indent);
131   void EmitMessage(raw_ostream &o, StringRef Message, unsigned indent);
132
133   void ReportControlFlow(raw_ostream &o,
134                          const PathDiagnosticControlFlowPiece& P,
135                          unsigned indent);
136   void ReportEvent(raw_ostream &o, const PathDiagnosticEventPiece& P,
137                    unsigned indent, unsigned depth, bool isKeyEvent = false);
138   void ReportCall(raw_ostream &o, const PathDiagnosticCallPiece &P,
139                   unsigned indent, unsigned depth);
140   void ReportMacroSubPieces(raw_ostream &o, const PathDiagnosticMacroPiece& P,
141                             unsigned indent, unsigned depth);
142   void ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
143                   unsigned indent);
144
145   void ReportPopUp(raw_ostream &o, const PathDiagnosticPopUpPiece &P,
146                    unsigned indent);
147 };
148
149 } // end of anonymous namespace
150
151 namespace {
152
153 struct ExpansionInfo {
154   std::string MacroName;
155   std::string Expansion;
156   ExpansionInfo(std::string N, std::string E)
157     : MacroName(std::move(N)), Expansion(std::move(E)) {}
158 };
159
160 } // end of anonymous namespace
161
162 static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
163                          AnalyzerOptions &AnOpts,
164                          const Preprocessor &PP,
165                          const PathPieces &Path);
166
167 /// Print coverage information to output stream {@code o}.
168 /// May modify the used list of files {@code Fids} by inserting new ones.
169 static void printCoverage(const PathDiagnostic *D,
170                           unsigned InputIndentLevel,
171                           SmallVectorImpl<FileID> &Fids,
172                           FIDMap &FM,
173                           llvm::raw_fd_ostream &o);
174
175 static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
176                                       const Preprocessor &PP);
177
178 //===----------------------------------------------------------------------===//
179 // Methods of PlistPrinter.
180 //===----------------------------------------------------------------------===//
181
182 void PlistPrinter::EmitRanges(raw_ostream &o,
183                               const ArrayRef<SourceRange> Ranges,
184                               unsigned indent) {
185
186   if (Ranges.empty())
187     return;
188
189   Indent(o, indent) << "<key>ranges</key>\n";
190   Indent(o, indent) << "<array>\n";
191   ++indent;
192
193   const SourceManager &SM = PP.getSourceManager();
194   const LangOptions &LangOpts = PP.getLangOpts();
195
196   for (auto &R : Ranges)
197     EmitRange(o, SM,
198               Lexer::getAsCharRange(SM.getExpansionRange(R), SM, LangOpts),
199               FM, indent + 1);
200   --indent;
201   Indent(o, indent) << "</array>\n";
202 }
203
204 void PlistPrinter::EmitMessage(raw_ostream &o, StringRef Message,
205                                unsigned indent) {
206   // Output the text.
207   assert(!Message.empty());
208   Indent(o, indent) << "<key>extended_message</key>\n";
209   Indent(o, indent);
210   EmitString(o, Message) << '\n';
211
212   // Output the short text.
213   // FIXME: Really use a short string.
214   Indent(o, indent) << "<key>message</key>\n";
215   Indent(o, indent);
216   EmitString(o, Message) << '\n';
217 }
218
219 void PlistPrinter::ReportControlFlow(raw_ostream &o,
220                                      const PathDiagnosticControlFlowPiece& P,
221                                      unsigned indent) {
222
223   const SourceManager &SM = PP.getSourceManager();
224   const LangOptions &LangOpts = PP.getLangOpts();
225
226   Indent(o, indent) << "<dict>\n";
227   ++indent;
228
229   Indent(o, indent) << "<key>kind</key><string>control</string>\n";
230
231   // Emit edges.
232   Indent(o, indent) << "<key>edges</key>\n";
233   ++indent;
234   Indent(o, indent) << "<array>\n";
235   ++indent;
236   for (PathDiagnosticControlFlowPiece::const_iterator I=P.begin(), E=P.end();
237        I!=E; ++I) {
238     Indent(o, indent) << "<dict>\n";
239     ++indent;
240
241     // Make the ranges of the start and end point self-consistent with adjacent edges
242     // by forcing to use only the beginning of the range.  This simplifies the layout
243     // logic for clients.
244     Indent(o, indent) << "<key>start</key>\n";
245     SourceRange StartEdge(
246         SM.getExpansionLoc(I->getStart().asRange().getBegin()));
247     EmitRange(o, SM, Lexer::getAsCharRange(StartEdge, SM, LangOpts), FM,
248               indent + 1);
249
250     Indent(o, indent) << "<key>end</key>\n";
251     SourceRange EndEdge(SM.getExpansionLoc(I->getEnd().asRange().getBegin()));
252     EmitRange(o, SM, Lexer::getAsCharRange(EndEdge, SM, LangOpts), FM,
253               indent + 1);
254
255     --indent;
256     Indent(o, indent) << "</dict>\n";
257   }
258   --indent;
259   Indent(o, indent) << "</array>\n";
260   --indent;
261
262   // Output any helper text.
263   const auto &s = P.getString();
264   if (!s.empty()) {
265     Indent(o, indent) << "<key>alternate</key>";
266     EmitString(o, s) << '\n';
267   }
268
269   --indent;
270   Indent(o, indent) << "</dict>\n";
271 }
272
273 void PlistPrinter::ReportEvent(raw_ostream &o, const PathDiagnosticEventPiece& P,
274                                unsigned indent, unsigned depth,
275                                bool isKeyEvent) {
276
277   const SourceManager &SM = PP.getSourceManager();
278
279   Indent(o, indent) << "<dict>\n";
280   ++indent;
281
282   Indent(o, indent) << "<key>kind</key><string>event</string>\n";
283
284   if (isKeyEvent) {
285     Indent(o, indent) << "<key>key_event</key><true/>\n";
286   }
287
288   // Output the location.
289   FullSourceLoc L = P.getLocation().asLocation();
290
291   Indent(o, indent) << "<key>location</key>\n";
292   EmitLocation(o, SM, L, FM, indent);
293
294   // Output the ranges (if any).
295   ArrayRef<SourceRange> Ranges = P.getRanges();
296   EmitRanges(o, Ranges, indent);
297
298   // Output the call depth.
299   Indent(o, indent) << "<key>depth</key>";
300   EmitInteger(o, depth) << '\n';
301
302   // Output the text.
303   EmitMessage(o, P.getString(), indent);
304
305   // Finish up.
306   --indent;
307   Indent(o, indent); o << "</dict>\n";
308 }
309
310 void PlistPrinter::ReportCall(raw_ostream &o, const PathDiagnosticCallPiece &P,
311                               unsigned indent,
312                               unsigned depth) {
313
314   if (auto callEnter = P.getCallEnterEvent())
315     ReportPiece(o, *callEnter, indent, depth, /*includeControlFlow*/ true,
316                 P.isLastInMainSourceFile());
317
318
319   ++depth;
320
321   if (auto callEnterWithinCaller = P.getCallEnterWithinCallerEvent())
322     ReportPiece(o, *callEnterWithinCaller, indent, depth,
323                 /*includeControlFlow*/ true);
324
325   for (PathPieces::const_iterator I = P.path.begin(), E = P.path.end();I!=E;++I)
326     ReportPiece(o, **I, indent, depth, /*includeControlFlow*/ true);
327
328   --depth;
329
330   if (auto callExit = P.getCallExitEvent())
331     ReportPiece(o, *callExit, indent, depth, /*includeControlFlow*/ true);
332 }
333
334 void PlistPrinter::ReportMacroSubPieces(raw_ostream &o,
335                                         const PathDiagnosticMacroPiece& P,
336                                         unsigned indent, unsigned depth) {
337   MacroPieces.push_back(&P);
338
339   for (PathPieces::const_iterator I = P.subPieces.begin(),
340                                   E = P.subPieces.end();
341        I != E; ++I) {
342     ReportPiece(o, **I, indent, depth, /*includeControlFlow*/ false);
343   }
344 }
345
346 void PlistPrinter::ReportMacroExpansions(raw_ostream &o, unsigned indent) {
347
348   for (const PathDiagnosticMacroPiece *P : MacroPieces) {
349     const SourceManager &SM = PP.getSourceManager();
350     ExpansionInfo EI = getExpandedMacro(P->getLocation().asLocation(), PP);
351
352     Indent(o, indent) << "<dict>\n";
353     ++indent;
354
355     // Output the location.
356     FullSourceLoc L = P->getLocation().asLocation();
357
358     Indent(o, indent) << "<key>location</key>\n";
359     EmitLocation(o, SM, L, FM, indent);
360
361     // Output the ranges (if any).
362     ArrayRef<SourceRange> Ranges = P->getRanges();
363     EmitRanges(o, Ranges, indent);
364
365     // Output the macro name.
366     Indent(o, indent) << "<key>name</key>";
367     EmitString(o, EI.MacroName) << '\n';
368
369     // Output what it expands into.
370     Indent(o, indent) << "<key>expansion</key>";
371     EmitString(o, EI.Expansion) << '\n';
372
373     // Finish up.
374     --indent;
375     Indent(o, indent);
376     o << "</dict>\n";
377   }
378 }
379
380 void PlistPrinter::ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
381                               unsigned indent) {
382
383   const SourceManager &SM = PP.getSourceManager();
384
385   Indent(o, indent) << "<dict>\n";
386   ++indent;
387
388   // Output the location.
389   FullSourceLoc L = P.getLocation().asLocation();
390
391   Indent(o, indent) << "<key>location</key>\n";
392   EmitLocation(o, SM, L, FM, indent);
393
394   // Output the ranges (if any).
395   ArrayRef<SourceRange> Ranges = P.getRanges();
396   EmitRanges(o, Ranges, indent);
397
398   // Output the text.
399   EmitMessage(o, P.getString(), indent);
400
401   // Finish up.
402   --indent;
403   Indent(o, indent); o << "</dict>\n";
404 }
405
406 void PlistPrinter::ReportPopUp(raw_ostream &o,
407                                const PathDiagnosticPopUpPiece &P,
408                                unsigned indent) {
409   const SourceManager &SM = PP.getSourceManager();
410
411   Indent(o, indent) << "<dict>\n";
412   ++indent;
413
414   Indent(o, indent) << "<key>kind</key><string>pop-up</string>\n";
415
416   // Output the location.
417   FullSourceLoc L = P.getLocation().asLocation();
418
419   Indent(o, indent) << "<key>location</key>\n";
420   EmitLocation(o, SM, L, FM, indent);
421
422   // Output the ranges (if any).
423   ArrayRef<SourceRange> Ranges = P.getRanges();
424   EmitRanges(o, Ranges, indent);
425
426   // Output the text.
427   EmitMessage(o, P.getString(), indent);
428
429   // Finish up.
430   --indent;
431   Indent(o, indent) << "</dict>\n";
432 }
433
434 //===----------------------------------------------------------------------===//
435 // Static function definitions.
436 //===----------------------------------------------------------------------===//
437
438 /// Print coverage information to output stream {@code o}.
439 /// May modify the used list of files {@code Fids} by inserting new ones.
440 static void printCoverage(const PathDiagnostic *D,
441                           unsigned InputIndentLevel,
442                           SmallVectorImpl<FileID> &Fids,
443                           FIDMap &FM,
444                           llvm::raw_fd_ostream &o) {
445   unsigned IndentLevel = InputIndentLevel;
446
447   Indent(o, IndentLevel) << "<key>ExecutedLines</key>\n";
448   Indent(o, IndentLevel) << "<dict>\n";
449   IndentLevel++;
450
451   // Mapping from file IDs to executed lines.
452   const FilesToLineNumsMap &ExecutedLines = D->getExecutedLines();
453   for (auto I = ExecutedLines.begin(), E = ExecutedLines.end(); I != E; ++I) {
454     unsigned FileKey = AddFID(FM, Fids, I->first);
455     Indent(o, IndentLevel) << "<key>" << FileKey << "</key>\n";
456     Indent(o, IndentLevel) << "<array>\n";
457     IndentLevel++;
458     for (unsigned LineNo : I->second) {
459       Indent(o, IndentLevel);
460       EmitInteger(o, LineNo) << "\n";
461     }
462     IndentLevel--;
463     Indent(o, IndentLevel) << "</array>\n";
464   }
465   IndentLevel--;
466   Indent(o, IndentLevel) << "</dict>\n";
467
468   assert(IndentLevel == InputIndentLevel);
469 }
470
471 static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
472                          AnalyzerOptions &AnOpts,
473                          const Preprocessor &PP,
474                          const PathPieces &Path) {
475   PlistPrinter Printer(FM, AnOpts, PP);
476   assert(std::is_partitioned(
477            Path.begin(), Path.end(),
478            [](const std::shared_ptr<PathDiagnosticPiece> &E)
479              { return E->getKind() == PathDiagnosticPiece::Note; }) &&
480          "PathDiagnostic is not partitioned so that notes precede the rest");
481
482   PathPieces::const_iterator FirstNonNote = std::partition_point(
483       Path.begin(), Path.end(),
484       [](const std::shared_ptr<PathDiagnosticPiece> &E)
485         { return E->getKind() == PathDiagnosticPiece::Note; });
486
487   PathPieces::const_iterator I = Path.begin();
488
489   if (FirstNonNote != Path.begin()) {
490     o << "   <key>notes</key>\n"
491          "   <array>\n";
492
493     for (; I != FirstNonNote; ++I)
494       Printer.ReportDiag(o, **I);
495
496     o << "   </array>\n";
497   }
498
499   o << "   <key>path</key>\n";
500
501   o << "   <array>\n";
502
503   for (PathPieces::const_iterator E = Path.end(); I != E; ++I)
504     Printer.ReportDiag(o, **I);
505
506   o << "   </array>\n";
507
508   if (!AnOpts.ShouldDisplayMacroExpansions)
509     return;
510
511   o << "   <key>macro_expansions</key>\n"
512        "   <array>\n";
513   Printer.ReportMacroExpansions(o, /* indent */ 4);
514   o << "   </array>\n";
515 }
516
517 //===----------------------------------------------------------------------===//
518 // Methods of PlistDiagnostics.
519 //===----------------------------------------------------------------------===//
520
521 PlistDiagnostics::PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
522                                    const std::string& output,
523                                    const Preprocessor &PP,
524                                    bool supportsMultipleFiles)
525   : OutputFile(output), PP(PP), AnOpts(AnalyzerOpts),
526     SupportsCrossFileDiagnostics(supportsMultipleFiles) {}
527
528 void ento::createPlistDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
529                                          PathDiagnosticConsumers &C,
530                                          const std::string& s,
531                                          const Preprocessor &PP) {
532   C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP,
533                                    /*supportsMultipleFiles*/ false));
534 }
535
536 void ento::createPlistMultiFileDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
537                                                   PathDiagnosticConsumers &C,
538                                                   const std::string &s,
539                                                   const Preprocessor &PP) {
540   C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP,
541                                    /*supportsMultipleFiles*/ true));
542 }
543 void PlistDiagnostics::FlushDiagnosticsImpl(
544                                     std::vector<const PathDiagnostic *> &Diags,
545                                     FilesMade *filesMade) {
546   // Build up a set of FIDs that we use by scanning the locations and
547   // ranges of the diagnostics.
548   FIDMap FM;
549   SmallVector<FileID, 10> Fids;
550   const SourceManager& SM = PP.getSourceManager();
551   const LangOptions &LangOpts = PP.getLangOpts();
552
553   auto AddPieceFID = [&FM, &Fids, &SM](const PathDiagnosticPiece &Piece) {
554     AddFID(FM, Fids, SM, Piece.getLocation().asLocation());
555     ArrayRef<SourceRange> Ranges = Piece.getRanges();
556     for (const SourceRange &Range : Ranges) {
557       AddFID(FM, Fids, SM, Range.getBegin());
558       AddFID(FM, Fids, SM, Range.getEnd());
559     }
560   };
561
562   for (const PathDiagnostic *D : Diags) {
563
564     SmallVector<const PathPieces *, 5> WorkList;
565     WorkList.push_back(&D->path);
566
567     while (!WorkList.empty()) {
568       const PathPieces &Path = *WorkList.pop_back_val();
569
570       for (const auto &Iter : Path) {
571         const PathDiagnosticPiece &Piece = *Iter;
572         AddPieceFID(Piece);
573
574         if (const PathDiagnosticCallPiece *Call =
575                 dyn_cast<PathDiagnosticCallPiece>(&Piece)) {
576           if (auto CallEnterWithin = Call->getCallEnterWithinCallerEvent())
577             AddPieceFID(*CallEnterWithin);
578
579           if (auto CallEnterEvent = Call->getCallEnterEvent())
580             AddPieceFID(*CallEnterEvent);
581
582           WorkList.push_back(&Call->path);
583         } else if (const PathDiagnosticMacroPiece *Macro =
584                        dyn_cast<PathDiagnosticMacroPiece>(&Piece)) {
585           WorkList.push_back(&Macro->subPieces);
586         }
587       }
588     }
589   }
590
591   // Open the file.
592   std::error_code EC;
593   llvm::raw_fd_ostream o(OutputFile, EC, llvm::sys::fs::F_Text);
594   if (EC) {
595     llvm::errs() << "warning: could not create file: " << EC.message() << '\n';
596     return;
597   }
598
599   EmitPlistHeader(o);
600
601   // Write the root object: a <dict> containing...
602   //  - "clang_version", the string representation of clang version
603   //  - "files", an <array> mapping from FIDs to file names
604   //  - "diagnostics", an <array> containing the path diagnostics
605   o << "<dict>\n" <<
606        " <key>clang_version</key>\n";
607   EmitString(o, getClangFullVersion()) << '\n';
608   o << " <key>diagnostics</key>\n"
609        " <array>\n";
610
611   for (std::vector<const PathDiagnostic*>::iterator DI=Diags.begin(),
612        DE = Diags.end(); DI!=DE; ++DI) {
613
614     o << "  <dict>\n";
615
616     const PathDiagnostic *D = *DI;
617     printBugPath(o, FM, AnOpts, PP, D->path);
618
619     // Output the bug type and bug category.
620     o << "   <key>description</key>";
621     EmitString(o, D->getShortDescription()) << '\n';
622     o << "   <key>category</key>";
623     EmitString(o, D->getCategory()) << '\n';
624     o << "   <key>type</key>";
625     EmitString(o, D->getBugType()) << '\n';
626     o << "   <key>check_name</key>";
627     EmitString(o, D->getCheckName()) << '\n';
628
629     o << "   <!-- This hash is experimental and going to change! -->\n";
630     o << "   <key>issue_hash_content_of_line_in_context</key>";
631     PathDiagnosticLocation UPDLoc = D->getUniqueingLoc();
632     FullSourceLoc L(SM.getExpansionLoc(UPDLoc.isValid()
633                                             ? UPDLoc.asLocation()
634                                             : D->getLocation().asLocation()),
635                     SM);
636     const Decl *DeclWithIssue = D->getDeclWithIssue();
637     EmitString(o, GetIssueHash(SM, L, D->getCheckName(), D->getBugType(),
638                                DeclWithIssue, LangOpts))
639         << '\n';
640
641     // Output information about the semantic context where
642     // the issue occurred.
643     if (const Decl *DeclWithIssue = D->getDeclWithIssue()) {
644       // FIXME: handle blocks, which have no name.
645       if (const NamedDecl *ND = dyn_cast<NamedDecl>(DeclWithIssue)) {
646         StringRef declKind;
647         switch (ND->getKind()) {
648           case Decl::CXXRecord:
649             declKind = "C++ class";
650             break;
651           case Decl::CXXMethod:
652             declKind = "C++ method";
653             break;
654           case Decl::ObjCMethod:
655             declKind = "Objective-C method";
656             break;
657           case Decl::Function:
658             declKind = "function";
659             break;
660           default:
661             break;
662         }
663         if (!declKind.empty()) {
664           const std::string &declName = ND->getDeclName().getAsString();
665           o << "  <key>issue_context_kind</key>";
666           EmitString(o, declKind) << '\n';
667           o << "  <key>issue_context</key>";
668           EmitString(o, declName) << '\n';
669         }
670
671         // Output the bug hash for issue unique-ing. Currently, it's just an
672         // offset from the beginning of the function.
673         if (const Stmt *Body = DeclWithIssue->getBody()) {
674
675           // If the bug uniqueing location exists, use it for the hash.
676           // For example, this ensures that two leaks reported on the same line
677           // will have different issue_hashes and that the hash will identify
678           // the leak location even after code is added between the allocation
679           // site and the end of scope (leak report location).
680           if (UPDLoc.isValid()) {
681             FullSourceLoc UFunL(
682                 SM.getExpansionLoc(
683                     D->getUniqueingDecl()->getBody()->getBeginLoc()),
684                 SM);
685             o << "  <key>issue_hash_function_offset</key><string>"
686               << L.getExpansionLineNumber() - UFunL.getExpansionLineNumber()
687               << "</string>\n";
688
689           // Otherwise, use the location on which the bug is reported.
690           } else {
691             FullSourceLoc FunL(SM.getExpansionLoc(Body->getBeginLoc()), SM);
692             o << "  <key>issue_hash_function_offset</key><string>"
693               << L.getExpansionLineNumber() - FunL.getExpansionLineNumber()
694               << "</string>\n";
695           }
696
697         }
698       }
699     }
700
701     // Output the location of the bug.
702     o << "  <key>location</key>\n";
703     EmitLocation(o, SM, D->getLocation().asLocation(), FM, 2);
704
705     // Output the diagnostic to the sub-diagnostic client, if any.
706     if (!filesMade->empty()) {
707       StringRef lastName;
708       PDFileEntry::ConsumerFiles *files = filesMade->getFiles(*D);
709       if (files) {
710         for (PDFileEntry::ConsumerFiles::const_iterator CI = files->begin(),
711                 CE = files->end(); CI != CE; ++CI) {
712           StringRef newName = CI->first;
713           if (newName != lastName) {
714             if (!lastName.empty()) {
715               o << "  </array>\n";
716             }
717             lastName = newName;
718             o <<  "  <key>" << lastName << "_files</key>\n";
719             o << "  <array>\n";
720           }
721           o << "   <string>" << CI->second << "</string>\n";
722         }
723         o << "  </array>\n";
724       }
725     }
726
727     printCoverage(D, /*IndentLevel=*/2, Fids, FM, o);
728
729     // Close up the entry.
730     o << "  </dict>\n";
731   }
732
733   o << " </array>\n";
734
735   o << " <key>files</key>\n"
736        " <array>\n";
737   for (FileID FID : Fids)
738     EmitString(o << "  ", SM.getFileEntryForID(FID)->getName()) << '\n';
739   o << " </array>\n";
740
741   if (llvm::AreStatisticsEnabled() && AnOpts.ShouldSerializeStats) {
742     o << " <key>statistics</key>\n";
743     std::string stats;
744     llvm::raw_string_ostream os(stats);
745     llvm::PrintStatisticsJSON(os);
746     os.flush();
747     EmitString(o, html::EscapeText(stats)) << '\n';
748   }
749
750   // Finish.
751   o << "</dict>\n</plist>\n";
752 }
753
754 //===----------------------------------------------------------------------===//
755 // Declarations of helper functions and data structures for expanding macros.
756 //===----------------------------------------------------------------------===//
757
758 namespace {
759
760 using ExpArgTokens = llvm::SmallVector<Token, 2>;
761
762 /// Maps unexpanded macro arguments to expanded arguments. A macro argument may
763 /// need to expanded further when it is nested inside another macro.
764 class MacroArgMap : public std::map<const IdentifierInfo *, ExpArgTokens> {
765 public:
766   void expandFromPrevMacro(const MacroArgMap &Super);
767 };
768
769 struct MacroNameAndArgs {
770   std::string Name;
771   const MacroInfo *MI = nullptr;
772   MacroArgMap Args;
773
774   MacroNameAndArgs(std::string N, const MacroInfo *MI, MacroArgMap M)
775     : Name(std::move(N)), MI(MI), Args(std::move(M)) {}
776 };
777
778 class TokenPrinter {
779   llvm::raw_ostream &OS;
780   const Preprocessor &PP;
781
782   Token PrevTok, PrevPrevTok;
783   TokenConcatenation ConcatInfo;
784
785 public:
786   TokenPrinter(llvm::raw_ostream &OS, const Preprocessor &PP)
787     : OS(OS), PP(PP), ConcatInfo(PP) {
788     PrevTok.setKind(tok::unknown);
789     PrevPrevTok.setKind(tok::unknown);
790   }
791
792   void printToken(const Token &Tok);
793 };
794
795 } // end of anonymous namespace
796
797 /// The implementation method of getMacroExpansion: It prints the expansion of
798 /// a macro to \p Printer, and returns with the name of the macro.
799 ///
800 /// Since macros can be nested in one another, this function may call itself
801 /// recursively.
802 ///
803 /// Unfortunately, macro arguments have to expanded manually. To understand why,
804 /// observe the following example:
805 ///
806 ///   #define PRINT(x) print(x)
807 ///   #define DO_SOMETHING(str) PRINT(str)
808 ///
809 ///   DO_SOMETHING("Cute panda cubs.");
810 ///
811 /// As we expand the last line, we'll immediately replace PRINT(str) with
812 /// print(x). The information that both 'str' and 'x' refers to the same string
813 /// is an information we have to forward, hence the argument \p PrevArgs.
814 ///
815 /// To avoid infinite recursion we maintain the already processed tokens in
816 /// a set. This is carried as a parameter through the recursive calls. The set
817 /// is extended with the currently processed token and after processing it, the
818 /// token is removed. If the token is already in the set, then recursion stops:
819 ///
820 /// #define f(y) x
821 /// #define x f(x)
822 static std::string getMacroNameAndPrintExpansion(
823     TokenPrinter &Printer,
824     SourceLocation MacroLoc,
825     const Preprocessor &PP,
826     const MacroArgMap &PrevArgs,
827     llvm::SmallPtrSet<IdentifierInfo *, 8> &AlreadyProcessedTokens);
828
829 /// Retrieves the name of the macro and what it's arguments expand into
830 /// at \p ExpanLoc.
831 ///
832 /// For example, for the following macro expansion:
833 ///
834 ///   #define SET_TO_NULL(x) x = 0
835 ///   #define NOT_SUSPICIOUS(a) \
836 ///     {                       \
837 ///       int b = 0;            \
838 ///     }                       \
839 ///     SET_TO_NULL(a)
840 ///
841 ///   int *ptr = new int(4);
842 ///   NOT_SUSPICIOUS(&ptr);
843 ///   *ptr = 5;
844 ///
845 /// When \p ExpanLoc references the last line, the macro name "NOT_SUSPICIOUS"
846 /// and the MacroArgMap map { (a, &ptr) } will be returned.
847 ///
848 /// When \p ExpanLoc references "SET_TO_NULL(a)" within the definition of
849 /// "NOT_SUSPICOUS", the macro name "SET_TO_NULL" and the MacroArgMap map
850 /// { (x, a) } will be returned.
851 static MacroNameAndArgs getMacroNameAndArgs(SourceLocation ExpanLoc,
852                                             const Preprocessor &PP);
853
854 /// Retrieves the ')' token that matches '(' \p It points to.
855 static MacroInfo::tokens_iterator getMatchingRParen(
856     MacroInfo::tokens_iterator It,
857     MacroInfo::tokens_iterator End);
858
859 /// Retrieves the macro info for \p II refers to at \p Loc. This is important
860 /// because macros can be redefined or undefined.
861 static const MacroInfo *getMacroInfoForLocation(const Preprocessor &PP,
862                                                 const SourceManager &SM,
863                                                 const IdentifierInfo *II,
864                                                 SourceLocation Loc);
865
866 //===----------------------------------------------------------------------===//
867 // Definitions of helper functions and methods for expanding macros.
868 //===----------------------------------------------------------------------===//
869
870 static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
871                                       const Preprocessor &PP) {
872
873   llvm::SmallString<200> ExpansionBuf;
874   llvm::raw_svector_ostream OS(ExpansionBuf);
875   TokenPrinter Printer(OS, PP);
876   llvm::SmallPtrSet<IdentifierInfo*, 8> AlreadyProcessedTokens;
877
878   std::string MacroName =
879             getMacroNameAndPrintExpansion(Printer, MacroLoc, PP, MacroArgMap{},
880                                          AlreadyProcessedTokens);
881   return { MacroName, OS.str() };
882 }
883
884 static std::string getMacroNameAndPrintExpansion(
885     TokenPrinter &Printer,
886     SourceLocation MacroLoc,
887     const Preprocessor &PP,
888     const MacroArgMap &PrevArgs,
889     llvm::SmallPtrSet<IdentifierInfo *, 8> &AlreadyProcessedTokens) {
890
891   const SourceManager &SM = PP.getSourceManager();
892
893   MacroNameAndArgs Info = getMacroNameAndArgs(SM.getExpansionLoc(MacroLoc), PP);
894   IdentifierInfo* IDInfo = PP.getIdentifierInfo(Info.Name);
895
896   // TODO: If the macro definition contains another symbol then this function is
897   // called recursively. In case this symbol is the one being defined, it will
898   // be an infinite recursion which is stopped by this "if" statement. However,
899   // in this case we don't get the full expansion text in the Plist file. See
900   // the test file where "value" is expanded to "garbage_" instead of
901   // "garbage_value".
902   if (AlreadyProcessedTokens.find(IDInfo) != AlreadyProcessedTokens.end())
903     return Info.Name;
904   AlreadyProcessedTokens.insert(IDInfo);
905
906   if (!Info.MI)
907     return Info.Name;
908
909   // Manually expand its arguments from the previous macro.
910   Info.Args.expandFromPrevMacro(PrevArgs);
911
912   // Iterate over the macro's tokens and stringify them.
913   for (auto It = Info.MI->tokens_begin(), E = Info.MI->tokens_end(); It != E;
914        ++It) {
915     Token T = *It;
916
917     // If this token is not an identifier, we only need to print it.
918     if (T.isNot(tok::identifier)) {
919       Printer.printToken(T);
920       continue;
921     }
922
923     const auto *II = T.getIdentifierInfo();
924     assert(II &&
925           "This token is an identifier but has no IdentifierInfo!");
926
927     // If this token is a macro that should be expanded inside the current
928     // macro.
929     if (getMacroInfoForLocation(PP, SM, II, T.getLocation())) {
930       getMacroNameAndPrintExpansion(Printer, T.getLocation(), PP, Info.Args,
931                                     AlreadyProcessedTokens);
932
933       // If this is a function-like macro, skip its arguments, as
934       // getExpandedMacro() already printed them. If this is the case, let's
935       // first jump to the '(' token.
936       auto N = std::next(It);
937       if (N != E && N->is(tok::l_paren))
938         It = getMatchingRParen(++It, E);
939       continue;
940     }
941
942     // If this token is the current macro's argument, we should expand it.
943     auto ArgMapIt = Info.Args.find(II);
944     if (ArgMapIt != Info.Args.end()) {
945       for (MacroInfo::tokens_iterator ArgIt = ArgMapIt->second.begin(),
946                                       ArgEnd = ArgMapIt->second.end();
947            ArgIt != ArgEnd; ++ArgIt) {
948
949         // These tokens may still be macros, if that is the case, handle it the
950         // same way we did above.
951         const auto *ArgII = ArgIt->getIdentifierInfo();
952         if (!ArgII) {
953           Printer.printToken(*ArgIt);
954           continue;
955         }
956
957         const auto *MI = PP.getMacroInfo(ArgII);
958         if (!MI) {
959           Printer.printToken(*ArgIt);
960           continue;
961         }
962
963         getMacroNameAndPrintExpansion(Printer, ArgIt->getLocation(), PP,
964                                       Info.Args, AlreadyProcessedTokens);
965         // Peek the next token if it is a tok::l_paren. This way we can decide
966         // if this is the application or just a reference to a function maxro
967         // symbol:
968         //
969         // #define apply(f) ...
970         // #define func(x) ...
971         // apply(func)
972         // apply(func(42))
973         auto N = std::next(ArgIt);
974         if (N != ArgEnd && N->is(tok::l_paren))
975           ArgIt = getMatchingRParen(++ArgIt, ArgEnd);
976       }
977       continue;
978     }
979
980     // If control reached here, then this token isn't a macro identifier, nor an
981     // unexpanded macro argument that we need to handle, print it.
982     Printer.printToken(T);
983   }
984
985   AlreadyProcessedTokens.erase(IDInfo);
986
987   return Info.Name;
988 }
989
990 static MacroNameAndArgs getMacroNameAndArgs(SourceLocation ExpanLoc,
991                                             const Preprocessor &PP) {
992
993   const SourceManager &SM = PP.getSourceManager();
994   const LangOptions &LangOpts = PP.getLangOpts();
995
996   // First, we create a Lexer to lex *at the expansion location* the tokens
997   // referring to the macro's name and its arguments.
998   std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(ExpanLoc);
999   const llvm::MemoryBuffer *MB = SM.getBuffer(LocInfo.first);
1000   const char *MacroNameTokenPos = MB->getBufferStart() + LocInfo.second;
1001
1002   Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), LangOpts,
1003                  MB->getBufferStart(), MacroNameTokenPos, MB->getBufferEnd());
1004
1005   // Acquire the macro's name.
1006   Token TheTok;
1007   RawLexer.LexFromRawLexer(TheTok);
1008
1009   std::string MacroName = PP.getSpelling(TheTok);
1010
1011   const auto *II = PP.getIdentifierInfo(MacroName);
1012   assert(II && "Failed to acquire the IndetifierInfo for the macro!");
1013
1014   const MacroInfo *MI = getMacroInfoForLocation(PP, SM, II, ExpanLoc);
1015   // assert(MI && "The macro must've been defined at it's expansion location!");
1016   //
1017   // We should always be able to obtain the MacroInfo in a given TU, but if
1018   // we're running the analyzer with CTU, the Preprocessor won't contain the
1019   // directive history (or anything for that matter) from another TU.
1020   // TODO: assert when we're not running with CTU.
1021   if (!MI)
1022     return { MacroName, MI, {} };
1023
1024   // Acquire the macro's arguments.
1025   //
1026   // The rough idea here is to lex from the first left parentheses to the last
1027   // right parentheses, and map the macro's unexpanded arguments to what they
1028   // will be expanded to. An expanded macro argument may contain several tokens
1029   // (like '3 + 4'), so we'll lex until we find a tok::comma or tok::r_paren, at
1030   // which point we start lexing the next argument or finish.
1031   ArrayRef<const IdentifierInfo *> MacroArgs = MI->params();
1032   if (MacroArgs.empty())
1033     return { MacroName, MI, {} };
1034
1035   RawLexer.LexFromRawLexer(TheTok);
1036   // When this is a token which expands to another macro function then its
1037   // parentheses are not at its expansion locaiton. For example:
1038   //
1039   // #define foo(x) int bar() { return x; }
1040   // #define apply_zero(f) f(0)
1041   // apply_zero(foo)
1042   //               ^
1043   //               This is not a tok::l_paren, but foo is a function.
1044   if (TheTok.isNot(tok::l_paren))
1045     return { MacroName, MI, {} };
1046
1047   MacroArgMap Args;
1048
1049   // When the macro's argument is a function call, like
1050   //   CALL_FN(someFunctionName(param1, param2))
1051   // we will find tok::l_paren, tok::r_paren, and tok::comma that do not divide
1052   // actual macro arguments, or do not represent the macro argument's closing
1053   // parentheses, so we'll count how many parentheses aren't closed yet.
1054   // If ParanthesesDepth
1055   //   * = 0, then there are no more arguments to lex.
1056   //   * = 1, then if we find a tok::comma, we can start lexing the next arg.
1057   //   * > 1, then tok::comma is a part of the current arg.
1058   int ParenthesesDepth = 1;
1059
1060   // If we encounter __VA_ARGS__, we will lex until the closing tok::r_paren,
1061   // even if we lex a tok::comma and ParanthesesDepth == 1.
1062   const IdentifierInfo *__VA_ARGS__II = PP.getIdentifierInfo("__VA_ARGS__");
1063
1064   for (const IdentifierInfo *UnexpArgII : MacroArgs) {
1065     MacroArgMap::mapped_type ExpandedArgTokens;
1066
1067     // One could also simply not supply a single argument to __VA_ARGS__ -- this
1068     // results in a preprocessor warning, but is not an error:
1069     //   #define VARIADIC(ptr, ...) \
1070     //     someVariadicTemplateFunction(__VA_ARGS__)
1071     //
1072     //   int *ptr;
1073     //   VARIADIC(ptr); // Note that there are no commas, this isn't just an
1074     //                  // empty parameter -- there are no parameters for '...'.
1075     // In any other case, ParenthesesDepth mustn't be 0 here.
1076     if (ParenthesesDepth != 0) {
1077
1078       // Lex the first token of the next macro parameter.
1079       RawLexer.LexFromRawLexer(TheTok);
1080
1081       while (!(ParenthesesDepth == 1 &&
1082               (UnexpArgII == __VA_ARGS__II ? false : TheTok.is(tok::comma)))) {
1083         assert(TheTok.isNot(tok::eof) &&
1084                "EOF encountered while looking for expanded macro args!");
1085
1086         if (TheTok.is(tok::l_paren))
1087           ++ParenthesesDepth;
1088
1089         if (TheTok.is(tok::r_paren))
1090           --ParenthesesDepth;
1091
1092         if (ParenthesesDepth == 0)
1093           break;
1094
1095         if (TheTok.is(tok::raw_identifier))
1096           PP.LookUpIdentifierInfo(TheTok);
1097
1098         ExpandedArgTokens.push_back(TheTok);
1099         RawLexer.LexFromRawLexer(TheTok);
1100       }
1101     } else {
1102       assert(UnexpArgII == __VA_ARGS__II);
1103     }
1104
1105     Args.emplace(UnexpArgII, std::move(ExpandedArgTokens));
1106   }
1107
1108   assert(TheTok.is(tok::r_paren) &&
1109          "Expanded macro argument acquisition failed! After the end of the loop"
1110          " this token should be ')'!");
1111
1112   return { MacroName, MI, Args };
1113 }
1114
1115 static MacroInfo::tokens_iterator getMatchingRParen(
1116     MacroInfo::tokens_iterator It,
1117     MacroInfo::tokens_iterator End) {
1118
1119   assert(It->is(tok::l_paren) && "This token should be '('!");
1120
1121   // Skip until we find the closing ')'.
1122   int ParenthesesDepth = 1;
1123   while (ParenthesesDepth != 0) {
1124     ++It;
1125
1126     assert(It->isNot(tok::eof) &&
1127            "Encountered EOF while attempting to skip macro arguments!");
1128     assert(It != End &&
1129            "End of the macro definition reached before finding ')'!");
1130
1131     if (It->is(tok::l_paren))
1132       ++ParenthesesDepth;
1133
1134     if (It->is(tok::r_paren))
1135       --ParenthesesDepth;
1136   }
1137   return It;
1138 }
1139
1140 static const MacroInfo *getMacroInfoForLocation(const Preprocessor &PP,
1141                                                 const SourceManager &SM,
1142                                                 const IdentifierInfo *II,
1143                                                 SourceLocation Loc) {
1144
1145   const MacroDirective *MD = PP.getLocalMacroDirectiveHistory(II);
1146   if (!MD)
1147     return nullptr;
1148
1149   return MD->findDirectiveAtLoc(Loc, SM).getMacroInfo();
1150 }
1151
1152 void MacroArgMap::expandFromPrevMacro(const MacroArgMap &Super) {
1153
1154   for (value_type &Pair : *this) {
1155     ExpArgTokens &CurrExpArgTokens = Pair.second;
1156
1157     // For each token in the expanded macro argument.
1158     auto It = CurrExpArgTokens.begin();
1159     while (It != CurrExpArgTokens.end()) {
1160       if (It->isNot(tok::identifier)) {
1161         ++It;
1162         continue;
1163       }
1164
1165       const auto *II = It->getIdentifierInfo();
1166       assert(II);
1167
1168       // Is this an argument that "Super" expands further?
1169       if (!Super.count(II)) {
1170         ++It;
1171         continue;
1172       }
1173
1174       const ExpArgTokens &SuperExpArgTokens = Super.at(II);
1175
1176       It = CurrExpArgTokens.insert(
1177           It, SuperExpArgTokens.begin(), SuperExpArgTokens.end());
1178       std::advance(It, SuperExpArgTokens.size());
1179       It = CurrExpArgTokens.erase(It);
1180     }
1181   }
1182 }
1183
1184 void TokenPrinter::printToken(const Token &Tok) {
1185   // If this is the first token to be printed, don't print space.
1186   if (PrevTok.isNot(tok::unknown)) {
1187     // If the tokens were already space separated, or if they must be to avoid
1188     // them being implicitly pasted, add a space between them.
1189     if(Tok.hasLeadingSpace() || ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok,
1190                                                        Tok)) {
1191       // AvoidConcat doesn't check for ##, don't print a space around it.
1192       if (PrevTok.isNot(tok::hashhash) && Tok.isNot(tok::hashhash)) {
1193         OS << ' ';
1194       }
1195     }
1196   }
1197
1198   if (!Tok.isOneOf(tok::hash, tok::hashhash)) {
1199     if (PrevTok.is(tok::hash))
1200       OS << '\"' << PP.getSpelling(Tok) << '\"';
1201     else
1202       OS << PP.getSpelling(Tok);
1203   }
1204
1205   PrevPrevTok = PrevTok;
1206   PrevTok = Tok;
1207 }