FrontendAction.cpp revision 243830
1199482Srdivacky//===--- FrontendAction.cpp -----------------------------------------------===// 2199482Srdivacky// 3199482Srdivacky// The LLVM Compiler Infrastructure 4199482Srdivacky// 5199482Srdivacky// This file is distributed under the University of Illinois Open Source 6199482Srdivacky// License. See LICENSE.TXT for details. 7199482Srdivacky// 8199482Srdivacky//===----------------------------------------------------------------------===// 9199482Srdivacky 10199482Srdivacky#include "clang/Frontend/FrontendAction.h" 11212904Sdim#include "clang/AST/ASTConsumer.h" 12199482Srdivacky#include "clang/AST/ASTContext.h" 13218893Sdim#include "clang/AST/DeclGroup.h" 14199482Srdivacky#include "clang/Lex/HeaderSearch.h" 15199482Srdivacky#include "clang/Lex/Preprocessor.h" 16199482Srdivacky#include "clang/Frontend/ASTUnit.h" 17234353Sdim#include "clang/Frontend/ChainedIncludesSource.h" 18199482Srdivacky#include "clang/Frontend/CompilerInstance.h" 19199482Srdivacky#include "clang/Frontend/FrontendDiagnostic.h" 20218893Sdim#include "clang/Frontend/FrontendPluginRegistry.h" 21234353Sdim#include "clang/Frontend/LayoutOverrideSource.h" 22218893Sdim#include "clang/Frontend/MultiplexConsumer.h" 23212904Sdim#include "clang/Parse/ParseAST.h" 24218893Sdim#include "clang/Serialization/ASTDeserializationListener.h" 25226633Sdim#include "clang/Serialization/ASTReader.h" 26243830Sdim#include "llvm/Support/ErrorHandling.h" 27243830Sdim#include "llvm/Support/FileSystem.h" 28199482Srdivacky#include "llvm/Support/MemoryBuffer.h" 29243830Sdim#include "llvm/Support/raw_ostream.h" 30243830Sdim#include "llvm/Support/system_error.h" 31199482Srdivacky#include "llvm/Support/Timer.h" 32199482Srdivackyusing namespace clang; 33199482Srdivacky 34218893Sdimnamespace { 35218893Sdim 36234353Sdimclass DelegatingDeserializationListener : public ASTDeserializationListener { 37218893Sdim ASTDeserializationListener *Previous; 38218893Sdim 39218893Sdimpublic: 40234353Sdim explicit DelegatingDeserializationListener( 41234353Sdim ASTDeserializationListener *Previous) 42218893Sdim : Previous(Previous) { } 43218893Sdim 44234353Sdim virtual void ReaderInitialized(ASTReader *Reader) { 45234353Sdim if (Previous) 46234353Sdim Previous->ReaderInitialized(Reader); 47234353Sdim } 48234353Sdim virtual void IdentifierRead(serialization::IdentID ID, 49234353Sdim IdentifierInfo *II) { 50234353Sdim if (Previous) 51234353Sdim Previous->IdentifierRead(ID, II); 52234353Sdim } 53234353Sdim virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { 54234353Sdim if (Previous) 55234353Sdim Previous->TypeRead(Idx, T); 56234353Sdim } 57218893Sdim virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 58234353Sdim if (Previous) 59234353Sdim Previous->DeclRead(ID, D); 60234353Sdim } 61234353Sdim virtual void SelectorRead(serialization::SelectorID ID, Selector Sel) { 62234353Sdim if (Previous) 63234353Sdim Previous->SelectorRead(ID, Sel); 64234353Sdim } 65234353Sdim virtual void MacroDefinitionRead(serialization::PreprocessedEntityID PPID, 66234353Sdim MacroDefinition *MD) { 67234353Sdim if (Previous) 68234353Sdim Previous->MacroDefinitionRead(PPID, MD); 69234353Sdim } 70234353Sdim}; 71234353Sdim 72234353Sdim/// \brief Dumps deserialized declarations. 73234353Sdimclass DeserializedDeclsDumper : public DelegatingDeserializationListener { 74234353Sdimpublic: 75234353Sdim explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous) 76234353Sdim : DelegatingDeserializationListener(Previous) { } 77234353Sdim 78234353Sdim virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 79218893Sdim llvm::outs() << "PCH DECL: " << D->getDeclKindName(); 80218893Sdim if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 81234353Sdim llvm::outs() << " - " << *ND; 82218893Sdim llvm::outs() << "\n"; 83218893Sdim 84234353Sdim DelegatingDeserializationListener::DeclRead(ID, D); 85218893Sdim } 86218893Sdim}; 87218893Sdim 88239462Sdim/// \brief Checks deserialized declarations and emits error if a name 89239462Sdim/// matches one given in command-line using -error-on-deserialized-decl. 90239462Sdimclass DeserializedDeclsChecker : public DelegatingDeserializationListener { 91239462Sdim ASTContext &Ctx; 92239462Sdim std::set<std::string> NamesToCheck; 93218893Sdim 94239462Sdimpublic: 95239462Sdim DeserializedDeclsChecker(ASTContext &Ctx, 96239462Sdim const std::set<std::string> &NamesToCheck, 97239462Sdim ASTDeserializationListener *Previous) 98239462Sdim : DelegatingDeserializationListener(Previous), 99239462Sdim Ctx(Ctx), NamesToCheck(NamesToCheck) { } 100218893Sdim 101239462Sdim virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 102239462Sdim if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 103239462Sdim if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { 104239462Sdim unsigned DiagID 105239462Sdim = Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, 106239462Sdim "%0 was deserialized"); 107239462Sdim Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID) 108239462Sdim << ND->getNameAsString(); 109239462Sdim } 110218893Sdim 111239462Sdim DelegatingDeserializationListener::DeclRead(ID, D); 112239462Sdim } 113218893Sdim}; 114218893Sdim 115218893Sdim} // end anonymous namespace 116218893Sdim 117199990SrdivackyFrontendAction::FrontendAction() : Instance(0) {} 118199482Srdivacky 119199482SrdivackyFrontendAction::~FrontendAction() {} 120199482Srdivacky 121234353Sdimvoid FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput, 122234353Sdim ASTUnit *AST) { 123234353Sdim this->CurrentInput = CurrentInput; 124199482Srdivacky CurrentASTUnit.reset(AST); 125199482Srdivacky} 126199482Srdivacky 127218893SdimASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, 128226633Sdim StringRef InFile) { 129218893Sdim ASTConsumer* Consumer = CreateASTConsumer(CI, InFile); 130218893Sdim if (!Consumer) 131218893Sdim return 0; 132218893Sdim 133218893Sdim if (CI.getFrontendOpts().AddPluginActions.size() == 0) 134218893Sdim return Consumer; 135218893Sdim 136218893Sdim // Make sure the non-plugin consumer is first, so that plugins can't 137218893Sdim // modifiy the AST. 138218893Sdim std::vector<ASTConsumer*> Consumers(1, Consumer); 139218893Sdim 140218893Sdim for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); 141218893Sdim i != e; ++i) { 142218893Sdim // This is O(|plugins| * |add_plugins|), but since both numbers are 143218893Sdim // way below 50 in practice, that's ok. 144218893Sdim for (FrontendPluginRegistry::iterator 145218893Sdim it = FrontendPluginRegistry::begin(), 146218893Sdim ie = FrontendPluginRegistry::end(); 147218893Sdim it != ie; ++it) { 148218893Sdim if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { 149234353Sdim OwningPtr<PluginASTAction> P(it->instantiate()); 150218893Sdim FrontendAction* c = P.get(); 151218893Sdim if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) 152218893Sdim Consumers.push_back(c->CreateASTConsumer(CI, InFile)); 153218893Sdim } 154218893Sdim } 155218893Sdim } 156218893Sdim 157218893Sdim return new MultiplexConsumer(Consumers); 158218893Sdim} 159218893Sdim 160243830Sdim 161199482Srdivackybool FrontendAction::BeginSourceFile(CompilerInstance &CI, 162234353Sdim const FrontendInputFile &Input) { 163199482Srdivacky assert(!Instance && "Already processing a source file!"); 164243830Sdim assert(!Input.isEmpty() && "Unexpected empty filename!"); 165234353Sdim setCurrentInput(Input); 166199482Srdivacky setCompilerInstance(&CI); 167199482Srdivacky 168243830Sdim StringRef InputFile = Input.getFile(); 169239462Sdim bool HasBegunSourceFile = false; 170224145Sdim if (!BeginInvocation(CI)) 171224145Sdim goto failure; 172224145Sdim 173199482Srdivacky // AST files follow a very different path, since they share objects via the 174199482Srdivacky // AST unit. 175243830Sdim if (Input.getKind() == IK_AST) { 176199482Srdivacky assert(!usesPreprocessorOnly() && 177199482Srdivacky "Attempt to pass AST file to preprocessor only action!"); 178210299Sed assert(hasASTFileSupport() && 179210299Sed "This action does not have AST file support!"); 180199482Srdivacky 181234353Sdim IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); 182199482Srdivacky std::string Error; 183243830Sdim ASTUnit *AST = ASTUnit::LoadFromASTFile(InputFile, Diags, 184218893Sdim CI.getFileSystemOpts()); 185200583Srdivacky if (!AST) 186199482Srdivacky goto failure; 187199482Srdivacky 188234353Sdim setCurrentInput(Input, AST); 189199482Srdivacky 190199482Srdivacky // Set the shared objects, these are reset when we finish processing the 191199482Srdivacky // file, otherwise the CompilerInstance will happily destroy them. 192199482Srdivacky CI.setFileManager(&AST->getFileManager()); 193199482Srdivacky CI.setSourceManager(&AST->getSourceManager()); 194199482Srdivacky CI.setPreprocessor(&AST->getPreprocessor()); 195199482Srdivacky CI.setASTContext(&AST->getASTContext()); 196199482Srdivacky 197199482Srdivacky // Initialize the action. 198243830Sdim if (!BeginSourceFileAction(CI, InputFile)) 199199482Srdivacky goto failure; 200199482Srdivacky 201199482Srdivacky /// Create the AST consumer. 202243830Sdim CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile)); 203199482Srdivacky if (!CI.hasASTConsumer()) 204199482Srdivacky goto failure; 205199482Srdivacky 206199482Srdivacky return true; 207199482Srdivacky } 208199482Srdivacky 209210299Sed // Set up the file and source managers, if needed. 210210299Sed if (!CI.hasFileManager()) 211210299Sed CI.createFileManager(); 212210299Sed if (!CI.hasSourceManager()) 213218893Sdim CI.createSourceManager(CI.getFileManager()); 214210299Sed 215210299Sed // IR files bypass the rest of initialization. 216243830Sdim if (Input.getKind() == IK_LLVM_IR) { 217210299Sed assert(hasIRSupport() && 218210299Sed "This action does not have IR file support!"); 219210299Sed 220210299Sed // Inform the diagnostic client we are processing a source file. 221210299Sed CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); 222239462Sdim HasBegunSourceFile = true; 223210299Sed 224210299Sed // Initialize the action. 225243830Sdim if (!BeginSourceFileAction(CI, InputFile)) 226210299Sed goto failure; 227210299Sed 228210299Sed return true; 229210299Sed } 230210299Sed 231243830Sdim // If the implicit PCH include is actually a directory, rather than 232243830Sdim // a single file, search for a suitable PCH file in that directory. 233243830Sdim if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 234243830Sdim FileManager &FileMgr = CI.getFileManager(); 235243830Sdim PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); 236243830Sdim StringRef PCHInclude = PPOpts.ImplicitPCHInclude; 237243830Sdim if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) { 238243830Sdim llvm::error_code EC; 239243830Sdim SmallString<128> DirNative; 240243830Sdim llvm::sys::path::native(PCHDir->getName(), DirNative); 241243830Sdim bool Found = false; 242243830Sdim for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 243243830Sdim Dir != DirEnd && !EC; Dir.increment(EC)) { 244243830Sdim // Check whether this is an acceptable AST file. 245243830Sdim if (ASTReader::isAcceptableASTFile(Dir->path(), FileMgr, 246243830Sdim CI.getLangOpts(), 247243830Sdim CI.getTargetOpts(), 248243830Sdim CI.getPreprocessorOpts())) { 249243830Sdim for (unsigned I = 0, N = PPOpts.Includes.size(); I != N; ++I) { 250243830Sdim if (PPOpts.Includes[I] == PPOpts.ImplicitPCHInclude) { 251243830Sdim PPOpts.Includes[I] = Dir->path(); 252243830Sdim PPOpts.ImplicitPCHInclude = Dir->path(); 253243830Sdim Found = true; 254243830Sdim break; 255243830Sdim } 256243830Sdim } 257243830Sdim 258243830Sdim assert(Found && "Implicit PCH include not in includes list?"); 259243830Sdim break; 260243830Sdim } 261243830Sdim } 262243830Sdim 263243830Sdim if (!Found) { 264243830Sdim CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude; 265243830Sdim return true; 266243830Sdim } 267243830Sdim } 268243830Sdim } 269243830Sdim 270210299Sed // Set up the preprocessor. 271210299Sed CI.createPreprocessor(); 272210299Sed 273199482Srdivacky // Inform the diagnostic client we are processing a source file. 274199482Srdivacky CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 275199482Srdivacky &CI.getPreprocessor()); 276239462Sdim HasBegunSourceFile = true; 277199482Srdivacky 278199482Srdivacky // Initialize the action. 279243830Sdim if (!BeginSourceFileAction(CI, InputFile)) 280199482Srdivacky goto failure; 281199482Srdivacky 282199482Srdivacky /// Create the AST context and consumer unless this is a preprocessor only 283199482Srdivacky /// action. 284199482Srdivacky if (!usesPreprocessorOnly()) { 285199482Srdivacky CI.createASTContext(); 286199482Srdivacky 287234353Sdim OwningPtr<ASTConsumer> Consumer( 288243830Sdim CreateWrappedASTConsumer(CI, InputFile)); 289218893Sdim if (!Consumer) 290218893Sdim goto failure; 291212904Sdim 292218893Sdim CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); 293243830Sdim CI.getPreprocessor().setPPMutationListener( 294243830Sdim Consumer->GetPPMutationListener()); 295243830Sdim 296221345Sdim if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { 297221345Sdim // Convert headers to PCH and chain them. 298234353Sdim OwningPtr<ExternalASTSource> source; 299221345Sdim source.reset(ChainedIncludesSource::create(CI)); 300221345Sdim if (!source) 301221345Sdim goto failure; 302221345Sdim CI.getASTContext().setExternalSource(source); 303221345Sdim 304221345Sdim } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 305221345Sdim // Use PCH. 306199482Srdivacky assert(hasPCHSupport() && "This action does not have PCH support!"); 307226633Sdim ASTDeserializationListener *DeserialListener = 308226633Sdim Consumer->GetASTDeserializationListener(); 309218893Sdim if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) 310218893Sdim DeserialListener = new DeserializedDeclsDumper(DeserialListener); 311218893Sdim if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) 312218893Sdim DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(), 313218893Sdim CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, 314218893Sdim DeserialListener); 315199482Srdivacky CI.createPCHExternalASTSource( 316212904Sdim CI.getPreprocessorOpts().ImplicitPCHInclude, 317212904Sdim CI.getPreprocessorOpts().DisablePCHValidation, 318234353Sdim CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, 319218893Sdim DeserialListener); 320199482Srdivacky if (!CI.getASTContext().getExternalSource()) 321199482Srdivacky goto failure; 322199482Srdivacky } 323210299Sed 324212904Sdim CI.setASTConsumer(Consumer.take()); 325210299Sed if (!CI.hasASTConsumer()) 326210299Sed goto failure; 327199482Srdivacky } 328199482Srdivacky 329226633Sdim // Initialize built-in info as long as we aren't using an external AST 330199482Srdivacky // source. 331199482Srdivacky if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { 332199482Srdivacky Preprocessor &PP = CI.getPreprocessor(); 333199482Srdivacky PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), 334234353Sdim PP.getLangOpts()); 335199482Srdivacky } 336199482Srdivacky 337234353Sdim // If there is a layout overrides file, attach an external AST source that 338234353Sdim // provides the layouts from that file. 339234353Sdim if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 340234353Sdim CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { 341234353Sdim OwningPtr<ExternalASTSource> 342234353Sdim Override(new LayoutOverrideSource( 343234353Sdim CI.getFrontendOpts().OverrideRecordLayoutsFile)); 344234353Sdim CI.getASTContext().setExternalSource(Override); 345234353Sdim } 346234353Sdim 347199482Srdivacky return true; 348199482Srdivacky 349199482Srdivacky // If we failed, reset state since the client will not end up calling the 350199482Srdivacky // matching EndSourceFile(). 351199482Srdivacky failure: 352199482Srdivacky if (isCurrentFileAST()) { 353221345Sdim CI.setASTContext(0); 354221345Sdim CI.setPreprocessor(0); 355221345Sdim CI.setSourceManager(0); 356221345Sdim CI.setFileManager(0); 357199482Srdivacky } 358199482Srdivacky 359239462Sdim if (HasBegunSourceFile) 360239462Sdim CI.getDiagnosticClient().EndSourceFile(); 361243830Sdim CI.clearOutputFiles(/*EraseFiles=*/true); 362234353Sdim setCurrentInput(FrontendInputFile()); 363199482Srdivacky setCompilerInstance(0); 364199482Srdivacky return false; 365199482Srdivacky} 366199482Srdivacky 367239462Sdimbool FrontendAction::Execute() { 368199482Srdivacky CompilerInstance &CI = getCompilerInstance(); 369199482Srdivacky 370199482Srdivacky // Initialize the main file entry. This needs to be delayed until after PCH 371199482Srdivacky // has loaded. 372234353Sdim if (!isCurrentFileAST()) { 373243830Sdim if (!CI.InitializeSourceManager(getCurrentInput())) 374239462Sdim return false; 375199482Srdivacky } 376199482Srdivacky 377199990Srdivacky if (CI.hasFrontendTimer()) { 378199990Srdivacky llvm::TimeRegion Timer(CI.getFrontendTimer()); 379199990Srdivacky ExecuteAction(); 380199990Srdivacky } 381199990Srdivacky else ExecuteAction(); 382239462Sdim 383239462Sdim return true; 384199482Srdivacky} 385199482Srdivacky 386199482Srdivackyvoid FrontendAction::EndSourceFile() { 387199482Srdivacky CompilerInstance &CI = getCompilerInstance(); 388199482Srdivacky 389218893Sdim // Inform the diagnostic client we are done with this source file. 390218893Sdim CI.getDiagnosticClient().EndSourceFile(); 391218893Sdim 392199482Srdivacky // Finalize the action. 393199482Srdivacky EndSourceFileAction(); 394199482Srdivacky 395199482Srdivacky // Release the consumer and the AST, in that order since the consumer may 396199482Srdivacky // perform actions in its destructor which require the context. 397199482Srdivacky // 398199482Srdivacky // FIXME: There is more per-file stuff we could just drop here? 399199482Srdivacky if (CI.getFrontendOpts().DisableFree) { 400199482Srdivacky CI.takeASTConsumer(); 401212904Sdim if (!isCurrentFileAST()) { 402212904Sdim CI.takeSema(); 403221345Sdim CI.resetAndLeakASTContext(); 404212904Sdim } 405199482Srdivacky } else { 406212904Sdim if (!isCurrentFileAST()) { 407212904Sdim CI.setSema(0); 408212904Sdim CI.setASTContext(0); 409212904Sdim } 410199482Srdivacky CI.setASTConsumer(0); 411199482Srdivacky } 412199482Srdivacky 413206084Srdivacky // Inform the preprocessor we are done. 414206084Srdivacky if (CI.hasPreprocessor()) 415206084Srdivacky CI.getPreprocessor().EndSourceFile(); 416206084Srdivacky 417199482Srdivacky if (CI.getFrontendOpts().ShowStats) { 418199482Srdivacky llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n"; 419199482Srdivacky CI.getPreprocessor().PrintStats(); 420199482Srdivacky CI.getPreprocessor().getIdentifierTable().PrintStats(); 421199482Srdivacky CI.getPreprocessor().getHeaderSearchInfo().PrintStats(); 422199482Srdivacky CI.getSourceManager().PrintStats(); 423199482Srdivacky llvm::errs() << "\n"; 424199482Srdivacky } 425199482Srdivacky 426199482Srdivacky // Cleanup the output streams, and erase the output files if we encountered 427199482Srdivacky // an error. 428218893Sdim CI.clearOutputFiles(/*EraseFiles=*/CI.getDiagnostics().hasErrorOccurred()); 429199482Srdivacky 430199482Srdivacky if (isCurrentFileAST()) { 431212904Sdim CI.takeSema(); 432221345Sdim CI.resetAndLeakASTContext(); 433221345Sdim CI.resetAndLeakPreprocessor(); 434221345Sdim CI.resetAndLeakSourceManager(); 435221345Sdim CI.resetAndLeakFileManager(); 436199482Srdivacky } 437199482Srdivacky 438199482Srdivacky setCompilerInstance(0); 439234353Sdim setCurrentInput(FrontendInputFile()); 440199482Srdivacky} 441199482Srdivacky 442199482Srdivacky//===----------------------------------------------------------------------===// 443199482Srdivacky// Utility Actions 444199482Srdivacky//===----------------------------------------------------------------------===// 445199482Srdivacky 446199482Srdivackyvoid ASTFrontendAction::ExecuteAction() { 447199482Srdivacky CompilerInstance &CI = getCompilerInstance(); 448199482Srdivacky 449199482Srdivacky // FIXME: Move the truncation aspect of this into Sema, we delayed this till 450199482Srdivacky // here so the source manager would be initialized. 451199482Srdivacky if (hasCodeCompletionSupport() && 452199482Srdivacky !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) 453199482Srdivacky CI.createCodeCompletionConsumer(); 454199482Srdivacky 455199482Srdivacky // Use a code completion consumer? 456199482Srdivacky CodeCompleteConsumer *CompletionConsumer = 0; 457199482Srdivacky if (CI.hasCodeCompletionConsumer()) 458199482Srdivacky CompletionConsumer = &CI.getCodeCompletionConsumer(); 459199482Srdivacky 460212904Sdim if (!CI.hasSema()) 461226633Sdim CI.createSema(getTranslationUnitKind(), CompletionConsumer); 462212904Sdim 463234353Sdim ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats, 464234353Sdim CI.getFrontendOpts().SkipFunctionBodies); 465199482Srdivacky} 466199482Srdivacky 467234353Sdimvoid PluginASTAction::anchor() { } 468234353Sdim 469199482SrdivackyASTConsumer * 470199482SrdivackyPreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI, 471226633Sdim StringRef InFile) { 472200583Srdivacky llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!"); 473199482Srdivacky} 474224145Sdim 475224145SdimASTConsumer *WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI, 476226633Sdim StringRef InFile) { 477224145Sdim return WrappedAction->CreateASTConsumer(CI, InFile); 478224145Sdim} 479224145Sdimbool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) { 480224145Sdim return WrappedAction->BeginInvocation(CI); 481224145Sdim} 482224145Sdimbool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI, 483226633Sdim StringRef Filename) { 484234353Sdim WrappedAction->setCurrentInput(getCurrentInput()); 485224145Sdim WrappedAction->setCompilerInstance(&CI); 486224145Sdim return WrappedAction->BeginSourceFileAction(CI, Filename); 487224145Sdim} 488224145Sdimvoid WrapperFrontendAction::ExecuteAction() { 489224145Sdim WrappedAction->ExecuteAction(); 490224145Sdim} 491224145Sdimvoid WrapperFrontendAction::EndSourceFileAction() { 492224145Sdim WrappedAction->EndSourceFileAction(); 493224145Sdim} 494224145Sdim 495224145Sdimbool WrapperFrontendAction::usesPreprocessorOnly() const { 496224145Sdim return WrappedAction->usesPreprocessorOnly(); 497224145Sdim} 498226633SdimTranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() { 499226633Sdim return WrappedAction->getTranslationUnitKind(); 500224145Sdim} 501224145Sdimbool WrapperFrontendAction::hasPCHSupport() const { 502224145Sdim return WrappedAction->hasPCHSupport(); 503224145Sdim} 504224145Sdimbool WrapperFrontendAction::hasASTFileSupport() const { 505224145Sdim return WrappedAction->hasASTFileSupport(); 506224145Sdim} 507224145Sdimbool WrapperFrontendAction::hasIRSupport() const { 508224145Sdim return WrappedAction->hasIRSupport(); 509224145Sdim} 510224145Sdimbool WrapperFrontendAction::hasCodeCompletionSupport() const { 511224145Sdim return WrappedAction->hasCodeCompletionSupport(); 512224145Sdim} 513224145Sdim 514224145SdimWrapperFrontendAction::WrapperFrontendAction(FrontendAction *WrappedAction) 515224145Sdim : WrappedAction(WrappedAction) {} 516224145Sdim 517