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/Frontend/ASTUnit.h" 15234353Sdim#include "clang/Frontend/ChainedIncludesSource.h" 16199482Srdivacky#include "clang/Frontend/CompilerInstance.h" 17199482Srdivacky#include "clang/Frontend/FrontendDiagnostic.h" 18218893Sdim#include "clang/Frontend/FrontendPluginRegistry.h" 19234353Sdim#include "clang/Frontend/LayoutOverrideSource.h" 20218893Sdim#include "clang/Frontend/MultiplexConsumer.h" 21249423Sdim#include "clang/Lex/HeaderSearch.h" 22249423Sdim#include "clang/Lex/Preprocessor.h" 23212904Sdim#include "clang/Parse/ParseAST.h" 24218893Sdim#include "clang/Serialization/ASTDeserializationListener.h" 25226633Sdim#include "clang/Serialization/ASTReader.h" 26249423Sdim#include "clang/Serialization/GlobalModuleIndex.h" 27243830Sdim#include "llvm/Support/ErrorHandling.h" 28243830Sdim#include "llvm/Support/FileSystem.h" 29199482Srdivacky#include "llvm/Support/MemoryBuffer.h" 30249423Sdim#include "llvm/Support/Timer.h" 31243830Sdim#include "llvm/Support/raw_ostream.h" 32243830Sdim#include "llvm/Support/system_error.h" 33199482Srdivackyusing namespace clang; 34199482Srdivacky 35218893Sdimnamespace { 36218893Sdim 37234353Sdimclass DelegatingDeserializationListener : public ASTDeserializationListener { 38218893Sdim ASTDeserializationListener *Previous; 39218893Sdim 40218893Sdimpublic: 41234353Sdim explicit DelegatingDeserializationListener( 42234353Sdim ASTDeserializationListener *Previous) 43218893Sdim : Previous(Previous) { } 44218893Sdim 45234353Sdim virtual void ReaderInitialized(ASTReader *Reader) { 46234353Sdim if (Previous) 47234353Sdim Previous->ReaderInitialized(Reader); 48234353Sdim } 49234353Sdim virtual void IdentifierRead(serialization::IdentID ID, 50234353Sdim IdentifierInfo *II) { 51234353Sdim if (Previous) 52234353Sdim Previous->IdentifierRead(ID, II); 53234353Sdim } 54234353Sdim virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { 55234353Sdim if (Previous) 56234353Sdim Previous->TypeRead(Idx, T); 57234353Sdim } 58218893Sdim virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 59234353Sdim if (Previous) 60234353Sdim Previous->DeclRead(ID, D); 61234353Sdim } 62234353Sdim virtual void SelectorRead(serialization::SelectorID ID, Selector Sel) { 63234353Sdim if (Previous) 64234353Sdim Previous->SelectorRead(ID, Sel); 65234353Sdim } 66234353Sdim virtual void MacroDefinitionRead(serialization::PreprocessedEntityID PPID, 67234353Sdim MacroDefinition *MD) { 68234353Sdim if (Previous) 69234353Sdim Previous->MacroDefinitionRead(PPID, MD); 70234353Sdim } 71234353Sdim}; 72234353Sdim 73234353Sdim/// \brief Dumps deserialized declarations. 74234353Sdimclass DeserializedDeclsDumper : public DelegatingDeserializationListener { 75234353Sdimpublic: 76234353Sdim explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous) 77234353Sdim : DelegatingDeserializationListener(Previous) { } 78234353Sdim 79234353Sdim virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 80218893Sdim llvm::outs() << "PCH DECL: " << D->getDeclKindName(); 81218893Sdim if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 82234353Sdim llvm::outs() << " - " << *ND; 83218893Sdim llvm::outs() << "\n"; 84218893Sdim 85234353Sdim DelegatingDeserializationListener::DeclRead(ID, D); 86218893Sdim } 87218893Sdim}; 88218893Sdim 89239462Sdim/// \brief Checks deserialized declarations and emits error if a name 90239462Sdim/// matches one given in command-line using -error-on-deserialized-decl. 91239462Sdimclass DeserializedDeclsChecker : public DelegatingDeserializationListener { 92239462Sdim ASTContext &Ctx; 93239462Sdim std::set<std::string> NamesToCheck; 94218893Sdim 95239462Sdimpublic: 96239462Sdim DeserializedDeclsChecker(ASTContext &Ctx, 97239462Sdim const std::set<std::string> &NamesToCheck, 98239462Sdim ASTDeserializationListener *Previous) 99239462Sdim : DelegatingDeserializationListener(Previous), 100239462Sdim Ctx(Ctx), NamesToCheck(NamesToCheck) { } 101218893Sdim 102239462Sdim virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 103239462Sdim if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 104239462Sdim if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { 105239462Sdim unsigned DiagID 106239462Sdim = Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, 107239462Sdim "%0 was deserialized"); 108239462Sdim Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID) 109239462Sdim << ND->getNameAsString(); 110239462Sdim } 111218893Sdim 112239462Sdim DelegatingDeserializationListener::DeclRead(ID, D); 113239462Sdim } 114218893Sdim}; 115218893Sdim 116218893Sdim} // end anonymous namespace 117218893Sdim 118199990SrdivackyFrontendAction::FrontendAction() : Instance(0) {} 119199482Srdivacky 120199482SrdivackyFrontendAction::~FrontendAction() {} 121199482Srdivacky 122234353Sdimvoid FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput, 123234353Sdim ASTUnit *AST) { 124234353Sdim this->CurrentInput = CurrentInput; 125199482Srdivacky CurrentASTUnit.reset(AST); 126199482Srdivacky} 127199482Srdivacky 128218893SdimASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, 129226633Sdim StringRef InFile) { 130218893Sdim ASTConsumer* Consumer = CreateASTConsumer(CI, InFile); 131218893Sdim if (!Consumer) 132218893Sdim return 0; 133218893Sdim 134218893Sdim if (CI.getFrontendOpts().AddPluginActions.size() == 0) 135218893Sdim return Consumer; 136218893Sdim 137218893Sdim // Make sure the non-plugin consumer is first, so that plugins can't 138218893Sdim // modifiy the AST. 139218893Sdim std::vector<ASTConsumer*> Consumers(1, Consumer); 140218893Sdim 141218893Sdim for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); 142218893Sdim i != e; ++i) { 143218893Sdim // This is O(|plugins| * |add_plugins|), but since both numbers are 144218893Sdim // way below 50 in practice, that's ok. 145218893Sdim for (FrontendPluginRegistry::iterator 146218893Sdim it = FrontendPluginRegistry::begin(), 147218893Sdim ie = FrontendPluginRegistry::end(); 148218893Sdim it != ie; ++it) { 149218893Sdim if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { 150234353Sdim OwningPtr<PluginASTAction> P(it->instantiate()); 151218893Sdim FrontendAction* c = P.get(); 152218893Sdim if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) 153218893Sdim Consumers.push_back(c->CreateASTConsumer(CI, InFile)); 154218893Sdim } 155218893Sdim } 156218893Sdim } 157218893Sdim 158218893Sdim return new MultiplexConsumer(Consumers); 159218893Sdim} 160218893Sdim 161243830Sdim 162199482Srdivackybool FrontendAction::BeginSourceFile(CompilerInstance &CI, 163234353Sdim const FrontendInputFile &Input) { 164199482Srdivacky assert(!Instance && "Already processing a source file!"); 165243830Sdim assert(!Input.isEmpty() && "Unexpected empty filename!"); 166234353Sdim setCurrentInput(Input); 167199482Srdivacky setCompilerInstance(&CI); 168199482Srdivacky 169243830Sdim StringRef InputFile = Input.getFile(); 170239462Sdim bool HasBegunSourceFile = false; 171224145Sdim if (!BeginInvocation(CI)) 172224145Sdim goto failure; 173224145Sdim 174199482Srdivacky // AST files follow a very different path, since they share objects via the 175199482Srdivacky // AST unit. 176243830Sdim if (Input.getKind() == IK_AST) { 177199482Srdivacky assert(!usesPreprocessorOnly() && 178199482Srdivacky "Attempt to pass AST file to preprocessor only action!"); 179210299Sed assert(hasASTFileSupport() && 180210299Sed "This action does not have AST file support!"); 181199482Srdivacky 182234353Sdim IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); 183199482Srdivacky std::string Error; 184243830Sdim ASTUnit *AST = ASTUnit::LoadFromASTFile(InputFile, Diags, 185218893Sdim CI.getFileSystemOpts()); 186200583Srdivacky if (!AST) 187199482Srdivacky goto failure; 188199482Srdivacky 189234353Sdim setCurrentInput(Input, AST); 190199482Srdivacky 191249423Sdim // Inform the diagnostic client we are processing a source file. 192249423Sdim CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); 193249423Sdim HasBegunSourceFile = true; 194249423Sdim 195199482Srdivacky // Set the shared objects, these are reset when we finish processing the 196199482Srdivacky // file, otherwise the CompilerInstance will happily destroy them. 197199482Srdivacky CI.setFileManager(&AST->getFileManager()); 198199482Srdivacky CI.setSourceManager(&AST->getSourceManager()); 199199482Srdivacky CI.setPreprocessor(&AST->getPreprocessor()); 200199482Srdivacky CI.setASTContext(&AST->getASTContext()); 201199482Srdivacky 202199482Srdivacky // Initialize the action. 203243830Sdim if (!BeginSourceFileAction(CI, InputFile)) 204199482Srdivacky goto failure; 205199482Srdivacky 206249423Sdim // Create the AST consumer. 207243830Sdim CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile)); 208199482Srdivacky if (!CI.hasASTConsumer()) 209199482Srdivacky goto failure; 210199482Srdivacky 211199482Srdivacky return true; 212199482Srdivacky } 213199482Srdivacky 214210299Sed // Set up the file and source managers, if needed. 215210299Sed if (!CI.hasFileManager()) 216210299Sed CI.createFileManager(); 217210299Sed if (!CI.hasSourceManager()) 218218893Sdim CI.createSourceManager(CI.getFileManager()); 219210299Sed 220210299Sed // IR files bypass the rest of initialization. 221243830Sdim if (Input.getKind() == IK_LLVM_IR) { 222210299Sed assert(hasIRSupport() && 223210299Sed "This action does not have IR file support!"); 224210299Sed 225210299Sed // Inform the diagnostic client we are processing a source file. 226210299Sed CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); 227239462Sdim HasBegunSourceFile = true; 228210299Sed 229210299Sed // Initialize the action. 230243830Sdim if (!BeginSourceFileAction(CI, InputFile)) 231210299Sed goto failure; 232210299Sed 233210299Sed return true; 234210299Sed } 235210299Sed 236243830Sdim // If the implicit PCH include is actually a directory, rather than 237243830Sdim // a single file, search for a suitable PCH file in that directory. 238243830Sdim if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 239243830Sdim FileManager &FileMgr = CI.getFileManager(); 240243830Sdim PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); 241243830Sdim StringRef PCHInclude = PPOpts.ImplicitPCHInclude; 242243830Sdim if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) { 243243830Sdim llvm::error_code EC; 244243830Sdim SmallString<128> DirNative; 245243830Sdim llvm::sys::path::native(PCHDir->getName(), DirNative); 246243830Sdim bool Found = false; 247243830Sdim for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 248243830Sdim Dir != DirEnd && !EC; Dir.increment(EC)) { 249243830Sdim // Check whether this is an acceptable AST file. 250243830Sdim if (ASTReader::isAcceptableASTFile(Dir->path(), FileMgr, 251243830Sdim CI.getLangOpts(), 252243830Sdim CI.getTargetOpts(), 253243830Sdim CI.getPreprocessorOpts())) { 254249423Sdim PPOpts.ImplicitPCHInclude = Dir->path(); 255249423Sdim Found = true; 256243830Sdim break; 257243830Sdim } 258243830Sdim } 259243830Sdim 260243830Sdim if (!Found) { 261243830Sdim CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude; 262243830Sdim return true; 263243830Sdim } 264243830Sdim } 265243830Sdim } 266243830Sdim 267210299Sed // Set up the preprocessor. 268210299Sed CI.createPreprocessor(); 269210299Sed 270199482Srdivacky // Inform the diagnostic client we are processing a source file. 271199482Srdivacky CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 272199482Srdivacky &CI.getPreprocessor()); 273239462Sdim HasBegunSourceFile = true; 274199482Srdivacky 275199482Srdivacky // Initialize the action. 276243830Sdim if (!BeginSourceFileAction(CI, InputFile)) 277199482Srdivacky goto failure; 278199482Srdivacky 279249423Sdim // Create the AST context and consumer unless this is a preprocessor only 280249423Sdim // action. 281199482Srdivacky if (!usesPreprocessorOnly()) { 282199482Srdivacky CI.createASTContext(); 283199482Srdivacky 284234353Sdim OwningPtr<ASTConsumer> Consumer( 285243830Sdim CreateWrappedASTConsumer(CI, InputFile)); 286218893Sdim if (!Consumer) 287218893Sdim goto failure; 288212904Sdim 289218893Sdim CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); 290243830Sdim 291221345Sdim if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { 292221345Sdim // Convert headers to PCH and chain them. 293234353Sdim OwningPtr<ExternalASTSource> source; 294221345Sdim source.reset(ChainedIncludesSource::create(CI)); 295221345Sdim if (!source) 296221345Sdim goto failure; 297251662Sdim CI.setModuleManager(static_cast<ASTReader*>( 298251662Sdim &static_cast<ChainedIncludesSource*>(source.get())->getFinalReader())); 299221345Sdim CI.getASTContext().setExternalSource(source); 300221345Sdim 301221345Sdim } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 302221345Sdim // Use PCH. 303199482Srdivacky assert(hasPCHSupport() && "This action does not have PCH support!"); 304226633Sdim ASTDeserializationListener *DeserialListener = 305226633Sdim Consumer->GetASTDeserializationListener(); 306218893Sdim if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) 307218893Sdim DeserialListener = new DeserializedDeclsDumper(DeserialListener); 308218893Sdim if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) 309218893Sdim DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(), 310218893Sdim CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, 311218893Sdim DeserialListener); 312199482Srdivacky CI.createPCHExternalASTSource( 313212904Sdim CI.getPreprocessorOpts().ImplicitPCHInclude, 314212904Sdim CI.getPreprocessorOpts().DisablePCHValidation, 315234353Sdim CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, 316218893Sdim DeserialListener); 317199482Srdivacky if (!CI.getASTContext().getExternalSource()) 318199482Srdivacky goto failure; 319199482Srdivacky } 320210299Sed 321212904Sdim CI.setASTConsumer(Consumer.take()); 322210299Sed if (!CI.hasASTConsumer()) 323210299Sed goto failure; 324199482Srdivacky } 325199482Srdivacky 326226633Sdim // Initialize built-in info as long as we aren't using an external AST 327199482Srdivacky // source. 328199482Srdivacky if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { 329199482Srdivacky Preprocessor &PP = CI.getPreprocessor(); 330199482Srdivacky PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), 331234353Sdim PP.getLangOpts()); 332199482Srdivacky } 333199482Srdivacky 334234353Sdim // If there is a layout overrides file, attach an external AST source that 335234353Sdim // provides the layouts from that file. 336234353Sdim if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 337234353Sdim CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { 338234353Sdim OwningPtr<ExternalASTSource> 339234353Sdim Override(new LayoutOverrideSource( 340234353Sdim CI.getFrontendOpts().OverrideRecordLayoutsFile)); 341234353Sdim CI.getASTContext().setExternalSource(Override); 342234353Sdim } 343234353Sdim 344199482Srdivacky return true; 345199482Srdivacky 346199482Srdivacky // If we failed, reset state since the client will not end up calling the 347199482Srdivacky // matching EndSourceFile(). 348199482Srdivacky failure: 349199482Srdivacky if (isCurrentFileAST()) { 350221345Sdim CI.setASTContext(0); 351221345Sdim CI.setPreprocessor(0); 352221345Sdim CI.setSourceManager(0); 353221345Sdim CI.setFileManager(0); 354199482Srdivacky } 355199482Srdivacky 356239462Sdim if (HasBegunSourceFile) 357239462Sdim CI.getDiagnosticClient().EndSourceFile(); 358243830Sdim CI.clearOutputFiles(/*EraseFiles=*/true); 359234353Sdim setCurrentInput(FrontendInputFile()); 360199482Srdivacky setCompilerInstance(0); 361199482Srdivacky return false; 362199482Srdivacky} 363199482Srdivacky 364239462Sdimbool FrontendAction::Execute() { 365199482Srdivacky CompilerInstance &CI = getCompilerInstance(); 366199482Srdivacky 367199482Srdivacky // Initialize the main file entry. This needs to be delayed until after PCH 368199482Srdivacky // has loaded. 369234353Sdim if (!isCurrentFileAST()) { 370243830Sdim if (!CI.InitializeSourceManager(getCurrentInput())) 371239462Sdim return false; 372199482Srdivacky } 373199482Srdivacky 374199990Srdivacky if (CI.hasFrontendTimer()) { 375199990Srdivacky llvm::TimeRegion Timer(CI.getFrontendTimer()); 376199990Srdivacky ExecuteAction(); 377199990Srdivacky } 378199990Srdivacky else ExecuteAction(); 379239462Sdim 380249423Sdim // If we are supposed to rebuild the global module index, do so now unless 381249423Sdim // there were any module-build failures. 382249423Sdim if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() && 383249423Sdim CI.hasPreprocessor()) { 384249423Sdim GlobalModuleIndex::writeIndex( 385249423Sdim CI.getFileManager(), 386249423Sdim CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 387249423Sdim } 388249423Sdim 389239462Sdim return true; 390199482Srdivacky} 391199482Srdivacky 392199482Srdivackyvoid FrontendAction::EndSourceFile() { 393199482Srdivacky CompilerInstance &CI = getCompilerInstance(); 394199482Srdivacky 395218893Sdim // Inform the diagnostic client we are done with this source file. 396218893Sdim CI.getDiagnosticClient().EndSourceFile(); 397218893Sdim 398199482Srdivacky // Finalize the action. 399199482Srdivacky EndSourceFileAction(); 400199482Srdivacky 401199482Srdivacky // Release the consumer and the AST, in that order since the consumer may 402199482Srdivacky // perform actions in its destructor which require the context. 403199482Srdivacky // 404199482Srdivacky // FIXME: There is more per-file stuff we could just drop here? 405199482Srdivacky if (CI.getFrontendOpts().DisableFree) { 406199482Srdivacky CI.takeASTConsumer(); 407212904Sdim if (!isCurrentFileAST()) { 408212904Sdim CI.takeSema(); 409221345Sdim CI.resetAndLeakASTContext(); 410212904Sdim } 411199482Srdivacky } else { 412212904Sdim if (!isCurrentFileAST()) { 413212904Sdim CI.setSema(0); 414212904Sdim CI.setASTContext(0); 415212904Sdim } 416199482Srdivacky CI.setASTConsumer(0); 417199482Srdivacky } 418199482Srdivacky 419206084Srdivacky // Inform the preprocessor we are done. 420206084Srdivacky if (CI.hasPreprocessor()) 421206084Srdivacky CI.getPreprocessor().EndSourceFile(); 422206084Srdivacky 423199482Srdivacky if (CI.getFrontendOpts().ShowStats) { 424199482Srdivacky llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n"; 425199482Srdivacky CI.getPreprocessor().PrintStats(); 426199482Srdivacky CI.getPreprocessor().getIdentifierTable().PrintStats(); 427199482Srdivacky CI.getPreprocessor().getHeaderSearchInfo().PrintStats(); 428199482Srdivacky CI.getSourceManager().PrintStats(); 429199482Srdivacky llvm::errs() << "\n"; 430199482Srdivacky } 431199482Srdivacky 432263508Sdim // Cleanup the output streams, and erase the output files if instructed by the 433263508Sdim // FrontendAction. 434263508Sdim CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles()); 435199482Srdivacky 436199482Srdivacky if (isCurrentFileAST()) { 437212904Sdim CI.takeSema(); 438221345Sdim CI.resetAndLeakASTContext(); 439221345Sdim CI.resetAndLeakPreprocessor(); 440221345Sdim CI.resetAndLeakSourceManager(); 441221345Sdim CI.resetAndLeakFileManager(); 442199482Srdivacky } 443199482Srdivacky 444199482Srdivacky setCompilerInstance(0); 445234353Sdim setCurrentInput(FrontendInputFile()); 446199482Srdivacky} 447199482Srdivacky 448263508Sdimbool FrontendAction::shouldEraseOutputFiles() { 449263508Sdim return getCompilerInstance().getDiagnostics().hasErrorOccurred(); 450263508Sdim} 451263508Sdim 452199482Srdivacky//===----------------------------------------------------------------------===// 453199482Srdivacky// Utility Actions 454199482Srdivacky//===----------------------------------------------------------------------===// 455199482Srdivacky 456199482Srdivackyvoid ASTFrontendAction::ExecuteAction() { 457199482Srdivacky CompilerInstance &CI = getCompilerInstance(); 458263508Sdim if (!CI.hasPreprocessor()) 459263508Sdim return; 460199482Srdivacky 461199482Srdivacky // FIXME: Move the truncation aspect of this into Sema, we delayed this till 462199482Srdivacky // here so the source manager would be initialized. 463199482Srdivacky if (hasCodeCompletionSupport() && 464199482Srdivacky !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) 465199482Srdivacky CI.createCodeCompletionConsumer(); 466199482Srdivacky 467199482Srdivacky // Use a code completion consumer? 468199482Srdivacky CodeCompleteConsumer *CompletionConsumer = 0; 469199482Srdivacky if (CI.hasCodeCompletionConsumer()) 470199482Srdivacky CompletionConsumer = &CI.getCodeCompletionConsumer(); 471199482Srdivacky 472212904Sdim if (!CI.hasSema()) 473226633Sdim CI.createSema(getTranslationUnitKind(), CompletionConsumer); 474212904Sdim 475234353Sdim ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats, 476234353Sdim CI.getFrontendOpts().SkipFunctionBodies); 477199482Srdivacky} 478199482Srdivacky 479234353Sdimvoid PluginASTAction::anchor() { } 480234353Sdim 481199482SrdivackyASTConsumer * 482199482SrdivackyPreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI, 483226633Sdim StringRef InFile) { 484200583Srdivacky llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!"); 485199482Srdivacky} 486224145Sdim 487224145SdimASTConsumer *WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI, 488226633Sdim StringRef InFile) { 489224145Sdim return WrappedAction->CreateASTConsumer(CI, InFile); 490224145Sdim} 491224145Sdimbool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) { 492224145Sdim return WrappedAction->BeginInvocation(CI); 493224145Sdim} 494224145Sdimbool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI, 495226633Sdim StringRef Filename) { 496234353Sdim WrappedAction->setCurrentInput(getCurrentInput()); 497224145Sdim WrappedAction->setCompilerInstance(&CI); 498224145Sdim return WrappedAction->BeginSourceFileAction(CI, Filename); 499224145Sdim} 500224145Sdimvoid WrapperFrontendAction::ExecuteAction() { 501224145Sdim WrappedAction->ExecuteAction(); 502224145Sdim} 503224145Sdimvoid WrapperFrontendAction::EndSourceFileAction() { 504224145Sdim WrappedAction->EndSourceFileAction(); 505224145Sdim} 506224145Sdim 507224145Sdimbool WrapperFrontendAction::usesPreprocessorOnly() const { 508224145Sdim return WrappedAction->usesPreprocessorOnly(); 509224145Sdim} 510226633SdimTranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() { 511226633Sdim return WrappedAction->getTranslationUnitKind(); 512224145Sdim} 513224145Sdimbool WrapperFrontendAction::hasPCHSupport() const { 514224145Sdim return WrappedAction->hasPCHSupport(); 515224145Sdim} 516224145Sdimbool WrapperFrontendAction::hasASTFileSupport() const { 517224145Sdim return WrappedAction->hasASTFileSupport(); 518224145Sdim} 519224145Sdimbool WrapperFrontendAction::hasIRSupport() const { 520224145Sdim return WrappedAction->hasIRSupport(); 521224145Sdim} 522224145Sdimbool WrapperFrontendAction::hasCodeCompletionSupport() const { 523224145Sdim return WrappedAction->hasCodeCompletionSupport(); 524224145Sdim} 525224145Sdim 526224145SdimWrapperFrontendAction::WrapperFrontendAction(FrontendAction *WrappedAction) 527224145Sdim : WrappedAction(WrappedAction) {} 528224145Sdim 529