FrontendAction.cpp revision ac447fce02d119fb70f0aab885d836dea43e7f26
13b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko//===--- FrontendAction.cpp -----------------------------------------------===//
23b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko//
33b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko//                     The LLVM Compiler Infrastructure
43b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko//
53b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko// This file is distributed under the University of Illinois Open Source
63b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko// License. See LICENSE.TXT for details.
73b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko//
83b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko//===----------------------------------------------------------------------===//
93b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
103b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Frontend/FrontendAction.h"
113b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/AST/ASTConsumer.h"
123b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/AST/ASTContext.h"
133b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/AST/DeclGroup.h"
143b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Lex/HeaderSearch.h"
153b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Lex/Preprocessor.h"
163b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Frontend/ASTUnit.h"
173b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Frontend/ChainedIncludesSource.h"
183b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Frontend/CompilerInstance.h"
193b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Frontend/FrontendDiagnostic.h"
203b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Frontend/FrontendPluginRegistry.h"
213b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Frontend/LayoutOverrideSource.h"
223b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Frontend/MultiplexConsumer.h"
233b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Parse/ParseAST.h"
243b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Serialization/ASTDeserializationListener.h"
253b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "clang/Serialization/ASTReader.h"
263b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "llvm/Support/MemoryBuffer.h"
273b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "llvm/Support/Timer.h"
283b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "llvm/Support/ErrorHandling.h"
293b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko#include "llvm/Support/raw_ostream.h"
303b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkousing namespace clang;
313b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
323b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkonamespace {
333b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
343b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkoclass DelegatingDeserializationListener : public ASTDeserializationListener {
353b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  ASTDeserializationListener *Previous;
363b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
373b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkopublic:
383b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  explicit DelegatingDeserializationListener(
393b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                           ASTDeserializationListener *Previous)
403b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    : Previous(Previous) { }
413b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
423b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  virtual void ReaderInitialized(ASTReader *Reader) {
433b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (Previous)
443b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      Previous->ReaderInitialized(Reader);
453b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
463b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  virtual void IdentifierRead(serialization::IdentID ID,
473b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                              IdentifierInfo *II) {
483b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (Previous)
493b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      Previous->IdentifierRead(ID, II);
503b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
513b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  virtual void TypeRead(serialization::TypeIdx Idx, QualType T) {
523b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (Previous)
533b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      Previous->TypeRead(Idx, T);
543b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
553b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
563b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (Previous)
573b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      Previous->DeclRead(ID, D);
583b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
593b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  virtual void SelectorRead(serialization::SelectorID ID, Selector Sel) {
603b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (Previous)
613b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      Previous->SelectorRead(ID, Sel);
623b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
633b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  virtual void MacroDefinitionRead(serialization::PreprocessedEntityID PPID,
643b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                   MacroDefinition *MD) {
653b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (Previous)
663b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      Previous->MacroDefinitionRead(PPID, MD);
673b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
683b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko};
693b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
703b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko/// \brief Dumps deserialized declarations.
713b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkoclass DeserializedDeclsDumper : public DelegatingDeserializationListener {
723b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkopublic:
733b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous)
743b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    : DelegatingDeserializationListener(Previous) { }
753b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
763b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
773b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    llvm::outs() << "PCH DECL: " << D->getDeclKindName();
783b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
793b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      llvm::outs() << " - " << *ND;
803b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    llvm::outs() << "\n";
813b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
823b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    DelegatingDeserializationListener::DeclRead(ID, D);
833b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
843b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko};
853b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
863b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko/// \brief Checks deserialized declarations and emits error if a name
873b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko/// matches one given in command-line using -error-on-deserialized-decl.
883b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkoclass DeserializedDeclsChecker : public DelegatingDeserializationListener {
893b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  ASTContext &Ctx;
903b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  std::set<std::string> NamesToCheck;
913b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
923b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkopublic:
933b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  DeserializedDeclsChecker(ASTContext &Ctx,
943b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                           const std::set<std::string> &NamesToCheck,
953b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                           ASTDeserializationListener *Previous)
963b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    : DelegatingDeserializationListener(Previous),
973b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      Ctx(Ctx), NamesToCheck(NamesToCheck) { }
983b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
993b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
1003b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
1013b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
1023b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        unsigned DiagID
1033b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko          = Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
1043b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                                 "%0 was deserialized");
1053b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
1063b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko            << ND->getNameAsString();
1073b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      }
1083b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1093b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    DelegatingDeserializationListener::DeclRead(ID, D);
1103b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
1113b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko};
1123b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1133b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko} // end anonymous namespace
1143b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1153b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander KornienkoFrontendAction::FrontendAction() : Instance(0) {}
1163b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1173b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander KornienkoFrontendAction::~FrontendAction() {}
1183b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1193b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkovoid FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput,
1203b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                     ASTUnit *AST) {
1213b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  this->CurrentInput = CurrentInput;
1223b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  CurrentASTUnit.reset(AST);
1233b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko}
1243b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1253b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander KornienkoASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
1263b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                                      StringRef InFile) {
1273b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  ASTConsumer* Consumer = CreateASTConsumer(CI, InFile);
1283b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  if (!Consumer)
1293b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    return 0;
1303b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1313b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  if (CI.getFrontendOpts().AddPluginActions.size() == 0)
1323b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    return Consumer;
1333b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1343b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  // Make sure the non-plugin consumer is first, so that plugins can't
1353b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  // modifiy the AST.
1363b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  std::vector<ASTConsumer*> Consumers(1, Consumer);
1373b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1383b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size();
1393b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko       i != e; ++i) {
1403b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    // This is O(|plugins| * |add_plugins|), but since both numbers are
1413b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    // way below 50 in practice, that's ok.
1423b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    for (FrontendPluginRegistry::iterator
1433b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        it = FrontendPluginRegistry::begin(),
1443b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        ie = FrontendPluginRegistry::end();
1453b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        it != ie; ++it) {
1463b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) {
1473b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        OwningPtr<PluginASTAction> P(it->instantiate());
1483b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        FrontendAction* c = P.get();
1493b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i]))
1503b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko          Consumers.push_back(c->CreateASTConsumer(CI, InFile));
1513b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      }
1523b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    }
1533b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
1543b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1553b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  return new MultiplexConsumer(Consumers);
1563b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko}
1573b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1583b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienkobool FrontendAction::BeginSourceFile(CompilerInstance &CI,
1593b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                     const FrontendInputFile &Input) {
1603b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  assert(!Instance && "Already processing a source file!");
1613b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  assert(!Input.File.empty() && "Unexpected empty filename!");
1623b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  setCurrentInput(Input);
1633b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  setCompilerInstance(&CI);
1643b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1653b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  bool HasBegunSourceFile = false;
1663b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  if (!BeginInvocation(CI))
1673b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    goto failure;
1683b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1693b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  // AST files follow a very different path, since they share objects via the
1703b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  // AST unit.
1713b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  if (Input.Kind == IK_AST) {
1723b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    assert(!usesPreprocessorOnly() &&
1733b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko           "Attempt to pass AST file to preprocessor only action!");
1743b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    assert(hasASTFileSupport() &&
1753b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko           "This action does not have AST file support!");
1763b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1773b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
1783b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    std::string Error;
1793b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    ASTUnit *AST = ASTUnit::LoadFromASTFile(Input.File, Diags,
1803b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                            CI.getFileSystemOpts());
1813b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (!AST)
1823b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      goto failure;
1833b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1843b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    setCurrentInput(Input, AST);
1853b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1863b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    // Set the shared objects, these are reset when we finish processing the
1873b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    // file, otherwise the CompilerInstance will happily destroy them.
1883b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.setFileManager(&AST->getFileManager());
1893b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.setSourceManager(&AST->getSourceManager());
1903b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.setPreprocessor(&AST->getPreprocessor());
1913b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.setASTContext(&AST->getASTContext());
1923b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1933b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    // Initialize the action.
1943b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (!BeginSourceFileAction(CI, Input.File))
1953b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      goto failure;
1963b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
1973b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    /// Create the AST consumer.
1983b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.setASTConsumer(CreateWrappedASTConsumer(CI, Input.File));
1993b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (!CI.hasASTConsumer())
2003b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      goto failure;
2013b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2023b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    return true;
2033b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
2043b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2053b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  // Set up the file and source managers, if needed.
2063b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  if (!CI.hasFileManager())
2073b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.createFileManager();
2083b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  if (!CI.hasSourceManager())
2093b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.createSourceManager(CI.getFileManager());
2103b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2113b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  // IR files bypass the rest of initialization.
2123b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  if (Input.Kind == IK_LLVM_IR) {
2133b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    assert(hasIRSupport() &&
2143b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko           "This action does not have IR file support!");
2153b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2163b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    // Inform the diagnostic client we are processing a source file.
2173b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
2183b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    HasBegunSourceFile = true;
2193b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2203b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    // Initialize the action.
2213b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (!BeginSourceFileAction(CI, Input.File))
2223b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      goto failure;
2233b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2243b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    return true;
2253b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  }
2263b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2273b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  // Set up the preprocessor.
2283b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  CI.createPreprocessor();
2293b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2303b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  // Inform the diagnostic client we are processing a source file.
2313b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
2323b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                           &CI.getPreprocessor());
2333b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  HasBegunSourceFile = true;
2343b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2353b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  // Initialize the action.
2363b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  if (!BeginSourceFileAction(CI, Input.File))
2373b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    goto failure;
2383b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2393b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  /// Create the AST context and consumer unless this is a preprocessor only
2403b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  /// action.
2413b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko  if (!usesPreprocessorOnly()) {
2423b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.createASTContext();
2433b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2443b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    OwningPtr<ASTConsumer> Consumer(
2453b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                   CreateWrappedASTConsumer(CI, Input.File));
2463b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (!Consumer)
2473b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      goto failure;
2483b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2493b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
2503b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    CI.getPreprocessor().setPPMutationListener(
2513b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      Consumer->GetPPMutationListener());
2523b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2533b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
2543b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      // Convert headers to PCH and chain them.
2553b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      OwningPtr<ExternalASTSource> source;
2563b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      source.reset(ChainedIncludesSource::create(CI));
2573b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      if (!source)
2583b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        goto failure;
2593b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      CI.getASTContext().setExternalSource(source);
2603b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
2613b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
2623b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      // Use PCH.
2633b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      assert(hasPCHSupport() && "This action does not have PCH support!");
2643b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      ASTDeserializationListener *DeserialListener =
2653b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko          Consumer->GetASTDeserializationListener();
2663b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls)
2673b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        DeserialListener = new DeserializedDeclsDumper(DeserialListener);
2683b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty())
2693b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(),
2703b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                         CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
2713b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                                        DeserialListener);
2723b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      CI.createPCHExternalASTSource(
2733b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                CI.getPreprocessorOpts().ImplicitPCHInclude,
2743b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                CI.getPreprocessorOpts().DisablePCHValidation,
2753b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                CI.getPreprocessorOpts().DisableStatCache,
2763b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                            CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
2773b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko                                DeserialListener);
2783b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko      if (!CI.getASTContext().getExternalSource())
2793b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko        goto failure;
2803b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko    }
2813b71155dc93fb3556dfe8b758ae6e448b6fbb9c8Alexander Kornienko
282    CI.setASTConsumer(Consumer.take());
283    if (!CI.hasASTConsumer())
284      goto failure;
285  }
286
287  // Initialize built-in info as long as we aren't using an external AST
288  // source.
289  if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
290    Preprocessor &PP = CI.getPreprocessor();
291    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
292                                           PP.getLangOpts());
293  }
294
295  // If there is a layout overrides file, attach an external AST source that
296  // provides the layouts from that file.
297  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
298      CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
299    OwningPtr<ExternalASTSource>
300      Override(new LayoutOverrideSource(
301                     CI.getFrontendOpts().OverrideRecordLayoutsFile));
302    CI.getASTContext().setExternalSource(Override);
303  }
304
305  return true;
306
307  // If we failed, reset state since the client will not end up calling the
308  // matching EndSourceFile().
309  failure:
310  if (isCurrentFileAST()) {
311    CI.setASTContext(0);
312    CI.setPreprocessor(0);
313    CI.setSourceManager(0);
314    CI.setFileManager(0);
315  }
316
317  if (HasBegunSourceFile)
318    CI.getDiagnosticClient().EndSourceFile();
319  CI.clearOutputFiles(/*EraseFiles=*/true);
320  setCurrentInput(FrontendInputFile());
321  setCompilerInstance(0);
322  return false;
323}
324
325bool FrontendAction::Execute() {
326  CompilerInstance &CI = getCompilerInstance();
327
328  // Initialize the main file entry. This needs to be delayed until after PCH
329  // has loaded.
330  if (!isCurrentFileAST()) {
331    if (!CI.InitializeSourceManager(getCurrentFile(),
332                                    getCurrentInput().IsSystem
333                                      ? SrcMgr::C_System
334                                      : SrcMgr::C_User))
335      return false;
336  }
337
338  if (CI.hasFrontendTimer()) {
339    llvm::TimeRegion Timer(CI.getFrontendTimer());
340    ExecuteAction();
341  }
342  else ExecuteAction();
343
344  return true;
345}
346
347void FrontendAction::EndSourceFile() {
348  CompilerInstance &CI = getCompilerInstance();
349
350  // Inform the diagnostic client we are done with this source file.
351  CI.getDiagnosticClient().EndSourceFile();
352
353  // Finalize the action.
354  EndSourceFileAction();
355
356  // Release the consumer and the AST, in that order since the consumer may
357  // perform actions in its destructor which require the context.
358  //
359  // FIXME: There is more per-file stuff we could just drop here?
360  if (CI.getFrontendOpts().DisableFree) {
361    CI.takeASTConsumer();
362    if (!isCurrentFileAST()) {
363      CI.takeSema();
364      CI.resetAndLeakASTContext();
365    }
366  } else {
367    if (!isCurrentFileAST()) {
368      CI.setSema(0);
369      CI.setASTContext(0);
370    }
371    CI.setASTConsumer(0);
372  }
373
374  // Inform the preprocessor we are done.
375  if (CI.hasPreprocessor())
376    CI.getPreprocessor().EndSourceFile();
377
378  if (CI.getFrontendOpts().ShowStats) {
379    llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n";
380    CI.getPreprocessor().PrintStats();
381    CI.getPreprocessor().getIdentifierTable().PrintStats();
382    CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
383    CI.getSourceManager().PrintStats();
384    llvm::errs() << "\n";
385  }
386
387  // Cleanup the output streams, and erase the output files if we encountered
388  // an error.
389  CI.clearOutputFiles(/*EraseFiles=*/CI.getDiagnostics().hasErrorOccurred());
390
391  if (isCurrentFileAST()) {
392    CI.takeSema();
393    CI.resetAndLeakASTContext();
394    CI.resetAndLeakPreprocessor();
395    CI.resetAndLeakSourceManager();
396    CI.resetAndLeakFileManager();
397  }
398
399  setCompilerInstance(0);
400  setCurrentInput(FrontendInputFile());
401}
402
403//===----------------------------------------------------------------------===//
404// Utility Actions
405//===----------------------------------------------------------------------===//
406
407void ASTFrontendAction::ExecuteAction() {
408  CompilerInstance &CI = getCompilerInstance();
409
410  // FIXME: Move the truncation aspect of this into Sema, we delayed this till
411  // here so the source manager would be initialized.
412  if (hasCodeCompletionSupport() &&
413      !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
414    CI.createCodeCompletionConsumer();
415
416  // Use a code completion consumer?
417  CodeCompleteConsumer *CompletionConsumer = 0;
418  if (CI.hasCodeCompletionConsumer())
419    CompletionConsumer = &CI.getCodeCompletionConsumer();
420
421  if (!CI.hasSema())
422    CI.createSema(getTranslationUnitKind(), CompletionConsumer);
423
424  ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats,
425           CI.getFrontendOpts().SkipFunctionBodies);
426}
427
428void PluginASTAction::anchor() { }
429
430ASTConsumer *
431PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
432                                              StringRef InFile) {
433  llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
434}
435
436ASTConsumer *WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
437                                                      StringRef InFile) {
438  return WrappedAction->CreateASTConsumer(CI, InFile);
439}
440bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) {
441  return WrappedAction->BeginInvocation(CI);
442}
443bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI,
444                                                  StringRef Filename) {
445  WrappedAction->setCurrentInput(getCurrentInput());
446  WrappedAction->setCompilerInstance(&CI);
447  return WrappedAction->BeginSourceFileAction(CI, Filename);
448}
449void WrapperFrontendAction::ExecuteAction() {
450  WrappedAction->ExecuteAction();
451}
452void WrapperFrontendAction::EndSourceFileAction() {
453  WrappedAction->EndSourceFileAction();
454}
455
456bool WrapperFrontendAction::usesPreprocessorOnly() const {
457  return WrappedAction->usesPreprocessorOnly();
458}
459TranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() {
460  return WrappedAction->getTranslationUnitKind();
461}
462bool WrapperFrontendAction::hasPCHSupport() const {
463  return WrappedAction->hasPCHSupport();
464}
465bool WrapperFrontendAction::hasASTFileSupport() const {
466  return WrappedAction->hasASTFileSupport();
467}
468bool WrapperFrontendAction::hasIRSupport() const {
469  return WrappedAction->hasIRSupport();
470}
471bool WrapperFrontendAction::hasCodeCompletionSupport() const {
472  return WrappedAction->hasCodeCompletionSupport();
473}
474
475WrapperFrontendAction::WrapperFrontendAction(FrontendAction *WrappedAction)
476  : WrappedAction(WrappedAction) {}
477
478