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