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