ASTUnit.cpp revision f7acc37450d59ef751df73acb91de73850cc6517
14b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===//
24b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
34b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
44b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
54b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
64b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
74b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
84b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
94b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
104b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// ASTUnit Implementation.
114b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
124b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
134b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis
140853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Frontend/ASTUnit.h"
150853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Frontend/PCHReader.h"
160853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/ASTContext.h"
17521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/AST/ASTConsumer.h"
180853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/DeclVisitor.h"
190853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/StmtVisitor.h"
207b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Compilation.h"
217b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Driver.h"
227b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Job.h"
237b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Tool.h"
24521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/CompilerInstance.h"
25521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendActions.h"
267b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h"
27521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendOptions.h"
280853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h"
290853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h"
30d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar#include "clang/Basic/TargetOptions.h"
310853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h"
320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h"
334db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor#include "llvm/Support/MemoryBuffer.h"
347b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "llvm/System/Host.h"
354a630d30cd8ee9c8f46b8d3c9ad7e7e00d393f32Benjamin Kramer#include "llvm/System/Path.h"
360853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisusing namespace clang;
370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
385262fda30b876c8aae95f2eb92e349418d6b14bbDaniel DunbarASTUnit::ASTUnit(bool _MainFileIsAST)
395262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar  : tempFile(false), MainFileIsAST(_MainFileIsAST) {
4036c4464ba6cfc2a63dc67c493ef2f5ab2aea09ccSteve Naroff}
41521bf9c529e653ab28896d027352d3e16e2672d5Daniel DunbarASTUnit::~ASTUnit() {
42e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff  if (tempFile)
434a630d30cd8ee9c8f46b8d3c9ad7e7e00d393f32Benjamin Kramer    llvm::sys::Path(getPCHFileName()).eraseFromDisk();
44e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff}
450853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
460853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisnamespace {
470853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
480853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// \brief Gathers information from PCHReader that will be used to initialize
490853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// a Preprocessor.
50bd21828179a61bd0954b082825cfb8a93345f602Benjamin Kramerclass PCHInfoCollector : public PCHReaderListener {
510853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  LangOptions &LangOpt;
520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  HeaderSearch &HSI;
530853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  std::string &TargetTriple;
540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  std::string &Predefines;
550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  unsigned &Counter;
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
570853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  unsigned NumHeaderInfos;
581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
590853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidispublic:
600853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI,
610853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                   std::string &TargetTriple, std::string &Predefines,
620853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                   unsigned &Counter)
630853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple),
640853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis      Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {}
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
660853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  virtual bool ReadLanguageOptions(const LangOptions &LangOpts) {
670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    LangOpt = LangOpts;
680853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return false;
690853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71dc3c0d20375bda7775b2fade05b20e315798b9feDaniel Dunbar  virtual bool ReadTargetTriple(llvm::StringRef Triple) {
720853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    TargetTriple = Triple;
730853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return false;
740853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
76dc3c0d20375bda7775b2fade05b20e315798b9feDaniel Dunbar  virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
770853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                    FileID PCHBufferID,
787b5a1210d93ca62ecd61800f245c87259b1f8f79Daniel Dunbar                                    llvm::StringRef OriginalFileName,
790853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                    std::string &SuggestedPredefines) {
800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    Predefines = PCHPredef;
810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return false;
820853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
840853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI) {
850853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
860853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
880853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  virtual void ReadCounter(unsigned Value) {
890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    Counter = Value;
900853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
910853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis};
920853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
930853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} // anonymous namespace
940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
9577accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroffconst std::string &ASTUnit::getOriginalSourceFileName() {
9668d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar  return OriginalSourceFile;
9777accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff}
980853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
99e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroffconst std::string &ASTUnit::getPCHFileName() {
100c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar  assert(isMainFileAST() && "Not an ASTUnit from a PCH file!");
1017297c18c843138625a61e01a137664a176739683Benjamin Kramer  return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName();
102e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff}
103e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff
1040853a02c3b04d96a3c432b883e403175c954cd81Argyrios KyrtzidisASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
1055262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar                                  Diagnostic &Diags,
1065cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek                                  bool OnlyLocalDecls,
1074db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                  bool UseBumpAllocator,
1084db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                  RemappedFile *RemappedFiles,
1094db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                  unsigned NumRemappedFiles) {
1105262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar  llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
1117d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor  AST->OnlyLocalDecls = OnlyLocalDecls;
11236c4464ba6cfc2a63dc67c493ef2f5ab2aea09ccSteve Naroff  AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
1130853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
1144db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
1154db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    // Create the file entry for the file that we're mapping from.
1164db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    const FileEntry *FromFile
1174db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor      = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
1184db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                    RemappedFiles[I].second->getBufferSize(),
1194db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                             0);
1204db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    if (!FromFile) {
1214db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor      Diags.Report(diag::err_fe_remap_missing_from_file)
1224db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor        << RemappedFiles[I].first;
1234db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor      continue;
1244db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    }
1254db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor
1264db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    // Override the contents of the "from" file with the contents of
1274db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    // the "to" file.
1284db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    AST->getSourceManager().overrideFileContents(FromFile,
1294db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                                 RemappedFiles[I].second);
1304db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  }
1314db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor
1320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Gather Info for preprocessor construction later on.
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1340853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  LangOptions LangInfo;
1350853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  HeaderSearch &HeaderInfo = *AST->HeaderInfo.get();
1360853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  std::string TargetTriple;
1370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  std::string Predefines;
1380853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  unsigned Counter;
1390853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
140bce6f62ae7d2c15992617f64e30067803fb5b47fDaniel Dunbar  llvm::OwningPtr<PCHReader> Reader;
1410853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  llvm::OwningPtr<ExternalASTSource> Source;
1420853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
143fc0622155fa61349698a8fd0053773c37d9f7ac4Ted Kremenek  Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(),
1445262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar                             Diags));
145cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple,
146cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar                                           Predefines, Counter));
147cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar
148cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  switch (Reader->ReadPCH(Filename)) {
1490853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  case PCHReader::Success:
1500853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    break;
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  case PCHReader::Failure:
153106c9981f18084e60602244f1feaeabbbe8ab5e8Argyrios Kyrtzidis  case PCHReader::IgnorePCH:
1545262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar    Diags.Report(diag::err_fe_unable_to_load_pch);
1550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return NULL;
1560853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15868d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar  AST->OriginalSourceFile = Reader->getOriginalSourceFile();
15968d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar
1600853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // PCH loaded successfully. Now create the preprocessor.
1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1620853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Get information about the target being compiled for.
163d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  //
164d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  // FIXME: This is broken, we should store the TargetOptions in the PCH.
165d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOptions TargetOpts;
166d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOpts.ABI = "";
167d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOpts.CPU = "";
168d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOpts.Features.clear();
169d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOpts.Triple = TargetTriple;
1705262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar  AST->Target.reset(TargetInfo::CreateTargetInfo(Diags, TargetOpts));
1715262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar  AST->PP.reset(new Preprocessor(Diags, LangInfo, *AST->Target.get(),
17231b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar                                 AST->getSourceManager(), HeaderInfo));
1730853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  Preprocessor &PP = *AST->PP.get();
1740853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
175d5b6126389e1e2fd89e498fe17da4bb44ece0302Daniel Dunbar  PP.setPredefines(Reader->getSuggestedPredefines());
1760853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  PP.setCounterValue(Counter);
177cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  Reader->setPreprocessor(PP);
1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1790853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Create and initialize the ASTContext.
1800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
1810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  AST->Ctx.reset(new ASTContext(LangInfo,
18231b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar                                AST->getSourceManager(),
1830853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                *AST->Target.get(),
1840853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                PP.getIdentifierTable(),
1850853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                PP.getSelectorTable(),
1860853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                PP.getBuiltinInfo(),
1875cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek                                /* FreeMemory = */ !UseBumpAllocator,
1880853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                /* size_reserve = */0));
1890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  ASTContext &Context = *AST->Ctx.get();
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
191cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  Reader->InitializeContext(Context);
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1930853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Attach the PCH reader to the AST context as an external AST
1940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // source, so that declarations will be deserialized from the
1950853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // PCH file as needed.
196cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  Source.reset(Reader.take());
1970853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  Context.setExternalSource(Source);
1980853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
1991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return AST.take();
2000853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis}
201521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
202521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarnamespace {
203521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
204f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerConsumer : public ASTConsumer {
205f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  ASTUnit &Unit;
206f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
207f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic:
208f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  TopLevelDeclTrackerConsumer(ASTUnit &_Unit) : Unit(_Unit) {}
209f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
210f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  void HandleTopLevelDecl(DeclGroupRef D) {
211f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar    for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it)
212f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar      Unit.getTopLevelDecls().push_back(*it);
213f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  }
214f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar};
215f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
216f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerAction : public ASTFrontendAction {
217f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic:
218f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  ASTUnit &Unit;
219f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
220521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
221521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar                                         llvm::StringRef InFile) {
222f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar    return new TopLevelDeclTrackerConsumer(Unit);
223521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  }
224521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
225521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarpublic:
226f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
227f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
228521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  virtual bool hasCodeCompletionSupport() const { return false; }
229521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar};
230521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
231521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}
232521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
233f7acc37450d59ef751df73acb91de73850cc6517Daniel DunbarASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
234521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar                                             Diagnostic &Diags,
23568ea2ac7fd98a5a44c7a5b04c54076cf794531cbDaniel Dunbar                                             bool OnlyLocalDecls) {
236521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the compiler instance to use for building the AST.
237cb6dda1a7abe2fe30b0345bfbbf872cc73446678Daniel Dunbar  CompilerInstance Clang;
238521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  llvm::OwningPtr<ASTUnit> AST;
239f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
240521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
241f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbar  Clang.setInvocation(CI);
242521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
243521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.setDiagnostics(&Diags);
244521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.setDiagnosticClient(Diags.getClient());
245521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
246521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the target instance.
247521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
248521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar                                               Clang.getTargetOpts()));
249521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  if (!Clang.hasTarget())
250521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar    goto error;
251521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
252521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Inform the target of the language options.
253521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  //
254521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // FIXME: We shouldn't need to do this, the target should be immutable once
255521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // created. This complexity should be lifted elsewhere.
256521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
257521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
258521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  assert(Clang.getFrontendOpts().Inputs.size() == 1 &&
259521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar         "Invocation must have exactly one source file!");
260521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  assert(Clang.getFrontendOpts().Inputs[0].first != FrontendOptions::IK_AST &&
261521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar         "FIXME: AST inputs not yet supported here!");
262521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
263521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the AST unit.
264c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar  AST.reset(new ASTUnit(false));
265521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
26668ea2ac7fd98a5a44c7a5b04c54076cf794531cbDaniel Dunbar  AST->OnlyLocalDecls = OnlyLocalDecls;
26768d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar  AST->OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
26868d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar
269521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create a file manager object to provide access to and cache the filesystem.
270521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.setFileManager(&AST->getFileManager());
271521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
272521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the source manager.
273521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.setSourceManager(&AST->getSourceManager());
274521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
275521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the preprocessor.
276521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.createPreprocessor();
277521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
278f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  Act.reset(new TopLevelDeclTrackerAction(*AST));
279f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
280521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar                           /*IsAST=*/false))
281521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar    goto error;
282521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
283f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  Act->Execute();
284521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
28564a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar  // Steal the created target, context, and preprocessor, and take back the
28664a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar  // source and file managers.
287521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  AST->Ctx.reset(Clang.takeASTContext());
288521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  AST->PP.reset(Clang.takePreprocessor());
289521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeSourceManager();
290521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeFileManager();
29164a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar  AST->Target.reset(Clang.takeTarget());
292521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
293f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  Act->EndSourceFile();
294521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
295521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeDiagnosticClient();
296521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeDiagnostics();
297807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  Clang.takeInvocation();
298521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
299f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbar  AST->Invocation.reset(Clang.takeInvocation());
300521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  return AST.take();
301521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
302521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarerror:
303521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeSourceManager();
304521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeFileManager();
305521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeDiagnosticClient();
306521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeDiagnostics();
307521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  return 0;
308521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}
3097b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
3107b55668db7618334cc40011d3c1e128524d89462Daniel DunbarASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
3117b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar                                      const char **ArgEnd,
3127b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar                                      Diagnostic &Diags,
313869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar                                      llvm::StringRef ResourceFilesPath,
3147b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar                                      bool OnlyLocalDecls,
3154db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                      bool UseBumpAllocator,
3164db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                      RemappedFile *RemappedFiles,
3174db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                      unsigned NumRemappedFiles) {
3187b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  llvm::SmallVector<const char *, 16> Args;
3197b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  Args.push_back("<clang>"); // FIXME: Remove dummy argument.
3207b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  Args.insert(Args.end(), ArgBegin, ArgEnd);
3217b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
3227b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  // FIXME: Find a cleaner way to force the driver into restricted modes. We
3237b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  // also want to force it to use clang.
3247b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  Args.push_back("-fsyntax-only");
3257b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
326869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar  // FIXME: We shouldn't have to pass in the path info.
327869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar  driver::Driver TheDriver("clang", "/", llvm::sys::getHostTriple(),
3287b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar                           "a.out", false, Diags);
3293bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar
3303bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar  // Don't check that inputs exist, they have been remapped.
3313bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar  TheDriver.setCheckInputsExist(false);
3323bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar
3337b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  llvm::OwningPtr<driver::Compilation> C(
3347b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    TheDriver.BuildCompilation(Args.size(), Args.data()));
3357b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
3367b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  // We expect to get back exactly one command job, if we didn't something
3377b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  // failed.
3387b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  const driver::JobList &Jobs = C->getJobs();
3397b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
3407b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    llvm::SmallString<256> Msg;
3417b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    llvm::raw_svector_ostream OS(Msg);
3427b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    C->PrintJob(OS, C->getJobs(), "; ", true);
3437b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
3447b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    return 0;
3457b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  }
3467b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
3477b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
3487b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
3497b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    Diags.Report(diag::err_fe_expected_clang_command);
3507b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    return 0;
3517b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  }
3527b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
3537b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  const driver::ArgStringList &CCArgs = Cmd->getArguments();
354807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
355807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  CompilerInvocation::CreateFromArgs(*CI, (const char**) CCArgs.data(),
3567b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar                                     (const char**) CCArgs.data()+CCArgs.size(),
3571e69fe3a9f0a42b32a3000bda51677d51416564eDaniel Dunbar                                     Diags);
3581e69fe3a9f0a42b32a3000bda51677d51416564eDaniel Dunbar
3594db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  // Override any files that need remapping
3604db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  for (unsigned I = 0; I != NumRemappedFiles; ++I)
361807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar    CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
3624db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                             RemappedFiles[I].second);
3634db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor
3648b9adfea5e834eaee0f45d8cc7fb052d68df4a46Daniel Dunbar  // Override the resources path.
365807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
3667b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
367807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  CI->getFrontendOpts().DisableFree = UseBumpAllocator;
368f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbar  return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls);
3697b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar}
370