clang  6.0.0svn
PrecompiledPreamble.cpp
Go to the documentation of this file.
1 //===--- PrecompiledPreamble.cpp - Build precompiled preambles --*- C++ -*-===//
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 // Helper class to build precompiled preamble.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/AST/DeclObjC.h"
16 #include "clang/Basic/TargetInfo.h"
22 #include "clang/Lex/Lexer.h"
25 #include "llvm/ADT/StringExtras.h"
26 #include "llvm/ADT/StringSet.h"
27 #include "llvm/Support/CrashRecoveryContext.h"
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/Mutex.h"
30 #include "llvm/Support/MutexGuard.h"
31 #include "llvm/Support/Process.h"
32 
33 using namespace clang;
34 
35 namespace {
36 
37 /// Keeps a track of files to be deleted in destructor.
38 class TemporaryFiles {
39 public:
40  // A static instance to be used by all clients.
41  static TemporaryFiles &getInstance();
42 
43 private:
44  // Disallow constructing the class directly.
45  TemporaryFiles() = default;
46  // Disallow copy.
47  TemporaryFiles(const TemporaryFiles &) = delete;
48 
49 public:
50  ~TemporaryFiles();
51 
52  /// Adds \p File to a set of tracked files.
53  void addFile(StringRef File);
54 
55  /// Remove \p File from disk and from the set of tracked files.
56  void removeFile(StringRef File);
57 
58 private:
59  llvm::sys::SmartMutex<false> Mutex;
60  llvm::StringSet<> Files;
61 };
62 
63 TemporaryFiles &TemporaryFiles::getInstance() {
64  static TemporaryFiles Instance;
65  return Instance;
66 }
67 
68 TemporaryFiles::~TemporaryFiles() {
69  llvm::MutexGuard Guard(Mutex);
70  for (const auto &File : Files)
71  llvm::sys::fs::remove(File.getKey());
72 }
73 
74 void TemporaryFiles::addFile(StringRef File) {
75  llvm::MutexGuard Guard(Mutex);
76  auto IsInserted = Files.insert(File).second;
77  (void)IsInserted;
78  assert(IsInserted && "File has already been added");
79 }
80 
81 void TemporaryFiles::removeFile(StringRef File) {
82  llvm::MutexGuard Guard(Mutex);
83  auto WasPresent = Files.erase(File);
84  (void)WasPresent;
85  assert(WasPresent && "File was not tracked");
86  llvm::sys::fs::remove(File);
87 }
88 
89 class PreambleMacroCallbacks : public PPCallbacks {
90 public:
91  PreambleMacroCallbacks(PreambleCallbacks &Callbacks) : Callbacks(Callbacks) {}
92 
93  void MacroDefined(const Token &MacroNameTok,
94  const MacroDirective *MD) override {
95  Callbacks.HandleMacroDefined(MacroNameTok, MD);
96  }
97 
98 private:
99  PreambleCallbacks &Callbacks;
100 };
101 
102 class PrecompilePreambleAction : public ASTFrontendAction {
103 public:
104  PrecompilePreambleAction(PreambleCallbacks &Callbacks)
105  : Callbacks(Callbacks) {}
106 
107  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
108  StringRef InFile) override;
109 
110  bool hasEmittedPreamblePCH() const { return HasEmittedPreamblePCH; }
111 
112  void setEmittedPreamblePCH(ASTWriter &Writer) {
113  this->HasEmittedPreamblePCH = true;
114  Callbacks.AfterPCHEmitted(Writer);
115  }
116 
117  bool shouldEraseOutputFiles() override { return !hasEmittedPreamblePCH(); }
118  bool hasCodeCompletionSupport() const override { return false; }
119  bool hasASTFileSupport() const override { return false; }
120  TranslationUnitKind getTranslationUnitKind() override { return TU_Prefix; }
121 
122 private:
123  friend class PrecompilePreambleConsumer;
124 
125  bool HasEmittedPreamblePCH = false;
126  PreambleCallbacks &Callbacks;
127 };
128 
129 class PrecompilePreambleConsumer : public PCHGenerator {
130 public:
131  PrecompilePreambleConsumer(PrecompilePreambleAction &Action,
132  const Preprocessor &PP, StringRef isysroot,
133  std::unique_ptr<raw_ostream> Out)
134  : PCHGenerator(PP, "", isysroot, std::make_shared<PCHBuffer>(),
135  ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
136  /*AllowASTWithErrors=*/true),
137  Action(Action), Out(std::move(Out)) {}
138 
139  bool HandleTopLevelDecl(DeclGroupRef DG) override {
140  Action.Callbacks.HandleTopLevelDecl(DG);
141  return true;
142  }
143 
144  void HandleTranslationUnit(ASTContext &Ctx) override {
146  if (!hasEmittedPCH())
147  return;
148 
149  // Write the generated bitstream to "Out".
150  *Out << getPCH();
151  // Make sure it hits disk now.
152  Out->flush();
153  // Free the buffer.
155  getPCH() = std::move(Empty);
156 
157  Action.setEmittedPreamblePCH(getWriter());
158  }
159 
160 private:
161  PrecompilePreambleAction &Action;
162  std::unique_ptr<raw_ostream> Out;
163 };
164 
165 std::unique_ptr<ASTConsumer>
166 PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
167 
168  StringRef InFile) {
169  std::string Sysroot;
170  std::string OutputFile;
171  std::unique_ptr<raw_ostream> OS =
173  OutputFile);
174  if (!OS)
175  return nullptr;
176 
178  Sysroot.clear();
179 
181  llvm::make_unique<PreambleMacroCallbacks>(Callbacks));
182  return llvm::make_unique<PrecompilePreambleConsumer>(
183  *this, CI.getPreprocessor(), Sysroot, std::move(OS));
184 }
185 
186 template <class T> bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
187  if (!Val)
188  return false;
189  Output = std::move(*Val);
190  return true;
191 }
192 
193 } // namespace
194 
196  llvm::MemoryBuffer *Buffer,
197  unsigned MaxLines) {
198  return Lexer::ComputePreamble(Buffer->getBuffer(), LangOpts, MaxLines);
199 }
200 
201 llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build(
202  const CompilerInvocation &Invocation,
203  const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
205  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
206  PreambleCallbacks &Callbacks) {
207  assert(VFS && "VFS is null");
208 
209  if (!Bounds.Size)
211 
212  auto PreambleInvocation = std::make_shared<CompilerInvocation>(Invocation);
213  FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts();
214  PreprocessorOptions &PreprocessorOpts =
215  PreambleInvocation->getPreprocessorOpts();
216 
217  // Create a temporary file for the precompiled preamble. In rare
218  // circumstances, this can fail.
219  llvm::ErrorOr<PrecompiledPreamble::TempPCHFile> PreamblePCHFile =
220  PrecompiledPreamble::TempPCHFile::CreateNewPreamblePCHFile();
221  if (!PreamblePCHFile)
223 
224  // Save the preamble text for later; we'll need to compare against it for
225  // subsequent reparses.
226  std::vector<char> PreambleBytes(MainFileBuffer->getBufferStart(),
227  MainFileBuffer->getBufferStart() +
228  Bounds.Size);
229  bool PreambleEndsAtStartOfLine = Bounds.PreambleEndsAtStartOfLine;
230 
231  // Tell the compiler invocation to generate a temporary precompiled header.
232  FrontendOpts.ProgramAction = frontend::GeneratePCH;
233  // FIXME: Generate the precompiled header into memory?
234  FrontendOpts.OutputFile = PreamblePCHFile->getFilePath();
235  PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
236  PreprocessorOpts.PrecompiledPreambleBytes.second = false;
237  // Inform preprocessor to record conditional stack when building the preamble.
238  PreprocessorOpts.GeneratePreamble = true;
239 
240  // Create the compiler instance to use for building the precompiled preamble.
241  std::unique_ptr<CompilerInstance> Clang(
242  new CompilerInstance(std::move(PCHContainerOps)));
243 
244  // Recover resources if we crash before exiting this method.
245  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> CICleanup(
246  Clang.get());
247 
248  Clang->setInvocation(std::move(PreambleInvocation));
249  Clang->setDiagnostics(&Diagnostics);
250 
251  // Create the target instance.
252  Clang->setTarget(TargetInfo::CreateTargetInfo(
253  Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
254  if (!Clang->hasTarget())
256 
257  // Inform the target of the language options.
258  //
259  // FIXME: We shouldn't need to do this, the target should be immutable once
260  // created. This complexity should be lifted elsewhere.
261  Clang->getTarget().adjust(Clang->getLangOpts());
262 
263  assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
264  "Invocation must have exactly one source file!");
265  assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
267  "FIXME: AST inputs not yet supported here!");
268  assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
270  "IR inputs not support here!");
271 
272  // Clear out old caches and data.
273  Diagnostics.Reset();
274  ProcessWarningOptions(Diagnostics, Clang->getDiagnosticOpts());
275 
276  VFS =
277  createVFSFromCompilerInvocation(Clang->getInvocation(), Diagnostics, VFS);
278  if (!VFS)
280 
281  // Create a file manager object to provide access to and cache the filesystem.
282  Clang->setFileManager(new FileManager(Clang->getFileSystemOpts(), VFS));
283 
284  // Create the source manager.
285  Clang->setSourceManager(
286  new SourceManager(Diagnostics, Clang->getFileManager()));
287 
288  auto PreambleDepCollector = std::make_shared<DependencyCollector>();
289  Clang->addDependencyCollector(PreambleDepCollector);
290 
291  // Remap the main source file to the preamble buffer.
292  StringRef MainFilePath = FrontendOpts.Inputs[0].getFile();
293  auto PreambleInputBuffer = llvm::MemoryBuffer::getMemBufferCopy(
294  MainFileBuffer->getBuffer().slice(0, Bounds.Size), MainFilePath);
295  if (PreprocessorOpts.RetainRemappedFileBuffers) {
296  // MainFileBuffer will be deleted by unique_ptr after leaving the method.
297  PreprocessorOpts.addRemappedFile(MainFilePath, PreambleInputBuffer.get());
298  } else {
299  // In that case, remapped buffer will be deleted by CompilerInstance on
300  // BeginSourceFile, so we call release() to avoid double deletion.
301  PreprocessorOpts.addRemappedFile(MainFilePath,
302  PreambleInputBuffer.release());
303  }
304 
305  std::unique_ptr<PrecompilePreambleAction> Act;
306  Act.reset(new PrecompilePreambleAction(Callbacks));
307  if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
309 
310  Act->Execute();
311 
312  // Run the callbacks.
313  Callbacks.AfterExecute(*Clang);
314 
315  Act->EndSourceFile();
316 
317  if (!Act->hasEmittedPreamblePCH())
319 
320  // Keep track of all of the files that the source manager knows about,
321  // so we can verify whether they have changed or not.
322  llvm::StringMap<PrecompiledPreamble::PreambleFileHash> FilesInPreamble;
323 
324  SourceManager &SourceMgr = Clang->getSourceManager();
325  for (auto &Filename : PreambleDepCollector->getDependencies()) {
326  const FileEntry *File = Clang->getFileManager().getFile(Filename);
327  if (!File || File == SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()))
328  continue;
329  if (time_t ModTime = File->getModificationTime()) {
330  FilesInPreamble[File->getName()] =
331  PrecompiledPreamble::PreambleFileHash::createForFile(File->getSize(),
332  ModTime);
333  } else {
334  llvm::MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File);
335  FilesInPreamble[File->getName()] =
336  PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(Buffer);
337  }
338  }
339 
340  return PrecompiledPreamble(
341  std::move(*PreamblePCHFile), std::move(PreambleBytes),
342  PreambleEndsAtStartOfLine, std::move(FilesInPreamble));
343 }
344 
346  return PreambleBounds(PreambleBytes.size(), PreambleEndsAtStartOfLine);
347 }
348 
350  const llvm::MemoryBuffer *MainFileBuffer,
351  PreambleBounds Bounds,
352  vfs::FileSystem *VFS) const {
353 
354  assert(
355  Bounds.Size <= MainFileBuffer->getBufferSize() &&
356  "Buffer is too large. Bounds were calculated from a different buffer?");
357 
358  auto PreambleInvocation = std::make_shared<CompilerInvocation>(Invocation);
359  PreprocessorOptions &PreprocessorOpts =
360  PreambleInvocation->getPreprocessorOpts();
361 
362  if (!Bounds.Size)
363  return false;
364 
365  // We've previously computed a preamble. Check whether we have the same
366  // preamble now that we did before, and that there's enough space in
367  // the main-file buffer within the precompiled preamble to fit the
368  // new main file.
369  if (PreambleBytes.size() != Bounds.Size ||
370  PreambleEndsAtStartOfLine != Bounds.PreambleEndsAtStartOfLine ||
371  memcmp(PreambleBytes.data(), MainFileBuffer->getBufferStart(),
372  Bounds.Size) != 0)
373  return false;
374  // The preamble has not changed. We may be able to re-use the precompiled
375  // preamble.
376 
377  // Check that none of the files used by the preamble have changed.
378  // First, make a record of those files that have been overridden via
379  // remapping or unsaved_files.
380  std::map<llvm::sys::fs::UniqueID, PreambleFileHash> OverriddenFiles;
381  for (const auto &R : PreprocessorOpts.RemappedFiles) {
382  vfs::Status Status;
383  if (!moveOnNoError(VFS->status(R.second), Status)) {
384  // If we can't stat the file we're remapping to, assume that something
385  // horrible happened.
386  return false;
387  }
388 
389  OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForFile(
390  Status.getSize(), llvm::sys::toTimeT(Status.getLastModificationTime()));
391  }
392 
393  for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
394  vfs::Status Status;
395  if (!moveOnNoError(VFS->status(RB.first), Status))
396  return false;
397 
398  OverriddenFiles[Status.getUniqueID()] =
399  PreambleFileHash::createForMemoryBuffer(RB.second);
400  }
401 
402  // Check whether anything has changed.
403  for (const auto &F : FilesInPreamble) {
404  vfs::Status Status;
405  if (!moveOnNoError(VFS->status(F.first()), Status)) {
406  // If we can't stat the file, assume that something horrible happened.
407  return false;
408  }
409 
410  std::map<llvm::sys::fs::UniqueID, PreambleFileHash>::iterator Overridden =
411  OverriddenFiles.find(Status.getUniqueID());
412  if (Overridden != OverriddenFiles.end()) {
413  // This file was remapped; check whether the newly-mapped file
414  // matches up with the previous mapping.
415  if (Overridden->second != F.second)
416  return false;
417  continue;
418  }
419 
420  // The file was not remapped; check whether it has changed on disk.
421  if (Status.getSize() != uint64_t(F.second.Size) ||
422  llvm::sys::toTimeT(Status.getLastModificationTime()) !=
423  F.second.ModTime)
424  return false;
425  }
426  return true;
427 }
428 
430  CompilerInvocation &CI, llvm::MemoryBuffer *MainFileBuffer) const {
431  auto &PreprocessorOpts = CI.getPreprocessorOpts();
432 
433  // Configure ImpicitPCHInclude.
434  PreprocessorOpts.PrecompiledPreambleBytes.first = PreambleBytes.size();
435  PreprocessorOpts.PrecompiledPreambleBytes.second = PreambleEndsAtStartOfLine;
436  PreprocessorOpts.ImplicitPCHInclude = PCHFile.getFilePath();
437  PreprocessorOpts.DisablePCHValidation = true;
438 
439  // Remap main file to point to MainFileBuffer.
440  auto MainFilePath = CI.getFrontendOpts().Inputs[0].getFile();
441  PreprocessorOpts.addRemappedFile(MainFilePath, MainFileBuffer);
442 }
443 
445  TempPCHFile PCHFile, std::vector<char> PreambleBytes,
446  bool PreambleEndsAtStartOfLine,
447  llvm::StringMap<PreambleFileHash> FilesInPreamble)
448  : PCHFile(std::move(PCHFile)), FilesInPreamble(FilesInPreamble),
449  PreambleBytes(std::move(PreambleBytes)),
450  PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {}
451 
452 llvm::ErrorOr<PrecompiledPreamble::TempPCHFile>
453 PrecompiledPreamble::TempPCHFile::CreateNewPreamblePCHFile() {
454  // FIXME: This is a hack so that we can override the preamble file during
455  // crash-recovery testing, which is the only case where the preamble files
456  // are not necessarily cleaned up.
457  const char *TmpFile = ::getenv("CINDEXTEST_PREAMBLE_FILE");
458  if (TmpFile)
459  return TempPCHFile::createFromCustomPath(TmpFile);
460  return TempPCHFile::createInSystemTempDir("preamble", "pch");
461 }
462 
463 llvm::ErrorOr<PrecompiledPreamble::TempPCHFile>
464 PrecompiledPreamble::TempPCHFile::createInSystemTempDir(const Twine &Prefix,
465  StringRef Suffix) {
467  // Using a version of createTemporaryFile with a file descriptor guarantees
468  // that we would never get a race condition in a multi-threaded setting (i.e.,
469  // multiple threads getting the same temporary path).
470  int FD;
471  auto EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, /*ref*/ FD,
472  /*ref*/ File);
473  if (EC)
474  return EC;
475  // We only needed to make sure the file exists, close the file right away.
476  llvm::sys::Process::SafelyCloseFileDescriptor(FD);
477  return TempPCHFile(std::move(File).str());
478 }
479 
480 llvm::ErrorOr<PrecompiledPreamble::TempPCHFile>
481 PrecompiledPreamble::TempPCHFile::createFromCustomPath(const Twine &Path) {
482  return TempPCHFile(Path.str());
483 }
484 
485 PrecompiledPreamble::TempPCHFile::TempPCHFile(std::string FilePath)
486  : FilePath(std::move(FilePath)) {
487  TemporaryFiles::getInstance().addFile(*this->FilePath);
488 }
489 
490 PrecompiledPreamble::TempPCHFile::TempPCHFile(TempPCHFile &&Other) {
491  FilePath = std::move(Other.FilePath);
492  Other.FilePath = None;
493 }
494 
495 PrecompiledPreamble::TempPCHFile &PrecompiledPreamble::TempPCHFile::
496 operator=(TempPCHFile &&Other) {
497  RemoveFileIfPresent();
498 
499  FilePath = std::move(Other.FilePath);
500  Other.FilePath = None;
501  return *this;
502 }
503 
504 PrecompiledPreamble::TempPCHFile::~TempPCHFile() { RemoveFileIfPresent(); }
505 
506 void PrecompiledPreamble::TempPCHFile::RemoveFileIfPresent() {
507  if (FilePath) {
508  TemporaryFiles::getInstance().removeFile(*FilePath);
509  FilePath = None;
510  }
511 }
512 
513 llvm::StringRef PrecompiledPreamble::TempPCHFile::getFilePath() const {
514  assert(FilePath && "TempPCHFile doesn't have a FilePath. Had it been moved?");
515  return *FilePath;
516 }
517 
518 PrecompiledPreamble::PreambleFileHash
519 PrecompiledPreamble::PreambleFileHash::createForFile(off_t Size,
520  time_t ModTime) {
521  PreambleFileHash Result;
522  Result.Size = Size;
523  Result.ModTime = ModTime;
524  Result.MD5 = {};
525  return Result;
526 }
527 
528 PrecompiledPreamble::PreambleFileHash
529 PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(
530  const llvm::MemoryBuffer *Buffer) {
531  PreambleFileHash Result;
532  Result.Size = Buffer->getBufferSize();
533  Result.ModTime = 0;
534 
535  llvm::MD5 MD5Ctx;
536  MD5Ctx.update(Buffer->getBuffer().data());
537  MD5Ctx.final(Result.MD5);
538 
539  return Result;
540 }
541 
546  const MacroDirective *MD) {}
547 
549  return std::error_code(static_cast<int>(Error), BuildPreambleErrorCategory());
550 }
551 
552 const char *BuildPreambleErrorCategory::name() const noexcept {
553  return "build-preamble.error";
554 }
555 
556 std::string BuildPreambleErrorCategory::message(int condition) const {
557  switch (static_cast<BuildPreambleError>(condition)) {
559  return "Preamble is empty";
561  return "Could not create temporary file for PCH";
563  return "CreateTargetInfo() return null";
565  return "Could not create VFS Overlay";
567  return "BeginSourceFile() return an error";
569  return "Could not emit PCH";
570  }
571  llvm_unreachable("unexpected BuildPreambleError");
572 }
Describes the bounds (start, size) of the preamble and a flag required by PreprocessorOptions::Precom...
Definition: Lexer.h:45
Implements support for file system lookup, file system caching, and directory search management...
Definition: FileManager.h:116
time_t getModificationTime() const
Definition: FileManager.h:91
The translation unit is a prefix to a translation unit, and is not complete.
Definition: LangOptions.h:246
static std::unique_ptr< raw_pwrite_stream > ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile, std::string &Sysroot, std::string &OutputFile)
Compute the AST consumer arguments that will be used to create the PCHGenerator instance returned by ...
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
void addRemappedFile(StringRef From, StringRef To)
This interface provides a way to observe the actions of the preprocessor as it does its thing...
Definition: PPCallbacks.h:36
The virtual file system interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:128
void HandleTranslationUnit(ASTContext &Ctx) override
HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...
Definition: GeneratePCH.cpp:40
Definition: Format.h:1821
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
unsigned RelocatablePCH
When generating PCH files, instruct the AST writer to create relocatable PCH files.
virtual llvm::ErrorOr< Status > status(const Twine &Path)=0
Get the status of the entry at Path, if one exists.
std::error_code make_error_code(BuildPreambleError Error)
FrontendOptions & getFrontendOpts()
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:147
bool RetainRemappedFileBuffers
Whether the compiler instance should retain (i.e., not free) the buffers associated with remapped fil...
void AddImplicitPreamble(CompilerInvocation &CI, llvm::MemoryBuffer *MainFileBuffer) const
Changes options inside CI to use PCH from this preamble.
The result of a status operation.
void Reset()
Reset the state of the diagnostic object to its initial configuration.
Definition: Diagnostic.cpp:113
FrontendOptions & getFrontendOpts()
bool PreambleEndsAtStartOfLine
Whether the preamble ends at the start of a new line.
Definition: Lexer.h:56
A set of callbacks to gather useful information while building a preamble.
StringRef Filename
Definition: Format.cpp:1316
const char * name() const noexcept override
PreambleBounds getBounds() const
PreambleBounds used to build the preamble.
bool CanReuse(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, vfs::FileSystem *VFS) const
Check whether PrecompiledPreamble can be reused for the new contents(MainFileBuffer) of the main file...
static PreambleBounds ComputePreamble(StringRef Buffer, const LangOptions &LangOpts, unsigned MaxLines=0)
Compute the preamble of the given file.
Definition: Lexer.cpp:555
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
const FunctionProtoType * T
IntrusiveRefCntPtr< vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
virtual void HandleMacroDefined(const Token &MacroNameTok, const MacroDirective *MD)
Called for each macro defined in the Preamble.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)
Construct a target for the given options.
Definition: Targets.cpp:576
bool GeneratePreamble
True indicates that a preamble is being generated.
PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts, llvm::MemoryBuffer *Buffer, unsigned MaxLines)
Runs lexer to compute suggested preamble bounds.
The result type of a method or function.
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Definition: MacroInfo.h:286
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
StringRef getName() const
Definition: FileManager.h:84
LLVM IR: we accept this so that we can run the optimizer on it, and compile it to assembly or object ...
std::vector< FrontendInputFile > Inputs
The input files and their types.
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:59
llvm::sys::TimePoint getLastModificationTime() const
void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, bool ReportDiags=true)
ProcessWarningOptions - Initialize the diagnostic client and process the warning options specified on...
Definition: Warnings.cpp:44
Abstract base class to use for AST consumer-based frontend actions.
virtual void AfterPCHEmitted(ASTWriter &Writer)
Called after PCH has been emitted.
llvm::MemoryBuffer * getMemoryBufferForFile(const FileEntry *File, bool *Invalid=nullptr)
Retrieve the memory buffer associated with the given file.
PrecompiledPreamble(PrecompiledPreamble &&)=default
std::string message(int condition) const override
Dataflow Directional Tag Classes.
A class holding a PCH and all information to check whether it is valid to reuse the PCH for the subse...
PreprocessorOptions & getPreprocessorOpts()
off_t getSize() const
Definition: FileManager.h:87
uint64_t getSize() const
FileID getMainFileID() const
Returns the FileID of the main source file.
Helper class for holding the data necessary to invoke the compiler.
Defines the virtual file system interface vfs::FileSystem.
FrontendOptions - Options for controlling the behavior of the frontend.
virtual void AfterExecute(CompilerInstance &CI)
Called after FrontendAction::Execute(), but before FrontendAction::EndSourceFile().
unsigned Size
Size of the preamble in bytes.
Definition: Lexer.h:51
llvm::sys::fs::UniqueID getUniqueID() const
Generate pre-compiled header.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
TranslationUnitKind
Describes the kind of translation unit being processed.
Definition: LangOptions.h:241
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:82
std::pair< unsigned, bool > PrecompiledPreambleBytes
If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...
Defines the clang::TargetInfo interface.
An abstract superclass that describes a custom extension to the module/precompiled header file format...
AST and semantic-analysis consumer that generates a precompiled header from the parsed source code...
Definition: ASTWriter.h:938
static llvm::ErrorOr< PrecompiledPreamble > Build(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, DiagnosticsEngine &Diagnostics, IntrusiveRefCntPtr< vfs::FileSystem > VFS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, PreambleCallbacks &Callbacks)
Try to build PrecompiledPreamble for Invocation.
#define true
Definition: stdbool.h:32
virtual void HandleTopLevelDecl(DeclGroupRef DG)
Called for each TopLevelDecl.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
Definition: Preprocessor.h:825
This class handles loading and caching of source files into memory.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:98