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() == IK_AST) { 242 assert(!usesPreprocessorOnly() && 243 "Attempt to pass AST file to preprocessor only action!"); 244 assert(hasASTFileSupport() && 245 "This action does not have AST file support!"); 246 247 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); 248 249 std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( 250 InputFile, CI.getPCHContainerReader(), Diags, CI.getFileSystemOpts(), 251 CI.getCodeGenOpts().DebugTypeExtRefs); 252 253 if (!AST) 254 goto failure; 255 256 // Inform the diagnostic client we are processing a source file. 257 CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); 258 HasBegunSourceFile = true; 259 260 // Set the shared objects, these are reset when we finish processing the 261 // file, otherwise the CompilerInstance will happily destroy them. 262 CI.setFileManager(&AST->getFileManager()); 263 CI.setSourceManager(&AST->getSourceManager()); 264 CI.setPreprocessor(AST->getPreprocessorPtr()); 265 Preprocessor &PP = CI.getPreprocessor(); 266 PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), 267 PP.getLangOpts()); 268 CI.setASTContext(&AST->getASTContext()); 269 270 setCurrentInput(Input, std::move(AST)); 271 272 // Initialize the action. 273 if (!BeginSourceFileAction(CI, InputFile)) 274 goto failure; 275 276 // Create the AST consumer. 277 CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile)); 278 if (!CI.hasASTConsumer()) 279 goto failure; 280 281 return true; 282 } 283 284 if (!CI.hasVirtualFileSystem()) { 285 if (IntrusiveRefCntPtr<vfs::FileSystem> VFS = 286 createVFSFromCompilerInvocation(CI.getInvocation(), 287 CI.getDiagnostics())) 288 CI.setVirtualFileSystem(VFS); 289 else 290 goto failure; 291 } 292 293 // Set up the file and source managers, if needed. 294 if (!CI.hasFileManager()) 295 CI.createFileManager(); 296 if (!CI.hasSourceManager()) 297 CI.createSourceManager(CI.getFileManager()); 298 299 // IR files bypass the rest of initialization. 300 if (Input.getKind() == IK_LLVM_IR) { 301 assert(hasIRSupport() && 302 "This action does not have IR file support!"); 303 304 // Inform the diagnostic client we are processing a source file. 305 CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); 306 HasBegunSourceFile = true; 307 308 // Initialize the action. 309 if (!BeginSourceFileAction(CI, InputFile)) 310 goto failure; 311 312 // Initialize the main file entry. 313 if (!CI.InitializeSourceManager(CurrentInput)) 314 goto failure; 315 316 return true; 317 } 318 319 // If the implicit PCH include is actually a directory, rather than 320 // a single file, search for a suitable PCH file in that directory. 321 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 322 FileManager &FileMgr = CI.getFileManager(); 323 PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); 324 StringRef PCHInclude = PPOpts.ImplicitPCHInclude; 325 std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath(); 326 if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) { 327 std::error_code EC; 328 SmallString<128> DirNative; 329 llvm::sys::path::native(PCHDir->getName(), DirNative); 330 bool Found = false; 331 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); 332 for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; 333 Dir != DirEnd && !EC; Dir.increment(EC)) { 334 // Check whether this is an acceptable AST file. 335 if (ASTReader::isAcceptableASTFile( 336 Dir->getName(), FileMgr, CI.getPCHContainerReader(), 337 CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(), 338 SpecificModuleCachePath)) { 339 PPOpts.ImplicitPCHInclude = Dir->getName(); 340 Found = true; 341 break; 342 } 343 } 344 345 if (!Found) { 346 CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude; 347 goto failure; 348 } 349 } 350 } 351 352 // Set up the preprocessor if needed. When parsing model files the 353 // preprocessor of the original source is reused. 354 if (!isModelParsingAction()) 355 CI.createPreprocessor(getTranslationUnitKind()); 356 357 // Inform the diagnostic client we are processing a source file. 358 CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 359 &CI.getPreprocessor()); 360 HasBegunSourceFile = true; 361 362 // Initialize the action. 363 if (!BeginSourceFileAction(CI, InputFile)) 364 goto failure; 365 366 // Initialize the main file entry. It is important that this occurs after 367 // BeginSourceFileAction, which may change CurrentInput during module builds. 368 if (!CI.InitializeSourceManager(CurrentInput)) 369 goto failure; 370 371 // Create the AST context and consumer unless this is a preprocessor only 372 // action. 373 if (!usesPreprocessorOnly()) { 374 // Parsing a model file should reuse the existing ASTContext. 375 if (!isModelParsingAction()) 376 CI.createASTContext(); 377 378 // For preprocessed files, check if the first line specifies the original 379 // source file name with a linemarker. 380 std::string OrigFile; 381 if (Input.isPreprocessed()) 382 if (ReadOriginalFileName(CI, OrigFile)) 383 InputFile = OrigFile; 384 385 std::unique_ptr<ASTConsumer> Consumer = 386 CreateWrappedASTConsumer(CI, InputFile); 387 if (!Consumer) 388 goto failure; 389 390 // FIXME: should not overwrite ASTMutationListener when parsing model files? 391 if (!isModelParsingAction()) 392 CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); 393 394 if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { 395 // Convert headers to PCH and chain them. 396 IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader; 397 source = createChainedIncludesSource(CI, FinalReader); 398 if (!source) 399 goto failure; 400 CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get())); 401 CI.getASTContext().setExternalSource(source); 402 } else if (CI.getLangOpts().Modules || 403 !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 404 // Use PCM or PCH. 405 assert(hasPCHSupport() && "This action does not have PCH support!"); 406 ASTDeserializationListener *DeserialListener = 407 Consumer->GetASTDeserializationListener(); 408 bool DeleteDeserialListener = false; 409 if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) { 410 DeserialListener = new DeserializedDeclsDumper(DeserialListener, 411 DeleteDeserialListener); 412 DeleteDeserialListener = true; 413 } 414 if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) { 415 DeserialListener = new DeserializedDeclsChecker( 416 CI.getASTContext(), 417 CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, 418 DeserialListener, DeleteDeserialListener); 419 DeleteDeserialListener = true; 420 } 421 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 422 CI.createPCHExternalASTSource( 423 CI.getPreprocessorOpts().ImplicitPCHInclude, 424 CI.getPreprocessorOpts().DisablePCHValidation, 425 CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener, 426 DeleteDeserialListener); 427 if (!CI.getASTContext().getExternalSource()) 428 goto failure; 429 } 430 // If modules are enabled, create the module manager before creating 431 // any builtins, so that all declarations know that they might be 432 // extended by an external source. 433 if (CI.getLangOpts().Modules || !CI.hasASTContext() || 434 !CI.getASTContext().getExternalSource()) { 435 CI.createModuleManager(); 436 CI.getModuleManager()->setDeserializationListener(DeserialListener, 437 DeleteDeserialListener); 438 } 439 } 440 441 CI.setASTConsumer(std::move(Consumer)); 442 if (!CI.hasASTConsumer()) 443 goto failure; 444 } 445 446 // Initialize built-in info as long as we aren't using an external AST 447 // source. 448 if (CI.getLangOpts().Modules || !CI.hasASTContext() || 449 !CI.getASTContext().getExternalSource()) { 450 Preprocessor &PP = CI.getPreprocessor(); 451 PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), 452 PP.getLangOpts()); 453 } else { 454 // FIXME: If this is a problem, recover from it by creating a multiplex 455 // source. 456 assert((!CI.getLangOpts().Modules || CI.getModuleManager()) && 457 "modules enabled but created an external source that " 458 "doesn't support modules"); 459 } 460 461 // If we were asked to load any module map files, do so now. 462 for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) { 463 if (auto *File = CI.getFileManager().getFile(Filename)) 464 CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile( 465 File, /*IsSystem*/false); 466 else 467 CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename; 468 } 469 470 // If we were asked to load any module files, do so now. 471 for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) 472 if (!CI.loadModuleFile(ModuleFile)) 473 goto failure; 474 475 // If there is a layout overrides file, attach an external AST source that 476 // provides the layouts from that file. 477 if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 478 CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { 479 IntrusiveRefCntPtr<ExternalASTSource> 480 Override(new LayoutOverrideSource( 481 CI.getFrontendOpts().OverrideRecordLayoutsFile)); 482 CI.getASTContext().setExternalSource(Override); 483 } 484 485 return true; 486 487 // If we failed, reset state since the client will not end up calling the 488 // matching EndSourceFile(). 489 failure: 490 if (isCurrentFileAST()) { 491 CI.setASTContext(nullptr); 492 CI.setPreprocessor(nullptr); 493 CI.setSourceManager(nullptr); 494 CI.setFileManager(nullptr); 495 } 496 497 if (HasBegunSourceFile) 498 CI.getDiagnosticClient().EndSourceFile(); 499 CI.clearOutputFiles(/*EraseFiles=*/true); 500 setCurrentInput(FrontendInputFile()); 501 setCompilerInstance(nullptr); 502 return false; 503 } 504 505 bool FrontendAction::Execute() { 506 CompilerInstance &CI = getCompilerInstance(); 507 508 if (CI.hasFrontendTimer()) { 509 llvm::TimeRegion Timer(CI.getFrontendTimer()); 510 ExecuteAction(); 511 } 512 else ExecuteAction(); 513 514 // If we are supposed to rebuild the global module index, do so now unless 515 // there were any module-build failures. 516 if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() && 517 CI.hasPreprocessor()) { 518 StringRef Cache = 519 CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath(); 520 if (!Cache.empty()) 521 GlobalModuleIndex::writeIndex(CI.getFileManager(), 522 CI.getPCHContainerReader(), Cache); 523 } 524 525 return true; 526 } 527 528 void FrontendAction::EndSourceFile() { 529 CompilerInstance &CI = getCompilerInstance(); 530 531 // Inform the diagnostic client we are done with this source file. 532 CI.getDiagnosticClient().EndSourceFile(); 533 534 // Inform the preprocessor we are done. 535 if (CI.hasPreprocessor()) 536 CI.getPreprocessor().EndSourceFile(); 537 538 // Finalize the action. 539 EndSourceFileAction(); 540 541 // Sema references the ast consumer, so reset sema first. 542 // 543 // FIXME: There is more per-file stuff we could just drop here? 544 bool DisableFree = CI.getFrontendOpts().DisableFree; 545 if (DisableFree) { 546 CI.resetAndLeakSema(); 547 CI.resetAndLeakASTContext(); 548 BuryPointer(CI.takeASTConsumer().get()); 549 } else { 550 CI.setSema(nullptr); 551 CI.setASTContext(nullptr); 552 CI.setASTConsumer(nullptr); 553 } 554 555 if (CI.getFrontendOpts().ShowStats) { 556 llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n"; 557 CI.getPreprocessor().PrintStats(); 558 CI.getPreprocessor().getIdentifierTable().PrintStats(); 559 CI.getPreprocessor().getHeaderSearchInfo().PrintStats(); 560 CI.getSourceManager().PrintStats(); 561 llvm::errs() << "\n"; 562 } 563 564 // Cleanup the output streams, and erase the output files if instructed by the 565 // FrontendAction. 566 CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles()); 567 568 if (isCurrentFileAST()) { 569 if (DisableFree) { 570 CI.resetAndLeakPreprocessor(); 571 CI.resetAndLeakSourceManager(); 572 CI.resetAndLeakFileManager(); 573 } else { 574 CI.setPreprocessor(nullptr); 575 CI.setSourceManager(nullptr); 576 CI.setFileManager(nullptr); 577 } 578 } 579 580 setCompilerInstance(nullptr); 581 setCurrentInput(FrontendInputFile()); 582 } 583 584 bool FrontendAction::shouldEraseOutputFiles() { 585 return getCompilerInstance().getDiagnostics().hasErrorOccurred(); 586 } 587 588 //===----------------------------------------------------------------------===// 589 // Utility Actions 590 //===----------------------------------------------------------------------===// 591 592 void ASTFrontendAction::ExecuteAction() { 593 CompilerInstance &CI = getCompilerInstance(); 594 if (!CI.hasPreprocessor()) 595 return; 596 597 // FIXME: Move the truncation aspect of this into Sema, we delayed this till 598 // here so the source manager would be initialized. 599 if (hasCodeCompletionSupport() && 600 !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) 601 CI.createCodeCompletionConsumer(); 602 603 // Use a code completion consumer? 604 CodeCompleteConsumer *CompletionConsumer = nullptr; 605 if (CI.hasCodeCompletionConsumer()) 606 CompletionConsumer = &CI.getCodeCompletionConsumer(); 607 608 if (!CI.hasSema()) 609 CI.createSema(getTranslationUnitKind(), CompletionConsumer); 610 611 ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats, 612 CI.getFrontendOpts().SkipFunctionBodies); 613 } 614 615 void PluginASTAction::anchor() { } 616 617 std::unique_ptr<ASTConsumer> 618 PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI, 619 StringRef InFile) { 620 llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!"); 621 } 622 623 std::unique_ptr<ASTConsumer> 624 WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI, 625 StringRef InFile) { 626 return WrappedAction->CreateASTConsumer(CI, InFile); 627 } 628 bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) { 629 return WrappedAction->BeginInvocation(CI); 630 } 631 bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI, 632 StringRef Filename) { 633 WrappedAction->setCurrentInput(getCurrentInput()); 634 WrappedAction->setCompilerInstance(&CI); 635 auto Ret = WrappedAction->BeginSourceFileAction(CI, Filename); 636 // BeginSourceFileAction may change CurrentInput, e.g. during module builds. 637 setCurrentInput(WrappedAction->getCurrentInput()); 638 return Ret; 639 } 640 void WrapperFrontendAction::ExecuteAction() { 641 WrappedAction->ExecuteAction(); 642 } 643 void WrapperFrontendAction::EndSourceFileAction() { 644 WrappedAction->EndSourceFileAction(); 645 } 646 647 bool WrapperFrontendAction::usesPreprocessorOnly() const { 648 return WrappedAction->usesPreprocessorOnly(); 649 } 650 TranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() { 651 return WrappedAction->getTranslationUnitKind(); 652 } 653 bool WrapperFrontendAction::hasPCHSupport() const { 654 return WrappedAction->hasPCHSupport(); 655 } 656 bool WrapperFrontendAction::hasASTFileSupport() const { 657 return WrappedAction->hasASTFileSupport(); 658 } 659 bool WrapperFrontendAction::hasIRSupport() const { 660 return WrappedAction->hasIRSupport(); 661 } 662 bool WrapperFrontendAction::hasCodeCompletionSupport() const { 663 return WrappedAction->hasCodeCompletionSupport(); 664 } 665 666 WrapperFrontendAction::WrapperFrontendAction( 667 std::unique_ptr<FrontendAction> WrappedAction) 668 : WrappedAction(std::move(WrappedAction)) {} 669 670