1 //===--- FrontendAction.cpp -----------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "clang/Frontend/FrontendAction.h" 11 #include "clang/AST/ASTConsumer.h" 12 #include "clang/AST/ASTContext.h" 13 #include "clang/AST/DeclGroup.h" 14 #include "clang/Frontend/ASTUnit.h" 15 #include "clang/Frontend/CompilerInstance.h" 16 #include "clang/Frontend/FrontendDiagnostic.h" 17 #include "clang/Frontend/FrontendPluginRegistry.h" 18 #include "clang/Frontend/LayoutOverrideSource.h" 19 #include "clang/Frontend/MultiplexConsumer.h" 20 #include "clang/Frontend/Utils.h" 21 #include "clang/Lex/HeaderSearch.h" 22 #include "clang/Lex/LiteralSupport.h" 23 #include "clang/Lex/Preprocessor.h" 24 #include "clang/Lex/PreprocessorOptions.h" 25 #include "clang/Parse/ParseAST.h" 26 #include "clang/Serialization/ASTDeserializationListener.h" 27 #include "clang/Serialization/ASTReader.h" 28 #include "clang/Serialization/GlobalModuleIndex.h" 29 #include "llvm/Support/ErrorHandling.h" 30 #include "llvm/Support/FileSystem.h" 31 #include "llvm/Support/Path.h" 32 #include "llvm/Support/Timer.h" 33 #include "llvm/Support/raw_ostream.h" 34 #include <system_error> 35 using namespace clang; 36 37 LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry) 38 39 namespace { 40 41 class DelegatingDeserializationListener : public ASTDeserializationListener { 42 ASTDeserializationListener *Previous; 43 bool DeletePrevious; 44 45 public: 46 explicit DelegatingDeserializationListener( 47 ASTDeserializationListener *Previous, bool DeletePrevious) 48 : Previous(Previous), DeletePrevious(DeletePrevious) {} 49 ~DelegatingDeserializationListener() override { 50 if (DeletePrevious) 51 delete Previous; 52 } 53 54 void ReaderInitialized(ASTReader *Reader) override { 55 if (Previous) 56 Previous->ReaderInitialized(Reader); 57 } 58 void IdentifierRead(serialization::IdentID ID, 59 IdentifierInfo *II) override { 60 if (Previous) 61 Previous->IdentifierRead(ID, II); 62 } 63 void TypeRead(serialization::TypeIdx Idx, QualType T) override { 64 if (Previous) 65 Previous->TypeRead(Idx, T); 66 } 67 void DeclRead(serialization::DeclID ID, const Decl *D) override { 68 if (Previous) 69 Previous->DeclRead(ID, D); 70 } 71 void SelectorRead(serialization::SelectorID ID, Selector Sel) override { 72 if (Previous) 73 Previous->SelectorRead(ID, Sel); 74 } 75 void MacroDefinitionRead(serialization::PreprocessedEntityID PPID, 76 MacroDefinitionRecord *MD) override { 77 if (Previous) 78 Previous->MacroDefinitionRead(PPID, MD); 79 } 80 }; 81 82 /// \brief Dumps deserialized declarations. 83 class DeserializedDeclsDumper : public DelegatingDeserializationListener { 84 public: 85 explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous, 86 bool DeletePrevious) 87 : DelegatingDeserializationListener(Previous, DeletePrevious) {} 88 89 void DeclRead(serialization::DeclID ID, const Decl *D) override { 90 llvm::outs() << "PCH DECL: " << D->getDeclKindName(); 91 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 92 llvm::outs() << " - " << *ND; 93 llvm::outs() << "\n"; 94 95 DelegatingDeserializationListener::DeclRead(ID, D); 96 } 97 }; 98 99 /// \brief Checks deserialized declarations and emits error if a name 100 /// matches one given in command-line using -error-on-deserialized-decl. 101 class DeserializedDeclsChecker : public DelegatingDeserializationListener { 102 ASTContext &Ctx; 103 std::set<std::string> NamesToCheck; 104 105 public: 106 DeserializedDeclsChecker(ASTContext &Ctx, 107 const std::set<std::string> &NamesToCheck, 108 ASTDeserializationListener *Previous, 109 bool DeletePrevious) 110 : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx), 111 NamesToCheck(NamesToCheck) {} 112 113 void DeclRead(serialization::DeclID ID, const Decl *D) override { 114 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 115 if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { 116 unsigned DiagID 117 = Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, 118 "%0 was deserialized"); 119 Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID) 120 << ND->getNameAsString(); 121 } 122 123 DelegatingDeserializationListener::DeclRead(ID, D); 124 } 125 }; 126 127 } // end anonymous namespace 128 129 FrontendAction::FrontendAction() : Instance(nullptr) {} 130 131 FrontendAction::~FrontendAction() {} 132 133 void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput, 134 std::unique_ptr<ASTUnit> AST) { 135 this->CurrentInput = CurrentInput; 136 CurrentASTUnit = std::move(AST); 137 } 138 139 std::unique_ptr<ASTConsumer> 140 FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, 141 StringRef InFile) { 142 std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile); 143 if (!Consumer) 144 return nullptr; 145 146 // If there are no registered plugins we don't need to wrap the consumer 147 if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end()) 148 return Consumer; 149 150 // Collect the list of plugins that go before the main action (in Consumers) 151 // or after it (in AfterConsumers) 152 std::vector<std::unique_ptr<ASTConsumer>> Consumers; 153 std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers; 154 for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), 155 ie = FrontendPluginRegistry::end(); 156 it != ie; ++it) { 157 std::unique_ptr<PluginASTAction> P = it->instantiate(); 158 PluginASTAction::ActionType ActionType = P->getActionType(); 159 if (ActionType == PluginASTAction::Cmdline) { 160 // This is O(|plugins| * |add_plugins|), but since both numbers are 161 // way below 50 in practice, that's ok. 162 for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); 163 i != e; ++i) { 164 if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { 165 ActionType = PluginASTAction::AddAfterMainAction; 166 break; 167 } 168 } 169 } 170 if ((ActionType == PluginASTAction::AddBeforeMainAction || 171 ActionType == PluginASTAction::AddAfterMainAction) && 172 P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()])) { 173 std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile); 174 if (ActionType == PluginASTAction::AddBeforeMainAction) { 175 Consumers.push_back(std::move(PluginConsumer)); 176 } else { 177 AfterConsumers.push_back(std::move(PluginConsumer)); 178 } 179 } 180 } 181 182 // Add to Consumers the main consumer, then all the plugins that go after it 183 Consumers.push_back(std::move(Consumer)); 184 for (auto &C : AfterConsumers) { 185 Consumers.push_back(std::move(C)); 186 } 187 188 return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); 189 } 190 191 // For preprocessed files, if the first line is the linemarker and specifies 192 // the original source file name, use that name as the input file name. 193 static bool ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile) 194 { 195 bool Invalid = false; 196 auto &SourceMgr = CI.getSourceManager(); 197 auto MainFileID = SourceMgr.getMainFileID(); 198 const auto *MainFileBuf = SourceMgr.getBuffer(MainFileID, &Invalid); 199 if (Invalid) 200 return false; 201 202 std::unique_ptr<Lexer> RawLexer( 203 new Lexer(MainFileID, MainFileBuf, SourceMgr, CI.getLangOpts())); 204 205 // If the first line has the syntax of 206 // 207 // # NUM "FILENAME" 208 // 209 // we use FILENAME as the input file name. 210 Token T; 211 if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash) 212 return false; 213 if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() || 214 T.getKind() != tok::numeric_constant) 215 return false; 216 RawLexer->LexFromRawLexer(T); 217 if (T.isAtStartOfLine() || T.getKind() != tok::string_literal) 218 return false; 219 220 StringLiteralParser Literal(T, CI.getPreprocessor()); 221 if (Literal.hadError) 222 return false; 223 InputFile = Literal.GetString().str(); 224 return true; 225 } 226 227 bool FrontendAction::BeginSourceFile(CompilerInstance &CI, 228 const FrontendInputFile &Input) { 229 assert(!Instance && "Already processing a source file!"); 230 assert(!Input.isEmpty() && "Unexpected empty filename!"); 231 setCurrentInput(Input); 232 setCompilerInstance(&CI); 233 234 StringRef InputFile = Input.getFile(); 235 bool HasBegunSourceFile = false; 236 if (!BeginInvocation(CI)) 237 goto failure; 238 239 // AST files follow a very different path, since they share objects via the 240 // AST unit. 241 if (Input.getKind().getFormat() == InputKind::Precompiled) { 242 // FIXME: We should not be asserting on bad command-line arguments. 243 assert(!usesPreprocessorOnly() && 244 "Attempt to pass AST file to preprocessor only action!"); 245 assert(hasASTFileSupport() && 246 "This action does not have AST file support!"); 247 248 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); 249 250 std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( 251 InputFile, CI.getPCHContainerReader(), Diags, CI.getFileSystemOpts(), 252 CI.getCodeGenOpts().DebugTypeExtRefs); 253 254 if (!AST) 255 goto failure; 256 257 // Inform the diagnostic client we are processing a source file. 258 CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); 259 HasBegunSourceFile = true; 260 261 // Set the shared objects, these are reset when we finish processing the 262 // file, otherwise the CompilerInstance will happily destroy them. 263 CI.setFileManager(&AST->getFileManager()); 264 CI.setSourceManager(&AST->getSourceManager()); 265 CI.setPreprocessor(AST->getPreprocessorPtr()); 266 Preprocessor &PP = CI.getPreprocessor(); 267 PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), 268 PP.getLangOpts()); 269 CI.setASTContext(&AST->getASTContext()); 270 271 setCurrentInput(Input, std::move(AST)); 272 273 // Initialize the action. 274 if (!BeginSourceFileAction(CI, InputFile)) 275 goto failure; 276 277 // Create the AST consumer. 278 CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile)); 279 if (!CI.hasASTConsumer()) 280 goto failure; 281 282 return true; 283 } 284 285 if (!CI.hasVirtualFileSystem()) { 286 if (IntrusiveRefCntPtr<vfs::FileSystem> VFS = 287 createVFSFromCompilerInvocation(CI.getInvocation(), 288 CI.getDiagnostics())) 289 CI.setVirtualFileSystem(VFS); 290 else 291 goto failure; 292 } 293 294 // Set up the file and source managers, if needed. 295 if (!CI.hasFileManager()) 296 CI.createFileManager(); 297 if (!CI.hasSourceManager()) 298 CI.createSourceManager(CI.getFileManager()); 299 300 // IR files bypass the rest of initialization. 301 if (Input.getKind().getLanguage() == InputKind::LLVM_IR) { 302 assert(hasIRSupport() && 303 "This action does not have IR file support!"); 304 305 // Inform the diagnostic client we are processing a source file. 306 CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); 307 HasBegunSourceFile = true; 308 309 // Initialize the action. 310 if (!BeginSourceFileAction(CI, InputFile)) 311 goto failure; 312 313 // Initialize the main file entry. 314 if (!CI.InitializeSourceManager(CurrentInput)) 315 goto failure; 316 317 return true; 318 } 319 320 // If the implicit PCH include is actually a directory, rather than 321 // a single file, search for a suitable PCH file in that directory. 322 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 323 FileManager &FileMgr = CI.getFileManager(); 324 PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); 325 StringRef PCHInclude = PPOpts.ImplicitPCHInclude; 326 std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath(); 327 if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) { 328 std::error_code EC; 329 SmallString<128> DirNative; 330 llvm::sys::path::native(PCHDir->getName(), DirNative); 331 bool Found = false; 332 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); 333 for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; 334 Dir != DirEnd && !EC; Dir.increment(EC)) { 335 // Check whether this is an acceptable AST file. 336 if (ASTReader::isAcceptableASTFile( 337 Dir->getName(), FileMgr, CI.getPCHContainerReader(), 338 CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(), 339 SpecificModuleCachePath)) { 340 PPOpts.ImplicitPCHInclude = Dir->getName(); 341 Found = true; 342 break; 343 } 344 } 345 346 if (!Found) { 347 CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude; 348 goto failure; 349 } 350 } 351 } 352 353 // Set up the preprocessor if needed. When parsing model files the 354 // preprocessor of the original source is reused. 355 if (!isModelParsingAction()) 356 CI.createPreprocessor(getTranslationUnitKind()); 357 358 // Inform the diagnostic client we are processing a source file. 359 CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 360 &CI.getPreprocessor()); 361 HasBegunSourceFile = true; 362 363 // Initialize the action. 364 if (!BeginSourceFileAction(CI, InputFile)) 365 goto failure; 366 367 // Initialize the main file entry. It is important that this occurs after 368 // BeginSourceFileAction, which may change CurrentInput during module builds. 369 if (!CI.InitializeSourceManager(CurrentInput)) 370 goto failure; 371 372 // Create the AST context and consumer unless this is a preprocessor only 373 // action. 374 if (!usesPreprocessorOnly()) { 375 // Parsing a model file should reuse the existing ASTContext. 376 if (!isModelParsingAction()) 377 CI.createASTContext(); 378 379 // For preprocessed files, check if the first line specifies the original 380 // source file name with a linemarker. 381 std::string OrigFile; 382 if (Input.isPreprocessed()) 383 if (ReadOriginalFileName(CI, OrigFile)) 384 InputFile = OrigFile; 385 386 std::unique_ptr<ASTConsumer> Consumer = 387 CreateWrappedASTConsumer(CI, InputFile); 388 if (!Consumer) 389 goto failure; 390 391 // FIXME: should not overwrite ASTMutationListener when parsing model files? 392 if (!isModelParsingAction()) 393 CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); 394 395 if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { 396 // Convert headers to PCH and chain them. 397 IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader; 398 source = createChainedIncludesSource(CI, FinalReader); 399 if (!source) 400 goto failure; 401 CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get())); 402 CI.getASTContext().setExternalSource(source); 403 } else if (CI.getLangOpts().Modules || 404 !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 405 // Use PCM or PCH. 406 assert(hasPCHSupport() && "This action does not have PCH support!"); 407 ASTDeserializationListener *DeserialListener = 408 Consumer->GetASTDeserializationListener(); 409 bool DeleteDeserialListener = false; 410 if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) { 411 DeserialListener = new DeserializedDeclsDumper(DeserialListener, 412 DeleteDeserialListener); 413 DeleteDeserialListener = true; 414 } 415 if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) { 416 DeserialListener = new DeserializedDeclsChecker( 417 CI.getASTContext(), 418 CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, 419 DeserialListener, DeleteDeserialListener); 420 DeleteDeserialListener = true; 421 } 422 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 423 CI.createPCHExternalASTSource( 424 CI.getPreprocessorOpts().ImplicitPCHInclude, 425 CI.getPreprocessorOpts().DisablePCHValidation, 426 CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener, 427 DeleteDeserialListener); 428 if (!CI.getASTContext().getExternalSource()) 429 goto failure; 430 } 431 // If modules are enabled, create the module manager before creating 432 // any builtins, so that all declarations know that they might be 433 // extended by an external source. 434 if (CI.getLangOpts().Modules || !CI.hasASTContext() || 435 !CI.getASTContext().getExternalSource()) { 436 CI.createModuleManager(); 437 CI.getModuleManager()->setDeserializationListener(DeserialListener, 438 DeleteDeserialListener); 439 } 440 } 441 442 CI.setASTConsumer(std::move(Consumer)); 443 if (!CI.hasASTConsumer()) 444 goto failure; 445 } 446 447 // Initialize built-in info as long as we aren't using an external AST 448 // source. 449 if (CI.getLangOpts().Modules || !CI.hasASTContext() || 450 !CI.getASTContext().getExternalSource()) { 451 Preprocessor &PP = CI.getPreprocessor(); 452 PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), 453 PP.getLangOpts()); 454 } else { 455 // FIXME: If this is a problem, recover from it by creating a multiplex 456 // source. 457 assert((!CI.getLangOpts().Modules || CI.getModuleManager()) && 458 "modules enabled but created an external source that " 459 "doesn't support modules"); 460 } 461 462 // If we were asked to load any module map files, do so now. 463 for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) { 464 if (auto *File = CI.getFileManager().getFile(Filename)) 465 CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile( 466 File, /*IsSystem*/false); 467 else 468 CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename; 469 } 470 471 // If we were asked to load any module files, do so now. 472 for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) 473 if (!CI.loadModuleFile(ModuleFile)) 474 goto failure; 475 476 // If there is a layout overrides file, attach an external AST source that 477 // provides the layouts from that file. 478 if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 479 CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { 480 IntrusiveRefCntPtr<ExternalASTSource> 481 Override(new LayoutOverrideSource( 482 CI.getFrontendOpts().OverrideRecordLayoutsFile)); 483 CI.getASTContext().setExternalSource(Override); 484 } 485 486 return true; 487 488 // If we failed, reset state since the client will not end up calling the 489 // matching EndSourceFile(). 490 failure: 491 if (isCurrentFileAST()) { 492 CI.setASTContext(nullptr); 493 CI.setPreprocessor(nullptr); 494 CI.setSourceManager(nullptr); 495 CI.setFileManager(nullptr); 496 } 497 498 if (HasBegunSourceFile) 499 CI.getDiagnosticClient().EndSourceFile(); 500 CI.clearOutputFiles(/*EraseFiles=*/true); 501 setCurrentInput(FrontendInputFile()); 502 setCompilerInstance(nullptr); 503 return false; 504 } 505 506 bool FrontendAction::Execute() { 507 CompilerInstance &CI = getCompilerInstance(); 508 509 if (CI.hasFrontendTimer()) { 510 llvm::TimeRegion Timer(CI.getFrontendTimer()); 511 ExecuteAction(); 512 } 513 else ExecuteAction(); 514 515 // If we are supposed to rebuild the global module index, do so now unless 516 // there were any module-build failures. 517 if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() && 518 CI.hasPreprocessor()) { 519 StringRef Cache = 520 CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath(); 521 if (!Cache.empty()) 522 GlobalModuleIndex::writeIndex(CI.getFileManager(), 523 CI.getPCHContainerReader(), Cache); 524 } 525 526 return true; 527 } 528 529 void FrontendAction::EndSourceFile() { 530 CompilerInstance &CI = getCompilerInstance(); 531 532 // Inform the diagnostic client we are done with this source file. 533 CI.getDiagnosticClient().EndSourceFile(); 534 535 // Inform the preprocessor we are done. 536 if (CI.hasPreprocessor()) 537 CI.getPreprocessor().EndSourceFile(); 538 539 // Finalize the action. 540 EndSourceFileAction(); 541 542 // Sema references the ast consumer, so reset sema first. 543 // 544 // FIXME: There is more per-file stuff we could just drop here? 545 bool DisableFree = CI.getFrontendOpts().DisableFree; 546 if (DisableFree) { 547 CI.resetAndLeakSema(); 548 CI.resetAndLeakASTContext(); 549 BuryPointer(CI.takeASTConsumer().get()); 550 } else { 551 CI.setSema(nullptr); 552 CI.setASTContext(nullptr); 553 CI.setASTConsumer(nullptr); 554 } 555 556 if (CI.getFrontendOpts().ShowStats) { 557 llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n"; 558 CI.getPreprocessor().PrintStats(); 559 CI.getPreprocessor().getIdentifierTable().PrintStats(); 560 CI.getPreprocessor().getHeaderSearchInfo().PrintStats(); 561 CI.getSourceManager().PrintStats(); 562 llvm::errs() << "\n"; 563 } 564 565 // Cleanup the output streams, and erase the output files if instructed by the 566 // FrontendAction. 567 CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles()); 568 569 if (isCurrentFileAST()) { 570 if (DisableFree) { 571 CI.resetAndLeakPreprocessor(); 572 CI.resetAndLeakSourceManager(); 573 CI.resetAndLeakFileManager(); 574 } else { 575 CI.setPreprocessor(nullptr); 576 CI.setSourceManager(nullptr); 577 CI.setFileManager(nullptr); 578 } 579 } 580 581 setCompilerInstance(nullptr); 582 setCurrentInput(FrontendInputFile()); 583 } 584 585 bool FrontendAction::shouldEraseOutputFiles() { 586 return getCompilerInstance().getDiagnostics().hasErrorOccurred(); 587 } 588 589 //===----------------------------------------------------------------------===// 590 // Utility Actions 591 //===----------------------------------------------------------------------===// 592 593 void ASTFrontendAction::ExecuteAction() { 594 CompilerInstance &CI = getCompilerInstance(); 595 if (!CI.hasPreprocessor()) 596 return; 597 598 // FIXME: Move the truncation aspect of this into Sema, we delayed this till 599 // here so the source manager would be initialized. 600 if (hasCodeCompletionSupport() && 601 !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) 602 CI.createCodeCompletionConsumer(); 603 604 // Use a code completion consumer? 605 CodeCompleteConsumer *CompletionConsumer = nullptr; 606 if (CI.hasCodeCompletionConsumer()) 607 CompletionConsumer = &CI.getCodeCompletionConsumer(); 608 609 if (!CI.hasSema()) 610 CI.createSema(getTranslationUnitKind(), CompletionConsumer); 611 612 ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats, 613 CI.getFrontendOpts().SkipFunctionBodies); 614 } 615 616 void PluginASTAction::anchor() { } 617 618 std::unique_ptr<ASTConsumer> 619 PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI, 620 StringRef InFile) { 621 llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!"); 622 } 623 624 std::unique_ptr<ASTConsumer> 625 WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI, 626 StringRef InFile) { 627 return WrappedAction->CreateASTConsumer(CI, InFile); 628 } 629 bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) { 630 return WrappedAction->BeginInvocation(CI); 631 } 632 bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI, 633 StringRef Filename) { 634 WrappedAction->setCurrentInput(getCurrentInput()); 635 WrappedAction->setCompilerInstance(&CI); 636 auto Ret = WrappedAction->BeginSourceFileAction(CI, Filename); 637 // BeginSourceFileAction may change CurrentInput, e.g. during module builds. 638 setCurrentInput(WrappedAction->getCurrentInput()); 639 return Ret; 640 } 641 void WrapperFrontendAction::ExecuteAction() { 642 WrappedAction->ExecuteAction(); 643 } 644 void WrapperFrontendAction::EndSourceFileAction() { 645 WrappedAction->EndSourceFileAction(); 646 } 647 648 bool WrapperFrontendAction::usesPreprocessorOnly() const { 649 return WrappedAction->usesPreprocessorOnly(); 650 } 651 TranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() { 652 return WrappedAction->getTranslationUnitKind(); 653 } 654 bool WrapperFrontendAction::hasPCHSupport() const { 655 return WrappedAction->hasPCHSupport(); 656 } 657 bool WrapperFrontendAction::hasASTFileSupport() const { 658 return WrappedAction->hasASTFileSupport(); 659 } 660 bool WrapperFrontendAction::hasIRSupport() const { 661 return WrappedAction->hasIRSupport(); 662 } 663 bool WrapperFrontendAction::hasCodeCompletionSupport() const { 664 return WrappedAction->hasCodeCompletionSupport(); 665 } 666 667 WrapperFrontendAction::WrapperFrontendAction( 668 std::unique_ptr<FrontendAction> WrappedAction) 669 : WrappedAction(std::move(WrappedAction)) {} 670 671