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);
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 // Because this is exposed via libclang we must disable RemoveFileOnSignal.
167 std::unique_ptr<raw_pwrite_stream> OS = CI.createDefaultOutputFile(
168 /*Binary=*/true, InFile, /*Extension=*/"", /*RemoveFileOnSignal=*/false);
169 if (!OS)
170 return nullptr;
171
172 OutputFile = CI.getFrontendOpts().OutputFile;
173 return OS;
174}
175
177 if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)
178 return false;
180}
181
186
187std::vector<std::unique_ptr<ASTConsumer>>
189 StringRef InFile) {
190 if (!OS)
191 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 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
211 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
212 return Consumers;
213}
214
215std::unique_ptr<ASTConsumer>
217 StringRef InFile) {
218 std::vector<std::unique_ptr<ASTConsumer>> Consumers =
219 CreateMultiplexConsumer(CI, InFile);
220 if (Consumers.empty())
221 return nullptr;
222
223 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
224}
225
230
231bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(
232 CompilerInstance &CI) {
233 if (!CI.getLangOpts().Modules) {
234 CI.getDiagnostics().Report(diag::err_module_build_requires_fmodules);
235 return false;
236 }
237
239}
240
241std::unique_ptr<raw_pwrite_stream>
242GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
243 StringRef InFile) {
244 // If no output file was provided, figure out where this module would go
245 // in the module cache.
246 if (CI.getFrontendOpts().OutputFile.empty()) {
247 StringRef ModuleMapFile = CI.getFrontendOpts().OriginalModuleMap;
248 if (ModuleMapFile.empty())
249 ModuleMapFile = InFile;
250
252 ModuleFileName FileName = HS.getCachedModuleFileName(
253 CI.getLangOpts().CurrentModule, ModuleMapFile);
255 }
256
257 // Because this is exposed via libclang we must disable RemoveFileOnSignal.
258 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, /*Extension=*/"",
259 /*RemoveFileOnSignal=*/false,
260 /*CreateMissingDirectories=*/true,
261 /*ForceUseTemporary=*/true);
262}
263
265 CompilerInstance &CI) {
266 for (const auto &FIF : CI.getFrontendOpts().Inputs) {
267 if (const auto InputFormat = FIF.getKind().getFormat();
268 InputFormat != InputKind::Format::Source) {
270 diag::err_frontend_action_unsupported_input_format)
271 << "module interface compilation" << FIF.getFile() << InputFormat;
272 return false;
273 }
274 }
276}
277
284
285std::unique_ptr<ASTConsumer>
287 StringRef InFile) {
288 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
289
291 !CI.getFrontendOpts().ModuleOutputPath.empty()) {
292 Consumers.push_back(std::make_unique<ReducedBMIGenerator>(
296 }
297
298 Consumers.push_back(std::make_unique<CXX20ModulesGenerator>(
302
303 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
304}
305
306std::unique_ptr<raw_pwrite_stream>
308 StringRef InFile) {
309 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
310}
311
312std::unique_ptr<ASTConsumer>
313GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
314 StringRef InFile) {
315 return std::make_unique<ReducedBMIGenerator>(
318}
319
320bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) {
321 if (!CI.getLangOpts().CPlusPlusModules) {
322 CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
323 return false;
324 }
325 CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderUnit);
327}
328
329std::unique_ptr<raw_pwrite_stream>
330GenerateHeaderUnitAction::CreateOutputFile(CompilerInstance &CI,
331 StringRef InFile) {
332 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
333}
334
337
338std::unique_ptr<ASTConsumer>
340 return std::make_unique<ASTConsumer>();
341}
342
343std::unique_ptr<ASTConsumer>
345 StringRef InFile) {
346 return std::make_unique<ASTConsumer>();
347}
348
349std::unique_ptr<ASTConsumer>
351 return std::make_unique<ASTConsumer>();
352}
353
357 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
358 std::unique_ptr<ASTReader> Reader(new ASTReader(
362 Sysroot.empty() ? "" : Sysroot.c_str(),
364 /*AllowASTWithCompilerErrors*/ false,
365 /*AllowConfigurationMismatch*/ true,
366 /*ValidateSystemInputs*/ true, /*ForceValidateUserInputs*/ true));
367
371}
372
373namespace {
374struct TemplightEntry {
375 std::string Name;
376 std::string Kind;
377 std::string Event;
378 std::string DefinitionLocation;
379 std::string PointOfInstantiation;
380};
381} // namespace
382
383namespace llvm {
384namespace yaml {
385template <> struct MappingTraits<TemplightEntry> {
386 static void mapping(IO &io, TemplightEntry &fields) {
387 io.mapRequired("name", fields.Name);
388 io.mapRequired("kind", fields.Kind);
389 io.mapRequired("event", fields.Event);
390 io.mapRequired("orig", fields.DefinitionLocation);
391 io.mapRequired("poi", fields.PointOfInstantiation);
392 }
393};
394} // namespace yaml
395} // namespace llvm
396
397namespace {
398class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
399 using CodeSynthesisContext = Sema::CodeSynthesisContext;
400
401public:
402 void initialize(const Sema &) override {}
403
404 void finalize(const Sema &) override {}
405
406 void atTemplateBegin(const Sema &TheSema,
407 const CodeSynthesisContext &Inst) override {
408 displayTemplightEntry<true>(llvm::outs(), TheSema, Inst);
409 }
410
411 void atTemplateEnd(const Sema &TheSema,
412 const CodeSynthesisContext &Inst) override {
413 displayTemplightEntry<false>(llvm::outs(), TheSema, Inst);
414 }
415
416private:
417 static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {
418 switch (Kind) {
419 case CodeSynthesisContext::TemplateInstantiation:
420 return "TemplateInstantiation";
421 case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
422 return "DefaultTemplateArgumentInstantiation";
423 case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
424 return "DefaultFunctionArgumentInstantiation";
425 case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
426 return "ExplicitTemplateArgumentSubstitution";
427 case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
428 return "DeducedTemplateArgumentSubstitution";
429 case CodeSynthesisContext::LambdaExpressionSubstitution:
430 return "LambdaExpressionSubstitution";
431 case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
432 return "PriorTemplateArgumentSubstitution";
433 case CodeSynthesisContext::DefaultTemplateArgumentChecking:
434 return "DefaultTemplateArgumentChecking";
435 case CodeSynthesisContext::ExceptionSpecEvaluation:
436 return "ExceptionSpecEvaluation";
437 case CodeSynthesisContext::ExceptionSpecInstantiation:
438 return "ExceptionSpecInstantiation";
439 case CodeSynthesisContext::DeclaringSpecialMember:
440 return "DeclaringSpecialMember";
441 case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
442 return "DeclaringImplicitEqualityComparison";
443 case CodeSynthesisContext::DefiningSynthesizedFunction:
444 return "DefiningSynthesizedFunction";
445 case CodeSynthesisContext::RewritingOperatorAsSpaceship:
446 return "RewritingOperatorAsSpaceship";
447 case CodeSynthesisContext::Memoization:
448 return "Memoization";
449 case CodeSynthesisContext::ConstraintsCheck:
450 return "ConstraintsCheck";
451 case CodeSynthesisContext::ConstraintSubstitution:
452 return "ConstraintSubstitution";
453 case CodeSynthesisContext::RequirementParameterInstantiation:
454 return "RequirementParameterInstantiation";
455 case CodeSynthesisContext::ParameterMappingSubstitution:
456 return "ParameterMappingSubstitution";
457 case CodeSynthesisContext::RequirementInstantiation:
458 return "RequirementInstantiation";
459 case CodeSynthesisContext::NestedRequirementConstraintsCheck:
460 return "NestedRequirementConstraintsCheck";
461 case CodeSynthesisContext::InitializingStructuredBinding:
462 return "InitializingStructuredBinding";
463 case CodeSynthesisContext::MarkingClassDllexported:
464 return "MarkingClassDllexported";
465 case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
466 return "BuildingBuiltinDumpStructCall";
467 case CodeSynthesisContext::BuildingDeductionGuides:
468 return "BuildingDeductionGuides";
469 case CodeSynthesisContext::TypeAliasTemplateInstantiation:
470 return "TypeAliasTemplateInstantiation";
471 case CodeSynthesisContext::PartialOrderingTTP:
472 return "PartialOrderingTTP";
473 case CodeSynthesisContext::SYCLKernelLaunchLookup:
474 return "SYCLKernelLaunchLookup";
475 case CodeSynthesisContext::SYCLKernelLaunchOverloadResolution:
476 return "SYCLKernelLaunchOverloadResolution";
477 }
478 return "";
479 }
480
481 template <bool BeginInstantiation>
482 static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema,
483 const CodeSynthesisContext &Inst) {
484 std::string YAML;
485 {
486 llvm::raw_string_ostream OS(YAML);
487 llvm::yaml::Output YO(OS);
488 TemplightEntry Entry =
489 getTemplightEntry<BeginInstantiation>(TheSema, Inst);
490 llvm::yaml::EmptyContext Context;
491 llvm::yaml::yamlize(YO, Entry, true, Context);
492 }
493 Out << "---" << YAML << "\n";
494 }
495
496 static void printEntryName(const Sema &TheSema, const Decl *Entity,
497 llvm::raw_string_ostream &OS) {
498 auto *NamedTemplate = cast<NamedDecl>(Entity);
499
500 PrintingPolicy Policy = TheSema.Context.getPrintingPolicy();
501 // FIXME: Also ask for FullyQualifiedNames?
502 Policy.SuppressDefaultTemplateArgs = false;
503 NamedTemplate->getNameForDiagnostic(OS, Policy, true);
504
505 if (!OS.str().empty())
506 return;
507
508 Decl *Ctx = Decl::castFromDeclContext(NamedTemplate->getDeclContext());
509 NamedDecl *NamedCtx = dyn_cast_or_null<NamedDecl>(Ctx);
510
511 if (const auto *Decl = dyn_cast<TagDecl>(NamedTemplate)) {
512 if (const auto *R = dyn_cast<RecordDecl>(Decl)) {
513 if (R->isLambda()) {
514 OS << "lambda at ";
515 Decl->getLocation().print(OS, TheSema.getSourceManager());
516 return;
517 }
518 }
519 OS << "unnamed " << Decl->getKindName();
520 return;
521 }
522
523 assert(NamedCtx && "NamedCtx cannot be null");
524
525 if (const auto *Decl = dyn_cast<ParmVarDecl>(NamedTemplate)) {
526 OS << "unnamed function parameter " << Decl->getFunctionScopeIndex()
527 << " ";
528 if (Decl->getFunctionScopeDepth() > 0)
529 OS << "(at depth " << Decl->getFunctionScopeDepth() << ") ";
530 OS << "of ";
531 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
532 return;
533 }
534
535 if (const auto *Decl = dyn_cast<TemplateTypeParmDecl>(NamedTemplate)) {
536 if (const Type *Ty = Decl->getTypeForDecl()) {
537 if (const auto *TTPT = dyn_cast_or_null<TemplateTypeParmType>(Ty)) {
538 OS << "unnamed template type parameter " << TTPT->getIndex() << " ";
539 if (TTPT->getDepth() > 0)
540 OS << "(at depth " << TTPT->getDepth() << ") ";
541 OS << "of ";
542 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
543 return;
544 }
545 }
546 }
547
548 if (const auto *Decl = dyn_cast<NonTypeTemplateParmDecl>(NamedTemplate)) {
549 OS << "unnamed template non-type parameter " << Decl->getIndex() << " ";
550 if (Decl->getDepth() > 0)
551 OS << "(at depth " << Decl->getDepth() << ") ";
552 OS << "of ";
553 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
554 return;
555 }
556
557 if (const auto *Decl = dyn_cast<TemplateTemplateParmDecl>(NamedTemplate)) {
558 OS << "unnamed template template parameter " << Decl->getIndex() << " ";
559 if (Decl->getDepth() > 0)
560 OS << "(at depth " << Decl->getDepth() << ") ";
561 OS << "of ";
562 NamedCtx->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
563 return;
564 }
565
566 llvm_unreachable("Failed to retrieve a name for this entry!");
567 OS << "unnamed identifier";
568 }
569
570 template <bool BeginInstantiation>
571 static TemplightEntry getTemplightEntry(const Sema &TheSema,
572 const CodeSynthesisContext &Inst) {
573 TemplightEntry Entry;
574 Entry.Kind = toString(Inst.Kind);
575 Entry.Event = BeginInstantiation ? "Begin" : "End";
576 llvm::raw_string_ostream OS(Entry.Name);
577 printEntryName(TheSema, Inst.Entity, OS);
578 const PresumedLoc DefLoc =
579 TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation());
580 if (!DefLoc.isInvalid())
581 Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +
582 std::to_string(DefLoc.getLine()) + ":" +
583 std::to_string(DefLoc.getColumn());
584 const PresumedLoc PoiLoc =
585 TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation);
586 if (!PoiLoc.isInvalid()) {
587 Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +
588 std::to_string(PoiLoc.getLine()) + ":" +
589 std::to_string(PoiLoc.getColumn());
590 }
591 return Entry;
592 }
593};
594} // namespace
595
596std::unique_ptr<ASTConsumer>
598 return std::make_unique<ASTConsumer>();
599}
600
603
604 // This part is normally done by ASTFrontEndAction, but needs to happen
605 // before Templight observers can be created
606 // FIXME: Move the truncation aspect of this into Sema, we delayed this till
607 // here so the source manager would be initialized.
608 EnsureSemaIsCreated(CI, *this);
609
610 CI.getSema().TemplateInstCallbacks.push_back(
611 std::make_unique<DefaultTemplateInstCallback>());
613}
614
615namespace {
616 /// AST reader listener that dumps module information for a module
617 /// file.
618 class DumpModuleInfoListener : public ASTReaderListener {
619 llvm::raw_ostream &Out;
621
622 public:
623 DumpModuleInfoListener(llvm::raw_ostream &Out, FileManager &FileMgr)
624 : Out(Out), FileMgr(FileMgr) {}
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`.
649 using CK = 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 ContextHash,
716 bool Complain) override {
717 std::string SpecificModuleCachePath = createSpecificModuleCachePath(
718 FileMgr, HSOpts.ModuleCachePath, HSOpts.DisableModuleHash,
719 std::string(ContextHash));
720
721 Out.indent(2) << "Header search options:\n";
722 Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
723 Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
724 Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
726 "Use builtin include directories [-nobuiltininc]");
728 "Use standard system include directories [-nostdinc]");
730 "Use standard C++ include directories [-nostdinc++]");
731 DUMP_BOOLEAN(HSOpts.UseLibcxx,
732 "Use libc++ (rather than libstdc++) [-stdlib=]");
733 return false;
734 }
735
736 bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
737 bool Complain) override {
738 Out.indent(2) << "Header search paths:\n";
739 Out.indent(4) << "User entries:\n";
740 for (const auto &Entry : HSOpts.UserEntries)
741 Out.indent(6) << Entry.Path << "\n";
742 Out.indent(4) << "System header prefixes:\n";
743 for (const auto &Prefix : HSOpts.SystemHeaderPrefixes)
744 Out.indent(6) << Prefix.Prefix << "\n";
745 Out.indent(4) << "VFS overlay files:\n";
746 for (const auto &Overlay : HSOpts.VFSOverlayFiles)
747 Out.indent(6) << Overlay << "\n";
748 return false;
749 }
750
751 bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
752 StringRef ModuleFilename, bool ReadMacros,
753 bool Complain,
754 std::string &SuggestedPredefines) override {
755 Out.indent(2) << "Preprocessor options:\n";
757 "Uses compiler/target-specific predefines [-undef]");
759 "Uses detailed preprocessing record (for indexing)");
760
761 if (ReadMacros) {
762 Out.indent(4) << "Predefined macros:\n";
763 }
764
765 for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
766 I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
767 I != IEnd; ++I) {
768 Out.indent(6);
769 if (I->second)
770 Out << "-U";
771 else
772 Out << "-D";
773 Out << I->first << "\n";
774 }
775 return false;
776 }
777
778 /// Indicates that a particular module file extension has been read.
779 void readModuleFileExtension(
780 const ModuleFileExtensionMetadata &Metadata) override {
781 Out.indent(2) << "Module file extension '"
782 << Metadata.BlockName << "' " << Metadata.MajorVersion
783 << "." << Metadata.MinorVersion;
784 if (!Metadata.UserInfo.empty()) {
785 Out << ": ";
786 Out.write_escaped(Metadata.UserInfo);
787 }
788
789 Out << "\n";
790 }
791
792 /// Tells the \c ASTReaderListener that we want to receive the
793 /// input files of the AST file via \c visitInputFile.
794 bool needsInputFileVisitation() override { return true; }
795
796 /// Tells the \c ASTReaderListener that we want to receive the
797 /// input files of the AST file via \c visitInputFile.
798 bool needsSystemInputFileVisitation() override { return true; }
799
800 /// Indicates that the AST file contains particular input file.
801 ///
802 /// \returns true to continue receiving the next input file, false to stop.
803 bool visitInputFileAsRequested(StringRef FilenameAsRequested,
804 StringRef Filename, bool isSystem,
805 bool isOverridden, time_t StoredTime,
806 bool isExplicitModule) override {
807
808 Out.indent(2) << "Input file: " << FilenameAsRequested;
809
810 if (isSystem || isOverridden || isExplicitModule) {
811 Out << " [";
812 if (isSystem) {
813 Out << "System";
814 if (isOverridden || isExplicitModule)
815 Out << ", ";
816 }
817 if (isOverridden) {
818 Out << "Overridden";
819 if (isExplicitModule)
820 Out << ", ";
821 }
822 if (isExplicitModule)
823 Out << "ExplicitModule";
824
825 Out << "]";
826 }
827
828 Out << "\n";
829
830 if (StoredTime > 0)
831 Out.indent(4) << "MTime: " << llvm::itostr(StoredTime) << "\n";
832
833 return true;
834 }
835
836 /// Returns true if this \c ASTReaderListener wants to receive the
837 /// imports of the AST file via \c visitImport, false otherwise.
838 bool needsImportVisitation() const override { return true; }
839
840 /// If needsImportVisitation returns \c true, this is called for each
841 /// AST file imported by this AST file.
842 void visitImport(StringRef ModuleName, StringRef Filename) override {
843 Out.indent(2) << "Imports module '" << ModuleName
844 << "': " << Filename.str() << "\n";
845 }
846#undef DUMP_BOOLEAN
847 };
848}
849
851 // The Object file reader also supports raw ast files and there is no point in
852 // being strict about the module file format in -module-file-info mode.
854 return true;
855}
856
857static StringRef ModuleKindName(Module::ModuleKind MK) {
858 switch (MK) {
860 return "Module Map Module";
862 return "Interface Unit";
864 return "Implementation Unit";
866 return "Partition Interface";
868 return "Partition Implementation";
870 return "Header Unit";
872 return "Global Module Fragment";
874 return "Implicit Module Fragment";
876 return "Private Module Fragment";
877 }
878 llvm_unreachable("unknown module kind!");
879}
880
883
884 // Don't process files of type other than module to avoid crash
885 if (!isCurrentFileAST()) {
886 CI.getDiagnostics().Report(diag::err_file_is_not_module)
887 << getCurrentFile();
888 return;
889 }
890
891 // Set up the output file.
892 StringRef OutputFileName = CI.getFrontendOpts().OutputFile;
893 if (!OutputFileName.empty() && OutputFileName != "-") {
894 std::error_code EC;
895 OutputStream.reset(new llvm::raw_fd_ostream(
896 OutputFileName.str(), EC, llvm::sys::fs::OF_TextWithCRLF));
897 }
898 llvm::raw_ostream &Out = OutputStream ? *OutputStream : llvm::outs();
899
900 Out << "Information for module file '" << getCurrentFile() << "':\n";
901 auto &FileMgr = CI.getFileManager();
902 auto Buffer = FileMgr.getBufferForFile(getCurrentFile());
903 StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();
904 bool IsRaw = Magic.starts_with("CPCH");
905 Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n";
906
907 Preprocessor &PP = CI.getPreprocessor();
908 DumpModuleInfoListener Listener(Out, CI.getFileManager());
909 const HeaderSearchOptions &HSOpts =
910 PP.getHeaderSearchInfo().getHeaderSearchOpts();
911
912 // The FrontendAction::BeginSourceFile () method loads the AST so that much
913 // of the information is already available and modules should have been
914 // loaded.
915
917 if (LO.CPlusPlusModules && !LO.CurrentModule.empty()) {
919 unsigned SubModuleCount = R->getTotalNumSubmodules();
920 serialization::ModuleFile &MF = R->getModuleManager().getPrimaryModule();
921 Out << " ====== C++20 Module structure ======\n";
922
923 if (MF.ModuleName != LO.CurrentModule)
924 Out << " Mismatched module names : " << MF.ModuleName << " and "
925 << LO.CurrentModule << "\n";
926
927 struct SubModInfo {
928 unsigned Idx;
929 Module *Mod;
931 std::string &Name;
932 bool Seen;
933 };
934 std::map<std::string, SubModInfo> SubModMap;
935 auto PrintSubMapEntry = [&](std::string Name, Module::ModuleKind Kind) {
936 Out << " " << ModuleKindName(Kind) << " '" << Name << "'";
937 auto I = SubModMap.find(Name);
938 if (I == SubModMap.end())
939 Out << " was not found in the sub modules!\n";
940 else {
941 I->second.Seen = true;
942 Out << " is at index #" << I->second.Idx << "\n";
943 }
944 };
945 Module *Primary = nullptr;
946 for (unsigned Idx = 0; Idx <= SubModuleCount; ++Idx) {
947 Module *M = R->getModule(Idx);
948 if (!M)
949 continue;
950 if (M->Name == LO.CurrentModule) {
951 Primary = M;
952 Out << " " << ModuleKindName(M->Kind) << " '" << LO.CurrentModule
953 << "' is the Primary Module at index #" << Idx << "\n";
954 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, true}});
955 } else
956 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, false}});
957 }
958 if (Primary) {
959 if (!Primary->submodules().empty())
960 Out << " Sub Modules:\n";
961 for (Module *MI : Primary->submodules()) {
962 PrintSubMapEntry(MI->Name, MI->Kind);
963 }
964 if (!Primary->Imports.empty())
965 Out << " Imports:\n";
966 for (Module *IMP : Primary->Imports) {
967 PrintSubMapEntry(IMP->Name, IMP->Kind);
968 }
969 if (!Primary->Exports.empty())
970 Out << " Exports:\n";
971 for (unsigned MN = 0, N = Primary->Exports.size(); MN != N; ++MN) {
972 if (Module *M = Primary->Exports[MN].first) {
973 PrintSubMapEntry(M->Name, M->Kind);
974 }
975 }
976 }
977
978 // Emit the macro definitions in the module file so that we can know how
979 // much definitions in the module file quickly.
980 // TODO: Emit the macro definition bodies completely.
981 {
982 std::vector<StringRef> MacroNames;
983 for (const auto &M : R->getPreprocessor().macros()) {
984 if (M.first->isFromAST())
985 MacroNames.push_back(M.first->getName());
986 }
987 llvm::sort(MacroNames);
988 if (!MacroNames.empty())
989 Out << " Macro Definitions:\n";
990 for (StringRef Name : MacroNames)
991 Out << " " << Name << "\n";
992 }
993
994 // Now let's print out any modules we did not see as part of the Primary.
995 for (const auto &SM : SubModMap) {
996 if (!SM.second.Seen && SM.second.Mod) {
997 Out << " " << ModuleKindName(SM.second.Kind) << " '" << SM.first
998 << "' at index #" << SM.second.Idx
999 << " has no direct reference in the Primary\n";
1000 }
1001 }
1002 Out << " ====== ======\n";
1003 }
1004
1005 // The reminder of the output is produced from the listener as the AST
1006 // FileCcontrolBlock is (re-)parsed.
1010 /*FindModuleFileExtensions=*/true, Listener,
1012}
1013
1014//===----------------------------------------------------------------------===//
1015// Preprocessor Actions
1016//===----------------------------------------------------------------------===//
1017
1021
1022 // Start lexing the specified input file.
1023 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
1024 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
1025 RawLex.SetKeepWhitespaceMode(true);
1026
1027 Token RawTok;
1028 RawLex.LexFromRawLexer(RawTok);
1029 while (RawTok.isNot(tok::eof)) {
1030 PP.DumpToken(RawTok, true);
1031 llvm::errs() << "\n";
1032 RawLex.LexFromRawLexer(RawTok);
1033 }
1034}
1035
1038 // Start preprocessing the specified input file.
1039 Token Tok;
1041 do {
1042 PP.Lex(Tok);
1043 PP.DumpToken(Tok, true);
1044 llvm::errs() << "\n";
1045 } while (Tok.isNot(tok::eof));
1046}
1047
1050
1051 // Ignore unknown pragmas.
1052 PP.IgnorePragmas();
1053
1054 Token Tok;
1055 // Start parsing the specified input file.
1057 do {
1058 PP.Lex(Tok);
1059 } while (Tok.isNot(tok::eof));
1060}
1061
1064 // Output file may need to be set to 'Binary', to avoid converting Unix style
1065 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>) on Windows.
1066 //
1067 // Look to see what type of line endings the file uses. If there's a
1068 // CRLF, then we won't open the file up in binary mode. If there is
1069 // just an LF or CR, then we will open the file up in binary mode.
1070 // In this fashion, the output format should match the input format, unless
1071 // the input format has inconsistent line endings.
1072 //
1073 // This should be a relatively fast operation since most files won't have
1074 // all of their source code on a single line. However, that is still a
1075 // concern, so if we scan for too long, we'll just assume the file should
1076 // be opened in binary mode.
1077
1078 bool BinaryMode = false;
1079 if (llvm::Triple(LLVM_HOST_TRIPLE).isOSWindows()) {
1080 BinaryMode = true;
1081 const SourceManager &SM = CI.getSourceManager();
1082 if (std::optional<llvm::MemoryBufferRef> Buffer =
1083 SM.getBufferOrNone(SM.getMainFileID())) {
1084 const char *cur = Buffer->getBufferStart();
1085 const char *end = Buffer->getBufferEnd();
1086 const char *next = (cur != end) ? cur + 1 : end;
1087
1088 // Limit ourselves to only scanning 256 characters into the source
1089 // file. This is mostly a check in case the file has no
1090 // newlines whatsoever.
1091 if (end - cur > 256)
1092 end = cur + 256;
1093
1094 while (next < end) {
1095 if (*cur == 0x0D) { // CR
1096 if (*next == 0x0A) // CRLF
1097 BinaryMode = false;
1098
1099 break;
1100 } else if (*cur == 0x0A) // LF
1101 break;
1102
1103 ++cur;
1104 ++next;
1105 }
1106 }
1107 }
1108
1109 std::unique_ptr<raw_ostream> OS =
1111 if (!OS) return;
1112
1113 // If we're preprocessing a module map, start by dumping the contents of the
1114 // module itself before switching to the input buffer.
1115 auto &Input = getCurrentInput();
1116 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
1117 if (Input.isFile()) {
1118 (*OS) << "# 1 \"";
1119 OS->write_escaped(Input.getFile());
1120 (*OS) << "\"\n";
1121 }
1122 getCurrentModule()->print(*OS);
1123 (*OS) << "#pragma clang module contents\n";
1124 }
1125
1128}
1129
1131 switch (getCurrentFileKind().getLanguage()) {
1132 case Language::C:
1133 case Language::CXX:
1134 case Language::ObjC:
1135 case Language::ObjCXX:
1136 case Language::OpenCL:
1138 case Language::CUDA:
1139 case Language::HIP:
1140 case Language::HLSL:
1141 case Language::CIR:
1142 break;
1143
1144 case Language::Unknown:
1145 case Language::Asm:
1146 case Language::LLVM_IR:
1147 // We can't do anything with these.
1148 return;
1149 }
1150
1151 // We don't expect to find any #include directives in a preprocessed input.
1152 if (getCurrentFileKind().isPreprocessed())
1153 return;
1154
1156 auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
1157 if (Buffer) {
1158 unsigned Preamble =
1159 Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).Size;
1160 llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
1161 }
1162}
1163
1166 std::unique_ptr<raw_ostream> OSP =
1168 if (!OSP)
1169 return;
1170
1171 raw_ostream &OS = *OSP;
1172 const Preprocessor &PP = CI.getPreprocessor();
1173 const LangOptions &LangOpts = PP.getLangOpts();
1174
1175 // FIXME: Rather than manually format the JSON (which is awkward due to
1176 // needing to remove trailing commas), this should make use of a JSON library.
1177 // FIXME: Instead of printing enums as an integral value and specifying the
1178 // type as a separate field, use introspection to print the enumerator.
1179
1180 OS << "{\n";
1181 OS << "\n\"features\" : [\n";
1182 {
1184#define FEATURE(Name, Predicate) \
1185 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
1186 .toVector(Str);
1187#include "clang/Basic/Features.def"
1188#undef FEATURE
1189 // Remove the newline and comma from the last entry to ensure this remains
1190 // valid JSON.
1191 OS << Str.substr(0, Str.size() - 2);
1192 }
1193 OS << "\n],\n";
1194
1195 OS << "\n\"extensions\" : [\n";
1196 {
1198#define EXTENSION(Name, Predicate) \
1199 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
1200 .toVector(Str);
1201#include "clang/Basic/Features.def"
1202#undef EXTENSION
1203 // Remove the newline and comma from the last entry to ensure this remains
1204 // valid JSON.
1205 OS << Str.substr(0, Str.size() - 2);
1206 }
1207 OS << "\n]\n";
1208
1209 OS << "}";
1210}
1211
1215 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
1216
1220 FromFile.getBuffer(), Tokens, Directives, &CI.getDiagnostics(),
1221 SM.getLocForStartOfFile(SM.getMainFileID()))) {
1222 assert(CI.getDiagnostics().hasErrorOccurred() &&
1223 "no errors reported for failure");
1224
1225 // Preprocess the source when verifying the diagnostics to capture the
1226 // 'expected' comments.
1227 if (CI.getDiagnosticOpts().VerifyDiagnostics) {
1228 // Make sure we don't emit new diagnostics!
1232 Token Tok;
1233 do {
1234 PP.Lex(Tok);
1235 } while (Tok.isNot(tok::eof));
1236 }
1237 return;
1238 }
1239 printDependencyDirectivesAsSource(FromFile.getBuffer(), Directives,
1240 llvm::outs());
1241}
1242
1243//===----------------------------------------------------------------------===//
1244// HLSL Specific Actions
1245//===----------------------------------------------------------------------===//
1246
1248private:
1249 Sema &Actions;
1250 StringRef RootSigName;
1251 llvm::dxbc::RootSignatureVersion Version;
1252
1253 std::optional<StringLiteral *> processStringLiteral(ArrayRef<Token> Tokens) {
1254 for (Token Tok : Tokens)
1255 if (!tok::isStringLiteral(Tok.getKind()))
1256 return std::nullopt;
1257
1258 ExprResult StringResult = Actions.ActOnUnevaluatedStringLiteral(Tokens);
1259 if (StringResult.isInvalid())
1260 return std::nullopt;
1261
1262 if (auto Signature = dyn_cast<StringLiteral>(StringResult.get()))
1263 return Signature;
1264
1265 return std::nullopt;
1266 }
1267
1268public:
1269 void MacroDefined(const Token &MacroNameTok,
1270 const MacroDirective *MD) override {
1271 if (RootSigName != MacroNameTok.getIdentifierInfo()->getName())
1272 return;
1273
1274 const MacroInfo *MI = MD->getMacroInfo();
1275 auto Signature = processStringLiteral(MI->tokens());
1276 if (!Signature.has_value()) {
1277 Actions.getDiagnostics().Report(MI->getDefinitionLoc(),
1278 diag::err_expected_string_literal)
1279 << /*in attributes...*/ 4 << "RootSignature";
1280 return;
1281 }
1282
1283 IdentifierInfo *DeclIdent =
1284 hlsl::ParseHLSLRootSignature(Actions, Version, *Signature);
1285 Actions.HLSL().SetRootSignatureOverride(DeclIdent);
1286 }
1287
1288 InjectRootSignatureCallback(Sema &Actions, StringRef RootSigName,
1289 llvm::dxbc::RootSignatureVersion Version)
1290 : PPCallbacks(), Actions(Actions), RootSigName(RootSigName),
1291 Version(Version) {}
1292};
1293
1295 // Pre-requisites to invoke
1297 if (!CI.hasASTContext() || !CI.hasPreprocessor())
1299
1300 // InjectRootSignatureCallback requires access to invoke Sema to lookup/
1301 // register a root signature declaration. The wrapped action is required to
1302 // account for this by only creating a Sema if one doesn't already exist
1303 // (like we have done, and, ASTFrontendAction::ExecuteAction)
1304 if (!CI.hasSema())
1306 /*CodeCompleteConsumer=*/nullptr);
1307 Sema &S = CI.getSema();
1308
1309 auto &TargetInfo = CI.getASTContext().getTargetInfo();
1310 bool IsRootSignatureTarget =
1311 TargetInfo.getTriple().getEnvironment() == llvm::Triple::RootSignature;
1312 StringRef HLSLEntry = TargetInfo.getTargetOpts().HLSLEntry;
1313
1314 // Register HLSL specific callbacks
1315 auto LangOpts = CI.getLangOpts();
1316 StringRef RootSigName =
1317 IsRootSignatureTarget ? HLSLEntry : LangOpts.HLSLRootSigOverride;
1318
1319 auto MacroCallback = std::make_unique<InjectRootSignatureCallback>(
1320 S, RootSigName, LangOpts.HLSLRootSigVer);
1321
1322 Preprocessor &PP = CI.getPreprocessor();
1323 PP.addPPCallbacks(std::move(MacroCallback));
1324
1325 // If we are targeting a root signature, invoke custom handling
1326 if (IsRootSignatureTarget)
1327 return hlsl::HandleRootSignatureTarget(S, HLSLEntry);
1328 else // otherwise, invoke as normal
1330}
1331
1333 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.
#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:654
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...
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:881
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:736
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:53
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.
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::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: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:669
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
static ModuleFileName makeExplicit(std::string Name)
Creates a file name for an explicit module.
Definition Module.h:116
Describes a module or submodule.
Definition Module.h:301
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition Module.h:632
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:455
ModuleKind Kind
The kind of this module.
Definition Module.h:346
std::string Name
The name of this module.
Definition Module.h:304
llvm::iterator_range< submodule_iterator > submodules()
Definition Module.h:1028
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
Definition Module.h:324
@ ModuleMapModule
This is a module that was defined by a module map and built out of header files.
Definition Module.h:315
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
Definition Module.h:342
@ ModulePartitionInterface
This is a C++20 module partition interface.
Definition Module.h:327
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
Definition Module.h:321
@ ModuleHeaderUnit
This is a C++20 header unit.
Definition Module.h:318
@ ModulePartitionImplementation
This is a C++20 module partition implementation.
Definition Module.h:330
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
Definition Module.h:337
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
Definition Module.h:334
llvm::SmallVector< ModuleRef, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition Module.h:619
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:1847
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:868
ASTContext & Context
Definition Sema.h:1308
const LangOptions & getLangOpts() const
Definition Sema.h:932
std::vector< std::unique_ptr< TemplateInstantiationCallback > > TemplateInstCallbacks
The template instantiation callbacks to trace or track instantiations (objects can be chained).
Definition Sema.h:13737
SourceManager & getSourceManager() const
Definition Sema.h:937
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:93
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:62
unsigned SuppressDefaultTemplateArgs
When true, attempt to suppress template arguments that match the default argument for the parameter.
static void mapping(IO &io, TemplightEntry &fields)