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

1

2

3

4

5

6

7

8

37#include "llvm/ADT/ScopeExit.h"

38#include "llvm/Support/BuryPointer.h"

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

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

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

42#include "llvm/Support/Timer.h"

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

44#include

45#include <system_error>

46using namespace clang;

47

49

50namespace {

51

54 bool DeletePrevious;

55

56public:

57 explicit DelegatingDeserializationListener(

60 ~DelegatingDeserializationListener() override {

61 if (DeletePrevious)

63 }

64

65 DelegatingDeserializationListener(const DelegatingDeserializationListener &) =

66 delete;

67 DelegatingDeserializationListener &

68 operator=(const DelegatingDeserializationListener &) = delete;

69

71 if (Previous)

72 Previous->ReaderInitialized(Reader);

73 }

76 if (Previous)

77 Previous->IdentifierRead(ID, II);

78 }

80 if (Previous)

82 }

84 if (Previous)

86 }

88 if (Previous)

89 Previous->SelectorRead(ID, Sel);

90 }

93 if (Previous)

94 Previous->MacroDefinitionRead(PPID, MD);

95 }

96};

97

98

99class DeserializedDeclsDumper : public DelegatingDeserializationListener {

100public:

102 bool DeletePrevious)

103 : DelegatingDeserializationListener(Previous, DeletePrevious) {}

104

107 if (const NamedDecl *ND = dyn_cast(D)) {

108 llvm::outs() << " - ";

109 ND->printQualifiedName(llvm::outs());

110 }

111 llvm::outs() << "\n";

112

113 DelegatingDeserializationListener::DeclRead(ID, D);

114 }

115};

116

117

118

119class DeserializedDeclsChecker : public DelegatingDeserializationListener {

121 std::setstd::string NamesToCheck;

122

123public:

124 DeserializedDeclsChecker(ASTContext &Ctx,

125 const std::setstd::string &NamesToCheck,

127 bool DeletePrevious)

128 : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),

129 NamesToCheck(NamesToCheck) {}

130

132 if (const NamedDecl *ND = dyn_cast(D))

133 if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {

134 unsigned DiagID

136 "%0 was deserialized");

138 << ND;

139 }

140

141 DelegatingDeserializationListener::DeclRead(ID, D);

142 }

143};

144

145}

146

148

150

152 std::unique_ptr AST) {

153 this->CurrentInput = CurrentInput;

154 CurrentASTUnit = std::move(AST);

155}

156

161}

162

163std::unique_ptr

164FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,

165 StringRef InFile) {

166 std::unique_ptr Consumer = CreateASTConsumer(CI, InFile);

167 if (!Consumer)

168 return nullptr;

169

170

171 bool FoundAllPlugins = true;

173 bool Found = false;

174 for (const FrontendPluginRegistry::entry &Plugin :

175 FrontendPluginRegistry::entries()) {

176 if (Plugin.getName() == Arg)

178 }

181 FoundAllPlugins = false;

182 }

183 }

184 if (!FoundAllPlugins)

185 return nullptr;

186

187

188 if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())

189 return Consumer;

190

191

193 return Consumer;

194

195

196

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

198 std::vector<std::unique_ptr> AfterConsumers;

199 for (const FrontendPluginRegistry::entry &Plugin :

200 FrontendPluginRegistry::entries()) {

201 std::unique_ptr P = Plugin.instantiate();

205

206

208 Plugin.getName())) {

211 else

213 }

214 }

217 P->ParseArgs(

218 CI,

220 std::unique_ptr PluginConsumer = P->CreateASTConsumer(CI, InFile);

222 Consumers.push_back(std::move(PluginConsumer));

223 } else {

224 AfterConsumers.push_back(std::move(PluginConsumer));

225 }

226 }

227 }

228

229

230 Consumers.push_back(std::move(Consumer));

231 if (!AfterConsumers.empty()) {

232

233

234

236 for (auto &C : AfterConsumers)

237 Consumers.push_back(std::move(C));

238 }

239

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

241}

242

243

244

245

246

247

248

249

250

251

253 std::string &InputFile,

254 bool IsModuleMap = false) {

257

258 auto MainFileBuf = SourceMgr.getBufferOrNone(MainFileID);

259 if (!MainFileBuf)

261

262 std::unique_ptr RawLexer(

263 new Lexer(MainFileID, *MainFileBuf, SourceMgr, CI.getLangOpts()));

264

265

266

267

268

269

271 if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)

273 if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||

274 T.getKind() != tok::numeric_constant)

276

277 unsigned LineNo;

279 if (IsModuleMap) {

282 .getAsInteger(10, LineNo))

284 }

285

286 RawLexer->LexFromRawLexer(T);

287 if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)

289

291 if (Literal.hadError)

293 RawLexer->LexFromRawLexer(T);

294 if (T.isNot(tok::eof) && T.isAtStartOfLine())

296 InputFile = Literal.GetString().str();

297

298 if (IsModuleMap)

300 LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,

302

303 return T.getLocation();

304}

305

308 Includes.append(RHS.begin(), RHS.end());

309 return Includes;

310}

311

315 bool IsExternC) {

316 if (IsExternC && LangOpts.CPlusPlus)

317 Includes += "extern \"C\" {\n";

318 if (LangOpts.ObjC)

319 Includes += "#import \"";

320 else

321 Includes += "#include \"";

322

323 Includes += HeaderName;

324

325 Includes += "\"\n";

326 if (IsExternC && LangOpts.CPlusPlus)

327 Includes += "}\n";

328}

329

330

331

332

333

334

335

336

340

342 return std::error_code();

343

344

346

347

348

349

350

351

354 Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)

355 << MissingHeader.IsUmbrella << MissingHeader.FileName;

356 return std::error_code();

357 }

358

359

363

364

365

366

367 addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,

369 }

370 }

371

372

373 if (std::optionalModule::Header UmbrellaHeader =

377

378 addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,

380 } else if (std::optionalModule::DirectoryName UmbrellaDir =

382

383 std::error_code EC;

385 llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);

386

389 for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;

390 Dir != End && !EC; Dir.increment(EC)) {

391

392

393 if (!llvm::StringSwitch(llvm::sys::path::extension(Dir->path()))

394 .Cases(".h", ".H", ".hh", ".hpp", true)

395 .Default(false))

396 continue;

397

399

400

401 if (!Header)

402 continue;

403

404

405

407 continue;

408

409

411 auto PathIt = llvm::sys::path::rbegin(Dir->path());

412 for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)

413 Components.push_back(*PathIt);

415 UmbrellaDir->PathRelativeToRootModuleDirectory);

416 for (auto It = Components.rbegin(), End = Components.rend(); It != End;

417 ++It)

418 llvm::sys::path::append(RelativeHeader, *It);

419

420 std::string RelName = RelativeHeader.c_str();

421 Headers.push_back(std::make_pair(RelName, *Header));

422 }

423

424 if (EC)

425 return EC;

426

427

428

429 llvm::sort(Headers, llvm::less_first());

430 for (auto &H : Headers) {

431

434 }

435 }

436

437

440 LangOpts, FileMgr, Diag, ModMap, Submodule, Includes))

441 return Err;

442

443 return std::error_code();

444}

445

447 bool IsPreprocessed,

448 std::string &PresumedModuleMapFile,

449 unsigned &Offset) {

452

453

454 FileID ModuleMapID = SrcMgr.getMainFileID();

456 assert(ModuleMap && "MainFileID without FileEntry");

457

458

459

460 Offset = 0;

461 if (IsPreprocessed) {

464 if (EndOfLineMarker.isValid())

466 }

467

468

470 PresumedModuleMapFile))

471 return true;

472

473 if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset)

474 Offset = 0;

475

476

479 llvm::sys::path::append(InferredFrameworkPath,

481 if (auto Dir =

483 (void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr);

484 }

485

486 return false;

487}

488

490 StringRef ModuleMapFilename) {

493

494

495

496

497

498 return nullptr;

499 }

500

501

504 true);

505 if (!M) {

508

509 return nullptr;

510 }

511

512

515 return nullptr;

516

517

518

520

521

522

523

524

526 if (!OriginalModuleMapName.empty()) {

527 auto OriginalModuleMap =

529 true);

530 if (!OriginalModuleMap) {

532 << OriginalModuleMapName;

533 return nullptr;

534 }

537 auto FileCharacter =

540 *OriginalModuleMap, FileCharacter);

545 }

546 }

547

548

549

550

555 return M;

556}

557

558

559static std::unique_ptrllvm::MemoryBuffer

562

563

565 std::error_code Err = std::error_code();

566 if (std::optionalModule::Header UmbrellaHeader =

568 addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,

573 HeaderContents);

574

575 if (Err) {

578 return nullptr;

579 }

580

581 return llvm::MemoryBuffer::getMemBufferCopy(

583}

584

588 assert(!Instance && "Already processing a source file!");

589 assert(!Input.isEmpty() && "Unexpected empty filename!");

592

593 bool HasBegunSourceFile = false;

596

597

598

599 auto FailureCleanup = llvm::make_scope_exit([&]() {

600 if (HasBegunSourceFile)

607 });

608

610 return false;

611

612

613

614 if (ReplayASTFile) {

616

617

620 &Diags->getDiagnosticOptions()));

621 ASTDiags->setClient(Diags->getClient(), false);

622

623

624 StringRef InputFile = Input.getFile();

625

629 nullptr);

630 if (!AST)

631 return false;

632

633

634

638

639

640

644

645

646

647

648 if (auto ASTReader = AST->getASTReader()) {

651

653 if (&MF != &PrimaryModule)

655

658 std::string(FE.getName()));

659 });

660 }

661

662

663 auto Kind = AST->getInputKind();

666 AST->getPreprocessor().getHeaderSearchInfo().lookupModule(

668 false);

669 assert(ASTModule && "module file does not define its own module");

671 } else {

672 auto &OldSM = AST->getSourceManager();

673 FileID ID = OldSM.getMainFileID();

674 if (auto File = OldSM.getFileEntryRefForID(ID))

676 else

678 }

680 }

681

682

683

687 "This action does not have AST file support!");

688

690

691

692 StringRef InputFile = Input.getFile();

693

698

699 if (!AST)

700 return false;

701

702

704 HasBegunSourceFile = true;

705

706

707

715

717

718

720 return false;

721

722

723 CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));

725 return false;

726

727 FailureCleanup.release();

728 return true;

729 }

730

731

734 return false;

735 }

736 }

741 ->setSarifWriter(

742 std::make_unique(CI.getSourceManager()));

743 }

744 }

745

746

747

751 else

753 }

756

757

762 return false;

763 }

764

765

767 HasBegunSourceFile = true;

768

769

771 return false;

772

773

775 return false;

776

777 FailureCleanup.release();

778 return true;

779 }

780

781

782

789 std::error_code EC;

791 llvm::sys::path::native(PCHDir->getName(), DirNative);

792 bool Found = false;

794 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),

795 DirEnd;

796 Dir != DirEnd && !EC; Dir.increment(EC)) {

797

802 SpecificModuleCachePath, true)) {

805 break;

806 }

807 }

808

811 return false;

812 }

813 }

814 }

815

816

817

820

821

824 HasBegunSourceFile = true;

825

826

827

828

829

836 "trying to build a header unit without a Pre-processor?");

838

841 CWD.push_back({std::nullopt, *Dir});

846 nullptr, nullptr, CWD, nullptr, nullptr, nullptr,

847 nullptr, nullptr, nullptr);

848 if (!FE) {

851 return false;

852 }

853

855

858 }

859

860

864 }

865

867 return false;

868

871

872

873

874

877

878

882 }

883

884

885

888

889 std::string PresumedModuleMapFile;

890 unsigned OffsetToContents;

893 PresumedModuleMapFile, OffsetToContents))

894 return false;

895

897 if (!CurrentModule)

898 return false;

899

900 CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;

901

902 if (OffsetToContents)

903

905 else {

906

908 if (!Buffer)

909 return false;

910

911

914 auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);

915 assert(BufferID.isValid() && "couldn't create module buffer ID");

916 SourceMgr.setMainFileID(BufferID);

917 }

918 }

919

920

922 return false;

923

924

928 *File, false);

929 else

931 }

932

933

935

936

937

942

943

944

946

949

950

951

955

956 std::unique_ptr Consumer =

957 CreateWrappedASTConsumer(CI, PresumedInputFile);

958 if (!Consumer)

959 return false;

960

961

964

966

969 if (!source)

970 return false;

975

976 assert(hasPCHSupport() && "This action does not have PCH support!");

978 Consumer->GetASTDeserializationListener();

979 bool DeleteDeserialListener = false;

981 DeserialListener = new DeserializedDeclsDumper(DeserialListener,

982 DeleteDeserialListener);

983 DeleteDeserialListener = true;

984 }

986 DeserialListener = new DeserializedDeclsChecker(

989 DeserialListener, DeleteDeserialListener);

990 DeleteDeserialListener = true;

991 }

997 DeserialListener, DeleteDeserialListener);

999 return false;

1000 }

1001

1002

1003

1007 CI.getASTReader()->setDeserializationListener(DeserialListener,

1008 DeleteDeserialListener);

1009 }

1010 }

1011

1014 return false;

1015 }

1016

1017

1018

1024 } else {

1025

1026

1028 "modules enabled but created an external source that "

1029 "doesn't support modules");

1030 }

1031

1032

1036 return false;

1037

1040 diag::warn_eagerly_load_for_standard_cplusplus_modules);

1041 }

1042

1043

1044

1051 }

1052

1053

1057 if (auto *SemaSource = dyn_cast_if_present(

1062 } else

1064 }

1065

1066 FailureCleanup.release();

1067 return true;

1068}

1069

1073

1074

1075

1078 StringRef Cache =

1080 if (Cache.empty()) {

1083

1084

1085

1086 consumeError(std::move(Err));

1087 }

1088 }

1089 }

1090

1091 return llvm::Error::success();

1092}

1093

1096

1097

1099

1100

1103

1104

1106

1107

1108

1109

1111 if (DisableFree) {

1115 } else {

1119 }

1120

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

1128 }

1129

1130

1131

1133

1134

1135

1136

1138 if (DisableFree) {

1142 llvm::BuryPointer(std::move(CurrentASTUnit));

1143 } else {

1147 }

1148 }

1149

1153}

1154

1157}

1158

1159

1160

1161

1162

1166 return;

1167

1168

1169

1171

1172

1173

1177

1178

1182

1185

1188}

1189

1190void PluginASTAction::anchor() { }

1191

1192std::unique_ptr

1194 StringRef InFile) {

1195 llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");

1196}

1197

1199 return WrappedAction->PrepareToExecuteAction(CI);

1200}

1201std::unique_ptr

1203 StringRef InFile) {

1204 return WrappedAction->CreateASTConsumer(CI, InFile);

1205}

1208}

1212 auto Ret = WrappedAction->BeginSourceFileAction(CI);

1213

1215 return Ret;

1216}

1219}

1223}

1226}

1227

1230}

1233}

1236}

1239}

1242}

1244 return WrappedAction->hasCodeCompletionSupport();

1245}

1246

1248 std::unique_ptr WrappedAction)

1249 : WrappedAction(std::move(WrappedAction)) {}

Defines the clang::ASTContext interface.

Defines enum values for all the target-independent builtin functions.

Defines interfaces for clang::FileEntry and clang::FileEntryRef.

static std::error_code collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag, ModuleMap &ModMap, clang::Module *Module, SmallVectorImpl< char > &Includes)

Collect the set of header includes needed to construct the given module and update the TopHeaders fil...

static Module * prepareToBuildModule(CompilerInstance &CI, StringRef ModuleMapFilename)

static void addHeaderInclude(StringRef HeaderName, SmallVectorImpl< char > &Includes, const LangOptions &LangOpts, bool IsExternC)

static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem, bool IsPreprocessed, std::string &PresumedModuleMapFile, unsigned &Offset)

static SourceLocation ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile, bool IsModuleMap=false)

For preprocessed files, if the first line is the linemarker and specifies the original source file na...

static SmallVectorImpl< char > & operator+=(SmallVectorImpl< char > &Includes, StringRef RHS)

static std::unique_ptr< llvm::MemoryBuffer > getInputBufferForModule(CompilerInstance &CI, Module *M)

Compute the input buffer that should be used to build the specified module.

Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

Defines the clang::Preprocessor interface.

Defines clang::SarifDocumentWriter, clang::SarifRule, clang::SarifResult.

Defines utilities for dealing with stack allocation and stack space.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

FullSourceLoc getFullLoc(SourceLocation Loc) const

void setASTMutationListener(ASTMutationListener *Listener)

Attach an AST mutation listener to the AST context.

void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)

Attach an external AST source to the AST context.

DiagnosticsEngine & getDiagnostics() const

ExternalASTSource * getExternalSource() const

Retrieve a pointer to the external AST source associated with this AST context, if any.

virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD)

A macro definition was read from the AST file.

virtual void TypeRead(serialization::TypeIdx Idx, QualType T)

A type was deserialized from the AST file.

virtual void SelectorRead(serialization::SelectorID iD, Selector Sel)

A selector was read from the AST file.

virtual void ReaderInitialized(ASTReader *Reader)

The ASTReader was initialized.

virtual void DeclRead(GlobalDeclID ID, const Decl *D)

A decl was deserialized from the AST file.

virtual void IdentifierRead(serialization::IdentifierID ID, IdentifierInfo *II)

An identifier was deserialized from the AST file.

void ExecuteAction() override

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

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

void visitTopLevelModuleMaps(serialization::ModuleFile &MF, llvm::function_ref< void(FileEntryRef)> Visitor)

Visit all the top-level module maps loaded when building the given module file.

ModuleManager & getModuleManager()

Retrieve the module manager.

static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr, const InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, StringRef ExistingModuleCachePath, bool RequireStrictOptionMatches=false)

Determine whether the given AST file is acceptable to load into a translation unit with the given lan...

@ LoadPreprocessorOnly

Load options and the preprocessor state.

@ LoadEverything

Load everything, including Sema.

static std::unique_ptr< ASTUnit > LoadFromASTFile(StringRef Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, std::shared_ptr< HeaderSearchOptions > HSOpts, std::shared_ptr< LangOptions > LangOpts=nullptr, bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, bool AllowASTWithCompilerErrors=false, bool UserFilesAreVolatile=false, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=llvm::vfs::getRealFileSystem())

Create a ASTUnit from an AST file.

void initializeBuiltins(IdentifierTable &Table, const LangOptions &LangOpts)

Mark the identifiers for all the builtins with their appropriate builtin ID # and mark any non-portab...

Abstract interface for a consumer of code-completion information.

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

void setFileManager(FileManager *Value)

Replace the current file manager and virtual file system.

void setSourceManager(SourceManager *Value)

setSourceManager - Replace the current source manager.

void createPCHExternalASTSource(StringRef Path, DisableValidationForModuleKind DisableValidation, bool AllowPCHWithCompilerErrors, void *DeserializationListener, bool OwnDeserializationListener)

Create an external AST source to read a PCH file and attach it to the AST context.

DiagnosticConsumer & getDiagnosticClient() const

void createPreprocessor(TranslationUnitKind TUKind)

Create the preprocessor, using the invocation, file, and source managers, and replace any existing on...

void createSourceManager(FileManager &FileMgr)

Create the source manager and replace any existing one with it.

FileManager * createFileManager(IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)

Create the file manager and replace any existing one with it.

bool hasFileManager() const

const PCHContainerReader & getPCHContainerReader() const

Return the appropriate PCHContainerReader depending on the current CodeGenOptions.

DiagnosticsEngine & getDiagnostics() const

Get the current diagnostics engine.

FileSystemOptions & getFileSystemOpts()

bool InitializeSourceManager(const FrontendInputFile &Input)

InitializeSourceManager - Initialize the source manager to set InputFile as the main file.

FileManager & getFileManager() const

Return the current file manager to the caller.

void resetAndLeakSourceManager()

void setASTConsumer(std::unique_ptr< ASTConsumer > Value)

setASTConsumer - Replace the current AST consumer; the compiler instance takes ownership of Value.

IntrusiveRefCntPtr< ASTReader > getASTReader() const

std::shared_ptr< LangOptions > getLangOptsPtr() const

InMemoryModuleCache & getModuleCache() const

void createASTContext()

Create the AST context.

bool hasASTContext() const

void resetAndLeakFileManager()

std::shared_ptr< HeaderSearchOptions > getHeaderSearchOptsPtr() const

void setASTContext(ASTContext *Value)

setASTContext - Replace the current AST context.

Preprocessor & getPreprocessor() const

Return the current preprocessor.

ASTContext & getASTContext() const

TargetOptions & getTargetOpts()

void setASTReader(IntrusiveRefCntPtr< ASTReader > Reader)

FrontendOptions & getFrontendOpts()

void setSema(Sema *S)

Replace the current Sema; the compiler instance takes ownership of S.

HeaderSearchOptions & getHeaderSearchOpts()

bool hasCodeCompletionConsumer() const

void resetAndLeakASTContext()

void resetAndLeakPreprocessor()

std::unique_ptr< ASTConsumer > takeASTConsumer()

takeASTConsumer - Remove the current AST consumer and give ownership to the caller.

PreprocessorOptions & getPreprocessorOpts()

std::string getSpecificModuleCachePath(StringRef ModuleHash)

TargetInfo & getTarget() const

void createCodeCompletionConsumer()

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

void clearOutputFiles(bool EraseFiles)

clearOutputFiles - Clear the output file list.

DiagnosticOptions & getDiagnosticOpts()

LangOptions & getLangOpts()

CodeGenOptions & getCodeGenOpts()

SourceManager & getSourceManager() const

Return the current source manager.

CodeCompleteConsumer & getCodeCompletionConsumer() const

bool shouldBuildGlobalModuleIndex() const

Indicates whether we should (re)build the global module index.

bool hasSourceManager() const

bool hasASTConsumer() const

bool loadModuleFile(StringRef FileName, serialization::ModuleFile *&LoadedModuleFile)

bool hasPreprocessor() const

void setPreprocessor(std::shared_ptr< Preprocessor > Value)

Replace the current preprocessor.

void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)

Create the Sema object to be used for parsing.

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

SourceLocation getLocation() const

const char * getDeclKindName() const

virtual void EndSourceFile()

Callback to inform the diagnostic client that processing of a source file has ended.

virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP=nullptr)

Callback to inform the diagnostic client that processing of a source file is beginning.

Concrete class used by the front-end to report problems and issues.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

bool hasErrorOccurred() const

A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...

StringRef getName() const

The name of this FileEntry.

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

Implements support for file system lookup, file system caching, and directory search management.

llvm::vfs::FileSystem & getVirtualFileSystem() const

OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)

Get a FileEntryRef if it exists, without doing anything on error.

OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)

Get a DirectoryEntryRef if it exists, without doing anything on error.

const FrontendInputFile & getCurrentInput() const

virtual void EndSourceFile()

Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...

virtual bool shouldEraseOutputFiles()

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

virtual bool hasIRSupport() const

Does this action support use with IR files?

virtual void EndSourceFileAction()

Callback at the end of processing a single input.

virtual std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile)=0

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

CompilerInstance & getCompilerInstance() const

llvm::Error Execute()

Set the source manager's main input file, and run the action.

virtual bool hasASTFileSupport() const

Does this action support use with AST files?

Module * getCurrentModule() const

void setCurrentInput(const FrontendInputFile &CurrentInput, std::unique_ptr< ASTUnit > AST=nullptr)

virtual bool BeginSourceFileAction(CompilerInstance &CI)

Callback at the start of processing a single input.

virtual void ExecuteAction()=0

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

void setCompilerInstance(CompilerInstance *Value)

virtual TranslationUnitKind getTranslationUnitKind()

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

virtual ~FrontendAction()

bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)

Prepare the action for processing the input file Input.

virtual bool hasCodeCompletionSupport() const

Does this action support use with code completion?

StringRef getCurrentFileOrBufferName() const

virtual bool isModelParsingAction() const

Is this action invoked on a model file?

bool isCurrentFileAST() const

virtual bool usesPreprocessorOnly() const =0

Does this action only use the preprocessor?

friend class WrapperFrontendAction

virtual bool BeginInvocation(CompilerInstance &CI)

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

virtual bool hasPCHSupport() const

Does this action support use with PCH?

An input file for the front end.

bool isPreprocessed() const

InputKind getKind() const

StringRef getFile() const

std::vector< std::string > ModuleFiles

The list of additional prebuilt module files to load before processing the input.

unsigned SkipFunctionBodies

Skip over function bodies to speed up parsing in cases you do not need them (e.g.

std::map< std::string, std::vector< std::string > > PluginArgs

Args to pass to the plugins.

unsigned ShowStats

Show frontend performance metrics and statistics.

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::vector< std::string > ModulesEmbedFiles

The list of files to embed into the compiled module file.

unsigned ModulesEmbedAllFiles

Whether we should embed all used files into the PCM file.

std::vector< std::string > AddPluginActions

The list of plugin actions to run in addition to the normal action.

unsigned DisableFree

Disable memory freeing on exit.

std::string OverrideRecordLayoutsFile

File name of the file that will provide record layouts (in the format produced by -fdump-record-layou...

std::vector< std::string > ModuleMapFiles

The list of module map files to load before processing the input.

A SourceLocation and its associated SourceManager.

static llvm::Error writeIndex(FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, llvm::StringRef Path)

Write a global index into the given.

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

void PrintStats() const

Print some statistics to stderr that indicate how well the hashing is doing.

The kind of a file that we've been handed as an input.

bool isPreprocessed() const

InputKind withHeaderUnit(HeaderUnitKind HU) const

bool isHeaderUnit() const

HeaderUnitKind getHeaderUnitKind() const

Language getLanguage() const

@ CMK_None

Not compiling a module interface at all.

@ CMK_ModuleMap

Compiling a module from a module map.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

std::string ModuleName

The module currently being compiled as specified by -fmodule-name.

std::string CurrentModule

The name of the current module, of which the main source file is a part.

An external AST source that overrides the layout of a specified set of record types.

Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.

static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)

getSpelling - This method is used to get the spelling of a token into a preallocated buffer,...

Record the location of a macro definition.

void finishModuleDeclarationScope()

Creates a new declaration scope for module names, allowing previously defined modules to shadow defin...

bool canInferFrameworkModule(const DirectoryEntry *Dir) const

Check whether a framework module can be inferred in the given directory.

bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const

Determine whether the given header is unavailable as part of the specified module.

void resolveHeaderDirectives(const FileEntry *File) const

Resolve all lazy header directives for the specified file.

void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)

Describes a module or submodule.

SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders

Headers that are mentioned in the module map file but could not be found on the file system.

Module * Parent

The parent of this module.

unsigned IsSystem

Whether this is a "system" module (which assumes that all headers in it are system headers).

static StringRef getModuleInputBufferName()

llvm::iterator_range< submodule_iterator > submodules()

unsigned IsExternC

Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...

std::optional< Header > getUmbrellaHeaderAsWritten() const

Retrieve the umbrella header as written.

OptionalDirectoryEntryRef Directory

The build directory of this module.

std::string PresumedModuleMapFile

The presumed file name for the module map defining this module.

ArrayRef< Header > getHeaders(HeaderKind HK) const

bool isAvailable() const

Determine whether this module is available for use within the current translation unit.

std::optional< DirectoryName > getUmbrellaDirAsWritten() const

Retrieve the umbrella directory as written.

std::string getFullModuleName(bool AllowStringLiterals=false) const

Retrieve the full name of this module, including the path from its top-level module.

void addTopHeader(FileEntryRef File)

Add a top-level header associated with this module.

An abstract interface that should be implemented by external AST sources that also provide informatio...

This represents a decl that may have a name.

@ AddAfterMainAction

Execute the action after the main action.

@ AddBeforeMainAction

Execute the action before the main action.

@ CmdlineBeforeMainAction

Execute the action before the main action if on the command line.

@ CmdlineAfterMainAction

Execute the action after the main action if on the command line.

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

Provide a default implementation which returns aborts; this method should never be called by Frontend...

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

std::set< std::string > DeserializedPCHDeclsToErrorOn

This is a set of names for decls that we do not want to be deserialized, and we emit an error if they...

std::vector< std::string > ChainedIncludes

Headers that will be converted to chained PCHs in memory.

std::string ImplicitPCHInclude

The implicit PCH included at the start of the translation unit, or empty.

DisableValidationForModuleKind DisablePCHOrModuleValidation

Whether to disable most of the normal validation performed on precompiled headers and module files.

bool DumpDeserializedPCHDecls

Dump declarations that are deserialized from PCH, for testing.

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 setMainFileDir(DirectoryEntryRef Dir)

Set the directory in which the main file should be considered to have been found, if it is not a real...

static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)

Check that the given module is available, producing a diagnostic if not.

Module * getCurrentModuleImplementation()

Retrieves the module whose implementation we're current compiling, if any.

HeaderSearch & getHeaderSearchInfo() const

IdentifierTable & getIdentifierTable()

Builtin::Context & getBuiltinInfo()

void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine)

Instruct the preprocessor to skip part of the main source file.

const LangOptions & getLangOpts() const

void EndSourceFile()

Inform the preprocessor callbacks that processing is complete.

A (possibly-)qualified type.

Smart pointer class that efficiently represents Objective-C method names.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

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

void setAllFilesAreTransient(bool Transient)

Specify that all files that are read during this compilation are transient.

void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, bool IsFileEntry, bool IsFileExit, SrcMgr::CharacteristicKind FileKind)

Add a line note to the line table for the FileID and offset specified by Loc.

void setFileIsTransient(FileEntryRef SourceFile)

Specify that a file is transient.

OptionalFileEntryRef getFileEntryRefForID(FileID FID) const

Returns the FileEntryRef for the provided FileID.

FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)

Create a new FileID that represents the specified file being #included from the specified IncludePosi...

void PrintStats() const

Print statistics to stderr.

ModuleBuildStack getModuleBuildStack() const

Retrieve the module build stack.

FileID getMainFileID() const

Returns the FileID of the main source file.

void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc)

Push an entry to the module build stack.

void initializeForReplay(const SourceManager &Old)

Initialize this source manager suitably to replay the compilation described by Old.

FileID getOrCreateFileID(FileEntryRef SourceFile, SrcMgr::CharacteristicKind FileCharacter)

Get the FileID for SourceFile if it exists.

std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const

Decompose the specified location into a raw FileID + Offset pair.

StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...

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

bool BeginSourceFileAction(CompilerInstance &CI) override

Callback at the start of processing a single input.

bool hasIRSupport() const override

Does this action support use with IR files?

bool PrepareToExecuteAction(CompilerInstance &CI) override

Prepare to execute the action on the given CompilerInstance.

bool hasASTFileSupport() const override

Does this action support use with AST files?

bool usesPreprocessorOnly() const override

Does this action only use the preprocessor?

void ExecuteAction() override

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

bool hasCodeCompletionSupport() const override

Does this action support use with code completion?

bool shouldEraseOutputFiles() override

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

TranslationUnitKind getTranslationUnitKind() override

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

void EndSourceFileAction() override

Callback at the end of processing a single input.

bool BeginInvocation(CompilerInstance &CI) override

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

bool hasPCHSupport() const override

Does this action support use with PCH?

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

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

std::unique_ptr< FrontendAction > WrappedAction

void EndSourceFile() override

Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...

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

bool StandardCXXModule

Whether this module file is a standard C++ module.

ModuleFile & getPrimaryModule()

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

A type index; the type ID with the qualifier bits removed.

uint32_t SelectorID

An ID number that refers to an ObjC selector in an AST file.

uint32_t PreprocessedEntityID

An ID number that refers to an entity in the detailed preprocessing record.

uint64_t IdentifierID

An ID number that refers to an identifier in an AST file.

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

void ParseAST(Preprocessor &pp, ASTConsumer *C, ASTContext &Ctx, bool PrintStats=false, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr, bool SkipFunctionBodies=false)

Parse the entire file specified, notifying the ASTConsumer as the file is parsed.

void noteBottomOfStack()

Call this once on each thread, as soon after starting the thread as feasible, to note the approximate...

IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ExternalSemaSource > &Reader)

The ChainedIncludesSource class converts headers to chained PCHs in memory, mainly for testing.

llvm::Registry< PluginASTAction > FrontendPluginRegistry

The frontend plugin registry.

TranslationUnitKind

Describes the kind of translation unit being processed.

const FunctionProtoType * T