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