clang 24.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
42//===----------------------------------------------------------------------===//
43// Custom Actions
44//===----------------------------------------------------------------------===//
45
46std::unique_ptr<ASTConsumer>
47InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
48 return std::make_unique<ASTConsumer>();
49}
50
52}
53
54// Basically PreprocessOnlyAction::ExecuteAction.
56 Preprocessor &PP = getCompilerInstance().getPreprocessor();
57
58 // Ignore unknown pragmas.
59 PP.IgnorePragmas();
60
61 Token Tok;
62 // Start parsing the specified input file.
64 do {
65 PP.Lex(Tok);
66 } while (Tok.isNot(tok::eof));
67}
68
69std::unique_ptr<ASTConsumer>
70ReadPCHAndPreprocessAction::CreateASTConsumer(CompilerInstance &CI,
71 StringRef InFile) {
72 return std::make_unique<ASTConsumer>();
73}
74
75//===----------------------------------------------------------------------===//
76// AST Consumer Actions
77//===----------------------------------------------------------------------===//
78
79std::unique_ptr<ASTConsumer>
81 if (std::unique_ptr<raw_ostream> OS =
82 CI.createDefaultOutputFile(false, InFile))
83 return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter);
84 return nullptr;
85}
86
87std::unique_ptr<ASTConsumer>
89 const FrontendOptions &Opts = CI.getFrontendOpts();
90 return CreateASTDumper(nullptr /*Dump to stdout.*/, Opts.ASTDumpFilter,
91 Opts.ASTDumpDecls, Opts.ASTDumpAll,
93 Opts.ASTDumpFormat);
94}
95
96std::unique_ptr<ASTConsumer>
100
101std::unique_ptr<ASTConsumer>
103 return CreateASTViewer();
104}
105
106std::unique_ptr<ASTConsumer>
108 std::string Sysroot;
109 if (!ComputeASTConsumerArguments(CI, /*ref*/ Sysroot))
110 return nullptr;
111
112 std::string OutputFile;
113 std::unique_ptr<raw_pwrite_stream> OS =
114 CreateOutputFile(CI, InFile, /*ref*/ OutputFile, SetOnlyIfDifferent);
115 if (!OS)
116 return nullptr;
117
119 Sysroot.clear();
120
121 const auto &FrontendOpts = CI.getFrontendOpts();
122 auto Buffer = std::make_shared<PCHBuffer>();
123 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
124 Consumers.push_back(std::make_unique<PCHGenerator>(
125 CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
126 CI.getCodeGenOpts(), FrontendOpts.ModuleFileExtensions,
128 FrontendOpts.IncludeTimestamps, FrontendOpts.BuildingImplicitModule));
129 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
130 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
131
132 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
133}
134
136 std::string &Sysroot) {
137 Sysroot = CI.getHeaderSearchOpts().Sysroot;
138 if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
139 CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
140 return false;
141 }
142
143 return true;
144}
145
146std::unique_ptr<llvm::raw_pwrite_stream>
148 std::string &OutputFile,
149 bool SetOnlyIfDifferent) {
150 // Because this is exposed via libclang we must disable RemoveFileOnSignal.
151 std::unique_ptr<raw_pwrite_stream> OS = CI.createDefaultOutputFile(
152 /*Binary=*/true, InFile, /*Extension=*/"", /*RemoveFileOnSignal=*/false,
153 /*CreateMissingDirectories=*/false, /*ForceUseTemporary=*/false,
155 if (!OS)
156 return nullptr;
157
158 OutputFile = CI.getFrontendOpts().OutputFile;
159 return OS;
160}
161
163 if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)
164 return false;
166}
167
172
173std::vector<std::unique_ptr<ASTConsumer>>
175 StringRef InFile) {
176 if (!OS)
177 OS = CreateOutputFile(CI, InFile);
178 if (!OS)
179 return {};
180
181 std::string OutputFile = CI.getFrontendOpts().OutputFile;
182 std::string Sysroot;
183
184 auto Buffer = std::make_shared<PCHBuffer>();
185 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
186
187 Consumers.push_back(std::make_unique<PCHGenerator>(
188 CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
190 /*AllowASTWithErrors=*/
192 /*IncludeTimestamps=*/
195 /*BuildingImplicitModule=*/+CI.getFrontendOpts().BuildingImplicitModule));
196 Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
197 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
198 return Consumers;
199}
200
201std::unique_ptr<ASTConsumer>
203 StringRef InFile) {
204 std::vector<std::unique_ptr<ASTConsumer>> Consumers =
205 CreateMultiplexConsumer(CI, InFile);
206 if (Consumers.empty())
207 return nullptr;
208
209 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
210}
211
216
217bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(
218 CompilerInstance &CI) {
219 if (!CI.getLangOpts().Modules) {
220 CI.getDiagnostics().Report(diag::err_module_build_requires_fmodules);
221 return false;
222 }
223
225}
226
227std::unique_ptr<raw_pwrite_stream>
228GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
229 StringRef InFile) {
230 // If no output file was provided, figure out where this module would go
231 // in the module cache.
232 if (CI.getFrontendOpts().OutputFile.empty()) {
233 StringRef ModuleMapFile = CI.getFrontendOpts().OriginalModuleMap;
234 if (ModuleMapFile.empty())
235 ModuleMapFile = InFile;
236
238 ModuleFileName FileName = HS.getCachedModuleFileName(
239 CI.getLangOpts().CurrentModule, ModuleMapFile);
241 }
242
243 // Because this is exposed via libclang we must disable RemoveFileOnSignal.
244 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, /*Extension=*/"",
245 /*RemoveFileOnSignal=*/false,
246 /*CreateMissingDirectories=*/true,
247 /*ForceUseTemporary=*/true,
248 /*SetOnlyIfDifferent=*/SetOnlyIfDifferent);
249}
250
252 CompilerInstance &CI) {
253 for (const auto &FIF : CI.getFrontendOpts().Inputs) {
254 if (const auto InputFormat = FIF.getKind().getFormat();
255 InputFormat != InputKind::Format::Source) {
257 diag::err_frontend_action_unsupported_input_format)
258 << "module interface compilation" << FIF.getFile() << InputFormat;
259 return false;
260 }
261 }
263}
264
271
272std::unique_ptr<ASTConsumer>
274 StringRef InFile) {
275 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
276
278 !CI.getFrontendOpts().ModuleOutputPath.empty()) {
279 Consumers.push_back(std::make_unique<ReducedBMIGenerator>(
283 }
284
285 Consumers.push_back(std::make_unique<CXX20ModulesGenerator>(
289
290 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
291}
292
293std::unique_ptr<raw_pwrite_stream>
295 StringRef InFile) {
296 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
297}
298
299std::unique_ptr<ASTConsumer>
300GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
301 StringRef InFile) {
302 return std::make_unique<ReducedBMIGenerator>(
305}
306
307bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) {
308 if (!CI.getLangOpts().CPlusPlusModules) {
309 CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
310 return false;
311 }
312 CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderUnit);
314}
315
316std::unique_ptr<raw_pwrite_stream>
317GenerateHeaderUnitAction::CreateOutputFile(CompilerInstance &CI,
318 StringRef InFile) {
319 return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
320}
321
324
325std::unique_ptr<ASTConsumer>
327 return std::make_unique<ASTConsumer>();
328}
329
330std::unique_ptr<ASTConsumer>
332 StringRef InFile) {
333 return std::make_unique<ASTConsumer>();
334}
335
336std::unique_ptr<ASTConsumer>
338 return std::make_unique<ASTConsumer>();
339}
340
344 const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
345 std::unique_ptr<ASTReader> Reader(new ASTReader(
349 Sysroot.empty() ? "" : Sysroot.c_str(),
351 /*AllowASTWithCompilerErrors*/ false,
352 /*AllowConfigurationMismatch*/ true,
353 /*ValidateSystemInputs*/ true, /*ForceValidateUserInputs*/ true));
354
358}
359
360namespace {
361 /// AST reader listener that dumps module information for a module
362 /// file.
363 class DumpModuleInfoListener : public ASTReaderListener {
364 llvm::raw_ostream &Out;
366
367 public:
368 DumpModuleInfoListener(llvm::raw_ostream &Out, FileManager &FileMgr)
369 : Out(Out), FileMgr(FileMgr) {}
370
371#define DUMP_BOOLEAN(Value, Text) \
372 Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
373
374 bool ReadFullVersionInformation(StringRef FullVersion) override {
375 Out.indent(2)
376 << "Generated by "
377 << (FullVersion == getClangFullRepositoryVersion()? "this"
378 : "a different")
379 << " Clang: " << FullVersion << "\n";
381 }
382
383 void ReadModuleName(StringRef ModuleName) override {
384 Out.indent(2) << "Module name: " << ModuleName << "\n";
385 }
386 void ReadModuleMapFile(StringRef ModuleMapPath) override {
387 Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
388 }
389
390 bool ReadLanguageOptions(const LangOptions &LangOpts,
391 StringRef ModuleFilename, bool Complain,
392 bool AllowCompatibleDifferences) override {
393 // FIXME: Replace with C++20 `using enum LangOptions::CompatibilityKind`.
394 using CK = LangOptions::CompatibilityKind;
395
396 Out.indent(2) << "Language options:\n";
397#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
398 if constexpr (CK::Compatibility != CK::Benign) \
399 DUMP_BOOLEAN(LangOpts.Name, Description);
400#define ENUM_LANGOPT(Name, Type, Bits, Default, Compatibility, Description) \
401 if constexpr (CK::Compatibility != CK::Benign) \
402 Out.indent(4) << Description << ": " \
403 << static_cast<unsigned>(LangOpts.get##Name()) << "\n";
404#define VALUE_LANGOPT(Name, Bits, Default, Compatibility, Description) \
405 if constexpr (CK::Compatibility != CK::Benign) \
406 Out.indent(4) << Description << ": " << LangOpts.Name << "\n";
407#include "clang/Basic/LangOptions.def"
408
409 if (!LangOpts.ModuleFeatures.empty()) {
410 Out.indent(4) << "Module features:\n";
411 for (StringRef Feature : LangOpts.ModuleFeatures)
412 Out.indent(6) << Feature << "\n";
413 }
414
415 return false;
416 }
417
418 bool ReadTargetOptions(const TargetOptions &TargetOpts,
419 StringRef ModuleFilename, bool Complain,
420 bool AllowCompatibleDifferences) override {
421 Out.indent(2) << "Target options:\n";
422 Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n";
423 Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n";
424 Out.indent(4) << " TuneCPU: " << TargetOpts.TuneCPU << "\n";
425 Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n";
426
427 if (!TargetOpts.FeaturesAsWritten.empty()) {
428 Out.indent(4) << "Target features:\n";
429 for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size();
430 I != N; ++I) {
431 Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n";
432 }
433 }
434
435 return false;
436 }
437
438 bool ReadDiagnosticOptions(DiagnosticOptions &DiagOpts,
439 StringRef ModuleFilename,
440 bool Complain) override {
441 Out.indent(2) << "Diagnostic options:\n";
442#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts.Name, #Name);
443#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
444 Out.indent(4) << #Name << ": " \
445 << static_cast<unsigned>(DiagOpts.get##Name()) << "\n";
446#define VALUE_DIAGOPT(Name, Bits, Default) \
447 Out.indent(4) << #Name << ": " << DiagOpts.Name << "\n";
448#include "clang/Basic/DiagnosticOptions.def"
449
450 Out.indent(4) << "Diagnostic flags:\n";
451 for (const std::string &Warning : DiagOpts.Warnings)
452 Out.indent(6) << "-W" << Warning << "\n";
453 for (const std::string &Remark : DiagOpts.Remarks)
454 Out.indent(6) << "-R" << Remark << "\n";
455
456 return false;
457 }
458
459 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
460 StringRef ModuleFilename,
461 StringRef ContextHash,
462 bool Complain) override {
463 std::string SpecificModuleCachePath = createSpecificModuleCachePath(
464 FileMgr, HSOpts.ModuleCachePath, HSOpts.DisableModuleHash,
465 std::string(ContextHash));
466
467 Out.indent(2) << "Header search options:\n";
468 Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
469 Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
470 Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
472 "Use builtin include directories [-nobuiltininc]");
474 "Use standard system include directories [-nostdinc]");
476 "Use standard C++ include directories [-nostdinc++]");
477 DUMP_BOOLEAN(HSOpts.UseLibcxx,
478 "Use libc++ (rather than libstdc++) [-stdlib=]");
479 return false;
480 }
481
482 bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
483 bool Complain) override {
484 Out.indent(2) << "Header search paths:\n";
485 Out.indent(4) << "User entries:\n";
486 for (const auto &Entry : HSOpts.UserEntries)
487 Out.indent(6) << Entry.Path << "\n";
488 Out.indent(4) << "System header prefixes:\n";
489 for (const auto &Prefix : HSOpts.SystemHeaderPrefixes)
490 Out.indent(6) << Prefix.Prefix << "\n";
491 Out.indent(4) << "VFS overlay files:\n";
492 for (const auto &Overlay : HSOpts.VFSOverlayFiles)
493 Out.indent(6) << Overlay << "\n";
494 return false;
495 }
496
497 bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
498 StringRef ModuleFilename, bool ReadMacros,
499 bool Complain,
500 std::string &SuggestedPredefines) override {
501 Out.indent(2) << "Preprocessor options:\n";
503 "Uses compiler/target-specific predefines [-undef]");
505 "Uses detailed preprocessing record (for indexing)");
506
507 if (ReadMacros) {
508 Out.indent(4) << "Predefined macros:\n";
509 }
510
511 for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
512 I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
513 I != IEnd; ++I) {
514 Out.indent(6);
515 if (I->second)
516 Out << "-U";
517 else
518 Out << "-D";
519 Out << I->first << "\n";
520 }
521 return false;
522 }
523
524 /// Indicates that a particular module file extension has been read.
525 void readModuleFileExtension(
526 const ModuleFileExtensionMetadata &Metadata) override {
527 Out.indent(2) << "Module file extension '"
528 << Metadata.BlockName << "' " << Metadata.MajorVersion
529 << "." << Metadata.MinorVersion;
530 if (!Metadata.UserInfo.empty()) {
531 Out << ": ";
532 Out.write_escaped(Metadata.UserInfo);
533 }
534
535 Out << "\n";
536 }
537
538 /// Tells the \c ASTReaderListener that we want to receive the
539 /// input files of the AST file via \c visitInputFile.
540 bool needsInputFileVisitation() override { return true; }
541
542 /// Tells the \c ASTReaderListener that we want to receive the
543 /// input files of the AST file via \c visitInputFile.
544 bool needsSystemInputFileVisitation() override { return true; }
545
546 /// Indicates that the AST file contains particular input file.
547 ///
548 /// \returns true to continue receiving the next input file, false to stop.
549 bool visitInputFileAsRequested(StringRef FilenameAsRequested,
550 StringRef Filename, bool isSystem,
551 bool isOverridden, time_t StoredTime,
552 bool isExplicitModule) override {
553
554 Out.indent(2) << "Input file: " << FilenameAsRequested;
555
556 if (isSystem || isOverridden || isExplicitModule) {
557 Out << " [";
558 if (isSystem) {
559 Out << "System";
560 if (isOverridden || isExplicitModule)
561 Out << ", ";
562 }
563 if (isOverridden) {
564 Out << "Overridden";
565 if (isExplicitModule)
566 Out << ", ";
567 }
568 if (isExplicitModule)
569 Out << "ExplicitModule";
570
571 Out << "]";
572 }
573
574 Out << "\n";
575
576 if (StoredTime > 0)
577 Out.indent(4) << "MTime: " << llvm::itostr(StoredTime) << "\n";
578
579 return true;
580 }
581
582 /// Returns true if this \c ASTReaderListener wants to receive the
583 /// imports of the AST file via \c visitImport, false otherwise.
584 bool needsImportVisitation() const override { return true; }
585
586 /// If needsImportVisitation returns \c true, this is called for each
587 /// AST file imported by this AST file.
588 void visitImport(StringRef ModuleName, StringRef Filename) override {
589 Out.indent(2) << "Imports module '" << ModuleName
590 << "': " << Filename.str() << "\n";
591 }
592#undef DUMP_BOOLEAN
593 };
594}
595
597 // The Object file reader also supports raw ast files and there is no point in
598 // being strict about the module file format in -module-file-info mode.
600 return true;
601}
602
603static StringRef ModuleKindName(Module::ModuleKind MK) {
604 switch (MK) {
606 return "Module Map Module";
608 return "Interface Unit";
610 return "Implementation Unit";
612 return "Partition Interface";
614 return "Partition Implementation";
616 return "Header Unit";
618 return "Global Module Fragment";
620 return "Implicit Module Fragment";
622 return "Private Module Fragment";
623 }
624 llvm_unreachable("unknown module kind!");
625}
626
629
630 // Don't process files of type other than module to avoid crash
631 if (!isCurrentFileAST()) {
632 CI.getDiagnostics().Report(diag::err_file_is_not_module)
633 << getCurrentFile();
634 return;
635 }
636
637 // Set up the output file.
638 StringRef OutputFileName = CI.getFrontendOpts().OutputFile;
639 if (!OutputFileName.empty() && OutputFileName != "-") {
640 std::error_code EC;
641 OutputStream.reset(new llvm::raw_fd_ostream(
642 OutputFileName.str(), EC, llvm::sys::fs::OF_TextWithCRLF));
643 }
644 llvm::raw_ostream &Out = OutputStream ? *OutputStream : llvm::outs();
645
646 Out << "Information for module file '" << getCurrentFile() << "':\n";
647 auto &FileMgr = CI.getFileManager();
648 auto Buffer = FileMgr.getBufferForFile(getCurrentFile());
649 StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();
650 bool IsRaw = Magic.starts_with("CPCH");
651 Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n";
652
653 Preprocessor &PP = CI.getPreprocessor();
654 DumpModuleInfoListener Listener(Out, CI.getFileManager());
655 const HeaderSearchOptions &HSOpts =
656 PP.getHeaderSearchInfo().getHeaderSearchOpts();
657
658 // The FrontendAction::BeginSourceFile () method loads the AST so that much
659 // of the information is already available and modules should have been
660 // loaded.
661
663 if (LO.CPlusPlusModules && !LO.CurrentModule.empty()) {
665 unsigned SubModuleCount = R->getTotalNumSubmodules();
666 serialization::ModuleFile &MF = R->getModuleManager().getPrimaryModule();
667 Out << " ====== C++20 Module structure ======\n";
668
669 if (MF.ModuleName != LO.CurrentModule)
670 Out << " Mismatched module names : " << MF.ModuleName << " and "
671 << LO.CurrentModule << "\n";
672
673 struct SubModInfo {
674 unsigned Idx;
675 Module *Mod;
677 std::string &Name;
678 bool Seen;
679 };
680 std::map<std::string, SubModInfo> SubModMap;
681 auto PrintSubMapEntry = [&](std::string Name, Module::ModuleKind Kind) {
682 Out << " " << ModuleKindName(Kind) << " '" << Name << "'";
683 auto I = SubModMap.find(Name);
684 if (I == SubModMap.end())
685 Out << " was not found in the sub modules!\n";
686 else {
687 I->second.Seen = true;
688 Out << " is at index #" << I->second.Idx << "\n";
689 }
690 };
691 Module *Primary = nullptr;
692 for (unsigned Idx = 0; Idx <= SubModuleCount; ++Idx) {
693 Module *M = R->getModule(Idx);
694 if (!M)
695 continue;
696 if (M->Name == LO.CurrentModule) {
697 Primary = M;
698 Out << " " << ModuleKindName(M->Kind) << " '" << LO.CurrentModule
699 << "' is the Primary Module at index #" << Idx << "\n";
700 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, true}});
701 } else
702 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, false}});
703 }
704 if (Primary) {
705 if (!Primary->submodules().empty())
706 Out << " Sub Modules:\n";
707 for (Module *MI : Primary->submodules()) {
708 PrintSubMapEntry(MI->Name, MI->Kind);
709 }
710 if (!Primary->Imports.empty())
711 Out << " Imports:\n";
712 for (Module *IMP : Primary->Imports) {
713 PrintSubMapEntry(IMP->Name, IMP->Kind);
714 }
715 if (!Primary->Exports.empty())
716 Out << " Exports:\n";
717 for (unsigned MN = 0, N = Primary->Exports.size(); MN != N; ++MN) {
718 if (Module *M = Primary->Exports[MN].first) {
719 PrintSubMapEntry(M->Name, M->Kind);
720 }
721 }
722 }
723
724 // Emit the macro definitions in the module file so that we can know how
725 // much definitions in the module file quickly.
726 // TODO: Emit the macro definition bodies completely.
727 {
728 std::vector<StringRef> MacroNames;
729 for (const auto &M : R->getPreprocessor().macros()) {
730 if (M.first->isFromAST())
731 MacroNames.push_back(M.first->getName());
732 }
733 llvm::sort(MacroNames);
734 if (!MacroNames.empty())
735 Out << " Macro Definitions:\n";
736 for (StringRef Name : MacroNames)
737 Out << " " << Name << "\n";
738 }
739
740 // Now let's print out any modules we did not see as part of the Primary.
741 for (const auto &SM : SubModMap) {
742 if (!SM.second.Seen && SM.second.Mod) {
743 Out << " " << ModuleKindName(SM.second.Kind) << " '" << SM.first
744 << "' at index #" << SM.second.Idx
745 << " has no direct reference in the Primary\n";
746 }
747 }
748 Out << " ====== ======\n";
749 }
750
751 // The reminder of the output is produced from the listener as the AST
752 // FileCcontrolBlock is (re-)parsed.
756 /*FindModuleFileExtensions=*/true, Listener,
758}
759
760//===----------------------------------------------------------------------===//
761// Preprocessor Actions
762//===----------------------------------------------------------------------===//
763
767
768 // Start lexing the specified input file.
769 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
770 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
771 RawLex.SetKeepWhitespaceMode(true);
772
773 Token RawTok;
774 RawLex.LexFromRawLexer(RawTok);
775 while (RawTok.isNot(tok::eof)) {
776 PP.DumpToken(RawTok, true);
777 llvm::errs() << "\n";
778 RawLex.LexFromRawLexer(RawTok);
779 }
780}
781
784 // Start preprocessing the specified input file.
785 Token Tok;
787 do {
788 PP.Lex(Tok);
789 PP.DumpToken(Tok, true);
790 llvm::errs() << "\n";
791 } while (Tok.isNot(tok::eof));
792}
793
796
797 // Ignore unknown pragmas.
798 PP.IgnorePragmas();
799
800 Token Tok;
801 // Start parsing the specified input file.
803 do {
804 PP.Lex(Tok);
805 } while (Tok.isNot(tok::eof));
806}
807
810 // Output file may need to be set to 'Binary', to avoid converting Unix style
811 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>) on Windows.
812 //
813 // Look to see what type of line endings the file uses. If there's a
814 // CRLF, then we won't open the file up in binary mode. If there is
815 // just an LF or CR, then we will open the file up in binary mode.
816 // In this fashion, the output format should match the input format, unless
817 // the input format has inconsistent line endings.
818 //
819 // This should be a relatively fast operation since most files won't have
820 // all of their source code on a single line. However, that is still a
821 // concern, so if we scan for too long, we'll just assume the file should
822 // be opened in binary mode.
823
824 bool BinaryMode = false;
825 if (llvm::Triple(LLVM_HOST_TRIPLE).isOSWindows()) {
826 BinaryMode = true;
827 const SourceManager &SM = CI.getSourceManager();
828 if (std::optional<llvm::MemoryBufferRef> Buffer =
830 const char *cur = Buffer->getBufferStart();
831 const char *end = Buffer->getBufferEnd();
832 const char *next = (cur != end) ? cur + 1 : end;
833
834 // Limit ourselves to only scanning 256 characters into the source
835 // file. This is mostly a check in case the file has no
836 // newlines whatsoever.
837 if (end - cur > 256)
838 end = cur + 256;
839
840 while (next < end) {
841 if (*cur == 0x0D) { // CR
842 if (*next == 0x0A) // CRLF
843 BinaryMode = false;
844
845 break;
846 } else if (*cur == 0x0A) // LF
847 break;
848
849 ++cur;
850 ++next;
851 }
852 }
853 }
854
855 std::unique_ptr<raw_ostream> OS =
857 if (!OS) return;
858
859 // If we're preprocessing a module map, start by dumping the contents of the
860 // module itself before switching to the input buffer.
861 auto &Input = getCurrentInput();
862 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
863 if (Input.isFile()) {
864 (*OS) << "# 1 \"";
865 OS->write_escaped(Input.getFile());
866 (*OS) << "\"\n";
867 }
868 getCurrentModule()->print(*OS);
869 (*OS) << "#pragma clang module contents\n";
870 }
871
874}
875
877 switch (getCurrentFileKind().getLanguage()) {
878 case Language::C:
879 case Language::CXX:
880 case Language::ObjC:
881 case Language::ObjCXX:
882 case Language::OpenCL:
884 case Language::CUDA:
885 case Language::HIP:
886 case Language::HLSL:
887 case Language::CIR:
888 break;
889
891 case Language::Asm:
893 // We can't do anything with these.
894 return;
895 }
896
897 // We don't expect to find any #include directives in a preprocessed input.
898 if (getCurrentFileKind().isPreprocessed())
899 return;
900
902 auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
903 if (Buffer) {
904 unsigned Preamble =
905 Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).Size;
906 llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
907 }
908}
909
910static void writeCompilerOptionValues(raw_ostream &OS,
911 StringRef CompilerOptionNames,
912 ArrayRef<bool> CompilerOptionValues) {
913 bool FirstValue = true;
914 for (bool CompilerOptionValue : CompilerOptionValues) {
915 auto [CompilerOptionName, RemainingCompilerOptionNames] =
916 CompilerOptionNames.split('\0');
917 CompilerOptionNames = RemainingCompilerOptionNames;
918 if (!FirstValue)
919 OS << ",\n";
920 FirstValue = false;
921 OS << "\t{\"" << CompilerOptionName
922 << "\" : " << (CompilerOptionValue ? "true" : "false") << "}";
923 }
924 assert(CompilerOptionNames.empty() && "compiler option name count mismatch");
925}
926
928 CompilerInstance &CI = getCompilerInstance();
929 std::unique_ptr<raw_ostream> OSP =
931 if (!OSP)
932 return;
933
934 raw_ostream &OS = *OSP;
935 const Preprocessor &PP = CI.getPreprocessor();
936 const LangOptions &LangOpts = PP.getLangOpts();
937
938 // FIXME: Rather than manually format the JSON (which is awkward due to
939 // needing to remove trailing commas), this should make use of a JSON library.
940 // FIXME: Instead of printing enums as an integral value and specifying the
941 // type as a separate field, use introspection to print the enumerator.
942
943 OS << "{\n";
944 OS << "\n\"features\" : [\n";
945 {
946 static constexpr char FeatureNames[] = {
947#define FEATURE(Name, Predicate) #Name "\0"
948#include "clang/Basic/Features.def"
949 };
950 const bool FeatureValues[] = {
951#define FEATURE(Name, Predicate) static_cast<bool>(Predicate),
952#include "clang/Basic/Features.def"
953 };
955 OS, StringRef(FeatureNames, sizeof(FeatureNames) - 1), FeatureValues);
956 }
957 OS << "\n],\n";
958
959 OS << "\n\"extensions\" : [\n";
960 {
961 static constexpr char ExtensionNames[] = {
962#define EXTENSION(Name, Predicate) #Name "\0"
963#include "clang/Basic/Features.def"
964 };
965 const bool ExtensionValues[] = {
966#define EXTENSION(Name, Predicate) static_cast<bool>(Predicate),
967#include "clang/Basic/Features.def"
968 };
970 OS, StringRef(ExtensionNames, sizeof(ExtensionNames) - 1),
971 ExtensionValues);
972 }
973 OS << "\n]\n";
974
975 OS << "}";
976}
977
981 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());
982
986 FromFile.getBuffer(), Tokens, Directives, &CI.getDiagnostics(),
988 assert(CI.getDiagnostics().hasErrorOccurred() &&
989 "no errors reported for failure");
990
991 // Preprocess the source when verifying the diagnostics to capture the
992 // 'expected' comments.
993 if (CI.getDiagnosticOpts().VerifyDiagnostics) {
994 // Make sure we don't emit new diagnostics!
998 Token Tok;
999 do {
1000 PP.Lex(Tok);
1001 } while (Tok.isNot(tok::eof));
1002 }
1003 return;
1004 }
1005 printDependencyDirectivesAsSource(FromFile.getBuffer(), Directives,
1006 llvm::outs());
1007}
1008
1009//===----------------------------------------------------------------------===//
1010// HLSL Specific Actions
1011//===----------------------------------------------------------------------===//
1012
1014private:
1015 Sema &Actions;
1016 StringRef RootSigName;
1017 llvm::dxbc::RootSignatureVersion Version;
1018
1019 std::optional<StringLiteral *> processStringLiteral(ArrayRef<Token> Tokens) {
1020 for (Token Tok : Tokens)
1021 if (!tok::isStringLiteral(Tok.getKind()))
1022 return std::nullopt;
1023
1024 ExprResult StringResult = Actions.ActOnUnevaluatedStringLiteral(Tokens);
1025 if (StringResult.isInvalid())
1026 return std::nullopt;
1027
1028 if (auto Signature = dyn_cast<StringLiteral>(StringResult.get()))
1029 return Signature;
1030
1031 return std::nullopt;
1032 }
1033
1034public:
1035 void MacroDefined(const Token &MacroNameTok,
1036 const MacroDirective *MD) override {
1037 if (RootSigName != MacroNameTok.getIdentifierInfo()->getName())
1038 return;
1039
1040 const MacroInfo *MI = MD->getMacroInfo();
1041 auto Signature = processStringLiteral(MI->tokens());
1042 if (!Signature.has_value()) {
1043 Actions.getDiagnostics().Report(MI->getDefinitionLoc(),
1044 diag::err_expected_string_literal)
1045 << /*in attributes...*/ 4 << "RootSignature";
1046 return;
1047 }
1048
1049 IdentifierInfo *DeclIdent =
1050 hlsl::ParseHLSLRootSignature(Actions, Version, *Signature);
1051 Actions.HLSL().SetRootSignatureOverride(DeclIdent);
1052 }
1053
1054 InjectRootSignatureCallback(Sema &Actions, StringRef RootSigName,
1055 llvm::dxbc::RootSignatureVersion Version)
1056 : PPCallbacks(), Actions(Actions), RootSigName(RootSigName),
1057 Version(Version) {}
1058};
1059
1061 // Pre-requisites to invoke
1063 if (!CI.hasASTContext() || !CI.hasPreprocessor())
1065
1066 // InjectRootSignatureCallback requires access to invoke Sema to lookup/
1067 // register a root signature declaration. The wrapped action is required to
1068 // account for this by only creating a Sema if one doesn't already exist
1069 // (like we have done, and, ASTFrontendAction::ExecuteAction)
1070 if (!CI.hasSema())
1072 /*CodeCompleteConsumer=*/nullptr);
1073 Sema &S = CI.getSema();
1074
1075 auto &TargetInfo = CI.getASTContext().getTargetInfo();
1076 bool IsRootSignatureTarget =
1077 TargetInfo.getTriple().getEnvironment() == llvm::Triple::RootSignature;
1078 StringRef HLSLEntry = TargetInfo.getTargetOpts().HLSLEntry;
1079
1080 // Register HLSL specific callbacks
1081 auto LangOpts = CI.getLangOpts();
1082 StringRef RootSigName =
1083 IsRootSignatureTarget ? HLSLEntry : LangOpts.HLSLRootSigOverride;
1084
1085 auto MacroCallback = std::make_unique<InjectRootSignatureCallback>(
1086 S, RootSigName, LangOpts.HLSLRootSigVer);
1087
1088 Preprocessor &PP = CI.getPreprocessor();
1089 PP.addPPCallbacks(std::move(MacroCallback));
1090
1091 // If we are targeting a root signature, invoke custom handling
1092 if (IsRootSignatureTarget)
1093 return hlsl::HandleRootSignatureTarget(S, HLSLEntry);
1094 else // otherwise, invoke as normal
1096}
1097
1099 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.
Defines the clang::Preprocessor interface.
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 TargetInfo & getTargetInfo() const
Definition ASTContext.h:947
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.
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:1834
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:477
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
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()
const PCHContainerWriter & getPCHContainerWriter() const
Return the appropriate PCHContainerWriter depending on the current CodeGenOptions.
PreprocessorOptions & getPreprocessorOpts()
DiagnosticOptions & getDiagnosticOpts()
CodeGenOptions & getCodeGenOpts()
SourceManager & getSourceManager() const
Return the current source manager.
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
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:893
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:748
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:57
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,...
const FrontendInputFile & getCurrentInput() const
InputKind getCurrentFileKind() const
virtual bool BeginSourceFileAction(CompilerInstance &CI)
Callback at the start of processing a single input.
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 void ExecuteAction()=0
Callback to run the program action, using the initialized compiler instance.
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.
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:669
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 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:2280
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
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:863
Encodes a location in the source.
This class handles loading and caching of source files into memory.
FileID getMainFileID() const
Returns the FileID of the main source file.
llvm::MemoryBufferRef getBufferOrFake(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
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:226
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition TargetInfo.h:332
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.
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)
@ 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:101
Top level wrappers for InstallAPI frontend operations.
void printDependencyDirectivesAsSource(StringRef Source, ArrayRef< dependency_directives_scan::Directive > Directives, llvm::raw_ostream &OS)
Print the previously scanned dependency directives as minimized source text.
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.
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
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