clang 23.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"
15#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
69}
70
71// Basically PreprocessOnlyAction::ExecuteAction.
73 Preprocessor &PP = getCompilerInstance().getPreprocessor();
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>
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, SetOnlyIfDifferent);
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 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 bool SetOnlyIfDifferent) {
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 /*CreateMissingDirectories=*/false, /*ForceUseTemporary=*/false,
172 if (!OS)
173 return nullptr;
174
175 OutputFile = CI.getFrontendOpts().OutputFile;
176 return OS;
177}
178
180 if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)
181 return false;
183}
184
189
190std::vector<std::unique_ptr<ASTConsumer>>
192 StringRef InFile) {
193 if (!OS)
194 OS = CreateOutputFile(CI, InFile);
195 if (!OS)
196 return {};
197
198 std::string OutputFile = CI.getFrontendOpts().OutputFile;
199 std::string Sysroot;
200
201 auto Buffer = std::make_shared<PCHBuffer>();
202 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
203
204 Consumers.push_back(std::make_unique<PCHGenerator>(
205 CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
207 /*AllowASTWithErrors=*/
209 /*IncludeTimestamps=*/
212 /*BuildingImplicitModule=*/+CI.getFrontendOpts().BuildingImplicitModule));
213 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
214 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
215 return Consumers;
216}
217
218std::unique_ptr<ASTConsumer>
220 StringRef InFile) {
221 std::vector<std::unique_ptr<ASTConsumer>> Consumers =
222 CreateMultiplexConsumer(CI, InFile);
223 if (Consumers.empty())
224 return nullptr;
225
226 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
227}
228
233
234bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(
235 CompilerInstance &CI) {
236 if (!CI.getLangOpts().Modules) {
237 CI.getDiagnostics().Report(diag::err_module_build_requires_fmodules);
238 return false;
239 }
240
242}
243
244std::unique_ptr<raw_pwrite_stream>
245GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
246 StringRef InFile) {
247 // If no output file was provided, figure out where this module would go
248 // in the module cache.
249 if (CI.getFrontendOpts().OutputFile.empty()) {
250 StringRef ModuleMapFile = CI.getFrontendOpts().OriginalModuleMap;
251 if (ModuleMapFile.empty())
252 ModuleMapFile = InFile;
253
255 ModuleFileName FileName = HS.getCachedModuleFileName(
256 CI.getLangOpts().CurrentModule, ModuleMapFile);
258 }
259
260 // Because this is exposed via libclang we must disable RemoveFileOnSignal.
261 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, /*Extension=*/"",
262 /*RemoveFileOnSignal=*/false,
263 /*CreateMissingDirectories=*/true,
264 /*ForceUseTemporary=*/true,
265 /*SetOnlyIfDifferent=*/SetOnlyIfDifferent);
266}
267
269 CompilerInstance &CI) {
270 for (const auto &FIF : CI.getFrontendOpts().Inputs) {
271 if (const auto InputFormat = FIF.getKind().getFormat();
272 InputFormat != InputKind::Format::Source) {
274 diag::err_frontend_action_unsupported_input_format)
275 << "module interface compilation" << FIF.getFile() << InputFormat;
276 return false;
277 }
278 }
280}
281
288
289std::unique_ptr<ASTConsumer>
291 StringRef InFile) {
292 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
293
295 !CI.getFrontendOpts().ModuleOutputPath.empty()) {
296 Consumers.push_back(std::make_unique<ReducedBMIGenerator>(
300 }
301
302 Consumers.push_back(std::make_unique<CXX20ModulesGenerator>(
306
307 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
308}
309
310std::unique_ptr<raw_pwrite_stream>
312 StringRef InFile) {
313 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
314}
315
316std::unique_ptr<ASTConsumer>
317GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
318 StringRef InFile) {
319 return std::make_unique<ReducedBMIGenerator>(
322}
323
324bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) {
325 if (!CI.getLangOpts().CPlusPlusModules) {
326 CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
327 return false;
328 }
329 CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderUnit);
331}
332
333std::unique_ptr<raw_pwrite_stream>
334GenerateHeaderUnitAction::CreateOutputFile(CompilerInstance &CI,
335 StringRef InFile) {
336 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
337}
338
341
342std::unique_ptr<ASTConsumer>
344 return std::make_unique<ASTConsumer>();
345}
346
347std::unique_ptr<ASTConsumer>
349 StringRef InFile) {
350 return std::make_unique<ASTConsumer>();
351}
352
353std::unique_ptr<ASTConsumer>
355 return std::make_unique<ASTConsumer>();
356}
357
361 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
362 std::unique_ptr<ASTReader> Reader(new ASTReader(
366 Sysroot.empty() ? "" : Sysroot.c_str(),
368 /*AllowASTWithCompilerErrors*/ false,
369 /*AllowConfigurationMismatch*/ true,
370 /*ValidateSystemInputs*/ true, /*ForceValidateUserInputs*/ true));
371
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::RequirementParameterInstantiation:
458 return "RequirementParameterInstantiation";
459 case CodeSynthesisContext::ParameterMappingSubstitution:
460 return "ParameterMappingSubstitution";
461 case CodeSynthesisContext::RequirementInstantiation:
462 return "RequirementInstantiation";
463 case CodeSynthesisContext::NestedRequirementConstraintsCheck:
464 return "NestedRequirementConstraintsCheck";
465 case CodeSynthesisContext::InitializingStructuredBinding:
466 return "InitializingStructuredBinding";
467 case CodeSynthesisContext::MarkingClassDllexported:
468 return "MarkingClassDllexported";
469 case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
470 return "BuildingBuiltinDumpStructCall";
471 case CodeSynthesisContext::BuildingDeductionGuides:
472 return "BuildingDeductionGuides";
473 case CodeSynthesisContext::TypeAliasTemplateInstantiation:
474 return "TypeAliasTemplateInstantiation";
475 case CodeSynthesisContext::PartialOrderingTTP:
476 return "PartialOrderingTTP";
477 case CodeSynthesisContext::SYCLKernelLaunchLookup:
478 return "SYCLKernelLaunchLookup";
479 case CodeSynthesisContext::SYCLKernelLaunchOverloadResolution:
480 return "SYCLKernelLaunchOverloadResolution";
481 }
482 return "";
483 }
484
485 template <bool BeginInstantiation>
486 static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema,
487 const CodeSynthesisContext &Inst) {
488 std::string YAML;
489 {
490 llvm::raw_string_ostream OS(YAML);
491 llvm::yaml::Output YO(OS);
492 TemplightEntry Entry =
493 getTemplightEntry<BeginInstantiation>(TheSema, Inst);
494 llvm::yaml::EmptyContext Context;
495 llvm::yaml::yamlize(YO, Entry, true, Context);
496 }
497 Out << "---" << YAML << "\n";
498 }
499
500 static void printEntryName(const Sema &TheSema, const Decl *Entity,
501 llvm::raw_string_ostream &OS) {
502 auto *NamedTemplate = cast<NamedDecl>(Entity);
503
504 PrintingPolicy Policy = TheSema.Context.getPrintingPolicy();
505 // FIXME: Also ask for FullyQualifiedNames?
506 Policy.SuppressDefaultTemplateArgs = false;
507 NamedTemplate->getNameForDiagnostic(OS, Policy, true);
508
509 if (!OS.str().empty())
510 return;
511
512 Decl *Ctx = Decl::castFromDeclContext(NamedTemplate->getDeclContext());
513 NamedDecl *NamedCtx = dyn_cast_or_null<NamedDecl>(Ctx);
514
515 if (const auto *Decl = dyn_cast<TagDecl>(NamedTemplate)) {
516 if (const auto *R = dyn_cast<RecordDecl>(Decl)) {
517 if (R->isLambda()) {
518 OS << "lambda at ";
519 Decl->getLocation().print(OS, TheSema.getSourceManager());
520 return;
521 }
522 }
523 OS << "unnamed " << Decl->getKindName();
524 return;
525 }
526
527 assert(NamedCtx && "NamedCtx cannot be null");
528
529 if (const auto *Decl = dyn_cast<ParmVarDecl>(NamedTemplate)) {
530 OS << "unnamed function parameter " << Decl->getFunctionScopeIndex()
531 << " ";
532 if (Decl->getFunctionScopeDepth() > 0)
533 OS << "(at depth " << Decl->getFunctionScopeDepth() << ") ";
534 OS << "of ";
535 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
536 return;
537 }
538
539 if (const auto *Decl = dyn_cast<TemplateTypeParmDecl>(NamedTemplate)) {
540 if (const Type *Ty = Decl->getTypeForDecl()) {
541 if (const auto *TTPT = dyn_cast_or_null<TemplateTypeParmType>(Ty)) {
542 OS << "unnamed template type parameter " << TTPT->getIndex() << " ";
543 if (TTPT->getDepth() > 0)
544 OS << "(at depth " << TTPT->getDepth() << ") ";
545 OS << "of ";
546 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
547 return;
548 }
549 }
550 }
551
552 if (const auto *Decl = dyn_cast<NonTypeTemplateParmDecl>(NamedTemplate)) {
553 OS << "unnamed template non-type parameter " << Decl->getIndex() << " ";
554 if (Decl->getDepth() > 0)
555 OS << "(at depth " << Decl->getDepth() << ") ";
556 OS << "of ";
557 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
558 return;
559 }
560
561 if (const auto *Decl = dyn_cast<TemplateTemplateParmDecl>(NamedTemplate)) {
562 OS << "unnamed template template parameter " << Decl->getIndex() << " ";
563 if (Decl->getDepth() > 0)
564 OS << "(at depth " << Decl->getDepth() << ") ";
565 OS << "of ";
566 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
567 return;
568 }
569
570 llvm_unreachable("Failed to retrieve a name for this entry!");
571 OS << "unnamed identifier";
572 }
573
574 template <bool BeginInstantiation>
575 static TemplightEntry getTemplightEntry(const Sema &TheSema,
576 const CodeSynthesisContext &Inst) {
577 TemplightEntry Entry;
578 Entry.Kind = toString(Inst.Kind);
579 Entry.Event = BeginInstantiation ? "Begin" : "End";
580 llvm::raw_string_ostream OS(Entry.Name);
581 printEntryName(TheSema, Inst.Entity, OS);
582 const PresumedLoc DefLoc =
583 TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation());
584 if (!DefLoc.isInvalid())
585 Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +
586 std::to_string(DefLoc.getLine()) + ":" +
587 std::to_string(DefLoc.getColumn());
588 const PresumedLoc PoiLoc =
589 TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation);
590 if (!PoiLoc.isInvalid()) {
591 Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +
592 std::to_string(PoiLoc.getLine()) + ":" +
593 std::to_string(PoiLoc.getColumn());
594 }
595 return Entry;
596 }
597};
598} // namespace
599
600std::unique_ptr<ASTConsumer>
602 return std::make_unique<ASTConsumer>();
603}
604
607
608 // This part is normally done by ASTFrontEndAction, but needs to happen
609 // before Templight observers can be created
610 // FIXME: Move the truncation aspect of this into Sema, we delayed this till
611 // here so the source manager would be initialized.
612 EnsureSemaIsCreated(CI, *this);
613
614 CI.getSema().TemplateInstCallbacks.push_back(
615 std::make_unique<DefaultTemplateInstCallback>());
617}
618
619namespace {
620 /// AST reader listener that dumps module information for a module
621 /// file.
622 class DumpModuleInfoListener : public ASTReaderListener {
623 llvm::raw_ostream &Out;
625
626 public:
627 DumpModuleInfoListener(llvm::raw_ostream &Out, FileManager &FileMgr)
628 : Out(Out), FileMgr(FileMgr) {}
629
630#define DUMP_BOOLEAN(Value, Text) \
631 Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
632
633 bool ReadFullVersionInformation(StringRef FullVersion) override {
634 Out.indent(2)
635 << "Generated by "
636 << (FullVersion == getClangFullRepositoryVersion()? "this"
637 : "a different")
638 << " Clang: " << FullVersion << "\n";
640 }
641
642 void ReadModuleName(StringRef ModuleName) override {
643 Out.indent(2) << "Module name: " << ModuleName << "\n";
644 }
645 void ReadModuleMapFile(StringRef ModuleMapPath) override {
646 Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
647 }
648
649 bool ReadLanguageOptions(const LangOptions &LangOpts,
650 StringRef ModuleFilename, bool Complain,
651 bool AllowCompatibleDifferences) override {
652 // FIXME: Replace with C++20 `using enum LangOptions::CompatibilityKind`.
653 using CK = LangOptions::CompatibilityKind;
654
655 Out.indent(2) << "Language options:\n";
656#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
657 if constexpr (CK::Compatibility != CK::Benign) \
658 DUMP_BOOLEAN(LangOpts.Name, Description);
659#define ENUM_LANGOPT(Name, Type, Bits, Default, Compatibility, Description) \
660 if constexpr (CK::Compatibility != CK::Benign) \
661 Out.indent(4) << Description << ": " \
662 << static_cast<unsigned>(LangOpts.get##Name()) << "\n";
663#define VALUE_LANGOPT(Name, Bits, Default, Compatibility, Description) \
664 if constexpr (CK::Compatibility != CK::Benign) \
665 Out.indent(4) << Description << ": " << LangOpts.Name << "\n";
666#include "clang/Basic/LangOptions.def"
667
668 if (!LangOpts.ModuleFeatures.empty()) {
669 Out.indent(4) << "Module features:\n";
670 for (StringRef Feature : LangOpts.ModuleFeatures)
671 Out.indent(6) << Feature << "\n";
672 }
673
674 return false;
675 }
676
677 bool ReadTargetOptions(const TargetOptions &TargetOpts,
678 StringRef ModuleFilename, bool Complain,
679 bool AllowCompatibleDifferences) override {
680 Out.indent(2) << "Target options:\n";
681 Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n";
682 Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n";
683 Out.indent(4) << " TuneCPU: " << TargetOpts.TuneCPU << "\n";
684 Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n";
685
686 if (!TargetOpts.FeaturesAsWritten.empty()) {
687 Out.indent(4) << "Target features:\n";
688 for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size();
689 I != N; ++I) {
690 Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n";
691 }
692 }
693
694 return false;
695 }
696
697 bool ReadDiagnosticOptions(DiagnosticOptions &DiagOpts,
698 StringRef ModuleFilename,
699 bool Complain) override {
700 Out.indent(2) << "Diagnostic options:\n";
701#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts.Name, #Name);
702#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
703 Out.indent(4) << #Name << ": " \
704 << static_cast<unsigned>(DiagOpts.get##Name()) << "\n";
705#define VALUE_DIAGOPT(Name, Bits, Default) \
706 Out.indent(4) << #Name << ": " << DiagOpts.Name << "\n";
707#include "clang/Basic/DiagnosticOptions.def"
708
709 Out.indent(4) << "Diagnostic flags:\n";
710 for (const std::string &Warning : DiagOpts.Warnings)
711 Out.indent(6) << "-W" << Warning << "\n";
712 for (const std::string &Remark : DiagOpts.Remarks)
713 Out.indent(6) << "-R" << Remark << "\n";
714
715 return false;
716 }
717
718 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
719 StringRef ModuleFilename,
720 StringRef ContextHash,
721 bool Complain) override {
722 std::string SpecificModuleCachePath = createSpecificModuleCachePath(
723 FileMgr, HSOpts.ModuleCachePath, HSOpts.DisableModuleHash,
724 std::string(ContextHash));
725
726 Out.indent(2) << "Header search options:\n";
727 Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
728 Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
729 Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
731 "Use builtin include directories [-nobuiltininc]");
733 "Use standard system include directories [-nostdinc]");
735 "Use standard C++ include directories [-nostdinc++]");
736 DUMP_BOOLEAN(HSOpts.UseLibcxx,
737 "Use libc++ (rather than libstdc++) [-stdlib=]");
738 return false;
739 }
740
741 bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
742 bool Complain) override {
743 Out.indent(2) << "Header search paths:\n";
744 Out.indent(4) << "User entries:\n";
745 for (const auto &Entry : HSOpts.UserEntries)
746 Out.indent(6) << Entry.Path << "\n";
747 Out.indent(4) << "System header prefixes:\n";
748 for (const auto &Prefix : HSOpts.SystemHeaderPrefixes)
749 Out.indent(6) << Prefix.Prefix << "\n";
750 Out.indent(4) << "VFS overlay files:\n";
751 for (const auto &Overlay : HSOpts.VFSOverlayFiles)
752 Out.indent(6) << Overlay << "\n";
753 return false;
754 }
755
756 bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
757 StringRef ModuleFilename, bool ReadMacros,
758 bool Complain,
759 std::string &SuggestedPredefines) override {
760 Out.indent(2) << "Preprocessor options:\n";
762 "Uses compiler/target-specific predefines [-undef]");
764 "Uses detailed preprocessing record (for indexing)");
765
766 if (ReadMacros) {
767 Out.indent(4) << "Predefined macros:\n";
768 }
769
770 for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
771 I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
772 I != IEnd; ++I) {
773 Out.indent(6);
774 if (I->second)
775 Out << "-U";
776 else
777 Out << "-D";
778 Out << I->first << "\n";
779 }
780 return false;
781 }
782
783 /// Indicates that a particular module file extension has been read.
784 void readModuleFileExtension(
785 const ModuleFileExtensionMetadata &Metadata) override {
786 Out.indent(2) << "Module file extension '"
787 << Metadata.BlockName << "' " << Metadata.MajorVersion
788 << "." << Metadata.MinorVersion;
789 if (!Metadata.UserInfo.empty()) {
790 Out << ": ";
791 Out.write_escaped(Metadata.UserInfo);
792 }
793
794 Out << "\n";
795 }
796
797 /// Tells the \c ASTReaderListener that we want to receive the
798 /// input files of the AST file via \c visitInputFile.
799 bool needsInputFileVisitation() override { return true; }
800
801 /// Tells the \c ASTReaderListener that we want to receive the
802 /// input files of the AST file via \c visitInputFile.
803 bool needsSystemInputFileVisitation() override { return true; }
804
805 /// Indicates that the AST file contains particular input file.
806 ///
807 /// \returns true to continue receiving the next input file, false to stop.
808 bool visitInputFileAsRequested(StringRef FilenameAsRequested,
809 StringRef Filename, bool isSystem,
810 bool isOverridden, time_t StoredTime,
811 bool isExplicitModule) override {
812
813 Out.indent(2) << "Input file: " << FilenameAsRequested;
814
815 if (isSystem || isOverridden || isExplicitModule) {
816 Out << " [";
817 if (isSystem) {
818 Out << "System";
819 if (isOverridden || isExplicitModule)
820 Out << ", ";
821 }
822 if (isOverridden) {
823 Out << "Overridden";
824 if (isExplicitModule)
825 Out << ", ";
826 }
827 if (isExplicitModule)
828 Out << "ExplicitModule";
829
830 Out << "]";
831 }
832
833 Out << "\n";
834
835 if (StoredTime > 0)
836 Out.indent(4) << "MTime: " << llvm::itostr(StoredTime) << "\n";
837
838 return true;
839 }
840
841 /// Returns true if this \c ASTReaderListener wants to receive the
842 /// imports of the AST file via \c visitImport, false otherwise.
843 bool needsImportVisitation() const override { return true; }
844
845 /// If needsImportVisitation returns \c true, this is called for each
846 /// AST file imported by this AST file.
847 void visitImport(StringRef ModuleName, StringRef Filename) override {
848 Out.indent(2) << "Imports module '" << ModuleName
849 << "': " << Filename.str() << "\n";
850 }
851#undef DUMP_BOOLEAN
852 };
853}
854
856 // The Object file reader also supports raw ast files and there is no point in
857 // being strict about the module file format in -module-file-info mode.
859 return true;
860}
861
862static StringRef ModuleKindName(Module::ModuleKind MK) {
863 switch (MK) {
865 return "Module Map Module";
867 return "Interface Unit";
869 return "Implementation Unit";
871 return "Partition Interface";
873 return "Partition Implementation";
875 return "Header Unit";
877 return "Global Module Fragment";
879 return "Implicit Module Fragment";
881 return "Private Module Fragment";
882 }
883 llvm_unreachable("unknown module kind!");
884}
885
888
889 // Don't process files of type other than module to avoid crash
890 if (!isCurrentFileAST()) {
891 CI.getDiagnostics().Report(diag::err_file_is_not_module)
892 << getCurrentFile();
893 return;
894 }
895
896 // Set up the output file.
897 StringRef OutputFileName = CI.getFrontendOpts().OutputFile;
898 if (!OutputFileName.empty() && OutputFileName != "-") {
899 std::error_code EC;
900 OutputStream.reset(new llvm::raw_fd_ostream(
901 OutputFileName.str(), EC, llvm::sys::fs::OF_TextWithCRLF));
902 }
903 llvm::raw_ostream &Out = OutputStream ? *OutputStream : llvm::outs();
904
905 Out << "Information for module file '" << getCurrentFile() << "':\n";
906 auto &FileMgr = CI.getFileManager();
907 auto Buffer = FileMgr.getBufferForFile(getCurrentFile());
908 StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();
909 bool IsRaw = Magic.starts_with("CPCH");
910 Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n";
911
912 Preprocessor &PP = CI.getPreprocessor();
913 DumpModuleInfoListener Listener(Out, CI.getFileManager());
914 const HeaderSearchOptions &HSOpts =
915 PP.getHeaderSearchInfo().getHeaderSearchOpts();
916
917 // The FrontendAction::BeginSourceFile () method loads the AST so that much
918 // of the information is already available and modules should have been
919 // loaded.
920
922 if (LO.CPlusPlusModules && !LO.CurrentModule.empty()) {
924 unsigned SubModuleCount = R->getTotalNumSubmodules();
925 serialization::ModuleFile &MF = R->getModuleManager().getPrimaryModule();
926 Out << " ====== C++20 Module structure ======\n";
927
928 if (MF.ModuleName != LO.CurrentModule)
929 Out << " Mismatched module names : " << MF.ModuleName << " and "
930 << LO.CurrentModule << "\n";
931
932 struct SubModInfo {
933 unsigned Idx;
934 Module *Mod;
936 std::string &Name;
937 bool Seen;
938 };
939 std::map<std::string, SubModInfo> SubModMap;
940 auto PrintSubMapEntry = [&](std::string Name, Module::ModuleKind Kind) {
941 Out << " " << ModuleKindName(Kind) << " '" << Name << "'";
942 auto I = SubModMap.find(Name);
943 if (I == SubModMap.end())
944 Out << " was not found in the sub modules!\n";
945 else {
946 I->second.Seen = true;
947 Out << " is at index #" << I->second.Idx << "\n";
948 }
949 };
950 Module *Primary = nullptr;
951 for (unsigned Idx = 0; Idx <= SubModuleCount; ++Idx) {
952 Module *M = R->getModule(Idx);
953 if (!M)
954 continue;
955 if (M->Name == LO.CurrentModule) {
956 Primary = M;
957 Out << " " << ModuleKindName(M->Kind) << " '" << LO.CurrentModule
958 << "' is the Primary Module at index #" << Idx << "\n";
959 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, true}});
960 } else
961 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, false}});
962 }
963 if (Primary) {
964 if (!Primary->submodules().empty())
965 Out << " Sub Modules:\n";
966 for (Module *MI : Primary->submodules()) {
967 PrintSubMapEntry(MI->Name, MI->Kind);
968 }
969 if (!Primary->Imports.empty())
970 Out << " Imports:\n";
971 for (Module *IMP : Primary->Imports) {
972 PrintSubMapEntry(IMP->Name, IMP->Kind);
973 }
974 if (!Primary->Exports.empty())
975 Out << " Exports:\n";
976 for (unsigned MN = 0, N = Primary->Exports.size(); MN != N; ++MN) {
977 if (Module *M = Primary->Exports[MN].first) {
978 PrintSubMapEntry(M->Name, M->Kind);
979 }
980 }
981 }
982
983 // Emit the macro definitions in the module file so that we can know how
984 // much definitions in the module file quickly.
985 // TODO: Emit the macro definition bodies completely.
986 {
987 std::vector<StringRef> MacroNames;
988 for (const auto &M : R->getPreprocessor().macros()) {
989 if (M.first->isFromAST())
990 MacroNames.push_back(M.first->getName());
991 }
992 llvm::sort(MacroNames);
993 if (!MacroNames.empty())
994 Out << " Macro Definitions:\n";
995 for (StringRef Name : MacroNames)
996 Out << " " << Name << "\n";
997 }
998
999 // Now let's print out any modules we did not see as part of the Primary.
1000 for (const auto &SM : SubModMap) {
1001 if (!SM.second.Seen && SM.second.Mod) {
1002 Out << " " << ModuleKindName(SM.second.Kind) << " '" << SM.first
1003 << "' at index #" << SM.second.Idx
1004 << " has no direct reference in the Primary\n";
1005 }
1006 }
1007 Out << " ====== ======\n";
1008 }
1009
1010 // The reminder of the output is produced from the listener as the AST
1011 // FileCcontrolBlock is (re-)parsed.
1015 /*FindModuleFileExtensions=*/true, Listener,
1017}
1018
1019//===----------------------------------------------------------------------===//
1020// Preprocessor Actions
1021//===----------------------------------------------------------------------===//
1022
1026
1027 // Start lexing the specified input file.
1028 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
1029 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
1030 RawLex.SetKeepWhitespaceMode(true);
1031
1032 Token RawTok;
1033 RawLex.LexFromRawLexer(RawTok);
1034 while (RawTok.isNot(tok::eof)) {
1035 PP.DumpToken(RawTok, true);
1036 llvm::errs() << "\n";
1037 RawLex.LexFromRawLexer(RawTok);
1038 }
1039}
1040
1043 // Start preprocessing the specified input file.
1044 Token Tok;
1046 do {
1047 PP.Lex(Tok);
1048 PP.DumpToken(Tok, true);
1049 llvm::errs() << "\n";
1050 } while (Tok.isNot(tok::eof));
1051}
1052
1055
1056 // Ignore unknown pragmas.
1057 PP.IgnorePragmas();
1058
1059 Token Tok;
1060 // Start parsing the specified input file.
1062 do {
1063 PP.Lex(Tok);
1064 } while (Tok.isNot(tok::eof));
1065}
1066
1069 // Output file may need to be set to 'Binary', to avoid converting Unix style
1070 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>) on Windows.
1071 //
1072 // Look to see what type of line endings the file uses. If there's a
1073 // CRLF, then we won't open the file up in binary mode. If there is
1074 // just an LF or CR, then we will open the file up in binary mode.
1075 // In this fashion, the output format should match the input format, unless
1076 // the input format has inconsistent line endings.
1077 //
1078 // This should be a relatively fast operation since most files won't have
1079 // all of their source code on a single line. However, that is still a
1080 // concern, so if we scan for too long, we'll just assume the file should
1081 // be opened in binary mode.
1082
1083 bool BinaryMode = false;
1084 if (llvm::Triple(LLVM_HOST_TRIPLE).isOSWindows()) {
1085 BinaryMode = true;
1086 const SourceManager &SM = CI.getSourceManager();
1087 if (std::optional<llvm::MemoryBufferRef> Buffer =
1088 SM.getBufferOrNone(SM.getMainFileID())) {
1089 const char *cur = Buffer->getBufferStart();
1090 const char *end = Buffer->getBufferEnd();
1091 const char *next = (cur != end) ? cur + 1 : end;
1092
1093 // Limit ourselves to only scanning 256 characters into the source
1094 // file. This is mostly a check in case the file has no
1095 // newlines whatsoever.
1096 if (end - cur > 256)
1097 end = cur + 256;
1098
1099 while (next < end) {
1100 if (*cur == 0x0D) { // CR
1101 if (*next == 0x0A) // CRLF
1102 BinaryMode = false;
1103
1104 break;
1105 } else if (*cur == 0x0A) // LF
1106 break;
1107
1108 ++cur;
1109 ++next;
1110 }
1111 }
1112 }
1113
1114 std::unique_ptr<raw_ostream> OS =
1116 if (!OS) return;
1117
1118 // If we're preprocessing a module map, start by dumping the contents of the
1119 // module itself before switching to the input buffer.
1120 auto &Input = getCurrentInput();
1121 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
1122 if (Input.isFile()) {
1123 (*OS) << "# 1 \"";
1124 OS->write_escaped(Input.getFile());
1125 (*OS) << "\"\n";
1126 }
1127 getCurrentModule()->print(*OS);
1128 (*OS) << "#pragma clang module contents\n";
1129 }
1130
1133}
1134
1136 switch (getCurrentFileKind().getLanguage()) {
1137 case Language::C:
1138 case Language::CXX:
1139 case Language::ObjC:
1140 case Language::ObjCXX:
1141 case Language::OpenCL:
1143 case Language::CUDA:
1144 case Language::HIP:
1145 case Language::HLSL:
1146 case Language::CIR:
1147 break;
1148
1149 case Language::Unknown:
1150 case Language::Asm:
1151 case Language::LLVM_IR:
1152 // We can't do anything with these.
1153 return;
1154 }
1155
1156 // We don't expect to find any #include directives in a preprocessed input.
1157 if (getCurrentFileKind().isPreprocessed())
1158 return;
1159
1161 auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
1162 if (Buffer) {
1163 unsigned Preamble =
1164 Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).Size;
1165 llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
1166 }
1167}
1168
1169static void writeCompilerOptionValues(raw_ostream &OS,
1170 StringRef CompilerOptionNames,
1171 ArrayRef<bool> CompilerOptionValues) {
1172 bool FirstValue = true;
1173 for (bool CompilerOptionValue : CompilerOptionValues) {
1174 auto [CompilerOptionName, RemainingCompilerOptionNames] =
1175 CompilerOptionNames.split('\0');
1176 CompilerOptionNames = RemainingCompilerOptionNames;
1177 if (!FirstValue)
1178 OS << ",\n";
1179 FirstValue = false;
1180 OS << "\t{\"" << CompilerOptionName
1181 << "\" : " << (CompilerOptionValue ? "true" : "false") << "}";
1182 }
1183 assert(CompilerOptionNames.empty() && "compiler option name count mismatch");
1184}
1185
1187 CompilerInstance &CI = getCompilerInstance();
1188 std::unique_ptr<raw_ostream> OSP =
1190 if (!OSP)
1191 return;
1192
1193 raw_ostream &OS = *OSP;
1194 const Preprocessor &PP = CI.getPreprocessor();
1195 const LangOptions &LangOpts = PP.getLangOpts();
1196
1197 // FIXME: Rather than manually format the JSON (which is awkward due to
1198 // needing to remove trailing commas), this should make use of a JSON library.
1199 // FIXME: Instead of printing enums as an integral value and specifying the
1200 // type as a separate field, use introspection to print the enumerator.
1201
1202 OS << "{\n";
1203 OS << "\n\"features\" : [\n";
1204 {
1205 static constexpr char FeatureNames[] = {
1206#define FEATURE(Name, Predicate) #Name "\0"
1207#include "clang/Basic/Features.def"
1208 };
1209 const bool FeatureValues[] = {
1210#define FEATURE(Name, Predicate) static_cast<bool>(Predicate),
1211#include "clang/Basic/Features.def"
1212 };
1214 OS, StringRef(FeatureNames, sizeof(FeatureNames) - 1), FeatureValues);
1215 }
1216 OS << "\n],\n";
1217
1218 OS << "\n\"extensions\" : [\n";
1219 {
1220 static constexpr char ExtensionNames[] = {
1221#define EXTENSION(Name, Predicate) #Name "\0"
1222#include "clang/Basic/Features.def"
1223 };
1224 const bool ExtensionValues[] = {
1225#define EXTENSION(Name, Predicate) static_cast<bool>(Predicate),
1226#include "clang/Basic/Features.def"
1227 };
1229 OS, StringRef(ExtensionNames, sizeof(ExtensionNames) - 1),
1230 ExtensionValues);
1231 }
1232 OS << "\n]\n";
1233
1234 OS << "}";
1235}
1236
1240 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
1241
1245 FromFile.getBuffer(), Tokens, Directives, &CI.getDiagnostics(),
1246 SM.getLocForStartOfFile(SM.getMainFileID()))) {
1247 assert(CI.getDiagnostics().hasErrorOccurred() &&
1248 "no errors reported for failure");
1249
1250 // Preprocess the source when verifying the diagnostics to capture the
1251 // 'expected' comments.
1252 if (CI.getDiagnosticOpts().VerifyDiagnostics) {
1253 // Make sure we don't emit new diagnostics!
1257 Token Tok;
1258 do {
1259 PP.Lex(Tok);
1260 } while (Tok.isNot(tok::eof));
1261 }
1262 return;
1263 }
1264 printDependencyDirectivesAsSource(FromFile.getBuffer(), Directives,
1265 llvm::outs());
1266}
1267
1268//===----------------------------------------------------------------------===//
1269// HLSL Specific Actions
1270//===----------------------------------------------------------------------===//
1271
1273private:
1274 Sema &Actions;
1275 StringRef RootSigName;
1276 llvm::dxbc::RootSignatureVersion Version;
1277
1278 std::optional<StringLiteral *> processStringLiteral(ArrayRef<Token> Tokens) {
1279 for (Token Tok : Tokens)
1280 if (!tok::isStringLiteral(Tok.getKind()))
1281 return std::nullopt;
1282
1283 ExprResult StringResult = Actions.ActOnUnevaluatedStringLiteral(Tokens);
1284 if (StringResult.isInvalid())
1285 return std::nullopt;
1286
1287 if (auto Signature = dyn_cast<StringLiteral>(StringResult.get()))
1288 return Signature;
1289
1290 return std::nullopt;
1291 }
1292
1293public:
1294 void MacroDefined(const Token &MacroNameTok,
1295 const MacroDirective *MD) override {
1296 if (RootSigName != MacroNameTok.getIdentifierInfo()->getName())
1297 return;
1298
1299 const MacroInfo *MI = MD->getMacroInfo();
1300 auto Signature = processStringLiteral(MI->tokens());
1301 if (!Signature.has_value()) {
1302 Actions.getDiagnostics().Report(MI->getDefinitionLoc(),
1303 diag::err_expected_string_literal)
1304 << /*in attributes...*/ 4 << "RootSignature";
1305 return;
1306 }
1307
1308 IdentifierInfo *DeclIdent =
1309 hlsl::ParseHLSLRootSignature(Actions, Version, *Signature);
1310 Actions.HLSL().SetRootSignatureOverride(DeclIdent);
1311 }
1312
1313 InjectRootSignatureCallback(Sema &Actions, StringRef RootSigName,
1314 llvm::dxbc::RootSignatureVersion Version)
1315 : PPCallbacks(), Actions(Actions), RootSigName(RootSigName),
1316 Version(Version) {}
1317};
1318
1320 // Pre-requisites to invoke
1322 if (!CI.hasASTContext() || !CI.hasPreprocessor())
1324
1325 // InjectRootSignatureCallback requires access to invoke Sema to lookup/
1326 // register a root signature declaration. The wrapped action is required to
1327 // account for this by only creating a Sema if one doesn't already exist
1328 // (like we have done, and, ASTFrontendAction::ExecuteAction)
1329 if (!CI.hasSema())
1331 /*CodeCompleteConsumer=*/nullptr);
1332 Sema &S = CI.getSema();
1333
1334 auto &TargetInfo = CI.getASTContext().getTargetInfo();
1335 bool IsRootSignatureTarget =
1336 TargetInfo.getTriple().getEnvironment() == llvm::Triple::RootSignature;
1337 StringRef HLSLEntry = TargetInfo.getTargetOpts().HLSLEntry;
1338
1339 // Register HLSL specific callbacks
1340 auto LangOpts = CI.getLangOpts();
1341 StringRef RootSigName =
1342 IsRootSignatureTarget ? HLSLEntry : LangOpts.HLSLRootSigOverride;
1343
1344 auto MacroCallback = std::make_unique<InjectRootSignatureCallback>(
1345 S, RootSigName, LangOpts.HLSLRootSigVer);
1346
1347 Preprocessor &PP = CI.getPreprocessor();
1348 PP.addPPCallbacks(std::move(MacroCallback));
1349
1350 // If we are targeting a root signature, invoke custom handling
1351 if (IsRootSignatureTarget)
1352 return hlsl::HandleRootSignatureTarget(S, HLSLEntry);
1353 else // otherwise, invoke as normal
1355}
1356
1358 std::unique_ptr<FrontendAction> WrappedAction)
This is the interface for scanning header and source files to get the minimum necessary preprocessor ...
Defines the clang::FileManager interface and associated types.
Token Tok
The Token.
static void writeCompilerOptionValues(raw_ostream &OS, StringRef CompilerOptionNames, ArrayRef< bool > CompilerOptionValues)
#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)
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:858
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:924
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:427
@ ARR_ConfigurationMismatch
The client can handle an AST file that cannot load because it's compiled configuration doesn't match ...
Definition ASTReader.h:1838
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.
const LangOptions & getLangOpts() const
Definition ASTUnit.h:476
IntrusiveRefCntPtr< ASTReader > getASTReader() const
Definition ASTUnit.cpp:647
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.
std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="", bool RemoveFileOnSignal=true, bool CreateMissingDirectories=false, bool ForceUseTemporary=false, bool SetOnlyIfDifferent=false)
Create the default output file (from the invocation's options) and add it to the list of tracked outp...
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
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()
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.
static Decl * castFromDeclContext(const DeclContext *)
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.
bool hasErrorOccurred() const
Definition Diagnostic.h:882
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:737
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.
Implements support for file system lookup, file system caching, and directory search management.
Definition FileManager.h:52
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.
Module * getCurrentModule() const
StringRef getCurrentFile() const
virtual bool BeginSourceFileAction(CompilerInstance &CI)
Callback at the start of processing a single input.
virtual void ExecuteAction()=0
Callback to run the program action, using the initialized compiler instance.
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.
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.
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.
static std::unique_ptr< llvm::raw_pwrite_stream > CreateOutputFile(CompilerInstance &CI, StringRef InFile, std::string &OutputFile, bool SetOnlyIfDifferent=false)
Creates file to write the PCH into and returns a stream to write it into.
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::string ModuleCachePath
The directory used for the module cache.
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.
unsigned DisableModuleHash
Whether we should disable the use of the hash string within the module cache.
ModuleFileName 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.
@ CMK_ModuleInterface
Compiling a C++ modules interface unit.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::string HLSLRootSigOverride
The HLSL root signature that will be used to overide the root signature used for the shader entry poi...
llvm::dxbc::RootSignatureVersion HLSLRootSigVer
The HLSL root signature version for dxil.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
std::vector< std::string > ModuleFeatures
The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
Definition Lexer.h:79
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:668
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
Definition MacroInfo.h:314
const MacroInfo * getMacroInfo() const
Definition MacroInfo.h:417
Encapsulates the data about a macro definition (e.g.
Definition MacroInfo.h:40
SourceLocation getDefinitionLoc() const
Return the location that the macro was defined at.
Definition MacroInfo.h:126
ArrayRef< Token > tokens() const
Definition MacroInfo.h:250
static ModuleFileName makeExplicit(std::string Name)
Creates a file name for an explicit module.
Definition Module.h:142
Describes a module or submodule.
Definition Module.h:340
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition Module.h:671
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:456
ModuleKind Kind
The kind of this module.
Definition Module.h:385
std::string Name
The name of this module.
Definition Module.h:343
llvm::iterator_range< submodule_iterator > submodules()
Definition Module.h:1067
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
Definition Module.h:363
@ ModuleMapModule
This is a module that was defined by a module map and built out of header files.
Definition Module.h:354
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
Definition Module.h:381
@ ModulePartitionInterface
This is a C++20 module partition interface.
Definition Module.h:366
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
Definition Module.h:360
@ ModuleHeaderUnit
This is a C++20 header unit.
Definition Module.h:357
@ ModulePartitionImplementation
This is a C++20 module partition implementation.
Definition Module.h:369
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
Definition Module.h:376
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
Definition Module.h:373
llvm::SmallVector< ModuleRef, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition Module.h:658
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:1848
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
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
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.
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:2219
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.
SourceManager & getSourceManager() const
HeaderSearch & getHeaderSearchInfo() const
const LangOptions & getLangOpts() const
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:869
ASTContext & Context
Definition Sema.h:1309
const LangOptions & getLangOpts() const
Definition Sema.h:933
std::vector< std::unique_ptr< TemplateInstantiationCallback > > TemplateInstCallbacks
The template instantiation callbacks to trace or track instantiations (objects can be chained).
Definition Sema.h:13678
SourceManager & getSourceManager() const
Definition Sema.h:938
Encodes a location in the source.
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.
Exposes information about the current target.
Definition TargetInfo.h:227
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition TargetInfo.h:327
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
std::string Triple
The name of the target triple to compile for.
std::string ABI
If given, the name of the target ABI to use.
std::string TuneCPU
If given, the name of the target CPU to tune code for.
std::string CPU
If given, the name of the target CPU to generate code for.
std::vector< std::string > FeaturesAsWritten
The list of target specific features to enable or disable, as written on the command line.
std::string HLSLEntry
The entry point name for HLSL shader being compiled as specified by -E.
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:197
bool isNot(tok::TokenKind K) const
Definition Token.h:111
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.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
WrapperFrontendAction(std::unique_ptr< FrontendAction > WrappedAction)
Construct a WrapperFrontendAction from an existing action, taking ownership of it.
TranslationUnitKind getTranslationUnitKind() override
For AST-based actions, the kind of translation unit we're handling.
std::unique_ptr< FrontendAction > WrappedAction
Information about a module that has been loaded by the ASTReader.
Definition ModuleFile.h:158
std::string ModuleName
The name of the module.
Definition ModuleFile.h:183
Defines the clang::TargetInfo interface.
@ HeaderSearch
Remove unused header search paths including header maps.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
void HandleRootSignatureTarget(Sema &S, StringRef EntryRootSig)
IdentifierInfo * ParseHLSLRootSignature(Sema &Actions, llvm::dxbc::RootSignatureVersion Version, StringLiteral *Signature)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
@ MK_PCH
File is a PCH file treated as such.
Definition ModuleFile.h:52
@ MK_Preamble
File is a PCH file treated as the preamble.
Definition ModuleFile.h:55
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:95
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.
std::string createSpecificModuleCachePath(FileManager &FileMgr, StringRef ModuleCachePath, bool DisableModuleHash, std::string ContextHash)
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)
DoPrintPreprocessedInput - Implement -E mode.
@ Type
The name was classified as a type.
Definition Sema.h:564
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)
U cast(CodeGen::Address addr)
Definition Address.h:327
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
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:63
unsigned SuppressDefaultTemplateArgs
When true, attempt to suppress template arguments that match the default argument for the parameter.
static void mapping(IO &io, TemplightEntry &fields)