clang 22.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"
30#include "llvm/Config/llvm-config.h" // for LLVM_HOST_TRIPLE
31#include "llvm/Support/ErrorHandling.h"
32#include "llvm/Support/FileSystem.h"
33#include "llvm/Support/MemoryBuffer.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 CI.getCodeGenOpts(), 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;
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 for (const auto &FIF : CI.getFrontendOpts().Inputs) {
269 if (const auto InputFormat = FIF.getKind().getFormat();
270 InputFormat != InputKind::Format::Source) {
272 diag::err_frontend_action_unsupported_input_format)
273 << "module interface compilation" << FIF.getFile() << InputFormat;
274 return false;
275 }
276 }
278}
279
281 CompilerInstance &CI) {
282 CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
283
285}
286
287std::unique_ptr<ASTConsumer>
289 StringRef InFile) {
290 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
291
293 !CI.getFrontendOpts().ModuleOutputPath.empty()) {
294 Consumers.push_back(std::make_unique<ReducedBMIGenerator>(
298 }
299
300 Consumers.push_back(std::make_unique<CXX20ModulesGenerator>(
304
305 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
306}
307
308std::unique_ptr<raw_pwrite_stream>
310 StringRef InFile) {
311 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
312}
313
314std::unique_ptr<ASTConsumer>
315GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
316 StringRef InFile) {
317 return std::make_unique<ReducedBMIGenerator>(
320}
321
322bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) {
323 if (!CI.getLangOpts().CPlusPlusModules) {
324 CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
325 return false;
326 }
327 CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderUnit);
329}
330
331std::unique_ptr<raw_pwrite_stream>
332GenerateHeaderUnitAction::CreateOutputFile(CompilerInstance &CI,
333 StringRef InFile) {
334 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
335}
336
338}
339
340std::unique_ptr<ASTConsumer>
342 return std::make_unique<ASTConsumer>();
343}
344
345std::unique_ptr<ASTConsumer>
347 StringRef InFile) {
348 return std::make_unique<ASTConsumer>();
349}
350
351std::unique_ptr<ASTConsumer>
353 return std::make_unique<ASTConsumer>();
354}
355
359 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
360 std::unique_ptr<ASTReader> Reader(new ASTReader(
364 Sysroot.empty() ? "" : Sysroot.c_str(),
366 /*AllowASTWithCompilerErrors*/ false,
367 /*AllowConfigurationMismatch*/ true,
368 /*ValidateSystemInputs*/ true, /*ForceValidateUserInputs*/ true));
369
370 Reader->ReadAST(getCurrentFile(),
375}
376
377namespace {
378struct TemplightEntry {
379 std::string Name;
380 std::string Kind;
381 std::string Event;
382 std::string DefinitionLocation;
383 std::string PointOfInstantiation;
384};
385} // namespace
386
387namespace llvm {
388namespace yaml {
389template <> struct MappingTraits<TemplightEntry> {
390 static void mapping(IO &io, TemplightEntry &fields) {
391 io.mapRequired("name", fields.Name);
392 io.mapRequired("kind", fields.Kind);
393 io.mapRequired("event", fields.Event);
394 io.mapRequired("orig", fields.DefinitionLocation);
395 io.mapRequired("poi", fields.PointOfInstantiation);
396 }
397};
398} // namespace yaml
399} // namespace llvm
400
401namespace {
402class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
403 using CodeSynthesisContext = Sema::CodeSynthesisContext;
404
405public:
406 void initialize(const Sema &) override {}
407
408 void finalize(const Sema &) override {}
409
410 void atTemplateBegin(const Sema &TheSema,
411 const CodeSynthesisContext &Inst) override {
412 displayTemplightEntry<true>(llvm::outs(), TheSema, Inst);
413 }
414
415 void atTemplateEnd(const Sema &TheSema,
416 const CodeSynthesisContext &Inst) override {
417 displayTemplightEntry<false>(llvm::outs(), TheSema, Inst);
418 }
419
420private:
421 static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {
422 switch (Kind) {
423 case CodeSynthesisContext::TemplateInstantiation:
424 return "TemplateInstantiation";
425 case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
426 return "DefaultTemplateArgumentInstantiation";
427 case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
428 return "DefaultFunctionArgumentInstantiation";
429 case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
430 return "ExplicitTemplateArgumentSubstitution";
431 case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
432 return "DeducedTemplateArgumentSubstitution";
433 case CodeSynthesisContext::LambdaExpressionSubstitution:
434 return "LambdaExpressionSubstitution";
435 case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
436 return "PriorTemplateArgumentSubstitution";
437 case CodeSynthesisContext::DefaultTemplateArgumentChecking:
438 return "DefaultTemplateArgumentChecking";
439 case CodeSynthesisContext::ExceptionSpecEvaluation:
440 return "ExceptionSpecEvaluation";
441 case CodeSynthesisContext::ExceptionSpecInstantiation:
442 return "ExceptionSpecInstantiation";
443 case CodeSynthesisContext::DeclaringSpecialMember:
444 return "DeclaringSpecialMember";
445 case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
446 return "DeclaringImplicitEqualityComparison";
447 case CodeSynthesisContext::DefiningSynthesizedFunction:
448 return "DefiningSynthesizedFunction";
449 case CodeSynthesisContext::RewritingOperatorAsSpaceship:
450 return "RewritingOperatorAsSpaceship";
451 case CodeSynthesisContext::Memoization:
452 return "Memoization";
453 case CodeSynthesisContext::ConstraintsCheck:
454 return "ConstraintsCheck";
455 case CodeSynthesisContext::ConstraintSubstitution:
456 return "ConstraintSubstitution";
457 case CodeSynthesisContext::ConstraintNormalization:
458 return "ConstraintNormalization";
459 case CodeSynthesisContext::RequirementParameterInstantiation:
460 return "RequirementParameterInstantiation";
461 case CodeSynthesisContext::ParameterMappingSubstitution:
462 return "ParameterMappingSubstitution";
463 case CodeSynthesisContext::RequirementInstantiation:
464 return "RequirementInstantiation";
465 case CodeSynthesisContext::NestedRequirementConstraintsCheck:
466 return "NestedRequirementConstraintsCheck";
467 case CodeSynthesisContext::InitializingStructuredBinding:
468 return "InitializingStructuredBinding";
469 case CodeSynthesisContext::MarkingClassDllexported:
470 return "MarkingClassDllexported";
471 case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
472 return "BuildingBuiltinDumpStructCall";
473 case CodeSynthesisContext::BuildingDeductionGuides:
474 return "BuildingDeductionGuides";
475 case CodeSynthesisContext::TypeAliasTemplateInstantiation:
476 return "TypeAliasTemplateInstantiation";
477 case CodeSynthesisContext::PartialOrderingTTP:
478 return "PartialOrderingTTP";
479 }
480 return "";
481 }
482
483 template <bool BeginInstantiation>
484 static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema,
485 const CodeSynthesisContext &Inst) {
486 std::string YAML;
487 {
488 llvm::raw_string_ostream OS(YAML);
489 llvm::yaml::Output YO(OS);
490 TemplightEntry Entry =
491 getTemplightEntry<BeginInstantiation>(TheSema, Inst);
492 llvm::yaml::EmptyContext Context;
493 llvm::yaml::yamlize(YO, Entry, true, Context);
494 }
495 Out << "---" << YAML << "\n";
496 }
497
498 static void printEntryName(const Sema &TheSema, const Decl *Entity,
499 llvm::raw_string_ostream &OS) {
500 auto *NamedTemplate = cast<NamedDecl>(Entity);
501
502 PrintingPolicy Policy = TheSema.Context.getPrintingPolicy();
503 // FIXME: Also ask for FullyQualifiedNames?
504 Policy.SuppressDefaultTemplateArgs = false;
505 NamedTemplate->getNameForDiagnostic(OS, Policy, true);
506
507 if (!OS.str().empty())
508 return;
509
510 Decl *Ctx = Decl::castFromDeclContext(NamedTemplate->getDeclContext());
511 NamedDecl *NamedCtx = dyn_cast_or_null<NamedDecl>(Ctx);
512
513 if (const auto *Decl = dyn_cast<TagDecl>(NamedTemplate)) {
514 if (const auto *R = dyn_cast<RecordDecl>(Decl)) {
515 if (R->isLambda()) {
516 OS << "lambda at ";
517 Decl->getLocation().print(OS, TheSema.getSourceManager());
518 return;
519 }
520 }
521 OS << "unnamed " << Decl->getKindName();
522 return;
523 }
524
525 assert(NamedCtx && "NamedCtx cannot be null");
526
527 if (const auto *Decl = dyn_cast<ParmVarDecl>(NamedTemplate)) {
528 OS << "unnamed function parameter " << Decl->getFunctionScopeIndex()
529 << " ";
530 if (Decl->getFunctionScopeDepth() > 0)
531 OS << "(at depth " << Decl->getFunctionScopeDepth() << ") ";
532 OS << "of ";
533 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
534 return;
535 }
536
537 if (const auto *Decl = dyn_cast<TemplateTypeParmDecl>(NamedTemplate)) {
538 if (const Type *Ty = Decl->getTypeForDecl()) {
539 if (const auto *TTPT = dyn_cast_or_null<TemplateTypeParmType>(Ty)) {
540 OS << "unnamed template type parameter " << TTPT->getIndex() << " ";
541 if (TTPT->getDepth() > 0)
542 OS << "(at depth " << TTPT->getDepth() << ") ";
543 OS << "of ";
544 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
545 return;
546 }
547 }
548 }
549
550 if (const auto *Decl = dyn_cast<NonTypeTemplateParmDecl>(NamedTemplate)) {
551 OS << "unnamed template non-type parameter " << Decl->getIndex() << " ";
552 if (Decl->getDepth() > 0)
553 OS << "(at depth " << Decl->getDepth() << ") ";
554 OS << "of ";
555 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
556 return;
557 }
558
559 if (const auto *Decl = dyn_cast<TemplateTemplateParmDecl>(NamedTemplate)) {
560 OS << "unnamed template template parameter " << Decl->getIndex() << " ";
561 if (Decl->getDepth() > 0)
562 OS << "(at depth " << Decl->getDepth() << ") ";
563 OS << "of ";
564 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
565 return;
566 }
567
568 llvm_unreachable("Failed to retrieve a name for this entry!");
569 OS << "unnamed identifier";
570 }
571
572 template <bool BeginInstantiation>
573 static TemplightEntry getTemplightEntry(const Sema &TheSema,
574 const CodeSynthesisContext &Inst) {
575 TemplightEntry Entry;
576 Entry.Kind = toString(Inst.Kind);
577 Entry.Event = BeginInstantiation ? "Begin" : "End";
578 llvm::raw_string_ostream OS(Entry.Name);
579 printEntryName(TheSema, Inst.Entity, OS);
580 const PresumedLoc DefLoc =
581 TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation());
582 if (!DefLoc.isInvalid())
583 Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +
584 std::to_string(DefLoc.getLine()) + ":" +
585 std::to_string(DefLoc.getColumn());
586 const PresumedLoc PoiLoc =
587 TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation);
588 if (!PoiLoc.isInvalid()) {
589 Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +
590 std::to_string(PoiLoc.getLine()) + ":" +
591 std::to_string(PoiLoc.getColumn());
592 }
593 return Entry;
594 }
595};
596} // namespace
597
598std::unique_ptr<ASTConsumer>
600 return std::make_unique<ASTConsumer>();
601}
602
605
606 // This part is normally done by ASTFrontEndAction, but needs to happen
607 // before Templight observers can be created
608 // FIXME: Move the truncation aspect of this into Sema, we delayed this till
609 // here so the source manager would be initialized.
610 EnsureSemaIsCreated(CI, *this);
611
612 CI.getSema().TemplateInstCallbacks.push_back(
613 std::make_unique<DefaultTemplateInstCallback>());
615}
616
617namespace {
618 /// AST reader listener that dumps module information for a module
619 /// file.
620 class DumpModuleInfoListener : public ASTReaderListener {
621 llvm::raw_ostream &Out;
622
623 public:
624 DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { }
625
626#define DUMP_BOOLEAN(Value, Text) \
627 Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
628
629 bool ReadFullVersionInformation(StringRef FullVersion) override {
630 Out.indent(2)
631 << "Generated by "
632 << (FullVersion == getClangFullRepositoryVersion()? "this"
633 : "a different")
634 << " Clang: " << FullVersion << "\n";
636 }
637
638 void ReadModuleName(StringRef ModuleName) override {
639 Out.indent(2) << "Module name: " << ModuleName << "\n";
640 }
641 void ReadModuleMapFile(StringRef ModuleMapPath) override {
642 Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
643 }
644
645 bool ReadLanguageOptions(const LangOptions &LangOpts,
646 StringRef ModuleFilename, bool Complain,
647 bool AllowCompatibleDifferences) override {
648 // FIXME: Replace with C++20 `using enum LangOptions::CompatibilityKind`.
650
651 Out.indent(2) << "Language options:\n";
652#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
653 if constexpr (CK::Compatibility != CK::Benign) \
654 DUMP_BOOLEAN(LangOpts.Name, Description);
655#define ENUM_LANGOPT(Name, Type, Bits, Default, Compatibility, Description) \
656 if constexpr (CK::Compatibility != CK::Benign) \
657 Out.indent(4) << Description << ": " \
658 << static_cast<unsigned>(LangOpts.get##Name()) << "\n";
659#define VALUE_LANGOPT(Name, Bits, Default, Compatibility, Description) \
660 if constexpr (CK::Compatibility != CK::Benign) \
661 Out.indent(4) << Description << ": " << LangOpts.Name << "\n";
662#include "clang/Basic/LangOptions.def"
663
664 if (!LangOpts.ModuleFeatures.empty()) {
665 Out.indent(4) << "Module features:\n";
666 for (StringRef Feature : LangOpts.ModuleFeatures)
667 Out.indent(6) << Feature << "\n";
668 }
669
670 return false;
671 }
672
673 bool ReadTargetOptions(const TargetOptions &TargetOpts,
674 StringRef ModuleFilename, bool Complain,
675 bool AllowCompatibleDifferences) override {
676 Out.indent(2) << "Target options:\n";
677 Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n";
678 Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n";
679 Out.indent(4) << " TuneCPU: " << TargetOpts.TuneCPU << "\n";
680 Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n";
681
682 if (!TargetOpts.FeaturesAsWritten.empty()) {
683 Out.indent(4) << "Target features:\n";
684 for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size();
685 I != N; ++I) {
686 Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n";
687 }
688 }
689
690 return false;
691 }
692
693 bool ReadDiagnosticOptions(DiagnosticOptions &DiagOpts,
694 StringRef ModuleFilename,
695 bool Complain) override {
696 Out.indent(2) << "Diagnostic options:\n";
697#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts.Name, #Name);
698#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
699 Out.indent(4) << #Name << ": " << DiagOpts.get##Name() << "\n";
700#define VALUE_DIAGOPT(Name, Bits, Default) \
701 Out.indent(4) << #Name << ": " << DiagOpts.Name << "\n";
702#include "clang/Basic/DiagnosticOptions.def"
703
704 Out.indent(4) << "Diagnostic flags:\n";
705 for (const std::string &Warning : DiagOpts.Warnings)
706 Out.indent(6) << "-W" << Warning << "\n";
707 for (const std::string &Remark : DiagOpts.Remarks)
708 Out.indent(6) << "-R" << Remark << "\n";
709
710 return false;
711 }
712
713 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
714 StringRef ModuleFilename,
715 StringRef SpecificModuleCachePath,
716 bool Complain) override {
717 Out.indent(2) << "Header search options:\n";
718 Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
719 Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
720 Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
722 "Use builtin include directories [-nobuiltininc]");
724 "Use standard system include directories [-nostdinc]");
726 "Use standard C++ include directories [-nostdinc++]");
727 DUMP_BOOLEAN(HSOpts.UseLibcxx,
728 "Use libc++ (rather than libstdc++) [-stdlib=]");
729 return false;
730 }
731
732 bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
733 bool Complain) override {
734 Out.indent(2) << "Header search paths:\n";
735 Out.indent(4) << "User entries:\n";
736 for (const auto &Entry : HSOpts.UserEntries)
737 Out.indent(6) << Entry.Path << "\n";
738 Out.indent(4) << "System header prefixes:\n";
739 for (const auto &Prefix : HSOpts.SystemHeaderPrefixes)
740 Out.indent(6) << Prefix.Prefix << "\n";
741 Out.indent(4) << "VFS overlay files:\n";
742 for (const auto &Overlay : HSOpts.VFSOverlayFiles)
743 Out.indent(6) << Overlay << "\n";
744 return false;
745 }
746
747 bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
748 StringRef ModuleFilename, bool ReadMacros,
749 bool Complain,
750 std::string &SuggestedPredefines) override {
751 Out.indent(2) << "Preprocessor options:\n";
753 "Uses compiler/target-specific predefines [-undef]");
755 "Uses detailed preprocessing record (for indexing)");
756
757 if (ReadMacros) {
758 Out.indent(4) << "Predefined macros:\n";
759 }
760
761 for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
762 I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
763 I != IEnd; ++I) {
764 Out.indent(6);
765 if (I->second)
766 Out << "-U";
767 else
768 Out << "-D";
769 Out << I->first << "\n";
770 }
771 return false;
772 }
773
774 /// Indicates that a particular module file extension has been read.
775 void readModuleFileExtension(
776 const ModuleFileExtensionMetadata &Metadata) override {
777 Out.indent(2) << "Module file extension '"
778 << Metadata.BlockName << "' " << Metadata.MajorVersion
779 << "." << Metadata.MinorVersion;
780 if (!Metadata.UserInfo.empty()) {
781 Out << ": ";
782 Out.write_escaped(Metadata.UserInfo);
783 }
784
785 Out << "\n";
786 }
787
788 /// Tells the \c ASTReaderListener that we want to receive the
789 /// input files of the AST file via \c visitInputFile.
790 bool needsInputFileVisitation() override { return true; }
791
792 /// Tells the \c ASTReaderListener that we want to receive the
793 /// input files of the AST file via \c visitInputFile.
794 bool needsSystemInputFileVisitation() override { return true; }
795
796 /// Indicates that the AST file contains particular input file.
797 ///
798 /// \returns true to continue receiving the next input file, false to stop.
799 bool visitInputFile(StringRef FilenameAsRequested, StringRef Filename,
800 bool isSystem, bool isOverridden,
801 bool isExplicitModule) override {
802
803 Out.indent(2) << "Input file: " << FilenameAsRequested;
804
805 if (isSystem || isOverridden || isExplicitModule) {
806 Out << " [";
807 if (isSystem) {
808 Out << "System";
809 if (isOverridden || isExplicitModule)
810 Out << ", ";
811 }
812 if (isOverridden) {
813 Out << "Overridden";
814 if (isExplicitModule)
815 Out << ", ";
816 }
817 if (isExplicitModule)
818 Out << "ExplicitModule";
819
820 Out << "]";
821 }
822
823 Out << "\n";
824
825 return true;
826 }
827
828 /// Returns true if this \c ASTReaderListener wants to receive the
829 /// imports of the AST file via \c visitImport, false otherwise.
830 bool needsImportVisitation() const override { return true; }
831
832 /// If needsImportVisitation returns \c true, this is called for each
833 /// AST file imported by this AST file.
834 void visitImport(StringRef ModuleName, StringRef Filename) override {
835 Out.indent(2) << "Imports module '" << ModuleName
836 << "': " << Filename.str() << "\n";
837 }
838#undef DUMP_BOOLEAN
839 };
840}
841
843 // The Object file reader also supports raw ast files and there is no point in
844 // being strict about the module file format in -module-file-info mode.
846 return true;
847}
848
849static StringRef ModuleKindName(Module::ModuleKind MK) {
850 switch (MK) {
852 return "Module Map Module";
854 return "Interface Unit";
856 return "Implementation Unit";
858 return "Partition Interface";
860 return "Partition Implementation";
862 return "Header Unit";
864 return "Global Module Fragment";
866 return "Implicit Module Fragment";
868 return "Private Module Fragment";
869 }
870 llvm_unreachable("unknown module kind!");
871}
872
875
876 // Don't process files of type other than module to avoid crash
877 if (!isCurrentFileAST()) {
878 CI.getDiagnostics().Report(diag::err_file_is_not_module)
879 << getCurrentFile();
880 return;
881 }
882
883 // Set up the output file.
884 StringRef OutputFileName = CI.getFrontendOpts().OutputFile;
885 if (!OutputFileName.empty() && OutputFileName != "-") {
886 std::error_code EC;
887 OutputStream.reset(new llvm::raw_fd_ostream(
888 OutputFileName.str(), EC, llvm::sys::fs::OF_TextWithCRLF));
889 }
890 llvm::raw_ostream &Out = OutputStream ? *OutputStream : llvm::outs();
891
892 Out << "Information for module file '" << getCurrentFile() << "':\n";
893 auto &FileMgr = CI.getFileManager();
894 auto Buffer = FileMgr.getBufferForFile(getCurrentFile());
895 StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();
896 bool IsRaw = Magic.starts_with("CPCH");
897 Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n";
898
899 Preprocessor &PP = CI.getPreprocessor();
900 DumpModuleInfoListener Listener(Out);
901 const HeaderSearchOptions &HSOpts =
902 PP.getHeaderSearchInfo().getHeaderSearchOpts();
903
904 // The FrontendAction::BeginSourceFile () method loads the AST so that much
905 // of the information is already available and modules should have been
906 // loaded.
907
909 if (LO.CPlusPlusModules && !LO.CurrentModule.empty()) {
911 unsigned SubModuleCount = R->getTotalNumSubmodules();
913 Out << " ====== C++20 Module structure ======\n";
914
915 if (MF.ModuleName != LO.CurrentModule)
916 Out << " Mismatched module names : " << MF.ModuleName << " and "
917 << LO.CurrentModule << "\n";
918
919 struct SubModInfo {
920 unsigned Idx;
921 Module *Mod;
923 std::string &Name;
924 bool Seen;
925 };
926 std::map<std::string, SubModInfo> SubModMap;
927 auto PrintSubMapEntry = [&](std::string Name, Module::ModuleKind Kind) {
928 Out << " " << ModuleKindName(Kind) << " '" << Name << "'";
929 auto I = SubModMap.find(Name);
930 if (I == SubModMap.end())
931 Out << " was not found in the sub modules!\n";
932 else {
933 I->second.Seen = true;
934 Out << " is at index #" << I->second.Idx << "\n";
935 }
936 };
937 Module *Primary = nullptr;
938 for (unsigned Idx = 0; Idx <= SubModuleCount; ++Idx) {
939 Module *M = R->getModule(Idx);
940 if (!M)
941 continue;
942 if (M->Name == LO.CurrentModule) {
943 Primary = M;
944 Out << " " << ModuleKindName(M->Kind) << " '" << LO.CurrentModule
945 << "' is the Primary Module at index #" << Idx << "\n";
946 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, true}});
947 } else
948 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, false}});
949 }
950 if (Primary) {
951 if (!Primary->submodules().empty())
952 Out << " Sub Modules:\n";
953 for (auto *MI : Primary->submodules()) {
954 PrintSubMapEntry(MI->Name, MI->Kind);
955 }
956 if (!Primary->Imports.empty())
957 Out << " Imports:\n";
958 for (auto *IMP : Primary->Imports) {
959 PrintSubMapEntry(IMP->Name, IMP->Kind);
960 }
961 if (!Primary->Exports.empty())
962 Out << " Exports:\n";
963 for (unsigned MN = 0, N = Primary->Exports.size(); MN != N; ++MN) {
964 if (Module *M = Primary->Exports[MN].getPointer()) {
965 PrintSubMapEntry(M->Name, M->Kind);
966 }
967 }
968 }
969
970 // Emit the macro definitions in the module file so that we can know how
971 // much definitions in the module file quickly.
972 // TODO: Emit the macro definition bodies completely.
973 if (auto FilteredMacros = llvm::make_filter_range(
974 R->getPreprocessor().macros(),
975 [](const auto &Macro) { return Macro.first->isFromAST(); });
976 !FilteredMacros.empty()) {
977 Out << " Macro Definitions:\n";
978 for (/*<IdentifierInfo *, MacroState> pair*/ const auto &Macro :
979 FilteredMacros)
980 Out << " " << Macro.first->getName() << "\n";
981 }
982
983 // Now let's print out any modules we did not see as part of the Primary.
984 for (const auto &SM : SubModMap) {
985 if (!SM.second.Seen && SM.second.Mod) {
986 Out << " " << ModuleKindName(SM.second.Kind) << " '" << SM.first
987 << "' at index #" << SM.second.Idx
988 << " has no direct reference in the Primary\n";
989 }
990 }
991 Out << " ====== ======\n";
992 }
993
994 // The reminder of the output is produced from the listener as the AST
995 // FileCcontrolBlock is (re-)parsed.
997 getCurrentFile(), FileMgr, CI.getModuleCache(),
999 /*FindModuleFileExtensions=*/true, Listener,
1001}
1002
1003//===----------------------------------------------------------------------===//
1004// Preprocessor Actions
1005//===----------------------------------------------------------------------===//
1006
1010
1011 // Start lexing the specified input file.
1012 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
1013 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
1014 RawLex.SetKeepWhitespaceMode(true);
1015
1016 Token RawTok;
1017 RawLex.LexFromRawLexer(RawTok);
1018 while (RawTok.isNot(tok::eof)) {
1019 PP.DumpToken(RawTok, true);
1020 llvm::errs() << "\n";
1021 RawLex.LexFromRawLexer(RawTok);
1022 }
1023}
1024
1027 // Start preprocessing the specified input file.
1028 Token Tok;
1030 do {
1031 PP.Lex(Tok);
1032 PP.DumpToken(Tok, true);
1033 llvm::errs() << "\n";
1034 } while (Tok.isNot(tok::eof));
1035}
1036
1039
1040 // Ignore unknown pragmas.
1041 PP.IgnorePragmas();
1042
1043 Token Tok;
1044 // Start parsing the specified input file.
1046 do {
1047 PP.Lex(Tok);
1048 } while (Tok.isNot(tok::eof));
1049}
1050
1053 // Output file may need to be set to 'Binary', to avoid converting Unix style
1054 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>) on Windows.
1055 //
1056 // Look to see what type of line endings the file uses. If there's a
1057 // CRLF, then we won't open the file up in binary mode. If there is
1058 // just an LF or CR, then we will open the file up in binary mode.
1059 // In this fashion, the output format should match the input format, unless
1060 // the input format has inconsistent line endings.
1061 //
1062 // This should be a relatively fast operation since most files won't have
1063 // all of their source code on a single line. However, that is still a
1064 // concern, so if we scan for too long, we'll just assume the file should
1065 // be opened in binary mode.
1066
1067 bool BinaryMode = false;
1068 if (llvm::Triple(LLVM_HOST_TRIPLE).isOSWindows()) {
1069 BinaryMode = true;
1070 const SourceManager &SM = CI.getSourceManager();
1071 if (std::optional<llvm::MemoryBufferRef> Buffer =
1072 SM.getBufferOrNone(SM.getMainFileID())) {
1073 const char *cur = Buffer->getBufferStart();
1074 const char *end = Buffer->getBufferEnd();
1075 const char *next = (cur != end) ? cur + 1 : end;
1076
1077 // Limit ourselves to only scanning 256 characters into the source
1078 // file. This is mostly a check in case the file has no
1079 // newlines whatsoever.
1080 if (end - cur > 256)
1081 end = cur + 256;
1082
1083 while (next < end) {
1084 if (*cur == 0x0D) { // CR
1085 if (*next == 0x0A) // CRLF
1086 BinaryMode = false;
1087
1088 break;
1089 } else if (*cur == 0x0A) // LF
1090 break;
1091
1092 ++cur;
1093 ++next;
1094 }
1095 }
1096 }
1097
1098 std::unique_ptr<raw_ostream> OS =
1100 if (!OS) return;
1101
1102 // If we're preprocessing a module map, start by dumping the contents of the
1103 // module itself before switching to the input buffer.
1104 auto &Input = getCurrentInput();
1105 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
1106 if (Input.isFile()) {
1107 (*OS) << "# 1 \"";
1108 OS->write_escaped(Input.getFile());
1109 (*OS) << "\"\n";
1110 }
1111 getCurrentModule()->print(*OS);
1112 (*OS) << "#pragma clang module contents\n";
1113 }
1114
1117}
1118
1120 switch (getCurrentFileKind().getLanguage()) {
1121 case Language::C:
1122 case Language::CXX:
1123 case Language::ObjC:
1124 case Language::ObjCXX:
1125 case Language::OpenCL:
1127 case Language::CUDA:
1128 case Language::HIP:
1129 case Language::HLSL:
1130 case Language::CIR:
1131 break;
1132
1133 case Language::Unknown:
1134 case Language::Asm:
1135 case Language::LLVM_IR:
1136 // We can't do anything with these.
1137 return;
1138 }
1139
1140 // We don't expect to find any #include directives in a preprocessed input.
1141 if (getCurrentFileKind().isPreprocessed())
1142 return;
1143
1145 auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
1146 if (Buffer) {
1147 unsigned Preamble =
1148 Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).Size;
1149 llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
1150 }
1151}
1152
1153void DumpCompilerOptionsAction::ExecuteAction() {
1155 std::unique_ptr<raw_ostream> OSP =
1157 if (!OSP)
1158 return;
1159
1160 raw_ostream &OS = *OSP;
1161 const Preprocessor &PP = CI.getPreprocessor();
1162 const LangOptions &LangOpts = PP.getLangOpts();
1163
1164 // FIXME: Rather than manually format the JSON (which is awkward due to
1165 // needing to remove trailing commas), this should make use of a JSON library.
1166 // FIXME: Instead of printing enums as an integral value and specifying the
1167 // type as a separate field, use introspection to print the enumerator.
1168
1169 OS << "{\n";
1170 OS << "\n\"features\" : [\n";
1171 {
1173#define FEATURE(Name, Predicate) \
1174 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
1175 .toVector(Str);
1176#include "clang/Basic/Features.def"
1177#undef FEATURE
1178 // Remove the newline and comma from the last entry to ensure this remains
1179 // valid JSON.
1180 OS << Str.substr(0, Str.size() - 2);
1181 }
1182 OS << "\n],\n";
1183
1184 OS << "\n\"extensions\" : [\n";
1185 {
1187#define EXTENSION(Name, Predicate) \
1188 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
1189 .toVector(Str);
1190#include "clang/Basic/Features.def"
1191#undef EXTENSION
1192 // Remove the newline and comma from the last entry to ensure this remains
1193 // valid JSON.
1194 OS << Str.substr(0, Str.size() - 2);
1195 }
1196 OS << "\n]\n";
1197
1198 OS << "}";
1199}
1200
1204 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
1205
1209 FromFile.getBuffer(), Tokens, Directives, &CI.getDiagnostics(),
1210 SM.getLocForStartOfFile(SM.getMainFileID()))) {
1211 assert(CI.getDiagnostics().hasErrorOccurred() &&
1212 "no errors reported for failure");
1213
1214 // Preprocess the source when verifying the diagnostics to capture the
1215 // 'expected' comments.
1216 if (CI.getDiagnosticOpts().VerifyDiagnostics) {
1217 // Make sure we don't emit new diagnostics!
1221 Token Tok;
1222 do {
1223 PP.Lex(Tok);
1224 } while (Tok.isNot(tok::eof));
1225 }
1226 return;
1227 }
1228 printDependencyDirectivesAsSource(FromFile.getBuffer(), Directives,
1229 llvm::outs());
1230}
1231
1232void GetDependenciesByModuleNameAction::ExecuteAction() {
1234 Preprocessor &PP = CI.getPreprocessor();
1236 FileID MainFileID = SM.getMainFileID();
1237 SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);
1239 IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName);
1240 Path.emplace_back(FileStart, ModuleID);
1241 auto ModResult = CI.loadModule(FileStart, Path, Module::Hidden, false);
1242 PPCallbacks *CB = PP.getPPCallbacks();
1243 CB->moduleImport(SourceLocation(), Path, ModResult);
1244}
1245
1246//===----------------------------------------------------------------------===//
1247// HLSL Specific Actions
1248//===----------------------------------------------------------------------===//
1249
1251private:
1252 Sema &Actions;
1253 StringRef RootSigName;
1254 llvm::dxbc::RootSignatureVersion Version;
1255
1256 std::optional<StringLiteral *> processStringLiteral(ArrayRef<Token> Tokens) {
1257 for (Token Tok : Tokens)
1258 if (!tok::isStringLiteral(Tok.getKind()))
1259 return std::nullopt;
1260
1261 ExprResult StringResult = Actions.ActOnUnevaluatedStringLiteral(Tokens);
1262 if (StringResult.isInvalid())
1263 return std::nullopt;
1264
1265 if (auto Signature = dyn_cast<StringLiteral>(StringResult.get()))
1266 return Signature;
1267
1268 return std::nullopt;
1269 }
1270
1271public:
1272 void MacroDefined(const Token &MacroNameTok,
1273 const MacroDirective *MD) override {
1274 if (RootSigName != MacroNameTok.getIdentifierInfo()->getName())
1275 return;
1276
1277 const MacroInfo *MI = MD->getMacroInfo();
1278 auto Signature = processStringLiteral(MI->tokens());
1279 if (!Signature.has_value()) {
1280 Actions.getDiagnostics().Report(MI->getDefinitionLoc(),
1281 diag::err_expected_string_literal)
1282 << /*in attributes...*/ 4 << "RootSignature";
1283 return;
1284 }
1285
1286 IdentifierInfo *DeclIdent =
1287 hlsl::ParseHLSLRootSignature(Actions, Version, *Signature);
1288 Actions.HLSL().SetRootSignatureOverride(DeclIdent);
1289 }
1290
1291 InjectRootSignatureCallback(Sema &Actions, StringRef RootSigName,
1292 llvm::dxbc::RootSignatureVersion Version)
1293 : PPCallbacks(), Actions(Actions), RootSigName(RootSigName),
1294 Version(Version) {}
1295};
1296
1298 // Pre-requisites to invoke
1300 if (!CI.hasASTContext() || !CI.hasPreprocessor())
1302
1303 // InjectRootSignatureCallback requires access to invoke Sema to lookup/
1304 // register a root signature declaration. The wrapped action is required to
1305 // account for this by only creating a Sema if one doesn't already exist
1306 // (like we have done, and, ASTFrontendAction::ExecuteAction)
1307 if (!CI.hasSema())
1309 /*CodeCompleteConsumer=*/nullptr);
1310 Sema &S = CI.getSema();
1311
1312 // Register HLSL specific callbacks
1313 auto LangOpts = CI.getLangOpts();
1314 auto MacroCallback = std::make_unique<InjectRootSignatureCallback>(
1315 S, LangOpts.HLSLRootSigOverride, LangOpts.HLSLRootSigVer);
1316
1317 Preprocessor &PP = CI.getPreprocessor();
1318 PP.addPPCallbacks(std::move(MacroCallback));
1319
1320 // Invoke as normal
1322}
1323
1325 std::unique_ptr<FrontendAction> WrappedAction)
1326 : WrapperFrontendAction(std::move(WrappedAction)) {}
IndirectLocalPath & Path
enum clang::sema::@1840::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:3177
#define DUMP_BOOLEAN(Value, Text)
static StringRef ModuleKindName(Module::ModuleKind MK)
Defines the clang::Module class, which describes a module in the source code.
#define SM(sm)
Definition: OffloadArch.cpp:16
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.
void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override
Hook called whenever a macro definition is seen.
InjectRootSignatureCallback(Sema &Actions, StringRef RootSigName, llvm::dxbc::RootSignatureVersion Version)
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:793
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:117
virtual bool ReadFullVersionInformation(StringRef FullVersion)
Receives the full Clang version information.
Definition: ASTReader.h:125
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:429
ModuleManager & getModuleManager()
Retrieve the module manager.
Definition: ASTReader.h:1990
@ ARR_ConfigurationMismatch
The client can handle an AST file that cannot load because it's compiled configuration doesn't match ...
Definition: ASTReader.h:1845
unsigned getTotalNumSubmodules() const
Returns the number of submodules known.
Definition: ASTReader.h:2083
Module * getModule(unsigned ID) override
Retrieve the module that corresponds to the given module ID.
Definition: ASTReader.cpp:9817
static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, 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:5794
Preprocessor & getPreprocessor() const
Retrieve the preprocessor.
Definition: ASTReader.h:1994
const LangOptions & getLangOpts() const
Definition: ASTUnit.h:487
IntrusiveRefCntPtr< ASTReader > getASTReader() const
Definition: ASTUnit.cpp:771
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
PtrTy get() const
Definition: Ownership.h:171
bool isInvalid() const
Definition: Ownership.h:167
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()
ModuleCache & 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()
CodeGenOptions & getCodeGenOpts()
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:1050
SourceLocation getLocation() const
Definition: DeclBase.h:439
Options for controlling the compiler diagnostics engine.
std::vector< std::string > Remarks
The list of -R... options used to alter the diagnostic mappings, with the prefixes removed.
std::vector< std::string > Warnings
The list of -W... options used to alter the diagnostic mappings, with the prefixes removed.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1529
bool hasErrorOccurred() const
Definition: Diagnostic.h:871
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:729
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
virtual bool PrepareToExecuteAction(CompilerInstance &CI)
Prepare to execute the action on the given CompilerInstance.
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
Module * getCurrentModule() 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.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
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.
bool PrepareToExecuteAction(CompilerInstance &CI) override
Prepare to execute the action on the given CompilerInstance.
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...
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
HLSLFrontendAction(std::unique_ptr< FrontendAction > WrappedAction)
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.
StringRef getName() const
Return the actual identifier string.
@ CMK_HeaderUnit
Compiling a module header unit.
Definition: LangOptions.h:124
@ CMK_ModuleInterface
Compiling a C++ modules interface unit.
Definition: LangOptions.h:127
CompatibilityKind
For ASTs produced with different option value, signifies their level of compatibility.
Definition: LangOptions.h:82
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:434
std::string HLSLRootSigOverride
The HLSL root signature that will be used to overide the root signature used for the shader entry poi...
Definition: LangOptions.h:557
llvm::dxbc::RootSignatureVersion HLSLRootSigVer
The HLSL root signature version for dxil.
Definition: LangOptions.h:552
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:489
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:495
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:635
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
Definition: MacroInfo.h:313
const MacroInfo * getMacroInfo() const
Definition: MacroInfo.h:416
Encapsulates the data about a macro definition (e.g.
Definition: MacroInfo.h:39
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
Definition: MacroInfo.h:125
ArrayRef< Token > tokens() const
Definition: MacroInfo.h:249
Describes a module or submodule.
Definition: Module.h:144
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition: Module.h:471
@ Hidden
All of the names in this module are hidden.
Definition: Module.h:445
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:463
ModuleKind Kind
The kind of this module.
Definition: Module.h:189
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition: Module.h:458
std::string Name
The name of this module.
Definition: Module.h:147
llvm::iterator_range< submodule_iterator > submodules()
Definition: Module.h:838
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
Definition: Module.h:167
@ ModuleMapModule
This is a module that was defined by a module map and built out of header files.
Definition: Module.h:158
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
Definition: Module.h:185
@ ModulePartitionInterface
This is a C++20 module partition interface.
Definition: Module.h:170
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
Definition: Module.h:164
@ ModuleHeaderUnit
This is a C++20 header unit.
Definition: Module.h:161
@ ModulePartitionImplementation
This is a C++20 module partition implementation.
Definition: Module.h:173
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
Definition: Module.h:180
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
Definition: Module.h:177
This represents a decl that may have a name.
Definition: Decl.h:273
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:1834
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:37
virtual void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported)
Callback invoked whenever there was an explicit module-import syntax.
Definition: PPCallbacks.h:210
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:145
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:2216
PPCallbacks * getPPCallbacks() const
void Lex(Token &Result)
Lex the next token for this preprocessor.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
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.
void SetRootSignatureOverride(IdentifierInfo *DeclIdent)
Definition: SemaHLSL.h:156
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:850
ASTContext & Context
Definition: Sema.h:1276
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:915
ExprResult ActOnUnevaluatedStringLiteral(ArrayRef< Token > StringToks)
Definition: SemaExpr.cpp:2065
const LangOptions & getLangOpts() const
Definition: Sema.h:911
SemaHLSL & HLSL()
Definition: Sema.h:1448
std::vector< std::unique_ptr< TemplateInstantiationCallback > > TemplateInstCallbacks
The template instantiation callbacks to trace or track instantiations (objects can be chained).
Definition: Sema.h:13482
SourceManager & getSourceManager() const
Definition: Sema.h:916
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
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:189
tok::TokenKind getKind() const
Definition: Token.h:97
bool isNot(tok::TokenKind K) const
Definition: Token.h:103
The base class of the type hierarchy.
Definition: TypeBase.h:1833
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.
A frontend action which simply wraps some other runtime-specified frontend action.
TranslationUnitKind getTranslationUnitKind() override
For AST-based actions, the kind of translation unit we're handling.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
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
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
Definition: TokenKinds.h:89
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:12953
static void mapping(IO &io, TemplightEntry &fields)