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/Support/ErrorHandling.h"
30#include "llvm/Support/FileSystem.h"
31#include "llvm/Support/MemoryBuffer.h"
32#include "llvm/Support/Path.h"
33#include "llvm/Support/YAMLTraits.h"
34#include "llvm/Support/raw_ostream.h"
35#include <memory>
36#include <optional>
37#include <system_error>
38
39using namespace clang;
40
41namespace {
42CodeCompleteConsumer *GetCodeCompletionConsumer(CompilerInstance &CI) {
44 : nullptr;
45}
46
47void EnsureSemaIsCreated(CompilerInstance &CI, FrontendAction &Action) {
48 if (Action.hasCodeCompletionSupport() &&
51
52 if (!CI.hasSema())
54 GetCodeCompletionConsumer(CI));
55}
56} // namespace
57
58//===----------------------------------------------------------------------===//
59// Custom Actions
60//===----------------------------------------------------------------------===//
61
62std::unique_ptr<ASTConsumer>
63InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
64 return std::make_unique<ASTConsumer>();
65}
66
67void InitOnlyAction::ExecuteAction() {
68}
69
70// Basically PreprocessOnlyAction::ExecuteAction.
71void ReadPCHAndPreprocessAction::ExecuteAction() {
73
74 // Ignore unknown pragmas.
75 PP.IgnorePragmas();
76
77 Token Tok;
78 // Start parsing the specified input file.
80 do {
81 PP.Lex(Tok);
82 } while (Tok.isNot(tok::eof));
83}
84
85std::unique_ptr<ASTConsumer>
86ReadPCHAndPreprocessAction::CreateASTConsumer(CompilerInstance &CI,
87 StringRef InFile) {
88 return std::make_unique<ASTConsumer>();
89}
90
91//===----------------------------------------------------------------------===//
92// AST Consumer Actions
93//===----------------------------------------------------------------------===//
94
95std::unique_ptr<ASTConsumer>
97 if (std::unique_ptr<raw_ostream> OS =
98 CI.createDefaultOutputFile(false, InFile))
99 return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter);
100 return nullptr;
101}
102
103std::unique_ptr<ASTConsumer>
105 const FrontendOptions &Opts = CI.getFrontendOpts();
106 return CreateASTDumper(nullptr /*Dump to stdout.*/, Opts.ASTDumpFilter,
107 Opts.ASTDumpDecls, Opts.ASTDumpAll,
109 Opts.ASTDumpFormat);
110}
111
112std::unique_ptr<ASTConsumer>
115}
116
117std::unique_ptr<ASTConsumer>
119 return CreateASTViewer();
120}
121
122std::unique_ptr<ASTConsumer>
124 std::string Sysroot;
125 if (!ComputeASTConsumerArguments(CI, /*ref*/ Sysroot))
126 return nullptr;
127
128 std::string OutputFile;
129 std::unique_ptr<raw_pwrite_stream> OS =
130 CreateOutputFile(CI, InFile, /*ref*/ OutputFile);
131 if (!OS)
132 return nullptr;
133
135 Sysroot.clear();
136
137 const auto &FrontendOpts = CI.getFrontendOpts();
138 auto Buffer = std::make_shared<PCHBuffer>();
139 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
140 Consumers.push_back(std::make_unique<PCHGenerator>(
141 CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
142 FrontendOpts.ModuleFileExtensions,
144 FrontendOpts.IncludeTimestamps, FrontendOpts.BuildingImplicitModule,
145 +CI.getLangOpts().CacheGeneratedPCH));
146 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
147 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
148
149 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
150}
151
153 std::string &Sysroot) {
154 Sysroot = CI.getHeaderSearchOpts().Sysroot;
155 if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
156 CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
157 return false;
158 }
159
160 return true;
161}
162
163std::unique_ptr<llvm::raw_pwrite_stream>
165 std::string &OutputFile) {
166 // Because this is exposed via libclang we must disable RemoveFileOnSignal.
167 std::unique_ptr<raw_pwrite_stream> OS = CI.createDefaultOutputFile(
168 /*Binary=*/true, InFile, /*Extension=*/"", /*RemoveFileOnSignal=*/false);
169 if (!OS)
170 return nullptr;
171
172 OutputFile = CI.getFrontendOpts().OutputFile;
173 return OS;
174}
175
177 if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)
178 return false;
180}
181
183 CI.getLangOpts().CompilingPCH = true;
184 return true;
185}
186
187std::vector<std::unique_ptr<ASTConsumer>>
189 StringRef InFile) {
190 std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile);
191 if (!OS)
192 return {};
193
194 std::string OutputFile = CI.getFrontendOpts().OutputFile;
195 std::string Sysroot;
196
197 auto Buffer = std::make_shared<PCHBuffer>();
198 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
199
200 Consumers.push_back(std::make_unique<PCHGenerator>(
201 CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
203 /*AllowASTWithErrors=*/
205 /*IncludeTimestamps=*/
208 /*BuildingImplicitModule=*/+CI.getFrontendOpts().BuildingImplicitModule,
209 /*ShouldCacheASTInMemory=*/
211 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
212 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
213 return Consumers;
214}
215
216std::unique_ptr<ASTConsumer>
218 StringRef InFile) {
219 std::vector<std::unique_ptr<ASTConsumer>> Consumers =
220 CreateMultiplexConsumer(CI, InFile);
221 if (Consumers.empty())
222 return nullptr;
223
224 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
225}
226
230}
231
232bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(
233 CompilerInstance &CI) {
234 if (!CI.getLangOpts().Modules) {
235 CI.getDiagnostics().Report(diag::err_module_build_requires_fmodules);
236 return false;
237 }
238
240}
241
242std::unique_ptr<raw_pwrite_stream>
243GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
244 StringRef InFile) {
245 // If no output file was provided, figure out where this module would go
246 // in the module cache.
247 if (CI.getFrontendOpts().OutputFile.empty()) {
248 StringRef ModuleMapFile = CI.getFrontendOpts().OriginalModuleMap;
249 if (ModuleMapFile.empty())
250 ModuleMapFile = InFile;
251
255 ModuleMapFile);
256 }
257
258 // Because this is exposed via libclang we must disable RemoveFileOnSignal.
259 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, /*Extension=*/"",
260 /*RemoveFileOnSignal=*/false,
261 /*CreateMissingDirectories=*/true,
262 /*ForceUseTemporary=*/true);
263}
264
266 CompilerInstance &CI) {
267 CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
268
270}
271
272std::unique_ptr<ASTConsumer>
274 StringRef InFile) {
275 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
276
278 !CI.getFrontendOpts().ModuleOutputPath.empty()) {
279 Consumers.push_back(std::make_unique<ReducedBMIGenerator>(
282 }
283
284 Consumers.push_back(std::make_unique<CXX20ModulesGenerator>(
287
288 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
289}
290
291std::unique_ptr<raw_pwrite_stream>
293 StringRef InFile) {
294 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
295}
296
297std::unique_ptr<ASTConsumer>
298GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
299 StringRef InFile) {
300 return std::make_unique<ReducedBMIGenerator>(CI.getPreprocessor(),
301 CI.getModuleCache(),
303}
304
305bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) {
306 if (!CI.getLangOpts().CPlusPlusModules) {
307 CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
308 return false;
309 }
310 CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderUnit);
312}
313
314std::unique_ptr<raw_pwrite_stream>
315GenerateHeaderUnitAction::CreateOutputFile(CompilerInstance &CI,
316 StringRef InFile) {
317 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
318}
319
321}
322
323std::unique_ptr<ASTConsumer>
325 return std::make_unique<ASTConsumer>();
326}
327
328std::unique_ptr<ASTConsumer>
330 StringRef InFile) {
331 return std::make_unique<ASTConsumer>();
332}
333
334std::unique_ptr<ASTConsumer>
336 return std::make_unique<ASTConsumer>();
337}
338
342 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
343 std::unique_ptr<ASTReader> Reader(new ASTReader(
346 Sysroot.empty() ? "" : Sysroot.c_str(),
348 /*AllowASTWithCompilerErrors*/ false,
349 /*AllowConfigurationMismatch*/ true,
350 /*ValidateSystemInputs*/ true));
351
352 Reader->ReadAST(getCurrentFile(),
357}
358
359namespace {
360struct TemplightEntry {
361 std::string Name;
362 std::string Kind;
363 std::string Event;
364 std::string DefinitionLocation;
365 std::string PointOfInstantiation;
366};
367} // namespace
368
369namespace llvm {
370namespace yaml {
371template <> struct MappingTraits<TemplightEntry> {
372 static void mapping(IO &io, TemplightEntry &fields) {
373 io.mapRequired("name", fields.Name);
374 io.mapRequired("kind", fields.Kind);
375 io.mapRequired("event", fields.Event);
376 io.mapRequired("orig", fields.DefinitionLocation);
377 io.mapRequired("poi", fields.PointOfInstantiation);
378 }
379};
380} // namespace yaml
381} // namespace llvm
382
383namespace {
384class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
385 using CodeSynthesisContext = Sema::CodeSynthesisContext;
386
387public:
388 void initialize(const Sema &) override {}
389
390 void finalize(const Sema &) override {}
391
392 void atTemplateBegin(const Sema &TheSema,
393 const CodeSynthesisContext &Inst) override {
394 displayTemplightEntry<true>(llvm::outs(), TheSema, Inst);
395 }
396
397 void atTemplateEnd(const Sema &TheSema,
398 const CodeSynthesisContext &Inst) override {
399 displayTemplightEntry<false>(llvm::outs(), TheSema, Inst);
400 }
401
402private:
403 static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {
404 switch (Kind) {
405 case CodeSynthesisContext::TemplateInstantiation:
406 return "TemplateInstantiation";
407 case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
408 return "DefaultTemplateArgumentInstantiation";
409 case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
410 return "DefaultFunctionArgumentInstantiation";
411 case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
412 return "ExplicitTemplateArgumentSubstitution";
413 case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
414 return "DeducedTemplateArgumentSubstitution";
415 case CodeSynthesisContext::LambdaExpressionSubstitution:
416 return "LambdaExpressionSubstitution";
417 case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
418 return "PriorTemplateArgumentSubstitution";
419 case CodeSynthesisContext::DefaultTemplateArgumentChecking:
420 return "DefaultTemplateArgumentChecking";
421 case CodeSynthesisContext::ExceptionSpecEvaluation:
422 return "ExceptionSpecEvaluation";
423 case CodeSynthesisContext::ExceptionSpecInstantiation:
424 return "ExceptionSpecInstantiation";
425 case CodeSynthesisContext::DeclaringSpecialMember:
426 return "DeclaringSpecialMember";
427 case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
428 return "DeclaringImplicitEqualityComparison";
429 case CodeSynthesisContext::DefiningSynthesizedFunction:
430 return "DefiningSynthesizedFunction";
431 case CodeSynthesisContext::RewritingOperatorAsSpaceship:
432 return "RewritingOperatorAsSpaceship";
433 case CodeSynthesisContext::Memoization:
434 return "Memoization";
435 case CodeSynthesisContext::ConstraintsCheck:
436 return "ConstraintsCheck";
437 case CodeSynthesisContext::ConstraintSubstitution:
438 return "ConstraintSubstitution";
439 case CodeSynthesisContext::ConstraintNormalization:
440 return "ConstraintNormalization";
441 case CodeSynthesisContext::RequirementParameterInstantiation:
442 return "RequirementParameterInstantiation";
443 case CodeSynthesisContext::ParameterMappingSubstitution:
444 return "ParameterMappingSubstitution";
445 case CodeSynthesisContext::RequirementInstantiation:
446 return "RequirementInstantiation";
447 case CodeSynthesisContext::NestedRequirementConstraintsCheck:
448 return "NestedRequirementConstraintsCheck";
449 case CodeSynthesisContext::InitializingStructuredBinding:
450 return "InitializingStructuredBinding";
451 case CodeSynthesisContext::MarkingClassDllexported:
452 return "MarkingClassDllexported";
453 case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
454 return "BuildingBuiltinDumpStructCall";
455 case CodeSynthesisContext::BuildingDeductionGuides:
456 return "BuildingDeductionGuides";
457 case CodeSynthesisContext::TypeAliasTemplateInstantiation:
458 return "TypeAliasTemplateInstantiation";
459 }
460 return "";
461 }
462
463 template <bool BeginInstantiation>
464 static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema,
465 const CodeSynthesisContext &Inst) {
466 std::string YAML;
467 {
468 llvm::raw_string_ostream OS(YAML);
469 llvm::yaml::Output YO(OS);
470 TemplightEntry Entry =
471 getTemplightEntry<BeginInstantiation>(TheSema, Inst);
472 llvm::yaml::EmptyContext Context;
473 llvm::yaml::yamlize(YO, Entry, true, Context);
474 }
475 Out << "---" << YAML << "\n";
476 }
477
478 static void printEntryName(const Sema &TheSema, const Decl *Entity,
479 llvm::raw_string_ostream &OS) {
480 auto *NamedTemplate = cast<NamedDecl>(Entity);
481
482 PrintingPolicy Policy = TheSema.Context.getPrintingPolicy();
483 // FIXME: Also ask for FullyQualifiedNames?
484 Policy.SuppressDefaultTemplateArgs = false;
485 NamedTemplate->getNameForDiagnostic(OS, Policy, true);
486
487 if (!OS.str().empty())
488 return;
489
490 Decl *Ctx = Decl::castFromDeclContext(NamedTemplate->getDeclContext());
491 NamedDecl *NamedCtx = dyn_cast_or_null<NamedDecl>(Ctx);
492
493 if (const auto *Decl = dyn_cast<TagDecl>(NamedTemplate)) {
494 if (const auto *R = dyn_cast<RecordDecl>(Decl)) {
495 if (R->isLambda()) {
496 OS << "lambda at ";
497 Decl->getLocation().print(OS, TheSema.getSourceManager());
498 return;
499 }
500 }
501 OS << "unnamed " << Decl->getKindName();
502 return;
503 }
504
505 assert(NamedCtx && "NamedCtx cannot be null");
506
507 if (const auto *Decl = dyn_cast<ParmVarDecl>(NamedTemplate)) {
508 OS << "unnamed function parameter " << Decl->getFunctionScopeIndex()
509 << " ";
510 if (Decl->getFunctionScopeDepth() > 0)
511 OS << "(at depth " << Decl->getFunctionScopeDepth() << ") ";
512 OS << "of ";
513 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
514 return;
515 }
516
517 if (const auto *Decl = dyn_cast<TemplateTypeParmDecl>(NamedTemplate)) {
518 if (const Type *Ty = Decl->getTypeForDecl()) {
519 if (const auto *TTPT = dyn_cast_or_null<TemplateTypeParmType>(Ty)) {
520 OS << "unnamed template type parameter " << TTPT->getIndex() << " ";
521 if (TTPT->getDepth() > 0)
522 OS << "(at depth " << TTPT->getDepth() << ") ";
523 OS << "of ";
524 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
525 return;
526 }
527 }
528 }
529
530 if (const auto *Decl = dyn_cast<NonTypeTemplateParmDecl>(NamedTemplate)) {
531 OS << "unnamed template non-type parameter " << Decl->getIndex() << " ";
532 if (Decl->getDepth() > 0)
533 OS << "(at depth " << Decl->getDepth() << ") ";
534 OS << "of ";
535 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
536 return;
537 }
538
539 if (const auto *Decl = dyn_cast<TemplateTemplateParmDecl>(NamedTemplate)) {
540 OS << "unnamed template template parameter " << Decl->getIndex() << " ";
541 if (Decl->getDepth() > 0)
542 OS << "(at depth " << Decl->getDepth() << ") ";
543 OS << "of ";
544 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
545 return;
546 }
547
548 llvm_unreachable("Failed to retrieve a name for this entry!");
549 OS << "unnamed identifier";
550 }
551
552 template <bool BeginInstantiation>
553 static TemplightEntry getTemplightEntry(const Sema &TheSema,
554 const CodeSynthesisContext &Inst) {
555 TemplightEntry Entry;
556 Entry.Kind = toString(Inst.Kind);
557 Entry.Event = BeginInstantiation ? "Begin" : "End";
558 llvm::raw_string_ostream OS(Entry.Name);
559 printEntryName(TheSema, Inst.Entity, OS);
560 const PresumedLoc DefLoc =
561 TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation());
562 if (!DefLoc.isInvalid())
563 Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +
564 std::to_string(DefLoc.getLine()) + ":" +
565 std::to_string(DefLoc.getColumn());
566 const PresumedLoc PoiLoc =
567 TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation);
568 if (!PoiLoc.isInvalid()) {
569 Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +
570 std::to_string(PoiLoc.getLine()) + ":" +
571 std::to_string(PoiLoc.getColumn());
572 }
573 return Entry;
574 }
575};
576} // namespace
577
578std::unique_ptr<ASTConsumer>
580 return std::make_unique<ASTConsumer>();
581}
582
585
586 // This part is normally done by ASTFrontEndAction, but needs to happen
587 // before Templight observers can be created
588 // FIXME: Move the truncation aspect of this into Sema, we delayed this till
589 // here so the source manager would be initialized.
590 EnsureSemaIsCreated(CI, *this);
591
592 CI.getSema().TemplateInstCallbacks.push_back(
593 std::make_unique<DefaultTemplateInstCallback>());
595}
596
597namespace {
598 /// AST reader listener that dumps module information for a module
599 /// file.
600 class DumpModuleInfoListener : public ASTReaderListener {
601 llvm::raw_ostream &Out;
602
603 public:
604 DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { }
605
606#define DUMP_BOOLEAN(Value, Text) \
607 Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
608
609 bool ReadFullVersionInformation(StringRef FullVersion) override {
610 Out.indent(2)
611 << "Generated by "
612 << (FullVersion == getClangFullRepositoryVersion()? "this"
613 : "a different")
614 << " Clang: " << FullVersion << "\n";
616 }
617
618 void ReadModuleName(StringRef ModuleName) override {
619 Out.indent(2) << "Module name: " << ModuleName << "\n";
620 }
621 void ReadModuleMapFile(StringRef ModuleMapPath) override {
622 Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
623 }
624
625 bool ReadLanguageOptions(const LangOptions &LangOpts,
626 StringRef ModuleFilename, bool Complain,
627 bool AllowCompatibleDifferences) override {
628 Out.indent(2) << "Language options:\n";
629#define LANGOPT(Name, Bits, Default, Description) \
630 DUMP_BOOLEAN(LangOpts.Name, Description);
631#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
632 Out.indent(4) << Description << ": " \
633 << static_cast<unsigned>(LangOpts.get##Name()) << "\n";
634#define VALUE_LANGOPT(Name, Bits, Default, Description) \
635 Out.indent(4) << Description << ": " << LangOpts.Name << "\n";
636#define BENIGN_LANGOPT(Name, Bits, Default, Description)
637#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
638#include "clang/Basic/LangOptions.def"
639
640 if (!LangOpts.ModuleFeatures.empty()) {
641 Out.indent(4) << "Module features:\n";
642 for (StringRef Feature : LangOpts.ModuleFeatures)
643 Out.indent(6) << Feature << "\n";
644 }
645
646 return false;
647 }
648
649 bool ReadTargetOptions(const TargetOptions &TargetOpts,
650 StringRef ModuleFilename, bool Complain,
651 bool AllowCompatibleDifferences) override {
652 Out.indent(2) << "Target options:\n";
653 Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n";
654 Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n";
655 Out.indent(4) << " TuneCPU: " << TargetOpts.TuneCPU << "\n";
656 Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n";
657
658 if (!TargetOpts.FeaturesAsWritten.empty()) {
659 Out.indent(4) << "Target features:\n";
660 for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size();
661 I != N; ++I) {
662 Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n";
663 }
664 }
665
666 return false;
667 }
668
669 bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
670 StringRef ModuleFilename,
671 bool Complain) override {
672 Out.indent(2) << "Diagnostic options:\n";
673#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
674#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
675 Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
676#define VALUE_DIAGOPT(Name, Bits, Default) \
677 Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
678#include "clang/Basic/DiagnosticOptions.def"
679
680 Out.indent(4) << "Diagnostic flags:\n";
681 for (const std::string &Warning : DiagOpts->Warnings)
682 Out.indent(6) << "-W" << Warning << "\n";
683 for (const std::string &Remark : DiagOpts->Remarks)
684 Out.indent(6) << "-R" << Remark << "\n";
685
686 return false;
687 }
688
689 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
690 StringRef ModuleFilename,
691 StringRef SpecificModuleCachePath,
692 bool Complain) override {
693 Out.indent(2) << "Header search options:\n";
694 Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
695 Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
696 Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
698 "Use builtin include directories [-nobuiltininc]");
700 "Use standard system include directories [-nostdinc]");
702 "Use standard C++ include directories [-nostdinc++]");
703 DUMP_BOOLEAN(HSOpts.UseLibcxx,
704 "Use libc++ (rather than libstdc++) [-stdlib=]");
705 return false;
706 }
707
708 bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
709 bool Complain) override {
710 Out.indent(2) << "Header search paths:\n";
711 Out.indent(4) << "User entries:\n";
712 for (const auto &Entry : HSOpts.UserEntries)
713 Out.indent(6) << Entry.Path << "\n";
714 Out.indent(4) << "System header prefixes:\n";
715 for (const auto &Prefix : HSOpts.SystemHeaderPrefixes)
716 Out.indent(6) << Prefix.Prefix << "\n";
717 Out.indent(4) << "VFS overlay files:\n";
718 for (const auto &Overlay : HSOpts.VFSOverlayFiles)
719 Out.indent(6) << Overlay << "\n";
720 return false;
721 }
722
723 bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
724 StringRef ModuleFilename, bool ReadMacros,
725 bool Complain,
726 std::string &SuggestedPredefines) override {
727 Out.indent(2) << "Preprocessor options:\n";
729 "Uses compiler/target-specific predefines [-undef]");
731 "Uses detailed preprocessing record (for indexing)");
732
733 if (ReadMacros) {
734 Out.indent(4) << "Predefined macros:\n";
735 }
736
737 for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
738 I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
739 I != IEnd; ++I) {
740 Out.indent(6);
741 if (I->second)
742 Out << "-U";
743 else
744 Out << "-D";
745 Out << I->first << "\n";
746 }
747 return false;
748 }
749
750 /// Indicates that a particular module file extension has been read.
751 void readModuleFileExtension(
752 const ModuleFileExtensionMetadata &Metadata) override {
753 Out.indent(2) << "Module file extension '"
754 << Metadata.BlockName << "' " << Metadata.MajorVersion
755 << "." << Metadata.MinorVersion;
756 if (!Metadata.UserInfo.empty()) {
757 Out << ": ";
758 Out.write_escaped(Metadata.UserInfo);
759 }
760
761 Out << "\n";
762 }
763
764 /// Tells the \c ASTReaderListener that we want to receive the
765 /// input files of the AST file via \c visitInputFile.
766 bool needsInputFileVisitation() override { return true; }
767
768 /// Tells the \c ASTReaderListener that we want to receive the
769 /// input files of the AST file via \c visitInputFile.
770 bool needsSystemInputFileVisitation() override { return true; }
771
772 /// Indicates that the AST file contains particular input file.
773 ///
774 /// \returns true to continue receiving the next input file, false to stop.
775 bool visitInputFile(StringRef Filename, bool isSystem,
776 bool isOverridden, bool isExplicitModule) override {
777
778 Out.indent(2) << "Input file: " << Filename;
779
780 if (isSystem || isOverridden || isExplicitModule) {
781 Out << " [";
782 if (isSystem) {
783 Out << "System";
784 if (isOverridden || isExplicitModule)
785 Out << ", ";
786 }
787 if (isOverridden) {
788 Out << "Overridden";
789 if (isExplicitModule)
790 Out << ", ";
791 }
792 if (isExplicitModule)
793 Out << "ExplicitModule";
794
795 Out << "]";
796 }
797
798 Out << "\n";
799
800 return true;
801 }
802
803 /// Returns true if this \c ASTReaderListener wants to receive the
804 /// imports of the AST file via \c visitImport, false otherwise.
805 bool needsImportVisitation() const override { return true; }
806
807 /// If needsImportVisitation returns \c true, this is called for each
808 /// AST file imported by this AST file.
809 void visitImport(StringRef ModuleName, StringRef Filename) override {
810 Out.indent(2) << "Imports module '" << ModuleName
811 << "': " << Filename.str() << "\n";
812 }
813#undef DUMP_BOOLEAN
814 };
815}
816
818 // The Object file reader also supports raw ast files and there is no point in
819 // being strict about the module file format in -module-file-info mode.
821 return true;
822}
823
824static StringRef ModuleKindName(Module::ModuleKind MK) {
825 switch (MK) {
827 return "Module Map Module";
829 return "Interface Unit";
831 return "Implementation Unit";
833 return "Partition Interface";
835 return "Partition Implementation";
837 return "Header Unit";
839 return "Global Module Fragment";
841 return "Implicit Module Fragment";
843 return "Private Module Fragment";
844 }
845 llvm_unreachable("unknown module kind!");
846}
847
850
851 // Don't process files of type other than module to avoid crash
852 if (!isCurrentFileAST()) {
853 CI.getDiagnostics().Report(diag::err_file_is_not_module)
854 << getCurrentFile();
855 return;
856 }
857
858 // Set up the output file.
859 StringRef OutputFileName = CI.getFrontendOpts().OutputFile;
860 if (!OutputFileName.empty() && OutputFileName != "-") {
861 std::error_code EC;
862 OutputStream.reset(new llvm::raw_fd_ostream(
863 OutputFileName.str(), EC, llvm::sys::fs::OF_TextWithCRLF));
864 }
865 llvm::raw_ostream &Out = OutputStream ? *OutputStream : llvm::outs();
866
867 Out << "Information for module file '" << getCurrentFile() << "':\n";
868 auto &FileMgr = CI.getFileManager();
869 auto Buffer = FileMgr.getBufferForFile(getCurrentFile());
870 StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();
871 bool IsRaw = Magic.starts_with("CPCH");
872 Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n";
873
874 Preprocessor &PP = CI.getPreprocessor();
875 DumpModuleInfoListener Listener(Out);
876 HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
877
878 // The FrontendAction::BeginSourceFile () method loads the AST so that much
879 // of the information is already available and modules should have been
880 // loaded.
881
883 if (LO.CPlusPlusModules && !LO.CurrentModule.empty()) {
885 unsigned SubModuleCount = R->getTotalNumSubmodules();
887 Out << " ====== C++20 Module structure ======\n";
888
889 if (MF.ModuleName != LO.CurrentModule)
890 Out << " Mismatched module names : " << MF.ModuleName << " and "
891 << LO.CurrentModule << "\n";
892
893 struct SubModInfo {
894 unsigned Idx;
895 Module *Mod;
897 std::string &Name;
898 bool Seen;
899 };
900 std::map<std::string, SubModInfo> SubModMap;
901 auto PrintSubMapEntry = [&](std::string Name, Module::ModuleKind Kind) {
902 Out << " " << ModuleKindName(Kind) << " '" << Name << "'";
903 auto I = SubModMap.find(Name);
904 if (I == SubModMap.end())
905 Out << " was not found in the sub modules!\n";
906 else {
907 I->second.Seen = true;
908 Out << " is at index #" << I->second.Idx << "\n";
909 }
910 };
911 Module *Primary = nullptr;
912 for (unsigned Idx = 0; Idx <= SubModuleCount; ++Idx) {
913 Module *M = R->getModule(Idx);
914 if (!M)
915 continue;
916 if (M->Name == LO.CurrentModule) {
917 Primary = M;
918 Out << " " << ModuleKindName(M->Kind) << " '" << LO.CurrentModule
919 << "' is the Primary Module at index #" << Idx << "\n";
920 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, true}});
921 } else
922 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, false}});
923 }
924 if (Primary) {
925 if (!Primary->submodules().empty())
926 Out << " Sub Modules:\n";
927 for (auto *MI : Primary->submodules()) {
928 PrintSubMapEntry(MI->Name, MI->Kind);
929 }
930 if (!Primary->Imports.empty())
931 Out << " Imports:\n";
932 for (auto *IMP : Primary->Imports) {
933 PrintSubMapEntry(IMP->Name, IMP->Kind);
934 }
935 if (!Primary->Exports.empty())
936 Out << " Exports:\n";
937 for (unsigned MN = 0, N = Primary->Exports.size(); MN != N; ++MN) {
938 if (Module *M = Primary->Exports[MN].getPointer()) {
939 PrintSubMapEntry(M->Name, M->Kind);
940 }
941 }
942 }
943
944 // Emit the macro definitions in the module file so that we can know how
945 // much definitions in the module file quickly.
946 // TODO: Emit the macro definition bodies completely.
947 if (auto FilteredMacros = llvm::make_filter_range(
948 R->getPreprocessor().macros(),
949 [](const auto &Macro) { return Macro.first->isFromAST(); });
950 !FilteredMacros.empty()) {
951 Out << " Macro Definitions:\n";
952 for (/*<IdentifierInfo *, MacroState> pair*/ const auto &Macro :
953 FilteredMacros)
954 Out << " " << Macro.first->getName() << "\n";
955 }
956
957 // Now let's print out any modules we did not see as part of the Primary.
958 for (const auto &SM : SubModMap) {
959 if (!SM.second.Seen && SM.second.Mod) {
960 Out << " " << ModuleKindName(SM.second.Kind) << " '" << SM.first
961 << "' at index #" << SM.second.Idx
962 << " has no direct reference in the Primary\n";
963 }
964 }
965 Out << " ====== ======\n";
966 }
967
968 // The reminder of the output is produced from the listener as the AST
969 // FileCcontrolBlock is (re-)parsed.
971 getCurrentFile(), FileMgr, CI.getModuleCache(),
973 /*FindModuleFileExtensions=*/true, Listener,
975}
976
977//===----------------------------------------------------------------------===//
978// Preprocessor Actions
979//===----------------------------------------------------------------------===//
980
984
985 // Start lexing the specified input file.
986 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
987 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
988 RawLex.SetKeepWhitespaceMode(true);
989
990 Token RawTok;
991 RawLex.LexFromRawLexer(RawTok);
992 while (RawTok.isNot(tok::eof)) {
993 PP.DumpToken(RawTok, true);
994 llvm::errs() << "\n";
995 RawLex.LexFromRawLexer(RawTok);
996 }
997}
998
1001 // Start preprocessing the specified input file.
1002 Token Tok;
1004 do {
1005 PP.Lex(Tok);
1006 PP.DumpToken(Tok, true);
1007 llvm::errs() << "\n";
1008 } while (Tok.isNot(tok::eof));
1009}
1010
1013
1014 // Ignore unknown pragmas.
1015 PP.IgnorePragmas();
1016
1017 Token Tok;
1018 // Start parsing the specified input file.
1020 do {
1021 PP.Lex(Tok);
1022 } while (Tok.isNot(tok::eof));
1023}
1024
1027 // Output file may need to be set to 'Binary', to avoid converting Unix style
1028 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>) on Windows.
1029 //
1030 // Look to see what type of line endings the file uses. If there's a
1031 // CRLF, then we won't open the file up in binary mode. If there is
1032 // just an LF or CR, then we will open the file up in binary mode.
1033 // In this fashion, the output format should match the input format, unless
1034 // the input format has inconsistent line endings.
1035 //
1036 // This should be a relatively fast operation since most files won't have
1037 // all of their source code on a single line. However, that is still a
1038 // concern, so if we scan for too long, we'll just assume the file should
1039 // be opened in binary mode.
1040
1041 bool BinaryMode = false;
1042 if (llvm::Triple(LLVM_HOST_TRIPLE).isOSWindows()) {
1043 BinaryMode = true;
1044 const SourceManager &SM = CI.getSourceManager();
1045 if (std::optional<llvm::MemoryBufferRef> Buffer =
1046 SM.getBufferOrNone(SM.getMainFileID())) {
1047 const char *cur = Buffer->getBufferStart();
1048 const char *end = Buffer->getBufferEnd();
1049 const char *next = (cur != end) ? cur + 1 : end;
1050
1051 // Limit ourselves to only scanning 256 characters into the source
1052 // file. This is mostly a check in case the file has no
1053 // newlines whatsoever.
1054 if (end - cur > 256)
1055 end = cur + 256;
1056
1057 while (next < end) {
1058 if (*cur == 0x0D) { // CR
1059 if (*next == 0x0A) // CRLF
1060 BinaryMode = false;
1061
1062 break;
1063 } else if (*cur == 0x0A) // LF
1064 break;
1065
1066 ++cur;
1067 ++next;
1068 }
1069 }
1070 }
1071
1072 std::unique_ptr<raw_ostream> OS =
1074 if (!OS) return;
1075
1076 // If we're preprocessing a module map, start by dumping the contents of the
1077 // module itself before switching to the input buffer.
1078 auto &Input = getCurrentInput();
1079 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
1080 if (Input.isFile()) {
1081 (*OS) << "# 1 \"";
1082 OS->write_escaped(Input.getFile());
1083 (*OS) << "\"\n";
1084 }
1085 getCurrentModule()->print(*OS);
1086 (*OS) << "#pragma clang module contents\n";
1087 }
1088
1091}
1092
1094 switch (getCurrentFileKind().getLanguage()) {
1095 case Language::C:
1096 case Language::CXX:
1097 case Language::ObjC:
1098 case Language::ObjCXX:
1099 case Language::OpenCL:
1101 case Language::CUDA:
1102 case Language::HIP:
1103 case Language::HLSL:
1104 case Language::CIR:
1105 break;
1106
1107 case Language::Unknown:
1108 case Language::Asm:
1109 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:83
IndirectLocalPath & Path
enum clang::sema::@1653::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:3001
#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:713
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:114
virtual bool ReadFullVersionInformation(StringRef FullVersion)
Receives the full Clang version information.
Definition: ASTReader.h:122
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:378
ModuleManager & getModuleManager()
Retrieve the module manager.
Definition: ASTReader.h:1795
@ ARR_ConfigurationMismatch
The client can handle an AST file that cannot load because it's compiled configuration doesn't match ...
Definition: ASTReader.h:1650
unsigned getTotalNumSubmodules() const
Returns the number of submodules known.
Definition: ASTReader.h:1891
Module * getModule(unsigned ID) override
Retrieve the module that corresponds to the given module ID.
Definition: ASTReader.cpp:9180
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:5440
Preprocessor & getPreprocessor() const
Retrieve the preprocessor.
Definition: ASTReader.h:1799
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:1041
SourceLocation getLocation() const
Definition: DeclBase.h:446
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1547
bool hasErrorOccurred() const
Definition: Diagnostic.h:843
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:697
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)
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:249
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:105
@ CMK_ModuleInterface
Compiling a C++ modules interface unit.
Definition: LangOptions.h:108
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:476
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:531
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:537
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:637
Describes a module or submodule.
Definition: Module.h:105
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition: Module.h:415
@ Hidden
All of the names in this module are hidden.
Definition: Module.h:389
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:482
ModuleKind Kind
The kind of this module.
Definition: Module.h:150
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition: Module.h:402
std::string Name
The name of this module.
Definition: Module.h:108
llvm::iterator_range< submodule_iterator > submodules()
Definition: Module.h:783
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
Definition: Module.h:128
@ ModuleMapModule
This is a module that was defined by a module map and built out of header files.
Definition: Module.h:119
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
Definition: Module.h:146
@ ModulePartitionInterface
This is a C++20 module partition interface.
Definition: Module.h:131
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
Definition: Module.h:125
@ ModuleHeaderUnit
This is a C++20 header unit.
Definition: Module.h:122
@ ModulePartitionImplementation
This is a C++20 module partition implementation.
Definition: Module.h:134
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
Definition: Module.h:141
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
Definition: Module.h:138
This represents a decl that may have a name.
Definition: Decl.h:249
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:1811
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:137
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:2196
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:493
ASTContext & Context
Definition: Sema.h:962
const LangOptions & getLangOpts() const
Definition: Sema.h:553
std::vector< std::unique_ptr< TemplateInstantiationCallback > > TemplateInstCallbacks
The template instantiation callbacks to trace or track instantiations (objects can be chained).
Definition: Sema.h:13191
SourceManager & getSourceManager() const
Definition: Sema.h:558
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:1829
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:124
std::string ModuleName
The name of the module.
Definition: ModuleFile.h:142
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:50
@ MK_Preamble
File is a PCH file treated as the preamble.
Definition: ModuleFile.h:53
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:12673
static void mapping(IO &io, TemplightEntry &fields)