ASTUnit.cpp revision 63fe86bee66fc145942c56b2cc564ea0b9b9ea12
1//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// ASTUnit Implementation.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Frontend/ASTUnit.h"
15#include "clang/Frontend/PCHReader.h"
16#include "clang/AST/ASTContext.h"
17#include "clang/AST/ASTConsumer.h"
18#include "clang/AST/DeclVisitor.h"
19#include "clang/AST/StmtVisitor.h"
20#include "clang/Driver/Compilation.h"
21#include "clang/Driver/Driver.h"
22#include "clang/Driver/Job.h"
23#include "clang/Driver/Tool.h"
24#include "clang/Frontend/CompilerInstance.h"
25#include "clang/Frontend/FrontendActions.h"
26#include "clang/Frontend/FrontendDiagnostic.h"
27#include "clang/Frontend/FrontendOptions.h"
28#include "clang/Lex/HeaderSearch.h"
29#include "clang/Lex/Preprocessor.h"
30#include "clang/Basic/TargetOptions.h"
31#include "clang/Basic/TargetInfo.h"
32#include "clang/Basic/Diagnostic.h"
33#include "llvm/Support/MemoryBuffer.h"
34#include "llvm/System/Host.h"
35#include "llvm/System/Path.h"
36#include <cstdlib>
37#include <cstdio>
38using namespace clang;
39
40ASTUnit::ASTUnit(bool _MainFileIsAST)
41  : CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST),
42    ConcurrencyCheckValue(CheckUnlocked) { }
43
44ASTUnit::~ASTUnit() {
45  ConcurrencyCheckValue = CheckLocked;
46  CleanTemporaryFiles();
47  if (!PreambleFile.empty())
48    PreambleFile.eraseFromDisk();
49}
50
51void ASTUnit::CleanTemporaryFiles() {
52  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
53    TemporaryFiles[I].eraseFromDisk();
54  TemporaryFiles.clear();
55}
56
57namespace {
58
59/// \brief Gathers information from PCHReader that will be used to initialize
60/// a Preprocessor.
61class PCHInfoCollector : public PCHReaderListener {
62  LangOptions &LangOpt;
63  HeaderSearch &HSI;
64  std::string &TargetTriple;
65  std::string &Predefines;
66  unsigned &Counter;
67
68  unsigned NumHeaderInfos;
69
70public:
71  PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI,
72                   std::string &TargetTriple, std::string &Predefines,
73                   unsigned &Counter)
74    : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple),
75      Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {}
76
77  virtual bool ReadLanguageOptions(const LangOptions &LangOpts) {
78    LangOpt = LangOpts;
79    return false;
80  }
81
82  virtual bool ReadTargetTriple(llvm::StringRef Triple) {
83    TargetTriple = Triple;
84    return false;
85  }
86
87  virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
88                                    llvm::StringRef OriginalFileName,
89                                    std::string &SuggestedPredefines) {
90    Predefines = Buffers[0].Data;
91    for (unsigned I = 1, N = Buffers.size(); I != N; ++I) {
92      Predefines += Buffers[I].Data;
93    }
94    return false;
95  }
96
97  virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) {
98    HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
99  }
100
101  virtual void ReadCounter(unsigned Value) {
102    Counter = Value;
103  }
104};
105
106class StoredDiagnosticClient : public DiagnosticClient {
107  llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags;
108
109public:
110  explicit StoredDiagnosticClient(
111                          llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags)
112    : StoredDiags(StoredDiags) { }
113
114  virtual void HandleDiagnostic(Diagnostic::Level Level,
115                                const DiagnosticInfo &Info);
116};
117
118/// \brief RAII object that optionally captures diagnostics, if
119/// there is no diagnostic client to capture them already.
120class CaptureDroppedDiagnostics {
121  Diagnostic &Diags;
122  StoredDiagnosticClient Client;
123  DiagnosticClient *PreviousClient;
124
125public:
126  CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags,
127                           llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags)
128    : Diags(Diags), Client(StoredDiags), PreviousClient(Diags.getClient())
129  {
130    if (RequestCapture || Diags.getClient() == 0)
131      Diags.setClient(&Client);
132  }
133
134  ~CaptureDroppedDiagnostics() {
135    Diags.setClient(PreviousClient);
136  }
137};
138
139} // anonymous namespace
140
141void StoredDiagnosticClient::HandleDiagnostic(Diagnostic::Level Level,
142                                              const DiagnosticInfo &Info) {
143  StoredDiags.push_back(StoredDiagnostic(Level, Info));
144}
145
146const std::string &ASTUnit::getOriginalSourceFileName() {
147  return OriginalSourceFile;
148}
149
150const std::string &ASTUnit::getPCHFileName() {
151  assert(isMainFileAST() && "Not an ASTUnit from a PCH file!");
152  return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName();
153}
154
155ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
156                                  llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
157                                  bool OnlyLocalDecls,
158                                  RemappedFile *RemappedFiles,
159                                  unsigned NumRemappedFiles,
160                                  bool CaptureDiagnostics) {
161  llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
162
163  if (!Diags.getPtr()) {
164    // No diagnostics engine was provided, so create our own diagnostics object
165    // with the default options.
166    DiagnosticOptions DiagOpts;
167    Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
168  }
169
170  AST->CaptureDiagnostics = CaptureDiagnostics;
171  AST->OnlyLocalDecls = OnlyLocalDecls;
172  AST->Diagnostics = Diags;
173  AST->FileMgr.reset(new FileManager);
174  AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics()));
175  AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
176
177  // If requested, capture diagnostics in the ASTUnit.
178  CaptureDroppedDiagnostics Capture(CaptureDiagnostics, AST->getDiagnostics(),
179                                    AST->StoredDiagnostics);
180
181  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
182    // Create the file entry for the file that we're mapping from.
183    const FileEntry *FromFile
184      = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
185                                    RemappedFiles[I].second->getBufferSize(),
186                                             0);
187    if (!FromFile) {
188      AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
189        << RemappedFiles[I].first;
190      delete RemappedFiles[I].second;
191      continue;
192    }
193
194    // Override the contents of the "from" file with the contents of
195    // the "to" file.
196    AST->getSourceManager().overrideFileContents(FromFile,
197                                                 RemappedFiles[I].second);
198  }
199
200  // Gather Info for preprocessor construction later on.
201
202  LangOptions LangInfo;
203  HeaderSearch &HeaderInfo = *AST->HeaderInfo.get();
204  std::string TargetTriple;
205  std::string Predefines;
206  unsigned Counter;
207
208  llvm::OwningPtr<PCHReader> Reader;
209  llvm::OwningPtr<ExternalASTSource> Source;
210
211  Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(),
212                             AST->getDiagnostics()));
213  Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple,
214                                           Predefines, Counter));
215
216  switch (Reader->ReadPCH(Filename)) {
217  case PCHReader::Success:
218    break;
219
220  case PCHReader::Failure:
221  case PCHReader::IgnorePCH:
222    AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
223    return NULL;
224  }
225
226  AST->OriginalSourceFile = Reader->getOriginalSourceFile();
227
228  // PCH loaded successfully. Now create the preprocessor.
229
230  // Get information about the target being compiled for.
231  //
232  // FIXME: This is broken, we should store the TargetOptions in the PCH.
233  TargetOptions TargetOpts;
234  TargetOpts.ABI = "";
235  TargetOpts.CXXABI = "itanium";
236  TargetOpts.CPU = "";
237  TargetOpts.Features.clear();
238  TargetOpts.Triple = TargetTriple;
239  AST->Target.reset(TargetInfo::CreateTargetInfo(AST->getDiagnostics(),
240                                                 TargetOpts));
241  AST->PP.reset(new Preprocessor(AST->getDiagnostics(), LangInfo,
242                                 *AST->Target.get(),
243                                 AST->getSourceManager(), HeaderInfo));
244  Preprocessor &PP = *AST->PP.get();
245
246  PP.setPredefines(Reader->getSuggestedPredefines());
247  PP.setCounterValue(Counter);
248  Reader->setPreprocessor(PP);
249
250  // Create and initialize the ASTContext.
251
252  AST->Ctx.reset(new ASTContext(LangInfo,
253                                AST->getSourceManager(),
254                                *AST->Target.get(),
255                                PP.getIdentifierTable(),
256                                PP.getSelectorTable(),
257                                PP.getBuiltinInfo(),
258                                /* size_reserve = */0));
259  ASTContext &Context = *AST->Ctx.get();
260
261  Reader->InitializeContext(Context);
262
263  // Attach the PCH reader to the AST context as an external AST
264  // source, so that declarations will be deserialized from the
265  // PCH file as needed.
266  Source.reset(Reader.take());
267  Context.setExternalSource(Source);
268
269  return AST.take();
270}
271
272namespace {
273
274class TopLevelDeclTrackerConsumer : public ASTConsumer {
275  ASTUnit &Unit;
276
277public:
278  TopLevelDeclTrackerConsumer(ASTUnit &_Unit) : Unit(_Unit) {}
279
280  void HandleTopLevelDecl(DeclGroupRef D) {
281    for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) {
282      Decl *D = *it;
283      // FIXME: Currently ObjC method declarations are incorrectly being
284      // reported as top-level declarations, even though their DeclContext
285      // is the containing ObjC @interface/@implementation.  This is a
286      // fundamental problem in the parser right now.
287      if (isa<ObjCMethodDecl>(D))
288        continue;
289      Unit.getTopLevelDecls().push_back(D);
290    }
291  }
292};
293
294class TopLevelDeclTrackerAction : public ASTFrontendAction {
295public:
296  ASTUnit &Unit;
297
298  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
299                                         llvm::StringRef InFile) {
300    return new TopLevelDeclTrackerConsumer(Unit);
301  }
302
303public:
304  TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
305
306  virtual bool hasCodeCompletionSupport() const { return false; }
307};
308
309}
310
311/// Parse the source file into a translation unit using the given compiler
312/// invocation, replacing the current translation unit.
313///
314/// \returns True if a failure occurred that causes the ASTUnit not to
315/// contain any translation-unit information, false otherwise.
316bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
317  if (!Invocation.get())
318    return true;
319
320  // Create the compiler instance to use for building the AST.
321  CompilerInstance Clang;
322  Clang.setInvocation(Invocation.take());
323  OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
324
325  // Set up diagnostics.
326  Clang.setDiagnostics(&getDiagnostics());
327  Clang.setDiagnosticClient(getDiagnostics().getClient());
328
329  // Create the target instance.
330  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
331                                               Clang.getTargetOpts()));
332  if (!Clang.hasTarget()) {
333    Clang.takeDiagnosticClient();
334    return true;
335  }
336
337  // Inform the target of the language options.
338  //
339  // FIXME: We shouldn't need to do this, the target should be immutable once
340  // created. This complexity should be lifted elsewhere.
341  Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
342
343  assert(Clang.getFrontendOpts().Inputs.size() == 1 &&
344         "Invocation must have exactly one source file!");
345  assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST &&
346         "FIXME: AST inputs not yet supported here!");
347  assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR &&
348         "IR inputs not support here!");
349
350  // Configure the various subsystems.
351  // FIXME: Should we retain the previous file manager?
352  FileMgr.reset(new FileManager);
353  SourceMgr.reset(new SourceManager(getDiagnostics()));
354  Ctx.reset();
355  PP.reset();
356
357  // Clear out old caches and data.
358  TopLevelDecls.clear();
359  StoredDiagnostics.clear();
360  CleanTemporaryFiles();
361  PreprocessedEntitiesByFile.clear();
362
363  // Capture any diagnostics that would otherwise be dropped.
364  CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
365                                    Clang.getDiagnostics(),
366                                    StoredDiagnostics);
367
368  // Create a file manager object to provide access to and cache the filesystem.
369  Clang.setFileManager(&getFileManager());
370
371  // Create the source manager.
372  Clang.setSourceManager(&getSourceManager());
373
374  llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
375  Act.reset(new TopLevelDeclTrackerAction(*this));
376  if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
377                            Clang.getFrontendOpts().Inputs[0].first))
378    goto error;
379
380  Act->Execute();
381
382  // Steal the created target, context, and preprocessor, and take back the
383  // source and file managers.
384  Ctx.reset(Clang.takeASTContext());
385  PP.reset(Clang.takePreprocessor());
386  Clang.takeSourceManager();
387  Clang.takeFileManager();
388  Target.reset(Clang.takeTarget());
389
390  Act->EndSourceFile();
391
392  Clang.takeDiagnosticClient();
393
394  Invocation.reset(Clang.takeInvocation());
395  return false;
396
397error:
398  Clang.takeSourceManager();
399  Clang.takeFileManager();
400  Clang.takeDiagnosticClient();
401  Invocation.reset(Clang.takeInvocation());
402  return true;
403}
404
405/// \brief Simple function to retrieve a path for a preamble precompiled header.
406static std::string GetPreamblePCHPath() {
407  // FIXME: This is lame; sys::Path should provide this function (in particular,
408  // it should know how to find the temporary files dir).
409  // FIXME: This is really lame. I copied this code from the Driver!
410  std::string Error;
411  const char *TmpDir = ::getenv("TMPDIR");
412  if (!TmpDir)
413    TmpDir = ::getenv("TEMP");
414  if (!TmpDir)
415    TmpDir = ::getenv("TMP");
416  if (!TmpDir)
417    TmpDir = "/tmp";
418  llvm::sys::Path P(TmpDir);
419  P.appendComponent("preamble");
420  if (P.createTemporaryFileOnDisk())
421    return std::string();
422
423  P.appendSuffix("pch");
424  return P.str();
425}
426
427/// \brief Compute the preamble for the main file, providing
428std::pair<llvm::MemoryBuffer *, unsigned>
429ASTUnit::ComputePreamble(CompilerInvocation &Invocation, bool &CreatedBuffer) {
430  FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();
431  PreprocessorOptions &PreprocessorOpts
432    = Invocation.getPreprocessorOpts();
433  CreatedBuffer = false;
434
435  // Try to determine if the main file has been remapped, either from the
436  // command line (to another file) or directly through the compiler invocation
437  // (to a memory buffer).
438  llvm::MemoryBuffer *Buffer = 0;
439  llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second);
440  if (const llvm::sys::FileStatus *MainFileStatus = MainFilePath.getFileStatus()) {
441    // Check whether there is a file-file remapping of the main file
442    for (PreprocessorOptions::remapped_file_iterator
443          M = PreprocessorOpts.remapped_file_begin(),
444          E = PreprocessorOpts.remapped_file_end();
445         M != E;
446         ++M) {
447      llvm::sys::PathWithStatus MPath(M->first);
448      if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) {
449        if (MainFileStatus->uniqueID == MStatus->uniqueID) {
450          // We found a remapping. Try to load the resulting, remapped source.
451          if (CreatedBuffer) {
452            delete Buffer;
453            CreatedBuffer = false;
454          }
455
456          Buffer = llvm::MemoryBuffer::getFile(M->second);
457          if (!Buffer)
458            return std::make_pair((llvm::MemoryBuffer*)0, 0);
459          CreatedBuffer = true;
460
461          // Remove this remapping. We've captured the buffer already.
462          M = PreprocessorOpts.eraseRemappedFile(M);
463          E = PreprocessorOpts.remapped_file_end();
464        }
465      }
466    }
467
468    // Check whether there is a file-buffer remapping. It supercedes the
469    // file-file remapping.
470    for (PreprocessorOptions::remapped_file_buffer_iterator
471           M = PreprocessorOpts.remapped_file_buffer_begin(),
472           E = PreprocessorOpts.remapped_file_buffer_end();
473         M != E;
474         ++M) {
475      llvm::sys::PathWithStatus MPath(M->first);
476      if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) {
477        if (MainFileStatus->uniqueID == MStatus->uniqueID) {
478          // We found a remapping.
479          if (CreatedBuffer) {
480            delete Buffer;
481            CreatedBuffer = false;
482          }
483
484          Buffer = const_cast<llvm::MemoryBuffer *>(M->second);
485
486          // Remove this remapping. We've captured the buffer already.
487          M = PreprocessorOpts.eraseRemappedFile(M);
488          E = PreprocessorOpts.remapped_file_buffer_end();
489        }
490      }
491    }
492  }
493
494  // If the main source file was not remapped, load it now.
495  if (!Buffer) {
496    Buffer = llvm::MemoryBuffer::getFile(FrontendOpts.Inputs[0].second);
497    if (!Buffer)
498      return std::make_pair((llvm::MemoryBuffer*)0, 0);
499
500    CreatedBuffer = true;
501  }
502
503  return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer));
504}
505
506static llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old,
507                                                      bool DeleteOld,
508                                                      unsigned NewSize,
509                                                      llvm::StringRef NewName) {
510  llvm::MemoryBuffer *Result
511    = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName);
512  memcpy(const_cast<char*>(Result->getBufferStart()),
513         Old->getBufferStart(), Old->getBufferSize());
514  memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(),
515         ' ', NewSize - Old->getBufferSize() - 2);
516  const_cast<char*>(Result->getBufferEnd())[-2] = '\n';
517  const_cast<char*>(Result->getBufferEnd())[-1] = 0;
518
519  if (DeleteOld)
520    delete Old;
521
522  return Result;
523}
524
525/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing
526/// the source file.
527///
528/// This routine will compute the preamble of the main source file. If a
529/// non-trivial preamble is found, it will precompile that preamble into a
530/// precompiled header so that the precompiled preamble can be used to reduce
531/// reparsing time. If a precompiled preamble has already been constructed,
532/// this routine will determine if it is still valid and, if so, avoid
533/// rebuilding the precompiled preamble.
534///
535/// \returns If the precompiled preamble can be used, returns a newly-allocated
536/// buffer that should be used in place of the main file when doing so.
537/// Otherwise, returns a NULL pointer.
538llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
539  CompilerInvocation PreambleInvocation(*Invocation);
540  FrontendOptions &FrontendOpts = PreambleInvocation.getFrontendOpts();
541  PreprocessorOptions &PreprocessorOpts
542    = PreambleInvocation.getPreprocessorOpts();
543
544  bool CreatedPreambleBuffer = false;
545  std::pair<llvm::MemoryBuffer *, unsigned> NewPreamble
546    = ComputePreamble(PreambleInvocation, CreatedPreambleBuffer);
547
548  if (!NewPreamble.second) {
549    // We couldn't find a preamble in the main source. Clear out the current
550    // preamble, if we have one. It's obviously no good any more.
551    Preamble.clear();
552    if (!PreambleFile.empty()) {
553      PreambleFile.eraseFromDisk();
554      PreambleFile.clear();
555    }
556    if (CreatedPreambleBuffer)
557      delete NewPreamble.first;
558
559    return 0;
560  }
561
562  if (!Preamble.empty()) {
563    // We've previously computed a preamble. Check whether we have the same
564    // preamble now that we did before, and that there's enough space in
565    // the main-file buffer within the precompiled preamble to fit the
566    // new main file.
567    if (Preamble.size() == NewPreamble.second &&
568        NewPreamble.first->getBufferSize() < PreambleReservedSize-2 &&
569        memcmp(&Preamble[0], NewPreamble.first->getBufferStart(),
570               NewPreamble.second) == 0) {
571      // The preamble has not changed. We may be able to re-use the precompiled
572      // preamble.
573      // FIXME: Check that none of the files used by the preamble have changed.
574
575
576      // Okay! Re-use the precompiled preamble.
577      return CreatePaddedMainFileBuffer(NewPreamble.first,
578                                        CreatedPreambleBuffer,
579                                        PreambleReservedSize,
580                                        FrontendOpts.Inputs[0].second);
581    }
582
583    // We can't reuse the previously-computed preamble. Build a new one.
584    Preamble.clear();
585    PreambleFile.eraseFromDisk();
586  }
587
588  // We did not previously compute a preamble, or it can't be reused anyway.
589
590  // Create a new buffer that stores the preamble. The buffer also contains
591  // extra space for the original contents of the file (which will be present
592  // when we actually parse the file) along with more room in case the file
593  // grows.
594  PreambleReservedSize = NewPreamble.first->getBufferSize();
595  if (PreambleReservedSize < 4096)
596    PreambleReservedSize = 8192;
597  else
598    PreambleReservedSize *= 2;
599
600  llvm::MemoryBuffer *PreambleBuffer
601    = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize,
602                                                FrontendOpts.Inputs[0].second);
603  memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()),
604         NewPreamble.first->getBufferStart(), Preamble.size());
605  memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(),
606         ' ', PreambleReservedSize - Preamble.size() - 2);
607  const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = 0;
608  const_cast<char*>(PreambleBuffer->getBufferEnd())[-2] = '\n';
609
610  // Save the preamble text for later; we'll need to compare against it for
611  // subsequent reparses.
612  Preamble.assign(NewPreamble.first->getBufferStart(),
613                  NewPreamble.first->getBufferStart() + NewPreamble.second);
614
615  // Remap the main source file to the preamble buffer.
616  llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second);
617  PreprocessorOpts.addRemappedFile(MainFilePath.str(), PreambleBuffer);
618
619  // Tell the compiler invocation to generate a temporary precompiled header.
620  FrontendOpts.ProgramAction = frontend::GeneratePCH;
621  // FIXME: Set ChainedPCH, once it is ready.
622  // FIXME: Generate the precompiled header into memory?
623  if (PreambleFile.isEmpty())
624    FrontendOpts.OutputFile = GetPreamblePCHPath();
625  else
626    FrontendOpts.OutputFile = PreambleFile.str();
627
628  // Create the compiler instance to use for building the precompiled preamble.
629  CompilerInstance Clang;
630  Clang.setInvocation(&PreambleInvocation);
631  OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
632
633  // Set up diagnostics.
634  Clang.setDiagnostics(&getDiagnostics());
635  Clang.setDiagnosticClient(getDiagnostics().getClient());
636
637  // Create the target instance.
638  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
639                                               Clang.getTargetOpts()));
640  if (!Clang.hasTarget()) {
641    Clang.takeDiagnosticClient();
642    llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
643    Preamble.clear();
644    if (CreatedPreambleBuffer)
645      delete NewPreamble.first;
646
647    return 0;
648  }
649
650  // Inform the target of the language options.
651  //
652  // FIXME: We shouldn't need to do this, the target should be immutable once
653  // created. This complexity should be lifted elsewhere.
654  Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
655
656  assert(Clang.getFrontendOpts().Inputs.size() == 1 &&
657         "Invocation must have exactly one source file!");
658  assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST &&
659         "FIXME: AST inputs not yet supported here!");
660  assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR &&
661         "IR inputs not support here!");
662
663  // Clear out old caches and data.
664  StoredDiagnostics.clear();
665
666  // Capture any diagnostics that would otherwise be dropped.
667  CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
668                                    Clang.getDiagnostics(),
669                                    StoredDiagnostics);
670
671  // Create a file manager object to provide access to and cache the filesystem.
672  Clang.setFileManager(new FileManager);
673
674  // Create the source manager.
675  Clang.setSourceManager(new SourceManager(getDiagnostics()));
676
677  // FIXME: Eventually, we'll have to track top-level declarations here, too.
678  llvm::OwningPtr<GeneratePCHAction> Act;
679  Act.reset(new GeneratePCHAction);
680  if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
681                            Clang.getFrontendOpts().Inputs[0].first)) {
682    Clang.takeDiagnosticClient();
683    Clang.takeInvocation();
684    llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
685    Preamble.clear();
686    if (CreatedPreambleBuffer)
687      delete NewPreamble.first;
688
689    return 0;
690  }
691
692  Act->Execute();
693  Act->EndSourceFile();
694  Clang.takeDiagnosticClient();
695  Clang.takeInvocation();
696
697  if (Diagnostics->getNumErrors() > 0) {
698    // There were errors parsing the preamble, so no precompiled header was
699    // generated. Forget that we even tried.
700    // FIXME: Should we leave a note for ourselves to try again?
701    llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
702    Preamble.clear();
703    if (CreatedPreambleBuffer)
704      delete NewPreamble.first;
705
706    return 0;
707  }
708
709  // Keep track of the preamble we precompiled.
710  PreambleFile = FrontendOpts.OutputFile;
711  fprintf(stderr, "Preamble PCH: %s\n", FrontendOpts.OutputFile.c_str());
712  return CreatePaddedMainFileBuffer(NewPreamble.first,
713                                    CreatedPreambleBuffer,
714                                    PreambleReservedSize,
715                                    FrontendOpts.Inputs[0].second);
716}
717
718ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
719                                   llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
720                                             bool OnlyLocalDecls,
721                                             bool CaptureDiagnostics,
722                                             bool PrecompilePreamble) {
723  if (!Diags.getPtr()) {
724    // No diagnostics engine was provided, so create our own diagnostics object
725    // with the default options.
726    DiagnosticOptions DiagOpts;
727    Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
728  }
729
730  // Create the AST unit.
731  llvm::OwningPtr<ASTUnit> AST;
732  AST.reset(new ASTUnit(false));
733  AST->Diagnostics = Diags;
734  AST->CaptureDiagnostics = CaptureDiagnostics;
735  AST->OnlyLocalDecls = OnlyLocalDecls;
736  AST->Invocation.reset(CI);
737
738  llvm::MemoryBuffer *OverrideMainBuffer = 0;
739  if (PrecompilePreamble)
740    OverrideMainBuffer = AST->BuildPrecompiledPreamble();
741
742  if (!AST->Parse(OverrideMainBuffer))
743    return AST.take();
744
745  delete OverrideMainBuffer;
746  return 0;
747}
748
749ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
750                                      const char **ArgEnd,
751                                    llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
752                                      llvm::StringRef ResourceFilesPath,
753                                      bool OnlyLocalDecls,
754                                      RemappedFile *RemappedFiles,
755                                      unsigned NumRemappedFiles,
756                                      bool CaptureDiagnostics,
757                                      bool PrecompilePreamble) {
758  if (!Diags.getPtr()) {
759    // No diagnostics engine was provided, so create our own diagnostics object
760    // with the default options.
761    DiagnosticOptions DiagOpts;
762    Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
763  }
764
765  llvm::SmallVector<const char *, 16> Args;
766  Args.push_back("<clang>"); // FIXME: Remove dummy argument.
767  Args.insert(Args.end(), ArgBegin, ArgEnd);
768
769  // FIXME: Find a cleaner way to force the driver into restricted modes. We
770  // also want to force it to use clang.
771  Args.push_back("-fsyntax-only");
772
773  // FIXME: We shouldn't have to pass in the path info.
774  driver::Driver TheDriver("clang", llvm::sys::getHostTriple(),
775                           "a.out", false, false, *Diags);
776
777  // Don't check that inputs exist, they have been remapped.
778  TheDriver.setCheckInputsExist(false);
779
780  llvm::OwningPtr<driver::Compilation> C(
781    TheDriver.BuildCompilation(Args.size(), Args.data()));
782
783  // We expect to get back exactly one command job, if we didn't something
784  // failed.
785  const driver::JobList &Jobs = C->getJobs();
786  if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
787    llvm::SmallString<256> Msg;
788    llvm::raw_svector_ostream OS(Msg);
789    C->PrintJob(OS, C->getJobs(), "; ", true);
790    Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
791    return 0;
792  }
793
794  const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
795  if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
796    Diags->Report(diag::err_fe_expected_clang_command);
797    return 0;
798  }
799
800  const driver::ArgStringList &CCArgs = Cmd->getArguments();
801  llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
802  CompilerInvocation::CreateFromArgs(*CI,
803                                     const_cast<const char **>(CCArgs.data()),
804                                     const_cast<const char **>(CCArgs.data()) +
805                                     CCArgs.size(),
806                                     *Diags);
807
808  // Override any files that need remapping
809  for (unsigned I = 0; I != NumRemappedFiles; ++I)
810    CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
811                                              RemappedFiles[I].second);
812
813  // Override the resources path.
814  CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
815
816  CI->getFrontendOpts().DisableFree = true;
817  return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls,
818                                    CaptureDiagnostics, PrecompilePreamble);
819}
820
821bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
822  if (!Invocation.get())
823    return true;
824
825  // If we have a preamble file lying around, build or reuse the precompiled
826  // preamble.
827  llvm::MemoryBuffer *OverrideMainBuffer = 0;
828  if (!PreambleFile.empty())
829    OverrideMainBuffer = BuildPrecompiledPreamble();
830
831  // Clear out the diagnostics state.
832  getDiagnostics().Reset();
833
834  // Remap files.
835  Invocation->getPreprocessorOpts().clearRemappedFiles();
836  for (unsigned I = 0; I != NumRemappedFiles; ++I)
837    Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
838                                                      RemappedFiles[I].second);
839
840  // Parse the sources
841  bool Result = Parse(OverrideMainBuffer);
842  delete OverrideMainBuffer;
843  return Result;
844}
845