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