25#include "llvm/ADT/SmallString.h" 
   26#include "llvm/ADT/StringSet.h" 
   27#include "llvm/ADT/iterator_range.h" 
   28#include "llvm/Config/llvm-config.h" 
   29#include "llvm/Support/CrashRecoveryContext.h" 
   30#include "llvm/Support/FileSystem.h" 
   31#include "llvm/Support/ManagedStatic.h" 
   32#include "llvm/Support/Path.h" 
   33#include "llvm/Support/Process.h" 
   34#include "llvm/Support/VirtualFileSystem.h" 
   43StringRef getInMemoryPreamblePath() {
 
   44#if defined(LLVM_ON_UNIX) 
   45  return "/__clang_tmp/___clang_inmemory_preamble___";
 
   47  return "C:\\__clang_tmp\\___clang_inmemory_preamble___";
 
   49#warning "Unknown platform. Defaulting to UNIX-style paths for in-memory PCHs" 
   50  return "/__clang_tmp/___clang_inmemory_preamble___";
 
   55createVFSOverlayForPreamblePCH(StringRef PCHFilename,
 
   56                               std::unique_ptr<llvm::MemoryBuffer> 
PCHBuffer,
 
   60  auto PCHFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
 
   61  PCHFS->addFile(PCHFilename, 0, std::move(
PCHBuffer));
 
   62  auto Overlay = llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(VFS);
 
   63  Overlay->pushOverlay(PCHFS);
 
   74  bool needSystemDependencies()
 override { 
return true; }
 
   87  llvm::StringSet<> &Out;
 
   89  const SourceManager &SM;
 
   92  MissingFileCollector(llvm::StringSet<> &Out, 
const HeaderSearch &Search,
 
   93                       const SourceManager &SM)
 
   94      : Out(Out), Search(Search), SM(SM) {}
 
   96  void InclusionDirective(SourceLocation HashLoc, 
const Token &IncludeTok,
 
   98                          CharSourceRange FilenameRange,
 
  100                          StringRef RelativePath, 
const Module *SuggestedModule,
 
  109    if (llvm::sys::path::is_absolute(
FileName)) {
 
  115    llvm::SmallString<256> Buf;
 
  116    auto NotFoundRelativeTo = [&](DirectoryEntryRef DE) {
 
  118      llvm::sys::path::append(Buf, 
FileName);
 
  119      llvm::sys::path::remove_dots(Buf, 
true);
 
  125              SM.getFileEntryRefForID(SM.getFileID(IncludeTok.
getLocation())))
 
  126        if (IncludingFile->getDir())
 
  127          NotFoundRelativeTo(IncludingFile->getDir());
 
  130    for (
const auto &Dir : llvm::make_range(
 
  131             IsAngled ? Search.angled_dir_begin() : Search.search_dir_begin(),
 
  132             Search.search_dir_end())) {
 
  134      if (Dir.isNormalDir())
 
  135        NotFoundRelativeTo(*Dir.getDirRef());
 
  141class TemporaryFiles {
 
  144  static TemporaryFiles &getInstance();
 
  148  TemporaryFiles() = 
default;
 
  150  TemporaryFiles(
const TemporaryFiles &) = 
delete;
 
  156  void addFile(StringRef 
File);
 
  159  void removeFile(StringRef 
File);
 
  163  llvm::StringSet<> Files;
 
  166TemporaryFiles &TemporaryFiles::getInstance() {
 
  167  static TemporaryFiles Instance;
 
  171TemporaryFiles::~TemporaryFiles() {
 
  172  std::lock_guard<std::mutex> Guard(Mutex);
 
  173  for (
const auto &
File : Files)
 
  174    llvm::sys::fs::remove(
File.getKey());
 
  177void TemporaryFiles::addFile(StringRef 
File) {
 
  178  std::lock_guard<std::mutex> Guard(Mutex);
 
  179  auto IsInserted = Files.insert(
File).second;
 
  181  assert(IsInserted && 
"File has already been added");
 
  184void TemporaryFiles::removeFile(StringRef 
File) {
 
  185  std::lock_guard<std::mutex> Guard(Mutex);
 
  186  auto WasPresent = Files.erase(
File);
 
  188  assert(WasPresent && 
"File was not tracked");
 
  189  llvm::sys::fs::remove(
File);
 
  200  static std::unique_ptr<TempPCHFile> 
create(StringRef StoragePath) {
 
  204    if (
const char *TmpFile = ::getenv(
"CINDEXTEST_PREAMBLE_FILE"))
 
  205      return std::unique_ptr<TempPCHFile>(
new TempPCHFile(TmpFile));
 
  207    llvm::SmallString<128> 
File;
 
  214    if (StoragePath.empty())
 
  215      EC = llvm::sys::fs::createTemporaryFile(
"preamble", 
"pch", FD, 
File);
 
  217      llvm::SmallString<128> TempPath = StoragePath;
 
  219      llvm::sys::path::append(TempPath, 
"preamble-%%%%%%.pch");
 
  220      namespace fs = llvm::sys::fs;
 
  222      EC = fs::createUniqueFile(TempPath, FD, 
File, fs::OF_None,
 
  223                                fs::owner_read | fs::owner_write);
 
  228    llvm::sys::Process::SafelyCloseFileDescriptor(FD);
 
  229    return std::unique_ptr<TempPCHFile>(
new TempPCHFile(
File.str().str()));
 
  232  TempPCHFile &operator=(
const TempPCHFile &) = 
delete;
 
  233  TempPCHFile(
const TempPCHFile &) = 
delete;
 
  234  ~TempPCHFile() { TemporaryFiles::getInstance().removeFile(FilePath); };
 
  237  llvm::StringRef getFilePath()
 const { 
return FilePath; };
 
  240  TempPCHFile(std::string FilePath) : FilePath(std::move(FilePath)) {
 
  241    TemporaryFiles::getInstance().addFile(this->FilePath);
 
  244  std::string FilePath;
 
  247class PrecompilePreambleAction : 
public ASTFrontendAction {
 
  249  PrecompilePreambleAction(std::shared_ptr<PCHBuffer> Buffer, 
bool WritePCHFile,
 
  250                           PreambleCallbacks &Callbacks)
 
  251      : Buffer(std::move(Buffer)), WritePCHFile(WritePCHFile),
 
  252        Callbacks(Callbacks) {}
 
  254  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
 
  255                                                 StringRef InFile) 
override;
 
  257  bool hasEmittedPreamblePCH()
 const { 
return HasEmittedPreamblePCH; }
 
  259  void setEmittedPreamblePCH(ASTWriter &Writer) {
 
  261      *FileOS << Buffer->Data;
 
  266    this->HasEmittedPreamblePCH = 
true;
 
  270  bool BeginSourceFileAction(CompilerInstance &CI)
 override {
 
  272    return ASTFrontendAction::BeginSourceFileAction(CI);
 
  275  bool shouldEraseOutputFiles()
 override { 
return !hasEmittedPreamblePCH(); }
 
  276  bool hasCodeCompletionSupport()
 const override { 
return false; }
 
  277  bool hasASTFileSupport()
 const override { 
return false; }
 
  281  friend class PrecompilePreambleConsumer;
 
  283  bool HasEmittedPreamblePCH = 
false;
 
  284  std::shared_ptr<PCHBuffer> Buffer;
 
  286  std::unique_ptr<llvm::raw_pwrite_stream> FileOS; 
 
  287  PreambleCallbacks &Callbacks;
 
  290class PrecompilePreambleConsumer : 
public PCHGenerator {
 
  292  PrecompilePreambleConsumer(PrecompilePreambleAction &Action, Preprocessor &PP,
 
  293                             ModuleCache &ModCache, StringRef isysroot,
 
  294                             std::shared_ptr<PCHBuffer> Buffer,
 
  295                             const CodeGenOptions &CodeGenOpts)
 
  296      : PCHGenerator(PP, ModCache, 
"", isysroot, std::move(Buffer), CodeGenOpts,
 
  297                     ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
 
  301  bool HandleTopLevelDecl(DeclGroupRef DG)
 override {
 
  306  void HandleTranslationUnit(ASTContext &Ctx)
 override {
 
  308    if (!hasEmittedPCH())
 
  310    Action.setEmittedPreamblePCH(getWriter());
 
  313  bool shouldSkipFunctionBody(Decl *D)
 override {
 
  318  PrecompilePreambleAction &Action;
 
  321std::unique_ptr<ASTConsumer>
 
  322PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
 
  329    std::string OutputFile; 
 
  338  return std::make_unique<PrecompilePreambleConsumer>(
 
  343template <
class T> 
bool moveOnNoError(llvm::ErrorOr<T> Val, 
T &Output) {
 
  346  Output = std::move(*Val);
 
  353                                            const llvm::MemoryBufferRef &Buffer,
 
 
  360  static std::unique_ptr<PCHStorage> 
file(std::unique_ptr<TempPCHFile> File) {
 
  362    std::unique_ptr<PCHStorage> S(
new PCHStorage());
 
  363    S->File = std::move(File);
 
 
  366  static std::unique_ptr<PCHStorage> 
inMemory(std::shared_ptr<PCHBuffer> Buf) {
 
  367    std::unique_ptr<PCHStorage> S(
new PCHStorage());
 
  368    S->Memory = std::move(Buf);
 
 
  372  enum class Kind { InMemory, TempFile };
 
  375      return Kind::InMemory;
 
  377      return Kind::TempFile;
 
  378    llvm_unreachable(
"Neither Memory nor File?");
 
 
  381    assert(
getKind() == Kind::TempFile);
 
  382    return File->getFilePath();
 
 
  385    assert(
getKind() == Kind::InMemory);
 
  386    return StringRef(Memory->Data.data(), Memory->Data.size());
 
 
  395    Memory->Data = 
decltype(Memory->Data)(Memory->Data);
 
 
  403  std::shared_ptr<PCHBuffer> Memory;
 
  404  std::unique_ptr<TempPCHFile> 
File;
 
 
  417    std::shared_ptr<PCHContainerOperations> PCHContainerOps, 
bool StoreInMemory,
 
  419  assert(VFS && 
"VFS is null");
 
  421  auto PreambleInvocation = std::make_shared<CompilerInvocation>(Invocation);
 
  424      PreambleInvocation->getPreprocessorOpts();
 
  426  std::shared_ptr<PCHBuffer> Buffer = std::make_shared<PCHBuffer>();
 
  427  std::unique_ptr<PCHStorage> Storage;
 
  433    std::unique_ptr<TempPCHFile> PreamblePCHFile =
 
  434        TempPCHFile::create(StoragePath);
 
  435    if (!PreamblePCHFile)
 
  442  std::vector<char> PreambleBytes(MainFileBuffer->getBufferStart(),
 
  443                                  MainFileBuffer->getBufferStart() +
 
  450      StoreInMemory ? getInMemoryPreamblePath() : Storage->filePath());
 
  457  auto Clang = std::make_unique<CompilerInstance>(std::move(PreambleInvocation),
 
  458                                                  std::move(PCHContainerOps));
 
  461  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> CICleanup(
 
  464  Clang->setDiagnostics(Diagnostics);
 
  467  if (!Clang->createTarget())
 
  470  if (Clang->getFrontendOpts().Inputs.size() != 1 ||
 
  471      Clang->getFrontendOpts().Inputs[0].getKind().getFormat() !=
 
  473      Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() ==
 
  479  Diagnostics->Reset();
 
  483  Clang->createVirtualFileSystem(VFS);
 
  484  Clang->createFileManager();
 
  487  Clang->createSourceManager();
 
  489  auto PreambleDepCollector = std::make_shared<PreambleDependencyCollector>();
 
  490  Clang->addDependencyCollector(PreambleDepCollector);
 
  492  Clang->getLangOpts().CompilingPCH = 
true;
 
  495  StringRef MainFilePath = FrontendOpts.
Inputs[0].getFile();
 
  496  auto PreambleInputBuffer = llvm::MemoryBuffer::getMemBufferCopy(
 
  497      MainFileBuffer->getBuffer().slice(0, Bounds.
Size), MainFilePath);
 
  500    PreprocessorOpts.
addRemappedFile(MainFilePath, PreambleInputBuffer.get());
 
  505                                     PreambleInputBuffer.release());
 
  508  auto Act = std::make_unique<PrecompilePreambleAction>(
 
  510      Storage->getKind() == PCHStorage::Kind::TempFile,
 
  512  if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
 
  519  std::unique_ptr<PPCallbacks> DelegatedPPCallbacks =
 
  521  if (DelegatedPPCallbacks)
 
  522    Clang->getPreprocessor().addPPCallbacks(std::move(DelegatedPPCallbacks));
 
  525  llvm::StringSet<> MissingFiles;
 
  526  Clang->getPreprocessor().addPPCallbacks(
 
  527      std::make_unique<MissingFileCollector>(
 
  528          MissingFiles, Clang->getPreprocessor().getHeaderSearchInfo(),
 
  529          Clang->getSourceManager()));
 
  531  if (llvm::Error Err = Act->Execute())
 
  532    return errorToErrorCode(std::move(Err));
 
  537  Act->EndSourceFile();
 
  539  if (!Act->hasEmittedPreamblePCH())
 
  545  llvm::StringMap<PrecompiledPreamble::PreambleFileHash> FilesInPreamble;
 
  548  for (
auto &Filename : PreambleDepCollector->getDependencies()) {
 
  549    auto MaybeFile = Clang->getFileManager().getOptionalFileRef(Filename);
 
  551        MaybeFile == SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID()))
 
  553    auto File = *MaybeFile;
 
  554    if (time_t ModTime = 
File.getModificationTime()) {
 
  555      FilesInPreamble[
File.getName()] =
 
  556          PrecompiledPreamble::PreambleFileHash::createForFile(
File.getSize(),
 
  559      llvm::MemoryBufferRef Buffer =
 
  560          SourceMgr.getMemoryBufferForFileOrFake(
File);
 
  561      FilesInPreamble[
File.getName()] =
 
  562          PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(Buffer);
 
  568  CICleanup.unregister();
 
  572      std::move(Storage), std::move(PreambleBytes), PreambleEndsAtStartOfLine,
 
  573      std::move(FilesInPreamble), std::move(MissingFiles));
 
 
  577  return PreambleBounds(PreambleBytes.size(), PreambleEndsAtStartOfLine);
 
 
  581  switch (Storage->getKind()) {
 
  582  case PCHStorage::Kind::InMemory:
 
  583    return Storage->memoryContents().size();
 
  584  case PCHStorage::Kind::TempFile: {
 
  586    if (llvm::sys::fs::file_size(Storage->filePath(), 
Result))
 
  589    assert(
Result <= std::numeric_limits<std::size_t>::max() &&
 
  590           "file size did not fit into size_t");
 
  594  llvm_unreachable(
"Unhandled storage kind");
 
 
  598                                   const llvm::MemoryBufferRef &MainFileBuffer,
 
  600                                   llvm::vfs::FileSystem &VFS)
 const {
 
  603      Bounds.
Size <= MainFileBuffer.getBufferSize() &&
 
  604      "Buffer is too large. Bounds were calculated from a different buffer?");
 
  606  auto PreambleInvocation = std::make_shared<CompilerInvocation>(Invocation);
 
  608      PreambleInvocation->getPreprocessorOpts();
 
  614  if (PreambleBytes.size() != Bounds.
Size ||
 
  616      !std::equal(PreambleBytes.begin(), PreambleBytes.end(),
 
  617                  MainFileBuffer.getBuffer().begin()))
 
  625  std::map<llvm::sys::fs::UniqueID, PreambleFileHash> OverriddenFiles;
 
  626  llvm::StringSet<> OverriddenAbsPaths; 
 
  628    llvm::vfs::Status Status;
 
  636    if (!VFS.makeAbsolute(MappedPath))
 
  637      OverriddenAbsPaths.insert(MappedPath);
 
  639    OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForFile(
 
  640        Status.getSize(), llvm::sys::toTimeT(Status.getLastModificationTime()));
 
  644  llvm::StringMap<PreambleFileHash> OverridenFileBuffers;
 
  646    const PrecompiledPreamble::PreambleFileHash PreambleHash =
 
  647        PreambleFileHash::createForMemoryBuffer(RB.second->getMemBufferRef());
 
  648    llvm::vfs::Status Status;
 
  650      OverriddenFiles[Status.getUniqueID()] = PreambleHash;
 
  652      OverridenFileBuffers[RB.first] = PreambleHash;
 
  655    if (!VFS.makeAbsolute(MappedPath))
 
  656      OverriddenAbsPaths.insert(MappedPath);
 
  660  for (
const auto &F : FilesInPreamble) {
 
  661    auto OverridenFileBuffer = OverridenFileBuffers.find(F.first());
 
  662    if (OverridenFileBuffer != OverridenFileBuffers.end()) {
 
  665      if (OverridenFileBuffer->second != F.second)
 
  670    llvm::vfs::Status Status;
 
  677    std::map<llvm::sys::fs::UniqueID, PreambleFileHash>::iterator Overridden =
 
  678        OverriddenFiles.find(Status.getUniqueID());
 
  679    if (Overridden != OverriddenFiles.end()) {
 
  682      if (Overridden->second != F.second)
 
  689    if (Status.getSize() != uint64_t(F.second.Size) ||
 
  690        llvm::sys::toTimeT(Status.getLastModificationTime()) !=
 
  694  for (
const auto &F : MissingFiles) {
 
  696    if (OverriddenAbsPaths.count(F.getKey()))
 
  700    if (
auto Status = VFS.status(F.getKey())) {
 
  701      if (Status->isRegularFile())
 
 
  710    llvm::MemoryBuffer *MainFileBuffer)
 const {
 
  711  PreambleBounds Bounds(PreambleBytes.size(), PreambleEndsAtStartOfLine);
 
  712  configurePreamble(Bounds, CI, VFS, MainFileBuffer);
 
 
  717    llvm::MemoryBuffer *MainFileBuffer)
 const {
 
  719  configurePreamble(Bounds, CI, VFS, MainFileBuffer);
 
 
  723    std::unique_ptr<PCHStorage> Storage, std::vector<char> PreambleBytes,
 
  724    bool PreambleEndsAtStartOfLine,
 
  725    llvm::StringMap<PreambleFileHash> FilesInPreamble,
 
  726    llvm::StringSet<> MissingFiles)
 
  727    : Storage(
std::move(Storage)), FilesInPreamble(
std::move(FilesInPreamble)),
 
  728      MissingFiles(
std::move(MissingFiles)),
 
  729      PreambleBytes(
std::move(PreambleBytes)),
 
  730      PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {
 
  731  assert(this->Storage != 
nullptr);
 
  734PrecompiledPreamble::PreambleFileHash
 
  735PrecompiledPreamble::PreambleFileHash::createForFile(off_t Size,
 
  737  PreambleFileHash Result;
 
  739  Result.ModTime = ModTime;
 
  744PrecompiledPreamble::PreambleFileHash
 
  745PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(
 
  746    const llvm::MemoryBufferRef &Buffer) {
 
  748  Result.Size = Buffer.getBufferSize();
 
  752  MD5Ctx.update(Buffer.getBuffer().data());
 
  758void PrecompiledPreamble::configurePreamble(
 
  759    PreambleBounds Bounds, CompilerInvocation &CI,
 
  760    IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS,
 
  761    llvm::MemoryBuffer *MainFileBuffer)
 const {
 
  768  PreprocessorOpts.addRemappedFile(MainFilePath, MainFileBuffer);
 
  771  PreprocessorOpts.PrecompiledPreambleBytes.first = Bounds.
Size;
 
  772  PreprocessorOpts.PrecompiledPreambleBytes.second =
 
  774  PreprocessorOpts.DisablePCHOrModuleValidation =
 
  779  PreprocessorOpts.UsePredefines = 
false;
 
  781  setupPreambleStorage(*Storage, PreprocessorOpts, VFS);
 
  784void PrecompiledPreamble::setupPreambleStorage(
 
  785    const PCHStorage &Storage, PreprocessorOptions &PreprocessorOpts,
 
  786    IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS) {
 
  787  if (Storage.getKind() == PCHStorage::Kind::TempFile) {
 
  788    llvm::StringRef PCHPath = Storage.filePath();
 
  792    IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS =
 
  793        llvm::vfs::getRealFileSystem();
 
  794    if (VFS == RealFS || 
VFS->exists(PCHPath))
 
  796    auto Buf = RealFS->getBufferForFile(PCHPath);
 
  806    VFS = createVFSOverlayForPreamblePCH(PCHPath, std::move(*Buf), VFS);
 
  808    assert(Storage.getKind() == PCHStorage::Kind::InMemory);
 
  811    StringRef PCHPath = getInMemoryPreamblePath();
 
  814    auto Buf = llvm::MemoryBuffer::getMemBuffer(
 
  815        Storage.memoryContents(), PCHPath, 
false);
 
  816    VFS = createVFSOverlayForPreamblePCH(PCHPath, std::move(Buf), VFS);
 
  836  return "build-preamble.error";
 
 
  842    return "Could not create temporary file for PCH";
 
  844    return "CreateTargetInfo() return null";
 
  846    return "BeginSourceFile() return an error";
 
  848    return "Could not emit PCH";
 
  850    return "Command line arguments must contain exactly one source file";
 
  852  llvm_unreachable(
"unexpected BuildPreambleError");
 
 
static bool moveOnNoError(llvm::ErrorOr< T > Val, T &Output)
 
static Decl::Kind getKind(const Decl *D)
 
Defines the clang::FileManager interface and associated types.
 
llvm::MachO::FileType FileType
 
static llvm::ManagedStatic< BuildPreambleErrorCategory > BuildPreambleErrCategory
 
Defines the clang::Preprocessor interface.
 
llvm::StringRef memoryContents() const
 
static std::unique_ptr< PCHStorage > file(std::unique_ptr< TempPCHFile > File)
 
static std::unique_ptr< PCHStorage > inMemory(std::shared_ptr< PCHBuffer > Buf)
 
llvm::StringRef filePath() const
 
Writes an AST file containing the contents of a translation unit.
 
std::string message(int condition) const override
 
const char * name() const noexcept override
 
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
 
ModuleCache & getModuleCache() const
 
Preprocessor & getPreprocessor() const
Return the current preprocessor.
 
FrontendOptions & getFrontendOpts()
 
LangOptions & getLangOpts()
 
CodeGenOptions & getCodeGenOpts()
 
Helper class for holding the data necessary to invoke the compiler.
 
PreprocessorOptions & getPreprocessorOpts()
 
LangOptions & getLangOpts()
Mutable getters.
 
FrontendOptions & getFrontendOpts()
 
An interface for collecting the dependencies of a compilation.
 
FrontendOptions - Options for controlling the behavior of the frontend.
 
std::string OutputFile
The output file, if any.
 
unsigned RelocatablePCH
When generating PCH files, instruct the AST writer to create relocatable PCH files.
 
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
 
frontend::ActionKind ProgramAction
The frontend action to perform.
 
static std::unique_ptr< llvm::raw_pwrite_stream > CreateOutputFile(CompilerInstance &CI, StringRef InFile, std::string &OutputFile)
Creates file to write the PCH into and returns a stream to write it into.
 
static bool ComputeASTConsumerArguments(CompilerInstance &CI, std::string &Sysroot)
Compute the AST consumer arguments that will be used to create the PCHGenerator instance returned by ...
 
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
 
static PreambleBounds ComputePreamble(StringRef Buffer, const LangOptions &LangOpts, unsigned MaxLines=0)
Compute the preamble of the given file.
 
void HandleTranslationUnit(ASTContext &Ctx) override
HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...
 
This interface provides a way to observe the actions of the preprocessor as it does its thing.
 
A set of callbacks to gather useful information while building a preamble.
 
virtual void AfterPCHEmitted(ASTWriter &Writer)
Called after PCH has been emitted.
 
virtual void BeforeExecute(CompilerInstance &CI)
Called before FrontendAction::Execute.
 
virtual CommentHandler * getCommentHandler()
The returned CommentHandler will be added to the preprocessor if not null.
 
virtual void HandleTopLevelDecl(DeclGroupRef DG)
Called for each TopLevelDecl.
 
virtual std::unique_ptr< PPCallbacks > createPPCallbacks()
Creates wrapper class for PPCallbacks so we can also process information about includes that are insi...
 
virtual void AfterExecute(CompilerInstance &CI)
Called after FrontendAction::Execute(), but before FrontendAction::EndSourceFile().
 
virtual bool shouldSkipFunctionBody(Decl *D)
Determines which function bodies are parsed, by default skips everything.
 
A class holding a PCH and all information to check whether it is valid to reuse the PCH for the subse...
 
void OverridePreamble(CompilerInvocation &CI, IntrusiveRefCntPtr< llvm::vfs::FileSystem > &VFS, llvm::MemoryBuffer *MainFileBuffer) const
Configure CI to use this preamble.
 
static llvm::ErrorOr< PrecompiledPreamble > Build(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, IntrusiveRefCntPtr< DiagnosticsEngine > Diagnostics, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, bool StoreInMemory, StringRef StoragePath, PreambleCallbacks &Callbacks)
Try to build PrecompiledPreamble for Invocation.
 
PrecompiledPreamble & operator=(PrecompiledPreamble &&)
 
bool CanReuse(const CompilerInvocation &Invocation, const llvm::MemoryBufferRef &MainFileBuffer, PreambleBounds Bounds, llvm::vfs::FileSystem &VFS) const
Check whether PrecompiledPreamble can be reused for the new contents(MainFileBuffer) of the main file...
 
void AddImplicitPreamble(CompilerInvocation &CI, IntrusiveRefCntPtr< llvm::vfs::FileSystem > &VFS, llvm::MemoryBuffer *MainFileBuffer) const
Changes options inside CI to use PCH from this preamble.
 
std::size_t getSize() const
Returns the size, in bytes, that preamble takes on disk or in memory.
 
PreambleBounds getBounds() const
PreambleBounds used to build the preamble.
 
PrecompiledPreamble(PrecompiledPreamble &&)
 
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
 
std::vector< std::pair< std::string, std::string > > RemappedFiles
The set of file remappings, which take existing files on the system (the first part of each pair) and...
 
std::pair< unsigned, bool > PrecompiledPreambleBytes
If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...
 
bool RetainRemappedFileBuffers
Whether the compiler instance should retain (i.e., not free) the buffers associated with remapped fil...
 
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
 
void addRemappedFile(StringRef From, StringRef To)
 
bool GeneratePreamble
True indicates that a preamble is being generated.
 
std::vector< std::pair< std::string, llvm::MemoryBuffer * > > RemappedFileBuffers
The set of file-to-buffer remappings, which take existing files on the system (the first part of each...
 
This class handles loading and caching of source files into memory.
 
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
 
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
 
@ GeneratePCH
Generate pre-compiled header.
 
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions &DiagOpts, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
 
The JSON file list parser is used to communicate input to InstallAPI.
 
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
 
std::error_code make_error_code(BuildPreambleError Error)
 
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
 
@ Result
The result type of a method or function.
 
const FunctionProtoType * T
 
void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, llvm::vfs::FileSystem &VFS, bool ReportDiags=true)
ProcessWarningOptions - Initialize the diagnostic client and process the warning options specified on...
 
TranslationUnitKind
Describes the kind of translation unit being processed.
 
@ TU_Prefix
The translation unit is a prefix to a translation unit, and is not complete.
 
@ PCH
Disable validation for a precompiled header and the modules it depends on.
 
PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts, const llvm::MemoryBufferRef &Buffer, unsigned MaxLines)
Runs lexer to compute suggested preamble bounds.
 
@ CouldntCreateTargetInfo
 
Describes the bounds (start, size) of the preamble and a flag required by PreprocessorOptions::Precom...
 
unsigned Size
Size of the preamble in bytes.
 
bool PreambleEndsAtStartOfLine
Whether the preamble ends at the start of a new line.