clang 20.0.0git
FrontendActions.cpp
Go to the documentation of this file.
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
11#include "clang/AST/Decl.h"
14#include "clang/Basic/Module.h"
29#include "llvm/Config/llvm-config.h" // for LLVM_HOST_TRIPLE
30#include "llvm/Support/ErrorHandling.h"
31#include "llvm/Support/FileSystem.h"
32#include "llvm/Support/MemoryBuffer.h"
33#include "llvm/Support/Path.h"
34#include "llvm/Support/YAMLTraits.h"
35#include "llvm/Support/raw_ostream.h"
36#include <memory>
37#include <optional>
38#include <system_error>
39
40using namespace clang;
41
42namespace {
43CodeCompleteConsumer *GetCodeCompletionConsumer(CompilerInstance &CI) {
45 : nullptr;
46}
47
48void EnsureSemaIsCreated(CompilerInstance &CI, FrontendAction &Action) {
49 if (Action.hasCodeCompletionSupport() &&
52
53 if (!CI.hasSema())
55 GetCodeCompletionConsumer(CI));
56}
57} // namespace
58
59//===----------------------------------------------------------------------===//
60// Custom Actions
61//===----------------------------------------------------------------------===//
62
63std::unique_ptr<ASTConsumer>
64InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
65 return std::make_unique<ASTConsumer>();
66}
67
68void InitOnlyAction::ExecuteAction() {
69}
70
71// Basically PreprocessOnlyAction::ExecuteAction.
72void ReadPCHAndPreprocessAction::ExecuteAction() {
74
75 // Ignore unknown pragmas.
76 PP.IgnorePragmas();
77
78 Token Tok;
79 // Start parsing the specified input file.
81 do {
82 PP.Lex(Tok);
83 } while (Tok.isNot(tok::eof));
84}
85
86std::unique_ptr<ASTConsumer>
87ReadPCHAndPreprocessAction::CreateASTConsumer(CompilerInstance &CI,
88 StringRef InFile) {
89 return std::make_unique<ASTConsumer>();
90}
91
92//===----------------------------------------------------------------------===//
93// AST Consumer Actions
94//===----------------------------------------------------------------------===//
95
96std::unique_ptr<ASTConsumer>
98 if (std::unique_ptr<raw_ostream> OS =
99 CI.createDefaultOutputFile(false, InFile))
100 return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter);
101 return nullptr;
102}
103
104std::unique_ptr<ASTConsumer>
106 const FrontendOptions &Opts = CI.getFrontendOpts();
107 return CreateASTDumper(nullptr /*Dump to stdout.*/, Opts.ASTDumpFilter,
108 Opts.ASTDumpDecls, Opts.ASTDumpAll,
110 Opts.ASTDumpFormat);
111}
112
113std::unique_ptr<ASTConsumer>
116}
117
118std::unique_ptr<ASTConsumer>
120 return CreateASTViewer();
121}
122
123std::unique_ptr<ASTConsumer>
125 std::string Sysroot;
126 if (!ComputeASTConsumerArguments(CI, /*ref*/ Sysroot))
127 return nullptr;
128
129 std::string OutputFile;
130 std::unique_ptr<raw_pwrite_stream> OS =
131 CreateOutputFile(CI, InFile, /*ref*/ OutputFile);
132 if (!OS)
133 return nullptr;
134
136 Sysroot.clear();
137
138 const auto &FrontendOpts = CI.getFrontendOpts();
139 auto Buffer = std::make_shared<PCHBuffer>();
140 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
141 Consumers.push_back(std::make_unique<PCHGenerator>(
142 CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
143 FrontendOpts.ModuleFileExtensions,
145 FrontendOpts.IncludeTimestamps, FrontendOpts.BuildingImplicitModule,
146 +CI.getLangOpts().CacheGeneratedPCH));
147 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
148 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
149
150 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
151}
152
154 std::string &Sysroot) {
155 Sysroot = CI.getHeaderSearchOpts().Sysroot;
156 if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
157 CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
158 return false;
159 }
160
161 return true;
162}
163
164std::unique_ptr<llvm::raw_pwrite_stream>
166 std::string &OutputFile) {
167 // Because this is exposed via libclang we must disable RemoveFileOnSignal.
168 std::unique_ptr<raw_pwrite_stream> OS = CI.createDefaultOutputFile(
169 /*Binary=*/true, InFile, /*Extension=*/"", /*RemoveFileOnSignal=*/false);
170 if (!OS)
171 return nullptr;
172
173 OutputFile = CI.getFrontendOpts().OutputFile;
174 return OS;
175}
176
178 if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)
179 return false;
181}
182
184 CI.getLangOpts().CompilingPCH = true;
185 return true;
186}
187
188std::vector<std::unique_ptr<ASTConsumer>>
190 StringRef InFile) {
191 std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile);
192 if (!OS)
193 return {};
194
195 std::string OutputFile = CI.getFrontendOpts().OutputFile;
196 std::string Sysroot;
197
198 auto Buffer = std::make_shared<PCHBuffer>();
199 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
200
201 Consumers.push_back(std::make_unique<PCHGenerator>(
202 CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
204 /*AllowASTWithErrors=*/
206 /*IncludeTimestamps=*/
209 /*BuildingImplicitModule=*/+CI.getFrontendOpts().BuildingImplicitModule,
210 /*ShouldCacheASTInMemory=*/
212 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
213 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
214 return Consumers;
215}
216
217std::unique_ptr<ASTConsumer>
219 StringRef InFile) {
220 std::vector<std::unique_ptr<ASTConsumer>> Consumers =
221 CreateMultiplexConsumer(CI, InFile);
222 if (Consumers.empty())
223 return nullptr;
224
225 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
226}
227
231}
232
233bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(
234 CompilerInstance &CI) {
235 if (!CI.getLangOpts().Modules) {
236 CI.getDiagnostics().Report(diag::err_module_build_requires_fmodules);
237 return false;
238 }
239
241}
242
243std::unique_ptr<raw_pwrite_stream>
244GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
245 StringRef InFile) {
246 // If no output file was provided, figure out where this module would go
247 // in the module cache.
248 if (CI.getFrontendOpts().OutputFile.empty()) {
249 StringRef ModuleMapFile = CI.getFrontendOpts().OriginalModuleMap;
250 if (ModuleMapFile.empty())
251 ModuleMapFile = InFile;
252
256 ModuleMapFile);
257 }
258
259 // Because this is exposed via libclang we must disable RemoveFileOnSignal.
260 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, /*Extension=*/"",
261 /*RemoveFileOnSignal=*/false,
262 /*CreateMissingDirectories=*/true,
263 /*ForceUseTemporary=*/true);
264}
265
267 CompilerInstance &CI) {
268 CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
269
271}
272
273std::unique_ptr<ASTConsumer>
275 StringRef InFile) {
276 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
277
279 !CI.getFrontendOpts().ModuleOutputPath.empty()) {
280 Consumers.push_back(std::make_unique<ReducedBMIGenerator>(
283 }
284
285 Consumers.push_back(std::make_unique<CXX20ModulesGenerator>(
288
289 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
290}
291
292std::unique_ptr<raw_pwrite_stream>
294 StringRef InFile) {
295 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
296}
297
298std::unique_ptr<ASTConsumer>
299GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
300 StringRef InFile) {
301 return std::make_unique<ReducedBMIGenerator>(CI.getPreprocessor(),
302 CI.getModuleCache(),
304}
305
306bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) {
307 if (!CI.getLangOpts().CPlusPlusModules) {
308 CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
309 return false;
310 }
311 CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderUnit);
313}
314
315std::unique_ptr<raw_pwrite_stream>
316GenerateHeaderUnitAction::CreateOutputFile(CompilerInstance &CI,
317 StringRef InFile) {
318 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
319}
320
322}
323
324std::unique_ptr<ASTConsumer>
326 return std::make_unique<ASTConsumer>();
327}
328
329std::unique_ptr<ASTConsumer>
331 StringRef InFile) {
332 return std::make_unique<ASTConsumer>();
333}
334
335std::unique_ptr<ASTConsumer>
337 return std::make_unique<ASTConsumer>();
338}
339
343 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
344 std::unique_ptr<ASTReader> Reader(new ASTReader(
347 Sysroot.empty() ? "" : Sysroot.c_str(),
349 /*AllowASTWithCompilerErrors*/ false,
350 /*AllowConfigurationMismatch*/ true,
351 /*ValidateSystemInputs*/ true));
352
353 Reader->ReadAST(getCurrentFile(),
358}
359
360namespace {
361struct TemplightEntry {
362 std::string Name;
363 std::string Kind;
364 std::string Event;
365 std::string DefinitionLocation;
366 std::string PointOfInstantiation;
367};
368} // namespace
369
370namespace llvm {
371namespace yaml {
372template <> struct MappingTraits<TemplightEntry> {
373 static void mapping(IO &io, TemplightEntry &fields) {
374 io.mapRequired("name", fields.Name);
375 io.mapRequired("kind", fields.Kind);
376 io.mapRequired("event", fields.Event);
377 io.mapRequired("orig", fields.DefinitionLocation);
378 io.mapRequired("poi", fields.PointOfInstantiation);
379 }
380};
381} // namespace yaml
382} // namespace llvm
383
384namespace {
385class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
386 using CodeSynthesisContext = Sema::CodeSynthesisContext;
387
388public:
389 void initialize(const Sema &) override {}
390
391 void finalize(const Sema &) override {}
392
393 void atTemplateBegin(const Sema &TheSema,
394 const CodeSynthesisContext &Inst) override {
395 displayTemplightEntry<true>(llvm::outs(), TheSema, Inst);
396 }
397
398 void atTemplateEnd(const Sema &TheSema,
399 const CodeSynthesisContext &Inst) override {
400 displayTemplightEntry<false>(llvm::outs(), TheSema, Inst);
401 }
402
403private:
404 static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {
405 switch (Kind) {
406 case CodeSynthesisContext::TemplateInstantiation:
407 return "TemplateInstantiation";
408 case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
409 return "DefaultTemplateArgumentInstantiation";
410 case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
411 return "DefaultFunctionArgumentInstantiation";
412 case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
413 return "ExplicitTemplateArgumentSubstitution";
414 case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
415 return "DeducedTemplateArgumentSubstitution";
416 case CodeSynthesisContext::LambdaExpressionSubstitution:
417 return "LambdaExpressionSubstitution";
418 case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
419 return "PriorTemplateArgumentSubstitution";
420 case CodeSynthesisContext::DefaultTemplateArgumentChecking:
421 return "DefaultTemplateArgumentChecking";
422 case CodeSynthesisContext::ExceptionSpecEvaluation:
423 return "ExceptionSpecEvaluation";
424 case CodeSynthesisContext::ExceptionSpecInstantiation:
425 return "ExceptionSpecInstantiation";
426 case CodeSynthesisContext::DeclaringSpecialMember:
427 return "DeclaringSpecialMember";
428 case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
429 return "DeclaringImplicitEqualityComparison";
430 case CodeSynthesisContext::DefiningSynthesizedFunction:
431 return "DefiningSynthesizedFunction";
432 case CodeSynthesisContext::RewritingOperatorAsSpaceship:
433 return "RewritingOperatorAsSpaceship";
434 case CodeSynthesisContext::Memoization:
435 return "Memoization";
436 case CodeSynthesisContext::ConstraintsCheck:
437 return "ConstraintsCheck";
438 case CodeSynthesisContext::ConstraintSubstitution:
439 return "ConstraintSubstitution";
440 case CodeSynthesisContext::ConstraintNormalization:
441 return "ConstraintNormalization";
442 case CodeSynthesisContext::RequirementParameterInstantiation:
443 return "RequirementParameterInstantiation";
444 case CodeSynthesisContext::ParameterMappingSubstitution:
445 return "ParameterMappingSubstitution";
446 case CodeSynthesisContext::RequirementInstantiation:
447 return "RequirementInstantiation";
448 case CodeSynthesisContext::NestedRequirementConstraintsCheck:
449 return "NestedRequirementConstraintsCheck";
450 case CodeSynthesisContext::InitializingStructuredBinding:
451 return "InitializingStructuredBinding";
452 case CodeSynthesisContext::MarkingClassDllexported:
453 return "MarkingClassDllexported";
454 case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
455 return "BuildingBuiltinDumpStructCall";
456 case CodeSynthesisContext::BuildingDeductionGuides:
457 return "BuildingDeductionGuides";
458 case CodeSynthesisContext::TypeAliasTemplateInstantiation:
459 return "TypeAliasTemplateInstantiation";
460 }
461 return "";
462 }
463
464 template <bool BeginInstantiation>
465 static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema,
466 const CodeSynthesisContext &Inst) {
467 std::string YAML;
468 {
469 llvm::raw_string_ostream OS(YAML);
470 llvm::yaml::Output YO(OS);
471 TemplightEntry Entry =
472 getTemplightEntry<BeginInstantiation>(TheSema, Inst);
473 llvm::yaml::EmptyContext Context;
474 llvm::yaml::yamlize(YO, Entry, true, Context);
475 }
476 Out << "---" << YAML << "\n";
477 }
478
479 static void printEntryName(const Sema &TheSema, const Decl *Entity,
480 llvm::raw_string_ostream &OS) {
481 auto *NamedTemplate = cast<NamedDecl>(Entity);
482
483 PrintingPolicy Policy = TheSema.Context.getPrintingPolicy();
484 // FIXME: Also ask for FullyQualifiedNames?
485 Policy.SuppressDefaultTemplateArgs = false;
486 NamedTemplate->getNameForDiagnostic(OS, Policy, true);
487
488 if (!OS.str().empty())
489 return;
490
491 Decl *Ctx = Decl::castFromDeclContext(NamedTemplate->getDeclContext());
492 NamedDecl *NamedCtx = dyn_cast_or_null<NamedDecl>(Ctx);
493
494 if (const auto *Decl = dyn_cast<TagDecl>(NamedTemplate)) {
495 if (const auto *R = dyn_cast<RecordDecl>(Decl)) {
496 if (R->isLambda()) {
497 OS << "lambda at ";
498 Decl->getLocation().print(OS, TheSema.getSourceManager());
499 return;
500 }
501 }
502 OS << "unnamed " << Decl->getKindName();
503 return;
504 }
505
506 assert(NamedCtx && "NamedCtx cannot be null");
507
508 if (const auto *Decl = dyn_cast<ParmVarDecl>(NamedTemplate)) {
509 OS << "unnamed function parameter " << Decl->getFunctionScopeIndex()
510 << " ";
511 if (Decl->getFunctionScopeDepth() > 0)
512 OS << "(at depth " << Decl->getFunctionScopeDepth() << ") ";
513 OS << "of ";
514 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
515 return;
516 }
517
518 if (const auto *Decl = dyn_cast<TemplateTypeParmDecl>(NamedTemplate)) {
519 if (const Type *Ty = Decl->getTypeForDecl()) {
520 if (const auto *TTPT = dyn_cast_or_null<TemplateTypeParmType>(Ty)) {
521 OS << "unnamed template type parameter " << TTPT->getIndex() << " ";
522 if (TTPT->getDepth() > 0)
523 OS << "(at depth " << TTPT->getDepth() << ") ";
524 OS << "of ";
525 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
526 return;
527 }
528 }
529 }
530
531 if (const auto *Decl = dyn_cast<NonTypeTemplateParmDecl>(NamedTemplate)) {
532 OS << "unnamed template non-type parameter " << Decl->getIndex() << " ";
533 if (Decl->getDepth() > 0)
534 OS << "(at depth " << Decl->getDepth() << ") ";
535 OS << "of ";
536 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
537 return;
538 }
539
540 if (const auto *Decl = dyn_cast<TemplateTemplateParmDecl>(NamedTemplate)) {
541 OS << "unnamed template template parameter " << Decl->getIndex() << " ";
542 if (Decl->getDepth() > 0)
543 OS << "(at depth " << Decl->getDepth() << ") ";
544 OS << "of ";
545 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
546 return;
547 }
548
549 llvm_unreachable("Failed to retrieve a name for this entry!");
550 OS << "unnamed identifier";
551 }
552
553 template <bool BeginInstantiation>
554 static TemplightEntry getTemplightEntry(const Sema &TheSema,
555 const CodeSynthesisContext &Inst) {
556 TemplightEntry Entry;
557 Entry.Kind = toString(Inst.Kind);
558 Entry.Event = BeginInstantiation ? "Begin" : "End";
559 llvm::raw_string_ostream OS(Entry.Name);
560 printEntryName(TheSema, Inst.Entity, OS);
561 const PresumedLoc DefLoc =
562 TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation());
563 if (!DefLoc.isInvalid())
564 Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +
565 std::to_string(DefLoc.getLine()) + ":" +
566 std::to_string(DefLoc.getColumn());
567 const PresumedLoc PoiLoc =
568 TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation);
569 if (!PoiLoc.isInvalid()) {
570 Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +
571 std::to_string(PoiLoc.getLine()) + ":" +
572 std::to_string(PoiLoc.getColumn());
573 }
574 return Entry;
575 }
576};
577} // namespace
578
579std::unique_ptr<ASTConsumer>
581 return std::make_unique<ASTConsumer>();
582}
583
586
587 // This part is normally done by ASTFrontEndAction, but needs to happen
588 // before Templight observers can be created
589 // FIXME: Move the truncation aspect of this into Sema, we delayed this till
590 // here so the source manager would be initialized.
591 EnsureSemaIsCreated(CI, *this);
592
593 CI.getSema().TemplateInstCallbacks.push_back(
594 std::make_unique<DefaultTemplateInstCallback>());
596}
597
598namespace {
599 /// AST reader listener that dumps module information for a module
600 /// file.
601 class DumpModuleInfoListener : public ASTReaderListener {
602 llvm::raw_ostream &Out;
603
604 public:
605 DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { }
606
607#define DUMP_BOOLEAN(Value, Text) \
608 Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
609
610 bool ReadFullVersionInformation(StringRef FullVersion) override {
611 Out.indent(2)
612 << "Generated by "
613 << (FullVersion == getClangFullRepositoryVersion()? "this"
614 : "a different")
615 << " Clang: " << FullVersion << "\n";
617 }
618
619 void ReadModuleName(StringRef ModuleName) override {
620 Out.indent(2) << "Module name: " << ModuleName << "\n";
621 }
622 void ReadModuleMapFile(StringRef ModuleMapPath) override {
623 Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
624 }
625
626 bool ReadLanguageOptions(const LangOptions &LangOpts,
627 StringRef ModuleFilename, bool Complain,
628 bool AllowCompatibleDifferences) override {
629 Out.indent(2) << "Language options:\n";
630#define LANGOPT(Name, Bits, Default, Description) \
631 DUMP_BOOLEAN(LangOpts.Name, Description);
632#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
633 Out.indent(4) << Description << ": " \
634 << static_cast<unsigned>(LangOpts.get##Name()) << "\n";
635#define VALUE_LANGOPT(Name, Bits, Default, Description) \
636 Out.indent(4) << Description << ": " << LangOpts.Name << "\n";
637#define BENIGN_LANGOPT(Name, Bits, Default, Description)
638#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
639#include "clang/Basic/LangOptions.def"
640
641 if (!LangOpts.ModuleFeatures.empty()) {
642 Out.indent(4) << "Module features:\n";
643 for (StringRef Feature : LangOpts.ModuleFeatures)
644 Out.indent(6) << Feature << "\n";
645 }
646
647 return false;
648 }
649
650 bool ReadTargetOptions(const TargetOptions &TargetOpts,
651 StringRef ModuleFilename, bool Complain,
652 bool AllowCompatibleDifferences) override {
653 Out.indent(2) << "Target options:\n";
654 Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n";
655 Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n";
656 Out.indent(4) << " TuneCPU: " << TargetOpts.TuneCPU << "\n";
657 Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n";
658
659 if (!TargetOpts.FeaturesAsWritten.empty()) {
660 Out.indent(4) << "Target features:\n";
661 for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size();
662 I != N; ++I) {
663 Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n";
664 }
665 }
666
667 return false;
668 }
669
670 bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
671 StringRef ModuleFilename,
672 bool Complain) override {
673 Out.indent(2) << "Diagnostic options:\n";
674#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
675#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
676 Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
677#define VALUE_DIAGOPT(Name, Bits, Default) \
678 Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
679#include "clang/Basic/DiagnosticOptions.def"
680
681 Out.indent(4) << "Diagnostic flags:\n";
682 for (const std::string &Warning : DiagOpts->Warnings)
683 Out.indent(6) << "-W" << Warning << "\n";
684 for (const std::string &Remark : DiagOpts->Remarks)
685 Out.indent(6) << "-R" << Remark << "\n";
686
687 return false;
688 }
689
690 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
691 StringRef ModuleFilename,
692 StringRef SpecificModuleCachePath,
693 bool Complain) override {
694 Out.indent(2) << "Header search options:\n";
695 Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
696 Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
697 Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
699 "Use builtin include directories [-nobuiltininc]");
701 "Use standard system include directories [-nostdinc]");
703 "Use standard C++ include directories [-nostdinc++]");
704 DUMP_BOOLEAN(HSOpts.UseLibcxx,
705 "Use libc++ (rather than libstdc++) [-stdlib=]");
706 return false;
707 }
708
709 bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
710 bool Complain) override {
711 Out.indent(2) << "Header search paths:\n";
712 Out.indent(4) << "User entries:\n";
713 for (const auto &Entry : HSOpts.UserEntries)
714 Out.indent(6) << Entry.Path << "\n";
715 Out.indent(4) << "System header prefixes:\n";
716 for (const auto &Prefix : HSOpts.SystemHeaderPrefixes)
717 Out.indent(6) << Prefix.Prefix << "\n";
718 Out.indent(4) << "VFS overlay files:\n";
719 for (const auto &Overlay : HSOpts.VFSOverlayFiles)
720 Out.indent(6) << Overlay << "\n";
721 return false;
722 }
723
724 bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
725 StringRef ModuleFilename, bool ReadMacros,
726 bool Complain,
727 std::string &SuggestedPredefines) override {
728 Out.indent(2) << "Preprocessor options:\n";
730 "Uses compiler/target-specific predefines [-undef]");
732 "Uses detailed preprocessing record (for indexing)");
733
734 if (ReadMacros) {
735 Out.indent(4) << "Predefined macros:\n";
736 }
737
738 for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
739 I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
740 I != IEnd; ++I) {
741 Out.indent(6);
742 if (I->second)
743 Out << "-U";
744 else
745 Out << "-D";
746 Out << I->first << "\n";
747 }
748 return false;
749 }
750
751 /// Indicates that a particular module file extension has been read.
752 void readModuleFileExtension(
753 const ModuleFileExtensionMetadata &Metadata) override {
754 Out.indent(2) << "Module file extension '"
755 << Metadata.BlockName << "' " << Metadata.MajorVersion
756 << "." << Metadata.MinorVersion;
757 if (!Metadata.UserInfo.empty()) {
758 Out << ": ";
759 Out.write_escaped(Metadata.UserInfo);
760 }
761
762 Out << "\n";
763 }
764
765 /// Tells the \c ASTReaderListener that we want to receive the
766 /// input files of the AST file via \c visitInputFile.
767 bool needsInputFileVisitation() override { return true; }
768
769 /// Tells the \c ASTReaderListener that we want to receive the
770 /// input files of the AST file via \c visitInputFile.
771 bool needsSystemInputFileVisitation() override { return true; }
772
773 /// Indicates that the AST file contains particular input file.
774 ///
775 /// \returns true to continue receiving the next input file, false to stop.
776 bool visitInputFile(StringRef Filename, bool isSystem,
777 bool isOverridden, bool isExplicitModule) override {
778
779 Out.indent(2) << "Input file: " << Filename;
780
781 if (isSystem || isOverridden || isExplicitModule) {
782 Out << " [";
783 if (isSystem) {
784 Out << "System";
785 if (isOverridden || isExplicitModule)
786 Out << ", ";
787 }
788 if (isOverridden) {
789 Out << "Overridden";
790 if (isExplicitModule)
791 Out << ", ";
792 }
793 if (isExplicitModule)
794 Out << "ExplicitModule";
795
796 Out << "]";
797 }
798
799 Out << "\n";
800
801 return true;
802 }
803
804 /// Returns true if this \c ASTReaderListener wants to receive the
805 /// imports of the AST file via \c visitImport, false otherwise.
806 bool needsImportVisitation() const override { return true; }
807
808 /// If needsImportVisitation returns \c true, this is called for each
809 /// AST file imported by this AST file.
810 void visitImport(StringRef ModuleName, StringRef Filename) override {
811 Out.indent(2) << "Imports module '" << ModuleName
812 << "': " << Filename.str() << "\n";
813 }
814#undef DUMP_BOOLEAN
815 };
816}
817
819 // The Object file reader also supports raw ast files and there is no point in
820 // being strict about the module file format in -module-file-info mode.
822 return true;
823}
824
825static StringRef ModuleKindName(Module::ModuleKind MK) {
826 switch (MK) {
828 return "Module Map Module";
830 return "Interface Unit";
832 return "Implementation Unit";
834 return "Partition Interface";
836 return "Partition Implementation";
838 return "Header Unit";
840 return "Global Module Fragment";
842 return "Implicit Module Fragment";
844 return "Private Module Fragment";
845 }
846 llvm_unreachable("unknown module kind!");
847}
848
851
852 // Don't process files of type other than module to avoid crash
853 if (!isCurrentFileAST()) {
854 CI.getDiagnostics().Report(diag::err_file_is_not_module)
855 << getCurrentFile();
856 return;
857 }
858
859 // Set up the output file.
860 StringRef OutputFileName = CI.getFrontendOpts().OutputFile;
861 if (!OutputFileName.empty() && OutputFileName != "-") {
862 std::error_code EC;
863 OutputStream.reset(new llvm::raw_fd_ostream(
864 OutputFileName.str(), EC, llvm::sys::fs::OF_TextWithCRLF));
865 }
866 llvm::raw_ostream &Out = OutputStream ? *OutputStream : llvm::outs();
867
868 Out << "Information for module file '" << getCurrentFile() << "':\n";
869 auto &FileMgr = CI.getFileManager();
870 auto Buffer = FileMgr.getBufferForFile(getCurrentFile());
871 StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();
872 bool IsRaw = Magic.starts_with("CPCH");
873 Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n";
874
875 Preprocessor &PP = CI.getPreprocessor();
876 DumpModuleInfoListener Listener(Out);
877 HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
878
879 // The FrontendAction::BeginSourceFile () method loads the AST so that much
880 // of the information is already available and modules should have been
881 // loaded.
882
884 if (LO.CPlusPlusModules && !LO.CurrentModule.empty()) {
886 unsigned SubModuleCount = R->getTotalNumSubmodules();
888 Out << " ====== C++20 Module structure ======\n";
889
890 if (MF.ModuleName != LO.CurrentModule)
891 Out << " Mismatched module names : " << MF.ModuleName << " and "
892 << LO.CurrentModule << "\n";
893
894 struct SubModInfo {
895 unsigned Idx;
896 Module *Mod;
898 std::string &Name;
899 bool Seen;
900 };
901 std::map<std::string, SubModInfo> SubModMap;
902 auto PrintSubMapEntry = [&](std::string Name, Module::ModuleKind Kind) {
903 Out << " " << ModuleKindName(Kind) << " '" << Name << "'";
904 auto I = SubModMap.find(Name);
905 if (I == SubModMap.end())
906 Out << " was not found in the sub modules!\n";
907 else {
908 I->second.Seen = true;
909 Out << " is at index #" << I->second.Idx << "\n";
910 }
911 };
912 Module *Primary = nullptr;
913 for (unsigned Idx = 0; Idx <= SubModuleCount; ++Idx) {
914 Module *M = R->getModule(Idx);
915 if (!M)
916 continue;
917 if (M->Name == LO.CurrentModule) {
918 Primary = M;
919 Out << " " << ModuleKindName(M->Kind) << " '" << LO.CurrentModule
920 << "' is the Primary Module at index #" << Idx << "\n";
921 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, true}});
922 } else
923 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, false}});
924 }
925 if (Primary) {
926 if (!Primary->submodules().empty())
927 Out << " Sub Modules:\n";
928 for (auto *MI : Primary->submodules()) {
929 PrintSubMapEntry(MI->Name, MI->Kind);
930 }
931 if (!Primary->Imports.empty())
932 Out << " Imports:\n";
933 for (auto *IMP : Primary->Imports) {
934 PrintSubMapEntry(IMP->Name, IMP->Kind);
935 }
936 if (!Primary->Exports.empty())
937 Out << " Exports:\n";
938 for (unsigned MN = 0, N = Primary->Exports.size(); MN != N; ++MN) {
939 if (Module *M = Primary->Exports[MN].getPointer()) {
940 PrintSubMapEntry(M->Name, M->Kind);
941 }
942 }
943 }
944
945 // Emit the macro definitions in the module file so that we can know how
946 // much definitions in the module file quickly.
947 // TODO: Emit the macro definition bodies completely.
948 if (auto FilteredMacros = llvm::make_filter_range(
949 R->getPreprocessor().macros(),
950 [](const auto &Macro) { return Macro.first->isFromAST(); });
951 !FilteredMacros.empty()) {
952 Out << " Macro Definitions:\n";
953 for (/*<IdentifierInfo *, MacroState> pair*/ const auto &Macro :
954 FilteredMacros)
955 Out << " " << Macro.first->getName() << "\n";
956 }
957
958 // Now let's print out any modules we did not see as part of the Primary.
959 for (const auto &SM : SubModMap) {
960 if (!SM.second.Seen && SM.second.Mod) {
961 Out << " " << ModuleKindName(SM.second.Kind) << " '" << SM.first
962 << "' at index #" << SM.second.Idx
963 << " has no direct reference in the Primary\n";
964 }
965 }
966 Out << " ====== ======\n";
967 }
968
969 // The reminder of the output is produced from the listener as the AST
970 // FileCcontrolBlock is (re-)parsed.
972 getCurrentFile(), FileMgr, CI.getModuleCache(),
974 /*FindModuleFileExtensions=*/true, Listener,
976}
977
978//===----------------------------------------------------------------------===//
979// Preprocessor Actions
980//===----------------------------------------------------------------------===//
981
985
986 // Start lexing the specified input file.
987 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
988 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
989 RawLex.SetKeepWhitespaceMode(true);
990
991 Token RawTok;
992 RawLex.LexFromRawLexer(RawTok);
993 while (RawTok.isNot(tok::eof)) {
994 PP.DumpToken(RawTok, true);
995 llvm::errs() << "\n";
996 RawLex.LexFromRawLexer(RawTok);
997 }
998}
999
1002 // Start preprocessing the specified input file.
1003 Token Tok;
1005 do {
1006 PP.Lex(Tok);
1007 PP.DumpToken(Tok, true);
1008 llvm::errs() << "\n";
1009 } while (Tok.isNot(tok::eof));
1010}
1011
1014
1015 // Ignore unknown pragmas.
1016 PP.IgnorePragmas();
1017
1018 Token Tok;
1019 // Start parsing the specified input file.
1021 do {
1022 PP.Lex(Tok);
1023 } while (Tok.isNot(tok::eof));
1024}
1025
1028 // Output file may need to be set to 'Binary', to avoid converting Unix style
1029 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>) on Windows.
1030 //
1031 // Look to see what type of line endings the file uses. If there's a
1032 // CRLF, then we won't open the file up in binary mode. If there is
1033 // just an LF or CR, then we will open the file up in binary mode.
1034 // In this fashion, the output format should match the input format, unless
1035 // the input format has inconsistent line endings.
1036 //
1037 // This should be a relatively fast operation since most files won't have
1038 // all of their source code on a single line. However, that is still a
1039 // concern, so if we scan for too long, we'll just assume the file should
1040 // be opened in binary mode.
1041
1042 bool BinaryMode = false;
1043 if (llvm::Triple(LLVM_HOST_TRIPLE).isOSWindows()) {
1044 BinaryMode = true;
1045 const SourceManager &SM = CI.getSourceManager();
1046 if (std::optional<llvm::MemoryBufferRef> Buffer =
1047 SM.getBufferOrNone(SM.getMainFileID())) {
1048 const char *cur = Buffer->getBufferStart();
1049 const char *end = Buffer->getBufferEnd();
1050 const char *next = (cur != end) ? cur + 1 : end;
1051
1052 // Limit ourselves to only scanning 256 characters into the source
1053 // file. This is mostly a check in case the file has no
1054 // newlines whatsoever.
1055 if (end - cur > 256)
1056 end = cur + 256;
1057
1058 while (next < end) {
1059 if (*cur == 0x0D) { // CR
1060 if (*next == 0x0A) // CRLF
1061 BinaryMode = false;
1062
1063 break;
1064 } else if (*cur == 0x0A) // LF
1065 break;
1066
1067 ++cur;
1068 ++next;
1069 }
1070 }
1071 }
1072
1073 std::unique_ptr<raw_ostream> OS =
1075 if (!OS) return;
1076
1077 // If we're preprocessing a module map, start by dumping the contents of the
1078 // module itself before switching to the input buffer.
1079 auto &Input = getCurrentInput();
1080 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
1081 if (Input.isFile()) {
1082 (*OS) << "# 1 \"";
1083 OS->write_escaped(Input.getFile());
1084 (*OS) << "\"\n";
1085 }
1086 getCurrentModule()->print(*OS);
1087 (*OS) << "#pragma clang module contents\n";
1088 }
1089
1092}
1093
1095 switch (getCurrentFileKind().getLanguage()) {
1096 case Language::C:
1097 case Language::CXX:
1098 case Language::ObjC:
1099 case Language::ObjCXX:
1100 case Language::OpenCL:
1102 case Language::CUDA:
1103 case Language::HIP:
1104 case Language::HLSL:
1105 case Language::CIR:
1106 break;
1107
1108 case Language::Unknown:
1109 case Language::Asm:
1110 case Language::LLVM_IR:
1111 // We can't do anything with these.
1112 return;
1113 }
1114
1115 // We don't expect to find any #include directives in a preprocessed input.
1116 if (getCurrentFileKind().isPreprocessed())
1117 return;
1118
1120 auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
1121 if (Buffer) {
1122 unsigned Preamble =
1123 Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).Size;
1124 llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
1125 }
1126}
1127
1128void DumpCompilerOptionsAction::ExecuteAction() {
1130 std::unique_ptr<raw_ostream> OSP =
1132 if (!OSP)
1133 return;
1134
1135 raw_ostream &OS = *OSP;
1136 const Preprocessor &PP = CI.getPreprocessor();
1137 const LangOptions &LangOpts = PP.getLangOpts();
1138
1139 // FIXME: Rather than manually format the JSON (which is awkward due to
1140 // needing to remove trailing commas), this should make use of a JSON library.
1141 // FIXME: Instead of printing enums as an integral value and specifying the
1142 // type as a separate field, use introspection to print the enumerator.
1143
1144 OS << "{\n";
1145 OS << "\n\"features\" : [\n";
1146 {
1148#define FEATURE(Name, Predicate) \
1149 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
1150 .toVector(Str);
1151#include "clang/Basic/Features.def"
1152#undef FEATURE
1153 // Remove the newline and comma from the last entry to ensure this remains
1154 // valid JSON.
1155 OS << Str.substr(0, Str.size() - 2);
1156 }
1157 OS << "\n],\n";
1158
1159 OS << "\n\"extensions\" : [\n";
1160 {
1162#define EXTENSION(Name, Predicate) \
1163 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
1164 .toVector(Str);
1165#include "clang/Basic/Features.def"
1166#undef EXTENSION
1167 // Remove the newline and comma from the last entry to ensure this remains
1168 // valid JSON.
1169 OS << Str.substr(0, Str.size() - 2);
1170 }
1171 OS << "\n]\n";
1172
1173 OS << "}";
1174}
1175
1179 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
1180
1184 FromFile.getBuffer(), Tokens, Directives, &CI.getDiagnostics(),
1185 SM.getLocForStartOfFile(SM.getMainFileID()))) {
1186 assert(CI.getDiagnostics().hasErrorOccurred() &&
1187 "no errors reported for failure");
1188
1189 // Preprocess the source when verifying the diagnostics to capture the
1190 // 'expected' comments.
1191 if (CI.getDiagnosticOpts().VerifyDiagnostics) {
1192 // Make sure we don't emit new diagnostics!
1196 Token Tok;
1197 do {
1198 PP.Lex(Tok);
1199 } while (Tok.isNot(tok::eof));
1200 }
1201 return;
1202 }
1203 printDependencyDirectivesAsSource(FromFile.getBuffer(), Directives,
1204 llvm::outs());
1205}
1206
1207void GetDependenciesByModuleNameAction::ExecuteAction() {
1209 Preprocessor &PP = CI.getPreprocessor();
1211 FileID MainFileID = SM.getMainFileID();
1212 SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);
1214 IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName);
1215 Path.push_back(std::make_pair(ModuleID, FileStart));
1216 auto ModResult = CI.loadModule(FileStart, Path, Module::Hidden, false);
1217 PPCallbacks *CB = PP.getPPCallbacks();
1218 CB->moduleImport(SourceLocation(), Path, ModResult);
1219}
#define SM(sm)
Definition: Cuda.cpp:84
IndirectLocalPath & Path
enum clang::sema::@1718::IndirectLocalPathEntry::EntryKind Kind
This is the interface for scanning header and source files to get the minimum necessary preprocessor ...
Defines the clang::FileManager interface and associated types.
StringRef Filename
Definition: Format.cpp:3032
#define DUMP_BOOLEAN(Value, Text)
static StringRef ModuleKindName(Module::ModuleKind MK)
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:733
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
Abstract interface for callback invocations by the ASTReader.
Definition: ASTReader.h:116
virtual bool ReadFullVersionInformation(StringRef FullVersion)
Receives the full Clang version information.
Definition: ASTReader.h:124
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:383
ModuleManager & getModuleManager()
Retrieve the module manager.
Definition: ASTReader.h:1890
@ ARR_ConfigurationMismatch
The client can handle an AST file that cannot load because it's compiled configuration doesn't match ...
Definition: ASTReader.h:1745
unsigned getTotalNumSubmodules() const
Returns the number of submodules known.
Definition: ASTReader.h:1986
Module * getModule(unsigned ID) override
Retrieve the module that corresponds to the given module ID.
Definition: ASTReader.cpp:9448
static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, ASTReaderListener &Listener, bool ValidateDiagnosticOptions, unsigned ClientLoadCapabilities=ARR_ConfigurationMismatch|ARR_OutOfDate)
Read the control block for the named AST file.
Definition: ASTReader.cpp:5544
Preprocessor & getPreprocessor() const
Retrieve the preprocessor.
Definition: ASTReader.h:1894
const LangOptions & getLangOpts() const
Definition: ASTUnit.h:464
IntrusiveRefCntPtr< ASTReader > getASTReader() const
Definition: ASTUnit.cpp:766
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
Abstract interface for a consumer of code-completion information.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="", bool RemoveFileOnSignal=true, bool CreateMissingDirectories=false, bool ForceUseTemporary=false)
Create the default output file (from the invocation's options) and add it to the list of tracked outp...
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) override
Attempt to load the given module.
FileManager & getFileManager() const
Return the current file manager to the caller.
PreprocessorOutputOptions & getPreprocessorOutputOpts()
InMemoryModuleCache & getModuleCache() const
Preprocessor & getPreprocessor() const
Return the current preprocessor.
ASTContext & getASTContext() const
FrontendOptions & getFrontendOpts()
HeaderSearchOptions & getHeaderSearchOpts()
bool hasCodeCompletionConsumer() const
const PCHContainerWriter & getPCHContainerWriter() const
Return the appropriate PCHContainerWriter depending on the current CodeGenOptions.
PreprocessorOptions & getPreprocessorOpts()
void createCodeCompletionConsumer()
Create a code completion consumer using the invocation; note that this will cause the source manager ...
DiagnosticOptions & getDiagnosticOpts()
LangOptions & getLangOpts()
SourceManager & getSourceManager() const
Return the current source manager.
CodeCompleteConsumer & getCodeCompletionConsumer() const
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
static Decl * castFromDeclContext(const DeclContext *)
Definition: DeclBase.cpp:1038
SourceLocation getLocation() const
Definition: DeclBase.h:442
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1493
bool hasErrorOccurred() const
Definition: Diagnostic.h:866
void setSuppressAllDiagnostics(bool Val)
Suppress all diagnostics, to silence the front end when we know that we don't want any more diagnosti...
Definition: Diagnostic.h:720
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
bool BeginInvocation(CompilerInstance &CI) override
Callback before starting processing a single input, giving the opportunity to modify the CompilerInvo...
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(FileEntryRef Entry, bool isVolatile=false, bool RequiresNullTerminator=true, std::optional< int64_t > MaybeLimit=std::nullopt, bool IsText=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Abstract base class for actions which can be performed by the frontend.
const FrontendInputFile & getCurrentInput() const
InputKind getCurrentFileKind() const
virtual bool shouldEraseOutputFiles()
Callback at the end of processing a single input, to determine if the output files should be erased o...
ASTUnit & getCurrentASTUnit() const
CompilerInstance & getCompilerInstance() const
Module * getCurrentModule() const
StringRef getCurrentFile() const
virtual bool BeginSourceFileAction(CompilerInstance &CI)
Callback at the start of processing a single input.
virtual TranslationUnitKind getTranslationUnitKind()
For AST-based actions, the kind of translation unit we're handling.
virtual bool hasCodeCompletionSupport() const
Does this action support use with code completion?
StringRef getCurrentFileOrBufferName() const
bool isCurrentFileAST() const
FrontendOptions - Options for controlling the behavior of the frontend.
unsigned BuildingImplicitModule
Whether we are performing an implicit module build.
unsigned AllowPCMWithCompilerErrors
Output (and read) PCM files regardless of compiler errors.
unsigned IncludeTimestamps
Whether timestamps should be written to the produced PCH file.
std::string ASTDumpFilter
If given, filter dumped AST Decl nodes by this substring.
unsigned ASTDumpLookups
Whether we include lookup table dumps in AST dumps.
ASTDumpOutputFormat ASTDumpFormat
Specifies the output format of the AST.
std::string OutputFile
The output file, if any.
unsigned GenReducedBMI
Whether to generate reduced BMI for C++20 named modules.
std::vector< std::shared_ptr< ModuleFileExtension > > ModuleFileExtensions
The list of module file extensions.
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
std::string OriginalModuleMap
When the input is a module map, the original module map file from which that map was inferred,...
std::string ModuleOutputPath
Output Path for module output file.
unsigned ASTDumpDeclTypes
Whether we include declaration type dumps in AST dumps.
unsigned ASTDumpAll
Whether we deserialize all decls when forming AST dumps.
unsigned RelocatablePCH
When generating PCH files, instruct the AST writer to create relocatable PCH files.
unsigned ASTDumpDecls
Whether we include declaration dumps in AST dumps.
bool shouldEraseOutputFiles() override
Callback at the end of processing a single input, to determine if the output files should be erased o...
std::vector< std::unique_ptr< ASTConsumer > > CreateMultiplexConsumer(CompilerInstance &CI, StringRef InFile)
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
bool BeginSourceFileAction(CompilerInstance &CI) override
Callback at the start of processing a single input.
std::unique_ptr< raw_pwrite_stream > CreateOutputFile(CompilerInstance &CI, StringRef InFile) override
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
static std::unique_ptr< llvm::raw_pwrite_stream > CreateOutputFile(CompilerInstance &CI, StringRef InFile, std::string &OutputFile)
Creates file to write the PCH into and returns a stream to write it into.
bool BeginSourceFileAction(CompilerInstance &CI) override
Callback at the start of processing a single input.
static bool ComputeASTConsumerArguments(CompilerInstance &CI, std::string &Sysroot)
Compute the AST consumer arguments that will be used to create the PCHGenerator instance returned by ...
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
bool shouldEraseOutputFiles() override
Callback at the end of processing a single input, to determine if the output files should be erased o...
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
std::vector< SystemHeaderPrefix > SystemHeaderPrefixes
User-specified system header prefixes.
std::string ModuleFormat
The module/pch container format.
std::string Sysroot
If non-empty, the directory to use as a "virtual system root" for include paths.
std::vector< std::string > VFSOverlayFiles
The set of user-provided virtual filesystem overlay files.
unsigned UseLibcxx
Use libc++ instead of the default libstdc++.
unsigned UseBuiltinIncludes
Include the compiler builtin includes.
unsigned UseStandardCXXIncludes
Include the system standard C++ library include search directories.
std::vector< Entry > UserEntries
User specified include entries.
std::string ResourceDir
The directory which holds the compiler resource files (builtin includes, etc.).
unsigned UseStandardSystemIncludes
Include the system standard include search directories.
Encapsulates the information needed to find the file referenced by a #include or #include_next,...
Definition: HeaderSearch.h:237
std::string getCachedModuleFileName(Module *Module)
Retrieve the name of the cached module file that should be used to load the given module.
One of these records is kept for each identifier that is lexed.
@ CMK_HeaderUnit
Compiling a module header unit.
Definition: LangOptions.h:107
@ CMK_ModuleInterface
Compiling a C++ modules interface unit.
Definition: LangOptions.h:110
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:499
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:554
std::vector< std::string > ModuleFeatures
The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...
Definition: LangOptions.h:560
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
Definition: Lexer.h:78
void SetKeepWhitespaceMode(bool Val)
SetKeepWhitespaceMode - This method lets clients enable or disable whitespace retention mode.
Definition: Lexer.h:254
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
Definition: Lexer.h:236
static PreambleBounds ComputePreamble(StringRef Buffer, const LangOptions &LangOpts, unsigned MaxLines=0)
Compute the preamble of the given file.
Definition: Lexer.cpp:636
Describes a module or submodule.
Definition: Module.h:115
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition: Module.h:442
@ Hidden
All of the names in this module are hidden.
Definition: Module.h:416
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
Definition: Module.cpp:465
ModuleKind Kind
The kind of this module.
Definition: Module.h:160
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition: Module.h:429
std::string Name
The name of this module.
Definition: Module.h:118
llvm::iterator_range< submodule_iterator > submodules()
Definition: Module.h:809
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
Definition: Module.h:138
@ ModuleMapModule
This is a module that was defined by a module map and built out of header files.
Definition: Module.h:129
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
Definition: Module.h:156
@ ModulePartitionInterface
This is a C++20 module partition interface.
Definition: Module.h:141
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
Definition: Module.h:135
@ ModuleHeaderUnit
This is a C++20 header unit.
Definition: Module.h:132
@ ModulePartitionImplementation
This is a C++20 module partition implementation.
Definition: Module.h:144
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
Definition: Module.h:151
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
Definition: Module.h:148
This represents a decl that may have a name.
Definition: Decl.h:253
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
Definition: Decl.cpp:1818
virtual std::unique_ptr< ASTConsumer > CreatePCHContainerGenerator(CompilerInstance &CI, const std::string &MainFileName, const std::string &OutputFileName, std::unique_ptr< llvm::raw_pwrite_stream > OS, std::shared_ptr< PCHBuffer > Buffer) const =0
Return an ASTConsumer that can be chained with a PCHGenerator that produces a wrapper file format con...
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Definition: PPCallbacks.h:36
virtual void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported)
Callback invoked whenever there was an explicit module-import syntax.
Definition: PPCallbacks.h:209
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::pair< unsigned, bool > PrecompiledPreambleBytes
If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...
bool DetailedRecord
Whether we should maintain a detailed record of all macro definitions and expansions.
bool UsePredefines
Initialize the preprocessor with the compiler and target specific predefines.
std::vector< std::pair< std::string, bool > > Macros
bool AllowPCHWithCompilerErrors
When true, a PCH with compiler errors will not be rejected.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:138
void DumpToken(const Token &Tok, bool DumpFlags=false) const
Print the token to stderr, used for debugging.
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
Definition: Pragma.cpp:2193
PPCallbacks * getPPCallbacks() const
void Lex(Token &Result)
Lex the next token for this preprocessor.
void EnterMainSourceFile()
Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
llvm::iterator_range< macro_iterator > macros(bool IncludeExternalMacros=true) const
HeaderSearch & getHeaderSearchInfo() const
const LangOptions & getLangOpts() const
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:463
ASTContext & Context
Definition: Sema.h:908
const LangOptions & getLangOpts() const
Definition: Sema.h:524
std::vector< std::unique_ptr< TemplateInstantiationCallback > > TemplateInstCallbacks
The template instantiation callbacks to trace or track instantiations (objects can be chained).
Definition: Sema.h:13179
SourceManager & getSourceManager() const
Definition: Sema.h:529
Encodes a location in the source.
void print(raw_ostream &OS, const SourceManager &SM) const
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
Options for controlling the target.
Definition: TargetOptions.h:26
std::string Triple
The name of the target triple to compile for.
Definition: TargetOptions.h:29
std::string ABI
If given, the name of the target ABI to use.
Definition: TargetOptions.h:45
std::string TuneCPU
If given, the name of the target CPU to tune code for.
Definition: TargetOptions.h:39
std::string CPU
If given, the name of the target CPU to generate code for.
Definition: TargetOptions.h:36
std::vector< std::string > FeaturesAsWritten
The list of target specific features to enable or disable, as written on the command line.
Definition: TargetOptions.h:54
This is a base class for callbacks that will be notified at every template instantiation.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
Token - This structure provides full information about a lexed token.
Definition: Token.h:36
bool isNot(tok::TokenKind K) const
Definition: Token.h:100
The base class of the type hierarchy.
Definition: Type.h:1828
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
Information about a module that has been loaded by the ASTReader.
Definition: ModuleFile.h:130
std::string ModuleName
The name of the module.
Definition: ModuleFile.h:148
ModuleFile & getPrimaryModule()
Returns the primary module associated with the manager, that is, the first module loaded.
Defines the clang::TargetInfo interface.
@ MK_PCH
File is a PCH file treated as such.
Definition: ModuleFile.h:51
@ MK_Preamble
File is a PCH file treated as the preamble.
Definition: ModuleFile.h:54
The JSON file list parser is used to communicate input to InstallAPI.
void atTemplateEnd(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema, const Sema::CodeSynthesisContext &Inst)
void atTemplateBegin(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema, const Sema::CodeSynthesisContext &Inst)
void printDependencyDirectivesAsSource(StringRef Source, ArrayRef< dependency_directives_scan::Directive > Directives, llvm::raw_ostream &OS)
Print the previously scanned dependency directives as minimized source text.
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
bool scanSourceForDependencyDirectives(StringRef Input, SmallVectorImpl< dependency_directives_scan::Token > &Tokens, SmallVectorImpl< dependency_directives_scan::Directive > &Directives, DiagnosticsEngine *Diags=nullptr, SourceLocation InputSourceLoc=SourceLocation())
Scan the input for the preprocessor directives that might have an effect on the dependencies for a co...
std::unique_ptr< ASTConsumer > CreateASTDeclNodeLister()
@ C
Languages that the frontend can parse and compile.
@ CIR
LLVM IR & CIR: we accept these so that we can run the optimizer on them, and compile them to assembly...
@ Asm
Assembly: we accept this only so that we can preprocess it.
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)
DoPrintPreprocessedInput - Implement -E mode.
std::unique_ptr< ASTConsumer > CreateASTDumper(std::unique_ptr< raw_ostream > OS, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups, bool DumpDeclTypes, ASTDumpOutputFormat Format)
std::unique_ptr< ASTConsumer > CreateASTPrinter(std::unique_ptr< raw_ostream > OS, StringRef FilterString)
std::unique_ptr< ASTConsumer > CreateASTViewer()
@ None
Perform validation, don't disable it.
std::string getClangFullRepositoryVersion()
Retrieves the full repository version that is an amalgamation of the information in getClangRepositor...
Definition: Version.cpp:68
void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
Metadata for a module file extension.
unsigned MajorVersion
The major version of the extension data.
std::string UserInfo
A string containing additional user information that will be stored with the metadata.
std::string BlockName
The name used to identify this particular extension block within the resulting module file.
unsigned MinorVersion
The minor version of the extension data.
unsigned Size
Size of the preamble in bytes.
Definition: Lexer.h:62
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned SuppressDefaultTemplateArgs
When true, attempt to suppress template arguments that match the default argument for the parameter.
A context in which code is being synthesized (where a source location alone is not sufficient to iden...
Definition: Sema.h:12653
static void mapping(IO &io, TemplightEntry &fields)