ASTUnit.cpp revision cb421fa690da545b58a720abe5f1c49b166dbde7
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
383687e9d3a5dbfa9963af02a49a2b139d91310813Douglas GregorASTUnit::ASTUnit(bool _MainFileIsAST)
393687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  : MainFileIsAST(_MainFileIsAST), ConcurrencyCheckValue(CheckUnlocked) { }
403687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor
41521bf9c529e653ab28896d027352d3e16e2672d5Daniel DunbarASTUnit::~ASTUnit() {
42bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  ConcurrencyCheckValue = CheckLocked;
43313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
44313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor    TemporaryFiles[I].eraseFromDisk();
45e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff}
460853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
470853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisnamespace {
480853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
490853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// \brief Gathers information from PCHReader that will be used to initialize
500853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// a Preprocessor.
51bd21828179a61bd0954b082825cfb8a93345f602Benjamin Kramerclass PCHInfoCollector : public PCHReaderListener {
520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  LangOptions &LangOpt;
530853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  HeaderSearch &HSI;
540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  std::string &TargetTriple;
550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  std::string &Predefines;
560853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  unsigned &Counter;
571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
580853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  unsigned NumHeaderInfos;
591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
600853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidispublic:
610853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI,
620853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                   std::string &TargetTriple, std::string &Predefines,
630853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                   unsigned &Counter)
640853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple),
650853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis      Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {}
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  virtual bool ReadLanguageOptions(const LangOptions &LangOpts) {
680853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    LangOpt = LangOpts;
690853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return false;
700853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
72dc3c0d20375bda7775b2fade05b20e315798b9feDaniel Dunbar  virtual bool ReadTargetTriple(llvm::StringRef Triple) {
730853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    TargetTriple = Triple;
740853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return false;
750853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
77dc3c0d20375bda7775b2fade05b20e315798b9feDaniel Dunbar  virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
780853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                    FileID PCHBufferID,
797b5a1210d93ca62ecd61800f245c87259b1f8f79Daniel Dunbar                                    llvm::StringRef OriginalFileName,
800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                    std::string &SuggestedPredefines) {
810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    Predefines = PCHPredef;
820853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return false;
830853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
85ec1afbfd8e880d0169aab0ececa2e7e1611f4955Douglas Gregor  virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) {
860853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
870853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  virtual void ReadCounter(unsigned Value) {
900853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    Counter = Value;
910853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
920853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis};
930853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
94a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass StoredDiagnosticClient : public DiagnosticClient {
95a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags;
96a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
97a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic:
98a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  explicit StoredDiagnosticClient(
99a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                          llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags)
100a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    : StoredDiags(StoredDiags) { }
101a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
102a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  virtual void HandleDiagnostic(Diagnostic::Level Level,
103a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                const DiagnosticInfo &Info);
104a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor};
105a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
106a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// \brief RAII object that optionally captures diagnostics, if
107a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// there is no diagnostic client to capture them already.
108a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass CaptureDroppedDiagnostics {
109a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  Diagnostic &Diags;
110a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  StoredDiagnosticClient Client;
111a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  DiagnosticClient *PreviousClient;
112a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
113a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic:
114a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags,
115a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                           llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags)
116a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    : Diags(Diags), Client(StoredDiags), PreviousClient(Diags.getClient())
117a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  {
118a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    if (RequestCapture || Diags.getClient() == 0)
119a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor      Diags.setClient(&Client);
120a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  }
121a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
122a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  ~CaptureDroppedDiagnostics() {
123a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    Diags.setClient(PreviousClient);
124a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  }
125a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor};
126a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
1270853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} // anonymous namespace
1280853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
129a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorvoid StoredDiagnosticClient::HandleDiagnostic(Diagnostic::Level Level,
130a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                              const DiagnosticInfo &Info) {
131a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  StoredDiags.push_back(StoredDiagnostic(Level, Info));
132a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
133a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
13477accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroffconst std::string &ASTUnit::getOriginalSourceFileName() {
13568d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar  return OriginalSourceFile;
13677accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff}
1370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
138e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroffconst std::string &ASTUnit::getPCHFileName() {
139c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar  assert(isMainFileAST() && "Not an ASTUnit from a PCH file!");
1407297c18c843138625a61e01a137664a176739683Benjamin Kramer  return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName();
141e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff}
142e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff
1430853a02c3b04d96a3c432b883e403175c954cd81Argyrios KyrtzidisASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
14428019772db70d4547be05a042eb950bc910f134fDouglas Gregor                                  llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
1455cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek                                  bool OnlyLocalDecls,
1464db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                  RemappedFile *RemappedFiles,
147a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                  unsigned NumRemappedFiles,
148a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                  bool CaptureDiagnostics) {
1493687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
1503687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor
15128019772db70d4547be05a042eb950bc910f134fDouglas Gregor  if (!Diags.getPtr()) {
1523687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    // No diagnostics engine was provided, so create our own diagnostics object
1533687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    // with the default options.
1543687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    DiagnosticOptions DiagOpts;
15528019772db70d4547be05a042eb950bc910f134fDouglas Gregor    Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
1563687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  }
1573687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor
1587d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor  AST->OnlyLocalDecls = OnlyLocalDecls;
15928019772db70d4547be05a042eb950bc910f134fDouglas Gregor  AST->Diagnostics = Diags;
1603687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  AST->FileMgr.reset(new FileManager);
1613687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics()));
16236c4464ba6cfc2a63dc67c493ef2f5ab2aea09ccSteve Naroff  AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
1630853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
164a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  // If requested, capture diagnostics in the ASTUnit.
1653687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  CaptureDroppedDiagnostics Capture(CaptureDiagnostics, AST->getDiagnostics(),
166405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor                                    AST->StoredDiagnostics);
167a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
1684db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
1694db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    // Create the file entry for the file that we're mapping from.
1704db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    const FileEntry *FromFile
1714db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor      = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
1724db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                    RemappedFiles[I].second->getBufferSize(),
1734db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                             0);
1744db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    if (!FromFile) {
1753687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor      AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
1764db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor        << RemappedFiles[I].first;
177c8dfe5ece04e683106eb96c58a2999f70b53ac21Douglas Gregor      delete RemappedFiles[I].second;
1784db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor      continue;
1794db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    }
1804db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor
1814db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    // Override the contents of the "from" file with the contents of
1824db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    // the "to" file.
1834db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    AST->getSourceManager().overrideFileContents(FromFile,
1844db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                                 RemappedFiles[I].second);
1854db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  }
1864db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor
1870853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Gather Info for preprocessor construction later on.
1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  LangOptions LangInfo;
1900853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  HeaderSearch &HeaderInfo = *AST->HeaderInfo.get();
1910853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  std::string TargetTriple;
1920853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  std::string Predefines;
1930853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  unsigned Counter;
1940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
195bce6f62ae7d2c15992617f64e30067803fb5b47fDaniel Dunbar  llvm::OwningPtr<PCHReader> Reader;
1960853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  llvm::OwningPtr<ExternalASTSource> Source;
1970853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
198fc0622155fa61349698a8fd0053773c37d9f7ac4Ted Kremenek  Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(),
1993687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor                             AST->getDiagnostics()));
200cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple,
201cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar                                           Predefines, Counter));
202cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar
203cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  switch (Reader->ReadPCH(Filename)) {
2040853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  case PCHReader::Success:
2050853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    break;
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2070853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  case PCHReader::Failure:
208106c9981f18084e60602244f1feaeabbbe8ab5e8Argyrios Kyrtzidis  case PCHReader::IgnorePCH:
2093687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
2100853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis    return NULL;
2110853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  }
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21368d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar  AST->OriginalSourceFile = Reader->getOriginalSourceFile();
21468d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar
2150853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // PCH loaded successfully. Now create the preprocessor.
2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2170853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Get information about the target being compiled for.
218d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  //
219d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  // FIXME: This is broken, we should store the TargetOptions in the PCH.
220d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOptions TargetOpts;
221d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOpts.ABI = "";
222d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOpts.CPU = "";
223d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOpts.Features.clear();
224d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar  TargetOpts.Triple = TargetTriple;
2253687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  AST->Target.reset(TargetInfo::CreateTargetInfo(AST->getDiagnostics(),
2263687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor                                                 TargetOpts));
2273687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  AST->PP.reset(new Preprocessor(AST->getDiagnostics(), LangInfo,
2283687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor                                 *AST->Target.get(),
22931b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar                                 AST->getSourceManager(), HeaderInfo));
2300853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  Preprocessor &PP = *AST->PP.get();
2310853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
232d5b6126389e1e2fd89e498fe17da4bb44ece0302Daniel Dunbar  PP.setPredefines(Reader->getSuggestedPredefines());
2330853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  PP.setCounterValue(Counter);
234cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  Reader->setPreprocessor(PP);
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2360853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Create and initialize the ASTContext.
2370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
2380853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  AST->Ctx.reset(new ASTContext(LangInfo,
23931b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar                                AST->getSourceManager(),
2400853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                *AST->Target.get(),
2410853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                PP.getIdentifierTable(),
2420853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                PP.getSelectorTable(),
2430853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                PP.getBuiltinInfo(),
244b26d483a9f7fdc815e87bbbac4af916307b4c07dDaniel Dunbar                                /* FreeMemory = */ false,
2450853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                /* size_reserve = */0));
2460853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  ASTContext &Context = *AST->Ctx.get();
2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
248cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  Reader->InitializeContext(Context);
2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2500853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Attach the PCH reader to the AST context as an external AST
2510853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // source, so that declarations will be deserialized from the
2520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // PCH file as needed.
253cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar  Source.reset(Reader.take());
2540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  Context.setExternalSource(Source);
2550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
2561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return AST.take();
2570853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis}
258521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
259521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarnamespace {
260521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
261f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerConsumer : public ASTConsumer {
262f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  ASTUnit &Unit;
263f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
264f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic:
265f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  TopLevelDeclTrackerConsumer(ASTUnit &_Unit) : Unit(_Unit) {}
266f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
267f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  void HandleTopLevelDecl(DeclGroupRef D) {
268f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar    for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it)
269f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar      Unit.getTopLevelDecls().push_back(*it);
270f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  }
271f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar};
272f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
273f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerAction : public ASTFrontendAction {
274f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic:
275f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  ASTUnit &Unit;
276f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
277521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
278521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar                                         llvm::StringRef InFile) {
279f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar    return new TopLevelDeclTrackerConsumer(Unit);
280521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  }
281521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
282521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarpublic:
283f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
284f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
285521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  virtual bool hasCodeCompletionSupport() const { return false; }
286521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar};
287521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
288521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}
289521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
290f7acc37450d59ef751df73acb91de73850cc6517Daniel DunbarASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
29128019772db70d4547be05a042eb950bc910f134fDouglas Gregor                                   llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
292a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                             bool OnlyLocalDecls,
29394dc8f640ebea52241412512ed48601626edbc58Douglas Gregor                                             bool CaptureDiagnostics) {
294521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the compiler instance to use for building the AST.
295cb6dda1a7abe2fe30b0345bfbbf872cc73446678Daniel Dunbar  CompilerInstance Clang;
296521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  llvm::OwningPtr<ASTUnit> AST;
297f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
298521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
29928019772db70d4547be05a042eb950bc910f134fDouglas Gregor  if (!Diags.getPtr()) {
3003687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    // No diagnostics engine was provided, so create our own diagnostics object
3013687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    // with the default options.
3023687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    DiagnosticOptions DiagOpts;
30328019772db70d4547be05a042eb950bc910f134fDouglas Gregor    Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
3043687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  }
3053687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor
306f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbar  Clang.setInvocation(CI);
307521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
30828019772db70d4547be05a042eb950bc910f134fDouglas Gregor  Clang.setDiagnostics(Diags.getPtr());
3093687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  Clang.setDiagnosticClient(Diags->getClient());
310521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
311521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the target instance.
312521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
313521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar                                               Clang.getTargetOpts()));
314a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  if (!Clang.hasTarget()) {
315a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    Clang.takeDiagnosticClient();
316a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    return 0;
317a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  }
318521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
319521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Inform the target of the language options.
320521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  //
321521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // FIXME: We shouldn't need to do this, the target should be immutable once
322521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // created. This complexity should be lifted elsewhere.
323521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
324521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
325521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  assert(Clang.getFrontendOpts().Inputs.size() == 1 &&
326521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar         "Invocation must have exactly one source file!");
327521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  assert(Clang.getFrontendOpts().Inputs[0].first != FrontendOptions::IK_AST &&
328521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar         "FIXME: AST inputs not yet supported here!");
329521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
330521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the AST unit.
3313687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  AST.reset(new ASTUnit(false));
3323687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  AST->Diagnostics = Diags;
3333687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  AST->FileMgr.reset(new FileManager);
3343687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics()));
33568ea2ac7fd98a5a44c7a5b04c54076cf794531cbDaniel Dunbar  AST->OnlyLocalDecls = OnlyLocalDecls;
33668d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar  AST->OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
33768d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar
338a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  // Capture any diagnostics that would otherwise be dropped.
339a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
340a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                    Clang.getDiagnostics(),
341405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor                                    AST->StoredDiagnostics);
342a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
343521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create a file manager object to provide access to and cache the filesystem.
344521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.setFileManager(&AST->getFileManager());
345521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
346521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the source manager.
347521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.setSourceManager(&AST->getSourceManager());
348521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
349521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  // Create the preprocessor.
350521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.createPreprocessor();
351521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
352f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  Act.reset(new TopLevelDeclTrackerAction(*AST));
353f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
354521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar                           /*IsAST=*/false))
355521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar    goto error;
356521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
357f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  Act->Execute();
358521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
35964a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar  // Steal the created target, context, and preprocessor, and take back the
36064a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar  // source and file managers.
361521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  AST->Ctx.reset(Clang.takeASTContext());
362521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  AST->PP.reset(Clang.takePreprocessor());
363521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeSourceManager();
364521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeFileManager();
36564a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar  AST->Target.reset(Clang.takeTarget());
366521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
367f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  Act->EndSourceFile();
368521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
369521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeDiagnosticClient();
370807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  Clang.takeInvocation();
371521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
372f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbar  AST->Invocation.reset(Clang.takeInvocation());
373521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  return AST.take();
374521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
375521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarerror:
376521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeSourceManager();
377521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeFileManager();
378521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  Clang.takeDiagnosticClient();
379521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  return 0;
380521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}
3817b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
3827b55668db7618334cc40011d3c1e128524d89462Daniel DunbarASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
3837b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar                                      const char **ArgEnd,
38428019772db70d4547be05a042eb950bc910f134fDouglas Gregor                                    llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
385869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar                                      llvm::StringRef ResourceFilesPath,
3867b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar                                      bool OnlyLocalDecls,
3874db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                      RemappedFile *RemappedFiles,
388a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                      unsigned NumRemappedFiles,
38994dc8f640ebea52241412512ed48601626edbc58Douglas Gregor                                      bool CaptureDiagnostics) {
39028019772db70d4547be05a042eb950bc910f134fDouglas Gregor  if (!Diags.getPtr()) {
3913687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    // No diagnostics engine was provided, so create our own diagnostics object
3923687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    // with the default options.
3933687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    DiagnosticOptions DiagOpts;
39428019772db70d4547be05a042eb950bc910f134fDouglas Gregor    Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
3953687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  }
3963687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor
3977b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  llvm::SmallVector<const char *, 16> Args;
3987b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  Args.push_back("<clang>"); // FIXME: Remove dummy argument.
3997b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  Args.insert(Args.end(), ArgBegin, ArgEnd);
4007b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
4017b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  // FIXME: Find a cleaner way to force the driver into restricted modes. We
4027b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  // also want to force it to use clang.
4037b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  Args.push_back("-fsyntax-only");
4047b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
405869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar  // FIXME: We shouldn't have to pass in the path info.
406869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar  driver::Driver TheDriver("clang", "/", llvm::sys::getHostTriple(),
4073687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor                           "a.out", false, false, *Diags);
4083bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar
4093bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar  // Don't check that inputs exist, they have been remapped.
4103bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar  TheDriver.setCheckInputsExist(false);
4113bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar
4127b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  llvm::OwningPtr<driver::Compilation> C(
4137b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    TheDriver.BuildCompilation(Args.size(), Args.data()));
4147b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
4157b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  // We expect to get back exactly one command job, if we didn't something
4167b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  // failed.
4177b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  const driver::JobList &Jobs = C->getJobs();
4187b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
4197b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    llvm::SmallString<256> Msg;
4207b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    llvm::raw_svector_ostream OS(Msg);
4217b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    C->PrintJob(OS, C->getJobs(), "; ", true);
4223687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
4237b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    return 0;
4247b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  }
4257b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
4267b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
4277b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
4283687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor    Diags->Report(diag::err_fe_expected_clang_command);
4297b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar    return 0;
4307b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  }
4317b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
4327b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar  const driver::ArgStringList &CCArgs = Cmd->getArguments();
433807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
434cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman  CompilerInvocation::CreateFromArgs(*CI,
435cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman                                     const_cast<const char **>(CCArgs.data()),
436cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman                                     const_cast<const char **>(CCArgs.data()) +
437cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman                                       CCArgs.size(),
4383687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor                                     *Diags);
4391e69fe3a9f0a42b32a3000bda51677d51416564eDaniel Dunbar
4404db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  // Override any files that need remapping
4414db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  for (unsigned I = 0; I != NumRemappedFiles; ++I)
442807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar    CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
443b26d483a9f7fdc815e87bbbac4af916307b4c07dDaniel Dunbar                                              RemappedFiles[I].second);
4444db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor
4458b9adfea5e834eaee0f45d8cc7fb052d68df4a46Daniel Dunbar  // Override the resources path.
446807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
4477b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar
448b26d483a9f7fdc815e87bbbac4af916307b4c07dDaniel Dunbar  CI->getFrontendOpts().DisableFree = true;
449a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls,
45094dc8f640ebea52241412512ed48601626edbc58Douglas Gregor                                    CaptureDiagnostics);
4517b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar}
452