1 //===--- FrontendActions.cpp ----------------------------------------------===//
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 #include "clang/Frontend/FrontendActions.h"
10 #include "clang/AST/ASTConsumer.h"
11 #include "clang/Basic/FileManager.h"
12 #include "clang/Basic/TargetInfo.h"
13 #include "clang/Basic/LangStandard.h"
14 #include "clang/Frontend/ASTConsumers.h"
15 #include "clang/Frontend/CompilerInstance.h"
16 #include "clang/Frontend/FrontendDiagnostic.h"
17 #include "clang/Frontend/MultiplexConsumer.h"
18 #include "clang/Frontend/Utils.h"
19 #include "clang/Lex/DependencyDirectivesSourceMinimizer.h"
20 #include "clang/Lex/HeaderSearch.h"
21 #include "clang/Lex/Preprocessor.h"
22 #include "clang/Lex/PreprocessorOptions.h"
23 #include "clang/Sema/TemplateInstCallback.h"
24 #include "clang/Serialization/ASTReader.h"
25 #include "clang/Serialization/ASTWriter.h"
26 #include "llvm/Support/FileSystem.h"
27 #include "llvm/Support/MemoryBuffer.h"
28 #include "llvm/Support/Path.h"
29 #include "llvm/Support/YAMLTraits.h"
30 #include "llvm/Support/raw_ostream.h"
31 #include <memory>
32 #include <system_error>
33 
34 using namespace clang;
35 
36 namespace {
37 CodeCompleteConsumer *GetCodeCompletionConsumer(CompilerInstance &CI) {
38   return CI.hasCodeCompletionConsumer() ? &CI.getCodeCompletionConsumer()
39                                         : nullptr;
40 }
41 
42 void EnsureSemaIsCreated(CompilerInstance &CI, FrontendAction &Action) {
43   if (Action.hasCodeCompletionSupport() &&
44       !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
45     CI.createCodeCompletionConsumer();
46 
47   if (!CI.hasSema())
48     CI.createSema(Action.getTranslationUnitKind(),
49                   GetCodeCompletionConsumer(CI));
50 }
51 } // namespace
52 
53 //===----------------------------------------------------------------------===//
54 // Custom Actions
55 //===----------------------------------------------------------------------===//
56 
57 std::unique_ptr<ASTConsumer>
58 InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
59   return std::make_unique<ASTConsumer>();
60 }
61 
62 void InitOnlyAction::ExecuteAction() {
63 }
64 
65 //===----------------------------------------------------------------------===//
66 // AST Consumer Actions
67 //===----------------------------------------------------------------------===//
68 
69 std::unique_ptr<ASTConsumer>
70 ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
71   if (std::unique_ptr<raw_ostream> OS =
72           CI.createDefaultOutputFile(false, InFile))
73     return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter);
74   return nullptr;
75 }
76 
77 std::unique_ptr<ASTConsumer>
78 ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
79   const FrontendOptions &Opts = CI.getFrontendOpts();
80   return CreateASTDumper(nullptr /*Dump to stdout.*/, Opts.ASTDumpFilter,
81                          Opts.ASTDumpDecls, Opts.ASTDumpAll,
82                          Opts.ASTDumpLookups, Opts.ASTDumpFormat);
83 }
84 
85 std::unique_ptr<ASTConsumer>
86 ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
87   return CreateASTDeclNodeLister();
88 }
89 
90 std::unique_ptr<ASTConsumer>
91 ASTViewAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
92   return CreateASTViewer();
93 }
94 
95 std::unique_ptr<ASTConsumer>
96 GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
97   std::string Sysroot;
98   if (!ComputeASTConsumerArguments(CI, /*ref*/ Sysroot))
99     return nullptr;
100 
101   std::string OutputFile;
102   std::unique_ptr<raw_pwrite_stream> OS =
103       CreateOutputFile(CI, InFile, /*ref*/ OutputFile);
104   if (!OS)
105     return nullptr;
106 
107   if (!CI.getFrontendOpts().RelocatablePCH)
108     Sysroot.clear();
109 
110   const auto &FrontendOpts = CI.getFrontendOpts();
111   auto Buffer = std::make_shared<PCHBuffer>();
112   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
113   Consumers.push_back(std::make_unique<PCHGenerator>(
114       CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
115       FrontendOpts.ModuleFileExtensions,
116       CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
117       FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH));
118   Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
119       CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
120 
121   return std::make_unique<MultiplexConsumer>(std::move(Consumers));
122 }
123 
124 bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
125                                                     std::string &Sysroot) {
126   Sysroot = CI.getHeaderSearchOpts().Sysroot;
127   if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
128     CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
129     return false;
130   }
131 
132   return true;
133 }
134 
135 std::unique_ptr<llvm::raw_pwrite_stream>
136 GeneratePCHAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile,
137                                     std::string &OutputFile) {
138   // We use createOutputFile here because this is exposed via libclang, and we
139   // must disable the RemoveFileOnSignal behavior.
140   // We use a temporary to avoid race conditions.
141   std::unique_ptr<raw_pwrite_stream> OS =
142       CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
143                           /*RemoveFileOnSignal=*/false, InFile,
144                           /*Extension=*/"", CI.getFrontendOpts().UseTemporary);
145   if (!OS)
146     return nullptr;
147 
148   OutputFile = CI.getFrontendOpts().OutputFile;
149   return OS;
150 }
151 
152 bool GeneratePCHAction::shouldEraseOutputFiles() {
153   if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)
154     return false;
155   return ASTFrontendAction::shouldEraseOutputFiles();
156 }
157 
158 bool GeneratePCHAction::BeginSourceFileAction(CompilerInstance &CI) {
159   CI.getLangOpts().CompilingPCH = true;
160   return true;
161 }
162 
163 std::unique_ptr<ASTConsumer>
164 GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
165                                         StringRef InFile) {
166   std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile);
167   if (!OS)
168     return nullptr;
169 
170   std::string OutputFile = CI.getFrontendOpts().OutputFile;
171   std::string Sysroot;
172 
173   auto Buffer = std::make_shared<PCHBuffer>();
174   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
175 
176   Consumers.push_back(std::make_unique<PCHGenerator>(
177       CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
178       CI.getFrontendOpts().ModuleFileExtensions,
179       /*AllowASTWithErrors=*/false,
180       /*IncludeTimestamps=*/
181       +CI.getFrontendOpts().BuildingImplicitModule,
182       /*ShouldCacheASTInMemory=*/
183       +CI.getFrontendOpts().BuildingImplicitModule));
184   Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
185       CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
186   return std::make_unique<MultiplexConsumer>(std::move(Consumers));
187 }
188 
189 bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(
190     CompilerInstance &CI) {
191   if (!CI.getLangOpts().Modules) {
192     CI.getDiagnostics().Report(diag::err_module_build_requires_fmodules);
193     return false;
194   }
195 
196   return GenerateModuleAction::BeginSourceFileAction(CI);
197 }
198 
199 std::unique_ptr<raw_pwrite_stream>
200 GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
201                                                     StringRef InFile) {
202   // If no output file was provided, figure out where this module would go
203   // in the module cache.
204   if (CI.getFrontendOpts().OutputFile.empty()) {
205     StringRef ModuleMapFile = CI.getFrontendOpts().OriginalModuleMap;
206     if (ModuleMapFile.empty())
207       ModuleMapFile = InFile;
208 
209     HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
210     CI.getFrontendOpts().OutputFile =
211         HS.getCachedModuleFileName(CI.getLangOpts().CurrentModule,
212                                    ModuleMapFile);
213   }
214 
215   // We use createOutputFile here because this is exposed via libclang, and we
216   // must disable the RemoveFileOnSignal behavior.
217   // We use a temporary to avoid race conditions.
218   return CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
219                              /*RemoveFileOnSignal=*/false, InFile,
220                              /*Extension=*/"", /*UseTemporary=*/true,
221                              /*CreateMissingDirectories=*/true);
222 }
223 
224 bool GenerateModuleInterfaceAction::BeginSourceFileAction(
225     CompilerInstance &CI) {
226   if (!CI.getLangOpts().ModulesTS && !CI.getLangOpts().CPlusPlusModules) {
227     CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
228     return false;
229   }
230 
231   CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
232 
233   return GenerateModuleAction::BeginSourceFileAction(CI);
234 }
235 
236 std::unique_ptr<raw_pwrite_stream>
237 GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI,
238                                                 StringRef InFile) {
239   return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
240 }
241 
242 bool GenerateHeaderModuleAction::PrepareToExecuteAction(
243     CompilerInstance &CI) {
244   if (!CI.getLangOpts().Modules) {
245     CI.getDiagnostics().Report(diag::err_header_module_requires_modules);
246     return false;
247   }
248 
249   auto &Inputs = CI.getFrontendOpts().Inputs;
250   if (Inputs.empty())
251     return GenerateModuleAction::BeginInvocation(CI);
252 
253   auto Kind = Inputs[0].getKind();
254 
255   // Convert the header file inputs into a single module input buffer.
256   SmallString<256> HeaderContents;
257   ModuleHeaders.reserve(Inputs.size());
258   for (const FrontendInputFile &FIF : Inputs) {
259     // FIXME: We should support re-compiling from an AST file.
260     if (FIF.getKind().getFormat() != InputKind::Source || !FIF.isFile()) {
261       CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
262           << (FIF.isFile() ? FIF.getFile()
263                            : FIF.getBuffer()->getBufferIdentifier());
264       return true;
265     }
266 
267     HeaderContents += "#include \"";
268     HeaderContents += FIF.getFile();
269     HeaderContents += "\"\n";
270     ModuleHeaders.push_back(std::string(FIF.getFile()));
271   }
272   Buffer = llvm::MemoryBuffer::getMemBufferCopy(
273       HeaderContents, Module::getModuleInputBufferName());
274 
275   // Set that buffer up as our "real" input.
276   Inputs.clear();
277   Inputs.push_back(FrontendInputFile(Buffer.get(), Kind, /*IsSystem*/false));
278 
279   return GenerateModuleAction::PrepareToExecuteAction(CI);
280 }
281 
282 bool GenerateHeaderModuleAction::BeginSourceFileAction(
283     CompilerInstance &CI) {
284   CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderModule);
285 
286   // Synthesize a Module object for the given headers.
287   auto &HS = CI.getPreprocessor().getHeaderSearchInfo();
288   SmallVector<Module::Header, 16> Headers;
289   for (StringRef Name : ModuleHeaders) {
290     const DirectoryLookup *CurDir = nullptr;
291     Optional<FileEntryRef> FE = HS.LookupFile(
292         Name, SourceLocation(), /*Angled*/ false, nullptr, CurDir, None,
293         nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
294     if (!FE) {
295       CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
296         << Name;
297       continue;
298     }
299     Headers.push_back({std::string(Name), &FE->getFileEntry()});
300   }
301   HS.getModuleMap().createHeaderModule(CI.getLangOpts().CurrentModule, Headers);
302 
303   return GenerateModuleAction::BeginSourceFileAction(CI);
304 }
305 
306 std::unique_ptr<raw_pwrite_stream>
307 GenerateHeaderModuleAction::CreateOutputFile(CompilerInstance &CI,
308                                              StringRef InFile) {
309   return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
310 }
311 
312 SyntaxOnlyAction::~SyntaxOnlyAction() {
313 }
314 
315 std::unique_ptr<ASTConsumer>
316 SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
317   return std::make_unique<ASTConsumer>();
318 }
319 
320 std::unique_ptr<ASTConsumer>
321 DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI,
322                                         StringRef InFile) {
323   return std::make_unique<ASTConsumer>();
324 }
325 
326 std::unique_ptr<ASTConsumer>
327 VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
328   return std::make_unique<ASTConsumer>();
329 }
330 
331 void VerifyPCHAction::ExecuteAction() {
332   CompilerInstance &CI = getCompilerInstance();
333   bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
334   const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
335   std::unique_ptr<ASTReader> Reader(new ASTReader(
336       CI.getPreprocessor(), CI.getModuleCache(), &CI.getASTContext(),
337       CI.getPCHContainerReader(), CI.getFrontendOpts().ModuleFileExtensions,
338       Sysroot.empty() ? "" : Sysroot.c_str(),
339       /*DisableValidation*/ false,
340       /*AllowPCHWithCompilerErrors*/ false,
341       /*AllowConfigurationMismatch*/ true,
342       /*ValidateSystemInputs*/ true));
343 
344   Reader->ReadAST(getCurrentFile(),
345                   Preamble ? serialization::MK_Preamble
346                            : serialization::MK_PCH,
347                   SourceLocation(),
348                   ASTReader::ARR_ConfigurationMismatch);
349 }
350 
351 namespace {
352 struct TemplightEntry {
353   std::string Name;
354   std::string Kind;
355   std::string Event;
356   std::string DefinitionLocation;
357   std::string PointOfInstantiation;
358 };
359 } // namespace
360 
361 namespace llvm {
362 namespace yaml {
363 template <> struct MappingTraits<TemplightEntry> {
364   static void mapping(IO &io, TemplightEntry &fields) {
365     io.mapRequired("name", fields.Name);
366     io.mapRequired("kind", fields.Kind);
367     io.mapRequired("event", fields.Event);
368     io.mapRequired("orig", fields.DefinitionLocation);
369     io.mapRequired("poi", fields.PointOfInstantiation);
370   }
371 };
372 } // namespace yaml
373 } // namespace llvm
374 
375 namespace {
376 class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
377   using CodeSynthesisContext = Sema::CodeSynthesisContext;
378 
379 public:
380   void initialize(const Sema &) override {}
381 
382   void finalize(const Sema &) override {}
383 
384   void atTemplateBegin(const Sema &TheSema,
385                        const CodeSynthesisContext &Inst) override {
386     displayTemplightEntry<true>(llvm::outs(), TheSema, Inst);
387   }
388 
389   void atTemplateEnd(const Sema &TheSema,
390                      const CodeSynthesisContext &Inst) override {
391     displayTemplightEntry<false>(llvm::outs(), TheSema, Inst);
392   }
393 
394 private:
395   static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {
396     switch (Kind) {
397     case CodeSynthesisContext::TemplateInstantiation:
398       return "TemplateInstantiation";
399     case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
400       return "DefaultTemplateArgumentInstantiation";
401     case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
402       return "DefaultFunctionArgumentInstantiation";
403     case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
404       return "ExplicitTemplateArgumentSubstitution";
405     case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
406       return "DeducedTemplateArgumentSubstitution";
407     case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
408       return "PriorTemplateArgumentSubstitution";
409     case CodeSynthesisContext::DefaultTemplateArgumentChecking:
410       return "DefaultTemplateArgumentChecking";
411     case CodeSynthesisContext::ExceptionSpecEvaluation:
412       return "ExceptionSpecEvaluation";
413     case CodeSynthesisContext::ExceptionSpecInstantiation:
414       return "ExceptionSpecInstantiation";
415     case CodeSynthesisContext::DeclaringSpecialMember:
416       return "DeclaringSpecialMember";
417     case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
418       return "DeclaringImplicitEqualityComparison";
419     case CodeSynthesisContext::DefiningSynthesizedFunction:
420       return "DefiningSynthesizedFunction";
421     case CodeSynthesisContext::RewritingOperatorAsSpaceship:
422       return "RewritingOperatorAsSpaceship";
423     case CodeSynthesisContext::Memoization:
424       return "Memoization";
425     case CodeSynthesisContext::ConstraintsCheck:
426       return "ConstraintsCheck";
427     case CodeSynthesisContext::ConstraintSubstitution:
428       return "ConstraintSubstitution";
429     case CodeSynthesisContext::ConstraintNormalization:
430       return "ConstraintNormalization";
431     case CodeSynthesisContext::ParameterMappingSubstitution:
432       return "ParameterMappingSubstitution";
433     case CodeSynthesisContext::RequirementInstantiation:
434       return "RequirementInstantiation";
435     case CodeSynthesisContext::NestedRequirementConstraintsCheck:
436       return "NestedRequirementConstraintsCheck";
437     }
438     return "";
439   }
440 
441   template <bool BeginInstantiation>
442   static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema,
443                                     const CodeSynthesisContext &Inst) {
444     std::string YAML;
445     {
446       llvm::raw_string_ostream OS(YAML);
447       llvm::yaml::Output YO(OS);
448       TemplightEntry Entry =
449           getTemplightEntry<BeginInstantiation>(TheSema, Inst);
450       llvm::yaml::EmptyContext Context;
451       llvm::yaml::yamlize(YO, Entry, true, Context);
452     }
453     Out << "---" << YAML << "\n";
454   }
455 
456   template <bool BeginInstantiation>
457   static TemplightEntry getTemplightEntry(const Sema &TheSema,
458                                           const CodeSynthesisContext &Inst) {
459     TemplightEntry Entry;
460     Entry.Kind = toString(Inst.Kind);
461     Entry.Event = BeginInstantiation ? "Begin" : "End";
462     if (auto *NamedTemplate = dyn_cast_or_null<NamedDecl>(Inst.Entity)) {
463       llvm::raw_string_ostream OS(Entry.Name);
464       NamedTemplate->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
465       const PresumedLoc DefLoc =
466         TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation());
467       if(!DefLoc.isInvalid())
468         Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +
469                                    std::to_string(DefLoc.getLine()) + ":" +
470                                    std::to_string(DefLoc.getColumn());
471     }
472     const PresumedLoc PoiLoc =
473         TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation);
474     if (!PoiLoc.isInvalid()) {
475       Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +
476                                    std::to_string(PoiLoc.getLine()) + ":" +
477                                    std::to_string(PoiLoc.getColumn());
478     }
479     return Entry;
480   }
481 };
482 } // namespace
483 
484 std::unique_ptr<ASTConsumer>
485 TemplightDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
486   return std::make_unique<ASTConsumer>();
487 }
488 
489 void TemplightDumpAction::ExecuteAction() {
490   CompilerInstance &CI = getCompilerInstance();
491 
492   // This part is normally done by ASTFrontEndAction, but needs to happen
493   // before Templight observers can be created
494   // FIXME: Move the truncation aspect of this into Sema, we delayed this till
495   // here so the source manager would be initialized.
496   EnsureSemaIsCreated(CI, *this);
497 
498   CI.getSema().TemplateInstCallbacks.push_back(
499       std::make_unique<DefaultTemplateInstCallback>());
500   ASTFrontendAction::ExecuteAction();
501 }
502 
503 namespace {
504   /// AST reader listener that dumps module information for a module
505   /// file.
506   class DumpModuleInfoListener : public ASTReaderListener {
507     llvm::raw_ostream &Out;
508 
509   public:
510     DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { }
511 
512 #define DUMP_BOOLEAN(Value, Text)                       \
513     Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
514 
515     bool ReadFullVersionInformation(StringRef FullVersion) override {
516       Out.indent(2)
517         << "Generated by "
518         << (FullVersion == getClangFullRepositoryVersion()? "this"
519                                                           : "a different")
520         << " Clang: " << FullVersion << "\n";
521       return ASTReaderListener::ReadFullVersionInformation(FullVersion);
522     }
523 
524     void ReadModuleName(StringRef ModuleName) override {
525       Out.indent(2) << "Module name: " << ModuleName << "\n";
526     }
527     void ReadModuleMapFile(StringRef ModuleMapPath) override {
528       Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
529     }
530 
531     bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
532                              bool AllowCompatibleDifferences) override {
533       Out.indent(2) << "Language options:\n";
534 #define LANGOPT(Name, Bits, Default, Description) \
535       DUMP_BOOLEAN(LangOpts.Name, Description);
536 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
537       Out.indent(4) << Description << ": "                   \
538                     << static_cast<unsigned>(LangOpts.get##Name()) << "\n";
539 #define VALUE_LANGOPT(Name, Bits, Default, Description) \
540       Out.indent(4) << Description << ": " << LangOpts.Name << "\n";
541 #define BENIGN_LANGOPT(Name, Bits, Default, Description)
542 #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
543 #include "clang/Basic/LangOptions.def"
544 
545       if (!LangOpts.ModuleFeatures.empty()) {
546         Out.indent(4) << "Module features:\n";
547         for (StringRef Feature : LangOpts.ModuleFeatures)
548           Out.indent(6) << Feature << "\n";
549       }
550 
551       return false;
552     }
553 
554     bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
555                            bool AllowCompatibleDifferences) override {
556       Out.indent(2) << "Target options:\n";
557       Out.indent(4) << "  Triple: " << TargetOpts.Triple << "\n";
558       Out.indent(4) << "  CPU: " << TargetOpts.CPU << "\n";
559       Out.indent(4) << "  ABI: " << TargetOpts.ABI << "\n";
560 
561       if (!TargetOpts.FeaturesAsWritten.empty()) {
562         Out.indent(4) << "Target features:\n";
563         for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size();
564              I != N; ++I) {
565           Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n";
566         }
567       }
568 
569       return false;
570     }
571 
572     bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
573                                bool Complain) override {
574       Out.indent(2) << "Diagnostic options:\n";
575 #define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
576 #define ENUM_DIAGOPT(Name, Type, Bits, Default) \
577       Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
578 #define VALUE_DIAGOPT(Name, Bits, Default) \
579       Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
580 #include "clang/Basic/DiagnosticOptions.def"
581 
582       Out.indent(4) << "Diagnostic flags:\n";
583       for (const std::string &Warning : DiagOpts->Warnings)
584         Out.indent(6) << "-W" << Warning << "\n";
585       for (const std::string &Remark : DiagOpts->Remarks)
586         Out.indent(6) << "-R" << Remark << "\n";
587 
588       return false;
589     }
590 
591     bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
592                                  StringRef SpecificModuleCachePath,
593                                  bool Complain) override {
594       Out.indent(2) << "Header search options:\n";
595       Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
596       Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
597       Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
598       DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes,
599                    "Use builtin include directories [-nobuiltininc]");
600       DUMP_BOOLEAN(HSOpts.UseStandardSystemIncludes,
601                    "Use standard system include directories [-nostdinc]");
602       DUMP_BOOLEAN(HSOpts.UseStandardCXXIncludes,
603                    "Use standard C++ include directories [-nostdinc++]");
604       DUMP_BOOLEAN(HSOpts.UseLibcxx,
605                    "Use libc++ (rather than libstdc++) [-stdlib=]");
606       return false;
607     }
608 
609     bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
610                                  bool Complain,
611                                  std::string &SuggestedPredefines) override {
612       Out.indent(2) << "Preprocessor options:\n";
613       DUMP_BOOLEAN(PPOpts.UsePredefines,
614                    "Uses compiler/target-specific predefines [-undef]");
615       DUMP_BOOLEAN(PPOpts.DetailedRecord,
616                    "Uses detailed preprocessing record (for indexing)");
617 
618       if (!PPOpts.Macros.empty()) {
619         Out.indent(4) << "Predefined macros:\n";
620       }
621 
622       for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
623              I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
624            I != IEnd; ++I) {
625         Out.indent(6);
626         if (I->second)
627           Out << "-U";
628         else
629           Out << "-D";
630         Out << I->first << "\n";
631       }
632       return false;
633     }
634 
635     /// Indicates that a particular module file extension has been read.
636     void readModuleFileExtension(
637            const ModuleFileExtensionMetadata &Metadata) override {
638       Out.indent(2) << "Module file extension '"
639                     << Metadata.BlockName << "' " << Metadata.MajorVersion
640                     << "." << Metadata.MinorVersion;
641       if (!Metadata.UserInfo.empty()) {
642         Out << ": ";
643         Out.write_escaped(Metadata.UserInfo);
644       }
645 
646       Out << "\n";
647     }
648 
649     /// Tells the \c ASTReaderListener that we want to receive the
650     /// input files of the AST file via \c visitInputFile.
651     bool needsInputFileVisitation() override { return true; }
652 
653     /// Tells the \c ASTReaderListener that we want to receive the
654     /// input files of the AST file via \c visitInputFile.
655     bool needsSystemInputFileVisitation() override { return true; }
656 
657     /// Indicates that the AST file contains particular input file.
658     ///
659     /// \returns true to continue receiving the next input file, false to stop.
660     bool visitInputFile(StringRef Filename, bool isSystem,
661                         bool isOverridden, bool isExplicitModule) override {
662 
663       Out.indent(2) << "Input file: " << Filename;
664 
665       if (isSystem || isOverridden || isExplicitModule) {
666         Out << " [";
667         if (isSystem) {
668           Out << "System";
669           if (isOverridden || isExplicitModule)
670             Out << ", ";
671         }
672         if (isOverridden) {
673           Out << "Overridden";
674           if (isExplicitModule)
675             Out << ", ";
676         }
677         if (isExplicitModule)
678           Out << "ExplicitModule";
679 
680         Out << "]";
681       }
682 
683       Out << "\n";
684 
685       return true;
686     }
687 
688     /// Returns true if this \c ASTReaderListener wants to receive the
689     /// imports of the AST file via \c visitImport, false otherwise.
690     bool needsImportVisitation() const override { return true; }
691 
692     /// If needsImportVisitation returns \c true, this is called for each
693     /// AST file imported by this AST file.
694     void visitImport(StringRef ModuleName, StringRef Filename) override {
695       Out.indent(2) << "Imports module '" << ModuleName
696                     << "': " << Filename.str() << "\n";
697     }
698 #undef DUMP_BOOLEAN
699   };
700 }
701 
702 bool DumpModuleInfoAction::BeginInvocation(CompilerInstance &CI) {
703   // The Object file reader also supports raw ast files and there is no point in
704   // being strict about the module file format in -module-file-info mode.
705   CI.getHeaderSearchOpts().ModuleFormat = "obj";
706   return true;
707 }
708 
709 void DumpModuleInfoAction::ExecuteAction() {
710   // Set up the output file.
711   std::unique_ptr<llvm::raw_fd_ostream> OutFile;
712   StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile;
713   if (!OutputFileName.empty() && OutputFileName != "-") {
714     std::error_code EC;
715     OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str(), EC,
716                                            llvm::sys::fs::OF_Text));
717   }
718   llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs();
719 
720   Out << "Information for module file '" << getCurrentFile() << "':\n";
721   auto &FileMgr = getCompilerInstance().getFileManager();
722   auto Buffer = FileMgr.getBufferForFile(getCurrentFile());
723   StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();
724   bool IsRaw = (Magic.size() >= 4 && Magic[0] == 'C' && Magic[1] == 'P' &&
725                 Magic[2] == 'C' && Magic[3] == 'H');
726   Out << "  Module format: " << (IsRaw ? "raw" : "obj") << "\n";
727 
728   Preprocessor &PP = getCompilerInstance().getPreprocessor();
729   DumpModuleInfoListener Listener(Out);
730   HeaderSearchOptions &HSOpts =
731       PP.getHeaderSearchInfo().getHeaderSearchOpts();
732   ASTReader::readASTFileControlBlock(
733       getCurrentFile(), FileMgr, getCompilerInstance().getPCHContainerReader(),
734       /*FindModuleFileExtensions=*/true, Listener,
735       HSOpts.ModulesValidateDiagnosticOptions);
736 }
737 
738 //===----------------------------------------------------------------------===//
739 // Preprocessor Actions
740 //===----------------------------------------------------------------------===//
741 
742 void DumpRawTokensAction::ExecuteAction() {
743   Preprocessor &PP = getCompilerInstance().getPreprocessor();
744   SourceManager &SM = PP.getSourceManager();
745 
746   // Start lexing the specified input file.
747   const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
748   Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
749   RawLex.SetKeepWhitespaceMode(true);
750 
751   Token RawTok;
752   RawLex.LexFromRawLexer(RawTok);
753   while (RawTok.isNot(tok::eof)) {
754     PP.DumpToken(RawTok, true);
755     llvm::errs() << "\n";
756     RawLex.LexFromRawLexer(RawTok);
757   }
758 }
759 
760 void DumpTokensAction::ExecuteAction() {
761   Preprocessor &PP = getCompilerInstance().getPreprocessor();
762   // Start preprocessing the specified input file.
763   Token Tok;
764   PP.EnterMainSourceFile();
765   do {
766     PP.Lex(Tok);
767     PP.DumpToken(Tok, true);
768     llvm::errs() << "\n";
769   } while (Tok.isNot(tok::eof));
770 }
771 
772 void PreprocessOnlyAction::ExecuteAction() {
773   Preprocessor &PP = getCompilerInstance().getPreprocessor();
774 
775   // Ignore unknown pragmas.
776   PP.IgnorePragmas();
777 
778   Token Tok;
779   // Start parsing the specified input file.
780   PP.EnterMainSourceFile();
781   do {
782     PP.Lex(Tok);
783   } while (Tok.isNot(tok::eof));
784 }
785 
786 void PrintPreprocessedAction::ExecuteAction() {
787   CompilerInstance &CI = getCompilerInstance();
788   // Output file may need to be set to 'Binary', to avoid converting Unix style
789   // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
790   //
791   // Look to see what type of line endings the file uses. If there's a
792   // CRLF, then we won't open the file up in binary mode. If there is
793   // just an LF or CR, then we will open the file up in binary mode.
794   // In this fashion, the output format should match the input format, unless
795   // the input format has inconsistent line endings.
796   //
797   // This should be a relatively fast operation since most files won't have
798   // all of their source code on a single line. However, that is still a
799   // concern, so if we scan for too long, we'll just assume the file should
800   // be opened in binary mode.
801   bool BinaryMode = true;
802   bool InvalidFile = false;
803   const SourceManager& SM = CI.getSourceManager();
804   const llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getMainFileID(),
805                                                      &InvalidFile);
806   if (!InvalidFile) {
807     const char *cur = Buffer->getBufferStart();
808     const char *end = Buffer->getBufferEnd();
809     const char *next = (cur != end) ? cur + 1 : end;
810 
811     // Limit ourselves to only scanning 256 characters into the source
812     // file.  This is mostly a sanity check in case the file has no
813     // newlines whatsoever.
814     if (end - cur > 256) end = cur + 256;
815 
816     while (next < end) {
817       if (*cur == 0x0D) {  // CR
818         if (*next == 0x0A)  // CRLF
819           BinaryMode = false;
820 
821         break;
822       } else if (*cur == 0x0A)  // LF
823         break;
824 
825       ++cur;
826       ++next;
827     }
828   }
829 
830   std::unique_ptr<raw_ostream> OS =
831       CI.createDefaultOutputFile(BinaryMode, getCurrentFileOrBufferName());
832   if (!OS) return;
833 
834   // If we're preprocessing a module map, start by dumping the contents of the
835   // module itself before switching to the input buffer.
836   auto &Input = getCurrentInput();
837   if (Input.getKind().getFormat() == InputKind::ModuleMap) {
838     if (Input.isFile()) {
839       (*OS) << "# 1 \"";
840       OS->write_escaped(Input.getFile());
841       (*OS) << "\"\n";
842     }
843     getCurrentModule()->print(*OS);
844     (*OS) << "#pragma clang module contents\n";
845   }
846 
847   DoPrintPreprocessedInput(CI.getPreprocessor(), OS.get(),
848                            CI.getPreprocessorOutputOpts());
849 }
850 
851 void PrintPreambleAction::ExecuteAction() {
852   switch (getCurrentFileKind().getLanguage()) {
853   case Language::C:
854   case Language::CXX:
855   case Language::ObjC:
856   case Language::ObjCXX:
857   case Language::OpenCL:
858   case Language::CUDA:
859   case Language::HIP:
860     break;
861 
862   case Language::Unknown:
863   case Language::Asm:
864   case Language::LLVM_IR:
865   case Language::RenderScript:
866     // We can't do anything with these.
867     return;
868   }
869 
870   // We don't expect to find any #include directives in a preprocessed input.
871   if (getCurrentFileKind().isPreprocessed())
872     return;
873 
874   CompilerInstance &CI = getCompilerInstance();
875   auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
876   if (Buffer) {
877     unsigned Preamble =
878         Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).Size;
879     llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
880   }
881 }
882 
883 void DumpCompilerOptionsAction::ExecuteAction() {
884   CompilerInstance &CI = getCompilerInstance();
885   std::unique_ptr<raw_ostream> OSP =
886       CI.createDefaultOutputFile(false, getCurrentFile());
887   if (!OSP)
888     return;
889 
890   raw_ostream &OS = *OSP;
891   const Preprocessor &PP = CI.getPreprocessor();
892   const LangOptions &LangOpts = PP.getLangOpts();
893 
894   // FIXME: Rather than manually format the JSON (which is awkward due to
895   // needing to remove trailing commas), this should make use of a JSON library.
896   // FIXME: Instead of printing enums as an integral value and specifying the
897   // type as a separate field, use introspection to print the enumerator.
898 
899   OS << "{\n";
900   OS << "\n\"features\" : [\n";
901   {
902     llvm::SmallString<128> Str;
903 #define FEATURE(Name, Predicate)                                               \
904   ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
905       .toVector(Str);
906 #include "clang/Basic/Features.def"
907 #undef FEATURE
908     // Remove the newline and comma from the last entry to ensure this remains
909     // valid JSON.
910     OS << Str.substr(0, Str.size() - 2);
911   }
912   OS << "\n],\n";
913 
914   OS << "\n\"extensions\" : [\n";
915   {
916     llvm::SmallString<128> Str;
917 #define EXTENSION(Name, Predicate)                                             \
918   ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
919       .toVector(Str);
920 #include "clang/Basic/Features.def"
921 #undef EXTENSION
922     // Remove the newline and comma from the last entry to ensure this remains
923     // valid JSON.
924     OS << Str.substr(0, Str.size() - 2);
925   }
926   OS << "\n]\n";
927 
928   OS << "}";
929 }
930 
931 void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() {
932   CompilerInstance &CI = getCompilerInstance();
933   SourceManager &SM = CI.getPreprocessor().getSourceManager();
934   const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
935 
936   llvm::SmallString<1024> Output;
937   llvm::SmallVector<minimize_source_to_dependency_directives::Token, 32> Toks;
938   if (minimizeSourceToDependencyDirectives(
939           FromFile->getBuffer(), Output, Toks, &CI.getDiagnostics(),
940           SM.getLocForStartOfFile(SM.getMainFileID()))) {
941     assert(CI.getDiagnostics().hasErrorOccurred() &&
942            "no errors reported for failure");
943 
944     // Preprocess the source when verifying the diagnostics to capture the
945     // 'expected' comments.
946     if (CI.getDiagnosticOpts().VerifyDiagnostics) {
947       // Make sure we don't emit new diagnostics!
948       CI.getDiagnostics().setSuppressAllDiagnostics(true);
949       Preprocessor &PP = getCompilerInstance().getPreprocessor();
950       PP.EnterMainSourceFile();
951       Token Tok;
952       do {
953         PP.Lex(Tok);
954       } while (Tok.isNot(tok::eof));
955     }
956     return;
957   }
958   llvm::outs() << Output;
959 }
960