clang: lib/Frontend/FrontendActions.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

29#include "llvm/Config/llvm-config.h"

30#include "llvm/Support/ErrorHandling.h"

31#include "llvm/Support/FileSystem.h"

32#include "llvm/Support/MemoryBuffer.h"

33#include "llvm/Support/Path.h"

34#include "llvm/Support/YAMLTraits.h"

35#include "llvm/Support/raw_ostream.h"

36#include

37#include

38#include <system_error>

39

40using namespace clang;

41

42namespace {

45 : nullptr;

46}

47

52

55 GetCodeCompletionConsumer(CI));

56}

57}

58

59

60

61

62

63std::unique_ptr

64InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {

65 return std::make_unique();

66}

67

68void InitOnlyAction::ExecuteAction() {

69}

70

71

72void ReadPCHAndPreprocessAction::ExecuteAction() {

74

75

77

79

81 do {

82 PP.Lex(Tok);

83 } while (Tok.isNot(tok::eof));

84}

85

86std::unique_ptr

87ReadPCHAndPreprocessAction::CreateASTConsumer(CompilerInstance &CI,

88 StringRef InFile) {

89 return std::make_unique();

90}

91

92

93

94

95

96std::unique_ptr

98 if (std::unique_ptr<raw_ostream> OS =

101 return nullptr;

102}

103

104std::unique_ptr

111}

112

113std::unique_ptr

116}

117

118std::unique_ptr

121}

122

123std::unique_ptr

125 std::string Sysroot;

127 return nullptr;

128

129 std::string OutputFile;

130 std::unique_ptr<raw_pwrite_stream> OS =

132 if (!OS)

133 return nullptr;

134

136 Sysroot.clear();

137

139 auto Buffer = std::make_shared();

140 std::vector<std::unique_ptr> Consumers;

141 Consumers.push_back(std::make_unique(

143 FrontendOpts.ModuleFileExtensions,

145 FrontendOpts.IncludeTimestamps, FrontendOpts.BuildingImplicitModule,

148 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));

149

150 return std::make_unique(std::move(Consumers));

151}

152

154 std::string &Sysroot) {

158 return false;

159 }

160

161 return true;

162}

163

164std::unique_ptrllvm::raw\_pwrite\_stream

166 std::string &OutputFile) {

167

169 true, InFile, "", false);

170 if (!OS)

171 return nullptr;

172

174 return OS;

175}

176

178 if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)

179 return false;

181}

182

185 return true;

186}

187

188std::vector<std::unique_ptr>

190 StringRef InFile) {

191 std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile);

192 if (!OS)

193 return {};

194

196 std::string Sysroot;

197

198 auto Buffer = std::make_shared();

199 std::vector<std::unique_ptr> Consumers;

200

201 Consumers.push_back(std::make_unique(

204

206

210

213 CI, std::string(InFile), OutputFile, std::move(OS), Buffer));

214 return Consumers;

215}

216

217std::unique_ptr

219 StringRef InFile) {

220 std::vector<std::unique_ptr> Consumers =

222 if (Consumers.empty())

223 return nullptr;

224

225 return std::make_unique(std::move(Consumers));

226}

227

231}

232

233bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(

237 return false;

238 }

239

241}

242

243std::unique_ptr<raw_pwrite_stream>

244GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,

245 StringRef InFile) {

246

247

250 if (ModuleMapFile.empty())

251 ModuleMapFile = InFile;

252

256 ModuleMapFile);

257 }

258

259

261 false,

262 true,

263 true);

264}

265

269

271}

272

273std::unique_ptr

275 StringRef InFile) {

276 std::vector<std::unique_ptr> Consumers;

277

280 Consumers.push_back(std::make_unique(

284 }

285

286 Consumers.push_back(std::make_unique(

290

291 return std::make_unique(std::move(Consumers));

292}

293

294std::unique_ptr<raw_pwrite_stream>

296 StringRef InFile) {

298}

299

300std::unique_ptr

301GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,

302 StringRef InFile) {

303 return std::make_unique(CI.getPreprocessor(),

306}

307

308bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) {

309 if (!CI.getLangOpts().CPlusPlusModules) {

311 return false;

312 }

315}

316

317std::unique_ptr<raw_pwrite_stream>

318GenerateHeaderUnitAction::CreateOutputFile(CompilerInstance &CI,

319 StringRef InFile) {

321}

322

324}

325

326std::unique_ptr

328 return std::make_unique();

329}

330

331std::unique_ptr

333 StringRef InFile) {

334 return std::make_unique();

335}

336

337std::unique_ptr

339 return std::make_unique();

340}

341

346 std::unique_ptr Reader(new ASTReader(

349 Sysroot.empty() ? "" : Sysroot.c_str(),

351 false,

352 true,

353 true));

354

360}

361

362namespace {

363struct TemplightEntry {

364 std::string Name;

365 std::string Kind;

366 std::string Event;

367 std::string DefinitionLocation;

368 std::string PointOfInstantiation;

369};

370}

371

372namespace llvm {

373namespace yaml {

374template <> struct MappingTraits {

375 static void mapping(IO &io, TemplightEntry &fields) {

376 io.mapRequired("name", fields.Name);

377 io.mapRequired("kind", fields.Kind);

378 io.mapRequired("event", fields.Event);

379 io.mapRequired("orig", fields.DefinitionLocation);

380 io.mapRequired("poi", fields.PointOfInstantiation);

381 }

382};

383}

384}

385

386namespace {

389

390public:

392

394

396 const CodeSynthesisContext &Inst) override {

397 displayTemplightEntry(llvm::outs(), TheSema, Inst);

398 }

399

401 const CodeSynthesisContext &Inst) override {

402 displayTemplightEntry(llvm::outs(), TheSema, Inst);

403 }

404

405private:

406 static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {

407 switch (Kind) {

408 case CodeSynthesisContext::TemplateInstantiation:

409 return "TemplateInstantiation";

410 case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:

411 return "DefaultTemplateArgumentInstantiation";

412 case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:

413 return "DefaultFunctionArgumentInstantiation";

414 case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:

415 return "ExplicitTemplateArgumentSubstitution";

416 case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:

417 return "DeducedTemplateArgumentSubstitution";

418 case CodeSynthesisContext::LambdaExpressionSubstitution:

419 return "LambdaExpressionSubstitution";

420 case CodeSynthesisContext::PriorTemplateArgumentSubstitution:

421 return "PriorTemplateArgumentSubstitution";

422 case CodeSynthesisContext::DefaultTemplateArgumentChecking:

423 return "DefaultTemplateArgumentChecking";

424 case CodeSynthesisContext::ExceptionSpecEvaluation:

425 return "ExceptionSpecEvaluation";

426 case CodeSynthesisContext::ExceptionSpecInstantiation:

427 return "ExceptionSpecInstantiation";

428 case CodeSynthesisContext::DeclaringSpecialMember:

429 return "DeclaringSpecialMember";

430 case CodeSynthesisContext::DeclaringImplicitEqualityComparison:

431 return "DeclaringImplicitEqualityComparison";

432 case CodeSynthesisContext::DefiningSynthesizedFunction:

433 return "DefiningSynthesizedFunction";

434 case CodeSynthesisContext::RewritingOperatorAsSpaceship:

435 return "RewritingOperatorAsSpaceship";

436 case CodeSynthesisContext::Memoization:

437 return "Memoization";

438 case CodeSynthesisContext::ConstraintsCheck:

439 return "ConstraintsCheck";

440 case CodeSynthesisContext::ConstraintSubstitution:

441 return "ConstraintSubstitution";

442 case CodeSynthesisContext::ConstraintNormalization:

443 return "ConstraintNormalization";

444 case CodeSynthesisContext::RequirementParameterInstantiation:

445 return "RequirementParameterInstantiation";

446 case CodeSynthesisContext::ParameterMappingSubstitution:

447 return "ParameterMappingSubstitution";

448 case CodeSynthesisContext::RequirementInstantiation:

449 return "RequirementInstantiation";

450 case CodeSynthesisContext::NestedRequirementConstraintsCheck:

451 return "NestedRequirementConstraintsCheck";

452 case CodeSynthesisContext::InitializingStructuredBinding:

453 return "InitializingStructuredBinding";

454 case CodeSynthesisContext::MarkingClassDllexported:

455 return "MarkingClassDllexported";

456 case CodeSynthesisContext::BuildingBuiltinDumpStructCall:

457 return "BuildingBuiltinDumpStructCall";

458 case CodeSynthesisContext::BuildingDeductionGuides:

459 return "BuildingDeductionGuides";

460 case CodeSynthesisContext::TypeAliasTemplateInstantiation:

461 return "TypeAliasTemplateInstantiation";

462 }

463 return "";

464 }

465

466 template

467 static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema,

468 const CodeSynthesisContext &Inst) {

469 std::string YAML;

470 {

471 llvm::raw_string_ostream OS(YAML);

472 llvm::yaml::Output YO(OS);

473 TemplightEntry Entry =

474 getTemplightEntry(TheSema, Inst);

475 llvm::yaml::EmptyContext Context;

476 llvm::yaml::yamlize(YO, Entry, true, Context);

477 }

478 Out << "---" << YAML << "\n";

479 }

480

481 static void printEntryName(const Sema &TheSema, const Decl *Entity,

482 llvm::raw_string_ostream &OS) {

483 auto *NamedTemplate = cast(Entity);

484

486

488 NamedTemplate->getNameForDiagnostic(OS, Policy, true);

489

490 if (!OS.str().empty())

491 return;

492

494 NamedDecl *NamedCtx = dyn_cast_or_null(Ctx);

495

496 if (const auto *Decl = dyn_cast(NamedTemplate)) {

497 if (const auto *R = dyn_cast(Decl)) {

498 if (R->isLambda()) {

499 OS << "lambda at ";

501 return;

502 }

503 }

504 OS << "unnamed " << Decl->getKindName();

505 return;

506 }

507

508 assert(NamedCtx && "NamedCtx cannot be null");

509

510 if (const auto *Decl = dyn_cast(NamedTemplate)) {

511 OS << "unnamed function parameter " << Decl->getFunctionScopeIndex()

512 << " ";

513 if (Decl->getFunctionScopeDepth() > 0)

514 OS << "(at depth " << Decl->getFunctionScopeDepth() << ") ";

515 OS << "of ";

517 return;

518 }

519

520 if (const auto *Decl = dyn_cast(NamedTemplate)) {

521 if (const Type *Ty = Decl->getTypeForDecl()) {

522 if (const auto *TTPT = dyn_cast_or_null(Ty)) {

523 OS << "unnamed template type parameter " << TTPT->getIndex() << " ";

524 if (TTPT->getDepth() > 0)

525 OS << "(at depth " << TTPT->getDepth() << ") ";

526 OS << "of ";

528 return;

529 }

530 }

531 }

532

533 if (const auto *Decl = dyn_cast(NamedTemplate)) {

534 OS << "unnamed template non-type parameter " << Decl->getIndex() << " ";

535 if (Decl->getDepth() > 0)

536 OS << "(at depth " << Decl->getDepth() << ") ";

537 OS << "of ";

539 return;

540 }

541

542 if (const auto *Decl = dyn_cast(NamedTemplate)) {

543 OS << "unnamed template template parameter " << Decl->getIndex() << " ";

544 if (Decl->getDepth() > 0)

545 OS << "(at depth " << Decl->getDepth() << ") ";

546 OS << "of ";

548 return;

549 }

550

551 llvm_unreachable("Failed to retrieve a name for this entry!");

552 OS << "unnamed identifier";

553 }

554

555 template

556 static TemplightEntry getTemplightEntry(const Sema &TheSema,

557 const CodeSynthesisContext &Inst) {

558 TemplightEntry Entry;

559 Entry.Kind = toString(Inst.Kind);

560 Entry.Event = BeginInstantiation ? "Begin" : "End";

561 llvm::raw_string_ostream OS(Entry.Name);

562 printEntryName(TheSema, Inst.Entity, OS);

566 Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +

567 std::to_string(DefLoc.getLine()) + ":" +

568 std::to_string(DefLoc.getColumn());

572 Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +

573 std::to_string(PoiLoc.getLine()) + ":" +

574 std::to_string(PoiLoc.getColumn());

575 }

576 return Entry;

577 }

578};

579}

580

581std::unique_ptr

583 return std::make_unique();

584}

585

588

589

590

591

592

593 EnsureSemaIsCreated(CI, *this);

594

596 std::make_unique());

598}

599

600namespace {

601

602

604 llvm::raw_ostream &Out;

605

606 public:

607 DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { }

608

609#define DUMP_BOOLEAN(Value, Text) \

610 Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"

611

612 bool ReadFullVersionInformation(StringRef FullVersion) override {

613 Out.indent(2)

614 << "Generated by "

616 : "a different")

617 << " Clang: " << FullVersion << "\n";

619 }

620

621 void ReadModuleName(StringRef ModuleName) override {

622 Out.indent(2) << "Module name: " << ModuleName << "\n";

623 }

624 void ReadModuleMapFile(StringRef ModuleMapPath) override {

625 Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";

626 }

627

628 bool ReadLanguageOptions(const LangOptions &LangOpts,

629 StringRef ModuleFilename, bool Complain,

630 bool AllowCompatibleDifferences) override {

631 Out.indent(2) << "Language options:\n";

632#define LANGOPT(Name, Bits, Default, Description) \

633 DUMP_BOOLEAN(LangOpts.Name, Description);

634#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \

635 Out.indent(4) << Description << ": " \

636 << static_cast(LangOpts.get##Name()) << "\n";

637#define VALUE_LANGOPT(Name, Bits, Default, Description) \

638 Out.indent(4) << Description << ": " << LangOpts.Name << "\n";

639#define BENIGN_LANGOPT(Name, Bits, Default, Description)

640#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)

641#include "clang/Basic/LangOptions.def"

642

644 Out.indent(4) << "Module features:\n";

646 Out.indent(6) << Feature << "\n";

647 }

648

649 return false;

650 }

651

652 bool ReadTargetOptions(const TargetOptions &TargetOpts,

653 StringRef ModuleFilename, bool Complain,

654 bool AllowCompatibleDifferences) override {

655 Out.indent(2) << "Target options:\n";

656 Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n";

657 Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n";

658 Out.indent(4) << " TuneCPU: " << TargetOpts.TuneCPU << "\n";

659 Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n";

660

662 Out.indent(4) << "Target features:\n";

664 I != N; ++I) {

666 }

667 }

668

669 return false;

670 }

671

673 StringRef ModuleFilename,

674 bool Complain) override {

675 Out.indent(2) << "Diagnostic options:\n";

676#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);

677#define ENUM_DIAGOPT(Name, Type, Bits, Default) \

678 Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";

679#define VALUE_DIAGOPT(Name, Bits, Default) \

680 Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";

681#include "clang/Basic/DiagnosticOptions.def"

682

683 Out.indent(4) << "Diagnostic flags:\n";

684 for (const std::string &Warning : DiagOpts->Warnings)

685 Out.indent(6) << "-W" << Warning << "\n";

686 for (const std::string &Remark : DiagOpts->Remarks)

687 Out.indent(6) << "-R" << Remark << "\n";

688

689 return false;

690 }

691

693 StringRef ModuleFilename,

694 StringRef SpecificModuleCachePath,

695 bool Complain) override {

696 Out.indent(2) << "Header search options:\n";

697 Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";

698 Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";

699 Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";

701 "Use builtin include directories [-nobuiltininc]");

703 "Use standard system include directories [-nostdinc]");

705 "Use standard C++ include directories [-nostdinc++]");

707 "Use libc++ (rather than libstdc++) [-stdlib=]");

708 return false;

709 }

710

712 bool Complain) override {

713 Out.indent(2) << "Header search paths:\n";

714 Out.indent(4) << "User entries:\n";

715 for (const auto &Entry : HSOpts.UserEntries)

716 Out.indent(6) << Entry.Path << "\n";

717 Out.indent(4) << "System header prefixes:\n";

719 Out.indent(6) << Prefix.Prefix << "\n";

720 Out.indent(4) << "VFS overlay files:\n";

722 Out.indent(6) << Overlay << "\n";

723 return false;

724 }

725

727 StringRef ModuleFilename, bool ReadMacros,

728 bool Complain,

729 std::string &SuggestedPredefines) override {

730 Out.indent(2) << "Preprocessor options:\n";

732 "Uses compiler/target-specific predefines [-undef]");

734 "Uses detailed preprocessing record (for indexing)");

735

736 if (ReadMacros) {

737 Out.indent(4) << "Predefined macros:\n";

738 }

739

740 for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator

741 I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();

742 I != IEnd; ++I) {

743 Out.indent(6);

744 if (I->second)

745 Out << "-U";

746 else

747 Out << "-D";

748 Out << I->first << "\n";

749 }

750 return false;

751 }

752

753

754 void readModuleFileExtension(

756 Out.indent(2) << "Module file extension '"

759 if (!Metadata.UserInfo.empty()) {

760 Out << ": ";

761 Out.write_escaped(Metadata.UserInfo);

762 }

763

764 Out << "\n";

765 }

766

767

768

769 bool needsInputFileVisitation() override { return true; }

770

771

772

773 bool needsSystemInputFileVisitation() override { return true; }

774

775

776

777

778 bool visitInputFile(StringRef Filename, bool isSystem,

779 bool isOverridden, bool isExplicitModule) override {

780

781 Out.indent(2) << "Input file: " << Filename;

782

783 if (isSystem || isOverridden || isExplicitModule) {

784 Out << " [";

785 if (isSystem) {

786 Out << "System";

787 if (isOverridden || isExplicitModule)

788 Out << ", ";

789 }

790 if (isOverridden) {

791 Out << "Overridden";

792 if (isExplicitModule)

793 Out << ", ";

794 }

795 if (isExplicitModule)

796 Out << "ExplicitModule";

797

798 Out << "]";

799 }

800

801 Out << "\n";

802

803 return true;

804 }

805

806

807

808 bool needsImportVisitation() const override { return true; }

809

810

811

812 void visitImport(StringRef ModuleName, StringRef Filename) override {

813 Out.indent(2) << "Imports module '" << ModuleName

814 << "': " << Filename.str() << "\n";

815 }

816#undef DUMP_BOOLEAN

817 };

818}

819

821

822

824 return true;

825}

826

828 switch (MK) {

830 return "Module Map Module";

832 return "Interface Unit";

834 return "Implementation Unit";

836 return "Partition Interface";

838 return "Partition Implementation";

840 return "Header Unit";

842 return "Global Module Fragment";

844 return "Implicit Module Fragment";

846 return "Private Module Fragment";

847 }

848 llvm_unreachable("unknown module kind!");

849}

850

853

854

858 return;

859 }

860

861

863 if (!OutputFileName.empty() && OutputFileName != "-") {

864 std::error_code EC;

865 OutputStream.reset(new llvm::raw_fd_ostream(

866 OutputFileName.str(), EC, llvm::sys::fs::OF_TextWithCRLF));

867 }

868 llvm::raw_ostream &Out = OutputStream ? *OutputStream : llvm::outs();

869

870 Out << "Information for module file '" << getCurrentFile() << "':\n";

873 StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();

874 bool IsRaw = Magic.starts_with("CPCH");

875 Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n";

876

878 DumpModuleInfoListener Listener(Out);

879 HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();

880

881

882

883

884

886 if (LO.CPlusPlusModules && !LO.CurrentModule.empty()) {

890 Out << " ====== C++20 Module structure ======\n";

891

893 Out << " Mismatched module names : " << MF.ModuleName << " and "

895

896 struct SubModInfo {

897 unsigned Idx;

900 std::string &Name;

901 bool Seen;

902 };

903 std::map<std::string, SubModInfo> SubModMap;

904 auto PrintSubMapEntry = [&](std::string Name, Module::ModuleKind Kind) {

905 Out << " " << ModuleKindName(Kind) << " '" << Name << "'";

906 auto I = SubModMap.find(Name);

907 if (I == SubModMap.end())

908 Out << " was not found in the sub modules!\n";

909 else {

910 I->second.Seen = true;

911 Out << " is at index #" << I->second.Idx << "\n";

912 }

913 };

914 Module *Primary = nullptr;

915 for (unsigned Idx = 0; Idx <= SubModuleCount; ++Idx) {

917 if (!M)

918 continue;

920 Primary = M;

922 << "' is the Primary Module at index #" << Idx << "\n";

923 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, true}});

924 } else

925 SubModMap.insert({M->Name, {Idx, M, M->Kind, M->Name, false}});

926 }

927 if (Primary) {

929 Out << " Sub Modules:\n";

930 for (auto *MI : Primary->submodules()) {

931 PrintSubMapEntry(MI->Name, MI->Kind);

932 }

933 if (!Primary->Imports.empty())

934 Out << " Imports:\n";

935 for (auto *IMP : Primary->Imports) {

936 PrintSubMapEntry(IMP->Name, IMP->Kind);

937 }

938 if (!Primary->Exports.empty())

939 Out << " Exports:\n";

940 for (unsigned MN = 0, N = Primary->Exports.size(); MN != N; ++MN) {

941 if (Module *M = Primary->Exports[MN].getPointer()) {

942 PrintSubMapEntry(M->Name, M->Kind);

943 }

944 }

945 }

946

947

948

949

950 if (auto FilteredMacros = llvm::make_filter_range(

952 [](const auto &Macro) { return Macro.first->isFromAST(); });

953 !FilteredMacros.empty()) {

954 Out << " Macro Definitions:\n";

955 for ( const auto &Macro :

956 FilteredMacros)

957 Out << " " << Macro.first->getName() << "\n";

958 }

959

960

961 for (const auto &SM : SubModMap) {

962 if (SM.second.Seen && SM.second.Mod) {

964 << "' at index #" << SM.second.Idx

965 << " has no direct reference in the Primary\n";

966 }

967 }

968 Out << " ====== ======\n";

969 }

970

971

972

976 true, Listener,

978}

979

980

981

982

983

987

988

989 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());

992

995 while (RawTok.isNot(tok::eof)) {

997 llvm::errs() << "\n";

999 }

1000}

1001

1004

1007 do {

1008 PP.Lex(Tok);

1010 llvm::errs() << "\n";

1011 } while (Tok.isNot(tok::eof));

1012}

1013

1016

1017

1019

1021

1023 do {

1024 PP.Lex(Tok);

1025 } while (Tok.isNot(tok::eof));

1026}

1027

1030

1031

1032

1033

1034

1035

1036

1037

1038

1039

1040

1041

1042

1043

1044 bool BinaryMode = false;

1045 if (llvm::Triple(LLVM_HOST_TRIPLE).isOSWindows()) {

1046 BinaryMode = true;

1048 if (std::optionalllvm::MemoryBufferRef Buffer =

1049 SM.getBufferOrNone(SM.getMainFileID())) {

1050 const char *cur = Buffer->getBufferStart();

1051 const char *end = Buffer->getBufferEnd();

1052 const char *next = (cur != end) ? cur + 1 : end;

1053

1054

1055

1056

1057 if (end - cur > 256)

1058 end = cur + 256;

1059

1060 while (next < end) {

1061 if (*cur == 0x0D) {

1062 if (*next == 0x0A)

1063 BinaryMode = false;

1064

1065 break;

1066 } else if (*cur == 0x0A)

1067 break;

1068

1069 ++cur;

1070 ++next;

1071 }

1072 }

1073 }

1074

1075 std::unique_ptr<raw_ostream> OS =

1077 if (!OS) return;

1078

1079

1080

1083 if (Input.isFile()) {

1084 (*OS) << "# 1 \"";

1085 OS->write_escaped(Input.getFile());

1086 (*OS) << "\"\n";

1087 }

1089 (*OS) << "#pragma clang module contents\n";

1090 }

1091

1094}

1095

1108 break;

1109

1113

1114 return;

1115 }

1116

1117

1119 return;

1120

1123 if (Buffer) {

1126 llvm::outs().write((*Buffer)->getBufferStart(), Preamble);

1127 }

1128}

1129

1130void DumpCompilerOptionsAction::ExecuteAction() {

1132 std::unique_ptr<raw_ostream> OSP =

1134 if (!OSP)

1135 return;

1136

1137 raw_ostream &OS = *OSP;

1140

1141

1142

1143

1144

1145

1146 OS << "{\n";

1147 OS << "\n\"features\" : [\n";

1148 {

1150#define FEATURE(Name, Predicate) \

1151 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \

1152 .toVector(Str);

1153#include "clang/Basic/Features.def"

1154#undef FEATURE

1155

1156

1157 OS << Str.substr(0, Str.size() - 2);

1158 }

1159 OS << "\n],\n";

1160

1161 OS << "\n\"extensions\" : [\n";

1162 {

1164#define EXTENSION(Name, Predicate) \

1165 ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \

1166 .toVector(Str);

1167#include "clang/Basic/Features.def"

1168#undef EXTENSION

1169

1170

1171 OS << Str.substr(0, Str.size() - 2);

1172 }

1173 OS << "\n]\n";

1174

1175 OS << "}";

1176}

1177

1181 llvm::MemoryBufferRef FromFile = SM.getBufferOrFake(SM.getMainFileID());

1182

1186 FromFile.getBuffer(), Tokens, Directives, &CI.getDiagnostics(),

1187 SM.getLocForStartOfFile(SM.getMainFileID()))) {

1189 "no errors reported for failure");

1190

1191

1192

1194

1199 do {

1200 PP.Lex(Tok);

1201 } while (Tok.isNot(tok::eof));

1202 }

1203 return;

1204 }

1206 llvm::outs());

1207}

1208

1209void GetDependenciesByModuleNameAction::ExecuteAction() {

1213 FileID MainFileID = SM.getMainFileID();

1214 SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);

1217 Path.push_back(std::make_pair(ModuleID, FileStart));

1221}

enum clang::sema::@1725::IndirectLocalPathEntry::EntryKind Kind

This is the interface for scanning header and source files to get the minimum necessary preprocessor ...

Defines the clang::FileManager interface and associated types.

#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.

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

const clang::PrintingPolicy & getPrintingPolicy() const

std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override

Create the AST consumer object for this action, if supported.

std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override

Create the AST consumer object for this action, if supported.

void ExecuteAction() override

Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.

std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override

Create the AST consumer object for this action, if supported.

Abstract interface for callback invocations by the ASTReader.

virtual bool ReadFullVersionInformation(StringRef FullVersion)

Receives the full Clang version information.

Reads an AST files chain containing the contents of a translation unit.

ModuleManager & getModuleManager()

Retrieve the module manager.

@ ARR_ConfigurationMismatch

The client can handle an AST file that cannot load because it's compiled configuration doesn't match ...

unsigned getTotalNumSubmodules() const

Returns the number of submodules known.

Module * getModule(unsigned ID) override

Retrieve the module that corresponds to the given module ID.

static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, ASTReaderListener &Listener, bool ValidateDiagnosticOptions, unsigned ClientLoadCapabilities=ARR_ConfigurationMismatch|ARR_OutOfDate)

Read the control block for the named AST file.

Preprocessor & getPreprocessor() const

Retrieve the preprocessor.

const LangOptions & getLangOpts() const

IntrusiveRefCntPtr< ASTReader > getASTReader() const

std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override

Create the AST consumer object for this action, if supported.

Abstract interface for a consumer of code-completion information.

CompilerInstance - Helper class for managing a single instance of the Clang compiler.

const PCHContainerReader & getPCHContainerReader() const

Return the appropriate PCHContainerReader depending on the current CodeGenOptions.

DiagnosticsEngine & getDiagnostics() const

Get the current diagnostics engine.

std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="", bool RemoveFileOnSignal=true, bool CreateMissingDirectories=false, bool ForceUseTemporary=false)

Create the default output file (from the invocation's options) and add it to the list of tracked outp...

ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) override

Attempt to load the given module.

FileManager & getFileManager() const

Return the current file manager to the caller.

PreprocessorOutputOptions & getPreprocessorOutputOpts()

InMemoryModuleCache & getModuleCache() const

Preprocessor & getPreprocessor() const

Return the current preprocessor.

ASTContext & getASTContext() const

FrontendOptions & getFrontendOpts()

HeaderSearchOptions & getHeaderSearchOpts()

bool hasCodeCompletionConsumer() const

const PCHContainerWriter & getPCHContainerWriter() const

Return the appropriate PCHContainerWriter depending on the current CodeGenOptions.

PreprocessorOptions & getPreprocessorOpts()

void createCodeCompletionConsumer()

Create a code completion consumer using the invocation; note that this will cause the source manager ...

DiagnosticOptions & getDiagnosticOpts()

LangOptions & getLangOpts()

SourceManager & getSourceManager() const

Return the current source manager.

CodeCompleteConsumer & getCodeCompletionConsumer() const

void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)

Create the Sema object to be used for parsing.

Decl - This represents one declaration (or definition), e.g.

static Decl * castFromDeclContext(const DeclContext *)

SourceLocation getLocation() const

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

bool hasErrorOccurred() const

void setSuppressAllDiagnostics(bool Val)

Suppress all diagnostics, to silence the front end when we know that we don't want any more diagnosti...

std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override

Create the AST consumer object for this action, if supported.

void ExecuteAction() override

Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.

bool BeginInvocation(CompilerInstance &CI) override

Callback before starting processing a single input, giving the opportunity to modify the CompilerInvo...

void ExecuteAction() override

Callback to run the program action, using the initialized compiler instance.

void ExecuteAction() override

Callback to run the program action, using the initialized compiler instance.

An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...

llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(FileEntryRef Entry, bool isVolatile=false, bool RequiresNullTerminator=true, std::optional< int64_t > MaybeLimit=std::nullopt, bool IsText=true)

Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...

Abstract base class for actions which can be performed by the frontend.

const FrontendInputFile & getCurrentInput() const

InputKind getCurrentFileKind() const

virtual bool shouldEraseOutputFiles()

Callback at the end of processing a single input, to determine if the output files should be erased o...

ASTUnit & getCurrentASTUnit() const

CompilerInstance & getCompilerInstance() const

Module * getCurrentModule() const

StringRef getCurrentFile() const

virtual bool BeginSourceFileAction(CompilerInstance &CI)

Callback at the start of processing a single input.

virtual TranslationUnitKind getTranslationUnitKind()

For AST-based actions, the kind of translation unit we're handling.

virtual bool hasCodeCompletionSupport() const

Does this action support use with code completion?

StringRef getCurrentFileOrBufferName() const

bool isCurrentFileAST() const

FrontendOptions - Options for controlling the behavior of the frontend.

unsigned BuildingImplicitModule

Whether we are performing an implicit module build.

unsigned AllowPCMWithCompilerErrors

Output (and read) PCM files regardless of compiler errors.

unsigned IncludeTimestamps

Whether timestamps should be written to the produced PCH file.

std::string ASTDumpFilter

If given, filter dumped AST Decl nodes by this substring.

unsigned ASTDumpLookups

Whether we include lookup table dumps in AST dumps.

ASTDumpOutputFormat ASTDumpFormat

Specifies the output format of the AST.

std::string OutputFile

The output file, if any.

unsigned GenReducedBMI

Whether to generate reduced BMI for C++20 named modules.

std::vector< std::shared_ptr< ModuleFileExtension > > ModuleFileExtensions

The list of module file extensions.

ParsedSourceLocation CodeCompletionAt

If given, enable code completion at the provided location.

std::string OriginalModuleMap

When the input is a module map, the original module map file from which that map was inferred,...

std::string ModuleOutputPath

Output Path for module output file.

unsigned ASTDumpDeclTypes

Whether we include declaration type dumps in AST dumps.

unsigned ASTDumpAll

Whether we deserialize all decls when forming AST dumps.

unsigned RelocatablePCH

When generating PCH files, instruct the AST writer to create relocatable PCH files.

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.

std::unique_ptr< raw_pwrite_stream > CreateOutputFile(CompilerInstance &CI, StringRef InFile) override

std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override

Create the AST consumer object for this action, if supported.

static std::unique_ptr< llvm::raw_pwrite_stream > CreateOutputFile(CompilerInstance &CI, StringRef InFile, std::string &OutputFile)

Creates file to write the PCH into and returns a stream to write it into.

bool BeginSourceFileAction(CompilerInstance &CI) override

Callback at the start of processing a single input.

static bool ComputeASTConsumerArguments(CompilerInstance &CI, std::string &Sysroot)

Compute the AST consumer arguments that will be used to create the PCHGenerator instance returned by ...

std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override

Create the AST consumer object for this action, if supported.

bool shouldEraseOutputFiles() override

Callback at the end of processing a single input, to determine if the output files should be erased o...

One of these records is kept for each identifier that is lexed.

@ 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 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.

void SetKeepWhitespaceMode(bool Val)

SetKeepWhitespaceMode - This method lets clients enable or disable whitespace retention mode.

bool LexFromRawLexer(Token &Result)

LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...

static PreambleBounds ComputePreamble(StringRef Buffer, const LangOptions &LangOpts, unsigned MaxLines=0)

Compute the preamble of the given file.

Describes a module or submodule.

SmallVector< ExportDecl, 2 > Exports

The set of export declarations.

@ Hidden

All of the names in this module are hidden.

void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const

Print the module map for this module to the given stream.

ModuleKind Kind

The kind of this module.

llvm::SmallSetVector< Module *, 2 > Imports

The set of modules imported by this module, and on which this module depends.

std::string Name

The name of this module.

llvm::iterator_range< submodule_iterator > submodules()

@ ModuleImplementationUnit

This is a C++20 module implementation unit.

@ ModuleMapModule

This is a module that was defined by a module map and built out of header files.

@ ImplicitGlobalModuleFragment

This is an implicit fragment of the global module which contains only language linkage declarations (...

@ ModulePartitionInterface

This is a C++20 module partition interface.

@ ModuleInterfaceUnit

This is a C++20 module interface unit.

@ ModuleHeaderUnit

This is a C++20 header unit.

@ ModulePartitionImplementation

This is a C++20 module partition implementation.

@ PrivateModuleFragment

This is the private module fragment within some C++ module.

@ ExplicitGlobalModuleFragment

This is the explicit Global Module Fragment of a modular TU.

This represents a decl that may have a name.

virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const

Appends a human-readable name for this declaration into the given stream.

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.

virtual void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported)

Callback invoked whenever there was an explicit module-import syntax.

void ExecuteAction() override

Callback to run the program action, using the initialized compiler instance.

PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...

std::pair< unsigned, bool > PrecompiledPreambleBytes

If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...

bool DetailedRecord

Whether we should maintain a detailed record of all macro definitions and expansions.

bool UsePredefines

Initialize the preprocessor with the compiler and target specific predefines.

std::vector< std::pair< std::string, bool > > Macros

bool AllowPCHWithCompilerErrors

When true, a PCH with compiler errors will not be rejected.

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

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).

PPCallbacks * getPPCallbacks() const

void Lex(Token &Result)

Lex the next token for this preprocessor.

void EnterMainSourceFile()

Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc.

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

SourceManager & getSourceManager() const

llvm::iterator_range< macro_iterator > macros(bool IncludeExternalMacros=true) const

HeaderSearch & getHeaderSearchInfo() const

const LangOptions & getLangOpts() const

Represents an unpacked "presumed" location which can be presented to the user.

unsigned getColumn() const

Return the presumed column number of this location.

const char * getFilename() const

Return the presumed filename of this location.

unsigned getLine() const

Return the presumed line number of this location.

bool isInvalid() const

Return true if this object is invalid or uninitialized.

void ExecuteAction() override

Callback to run the program action, using the initialized compiler instance.

void ExecuteAction() override

Callback to run the program action, using the initialized compiler instance.

void ExecuteAction() override

Callback to run the program action, using the initialized compiler instance.

Sema - This implements semantic analysis and AST building for C.

const LangOptions & getLangOpts() const

std::vector< std::unique_ptr< TemplateInstantiationCallback > > TemplateInstCallbacks

The template instantiation callbacks to trace or track instantiations (objects can be chained).

SourceManager & getSourceManager() const

Encodes a location in the source.

void print(raw_ostream &OS, const SourceManager &SM) const

This class handles loading and caching of source files into memory.

PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const

Returns the "presumed" location of a SourceLocation specifies.

~SyntaxOnlyAction() override

std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override

Create the AST consumer object for this action, if supported.

Options for controlling the target.

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.

This is a base class for callbacks that will be notified at every template instantiation.

std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override

Create the AST consumer object for this action, if supported.

void ExecuteAction() override

Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.

Token - This structure provides full information about a lexed token.

bool isNot(tok::TokenKind K) const

The base class of the type hierarchy.

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.

Information about a module that has been loaded by the ASTReader.

std::string ModuleName

The name of the module.

ModuleFile & getPrimaryModule()

Returns the primary module associated with the manager, that is, the first module loaded.

Defines the clang::TargetInfo interface.

@ MK_PCH

File is a PCH file treated as such.

@ MK_Preamble

File is a PCH file treated as the preamble.

The JSON file list parser is used to communicate input to InstallAPI.

void atTemplateEnd(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema, const Sema::CodeSynthesisContext &Inst)

void atTemplateBegin(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema, const Sema::CodeSynthesisContext &Inst)

void printDependencyDirectivesAsSource(StringRef Source, ArrayRef< dependency_directives_scan::Directive > Directives, llvm::raw_ostream &OS)

Print the previously scanned dependency directives as minimized source text.

void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)

bool scanSourceForDependencyDirectives(StringRef Input, SmallVectorImpl< dependency_directives_scan::Token > &Tokens, SmallVectorImpl< dependency_directives_scan::Directive > &Directives, DiagnosticsEngine *Diags=nullptr, SourceLocation InputSourceLoc=SourceLocation())

Scan the input for the preprocessor directives that might have an effect on the dependencies for a co...

std::unique_ptr< ASTConsumer > CreateASTDeclNodeLister()

@ C

Languages that the frontend can parse and compile.

@ CIR

LLVM IR & CIR: we accept these so that we can run the optimizer on them, and compile them to assembly...

@ Asm

Assembly: we accept this only so that we can preprocess it.

void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)

DoPrintPreprocessedInput - Implement -E mode.

std::unique_ptr< ASTConsumer > CreateASTDumper(std::unique_ptr< raw_ostream > OS, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups, bool DumpDeclTypes, ASTDumpOutputFormat Format)

std::unique_ptr< ASTConsumer > CreateASTPrinter(std::unique_ptr< raw_ostream > OS, StringRef FilterString)

std::unique_ptr< ASTConsumer > CreateASTViewer()

@ None

Perform validation, don't disable it.

std::string getClangFullRepositoryVersion()

Retrieves the full repository version that is an amalgamation of the information in getClangRepositor...

void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)

Diagnostic wrappers for TextAPI types for error reporting.

unsigned Size

Size of the preamble in bytes.

Describes how types, statements, expressions, and declarations should be printed.

unsigned SuppressDefaultTemplateArgs

When true, attempt to suppress template arguments that match the default argument for the parameter.

A context in which code is being synthesized (where a source location alone is not sufficient to iden...

static void mapping(IO &io, TemplightEntry &fields)