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();
486 Clang->setFileManager(
487 llvm::makeIntrusiveRefCnt<FileManager>(Clang->getFileSystemOpts(), VFS));
490 Clang->setSourceManager(llvm::makeIntrusiveRefCnt<SourceManager>(
491 *Diagnostics, Clang->getFileManager()));
493 auto PreambleDepCollector = std::make_shared<PreambleDependencyCollector>();
494 Clang->addDependencyCollector(PreambleDepCollector);
496 Clang->getLangOpts().CompilingPCH =
true;
499 StringRef MainFilePath = FrontendOpts.
Inputs[0].getFile();
500 auto PreambleInputBuffer = llvm::MemoryBuffer::getMemBufferCopy(
501 MainFileBuffer->getBuffer().slice(0, Bounds.
Size), MainFilePath);
504 PreprocessorOpts.
addRemappedFile(MainFilePath, PreambleInputBuffer.get());
509 PreambleInputBuffer.release());
512 auto Act = std::make_unique<PrecompilePreambleAction>(
514 Storage->getKind() == PCHStorage::Kind::TempFile,
516 if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
523 std::unique_ptr<PPCallbacks> DelegatedPPCallbacks =
525 if (DelegatedPPCallbacks)
526 Clang->getPreprocessor().addPPCallbacks(std::move(DelegatedPPCallbacks));
529 llvm::StringSet<> MissingFiles;
530 Clang->getPreprocessor().addPPCallbacks(
531 std::make_unique<MissingFileCollector>(
532 MissingFiles, Clang->getPreprocessor().getHeaderSearchInfo(),
533 Clang->getSourceManager()));
535 if (llvm::Error Err = Act->Execute())
536 return errorToErrorCode(std::move(Err));
541 Act->EndSourceFile();
543 if (!Act->hasEmittedPreamblePCH())
549 llvm::StringMap<PrecompiledPreamble::PreambleFileHash> FilesInPreamble;
552 for (
auto &Filename : PreambleDepCollector->getDependencies()) {
553 auto MaybeFile = Clang->getFileManager().getOptionalFileRef(Filename);
555 MaybeFile == SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID()))
557 auto File = *MaybeFile;
558 if (time_t ModTime =
File.getModificationTime()) {
559 FilesInPreamble[
File.getName()] =
560 PrecompiledPreamble::PreambleFileHash::createForFile(
File.getSize(),
563 llvm::MemoryBufferRef Buffer =
564 SourceMgr.getMemoryBufferForFileOrFake(
File);
565 FilesInPreamble[
File.getName()] =
566 PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(Buffer);
572 CICleanup.unregister();
576 std::move(Storage), std::move(PreambleBytes), PreambleEndsAtStartOfLine,
577 std::move(FilesInPreamble), std::move(MissingFiles));
581 return PreambleBounds(PreambleBytes.size(), PreambleEndsAtStartOfLine);
585 switch (Storage->getKind()) {
586 case PCHStorage::Kind::InMemory:
587 return Storage->memoryContents().size();
588 case PCHStorage::Kind::TempFile: {
590 if (llvm::sys::fs::file_size(Storage->filePath(),
Result))
593 assert(
Result <= std::numeric_limits<std::size_t>::max() &&
594 "file size did not fit into size_t");
598 llvm_unreachable(
"Unhandled storage kind");
602 const llvm::MemoryBufferRef &MainFileBuffer,
604 llvm::vfs::FileSystem &VFS)
const {
607 Bounds.
Size <= MainFileBuffer.getBufferSize() &&
608 "Buffer is too large. Bounds were calculated from a different buffer?");
610 auto PreambleInvocation = std::make_shared<CompilerInvocation>(Invocation);
612 PreambleInvocation->getPreprocessorOpts();
618 if (PreambleBytes.size() != Bounds.
Size ||
620 !std::equal(PreambleBytes.begin(), PreambleBytes.end(),
621 MainFileBuffer.getBuffer().begin()))
629 std::map<llvm::sys::fs::UniqueID, PreambleFileHash> OverriddenFiles;
630 llvm::StringSet<> OverriddenAbsPaths;
632 llvm::vfs::Status Status;
640 if (!VFS.makeAbsolute(MappedPath))
641 OverriddenAbsPaths.insert(MappedPath);
643 OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForFile(
644 Status.getSize(), llvm::sys::toTimeT(Status.getLastModificationTime()));
648 llvm::StringMap<PreambleFileHash> OverridenFileBuffers;
650 const PrecompiledPreamble::PreambleFileHash PreambleHash =
651 PreambleFileHash::createForMemoryBuffer(RB.second->getMemBufferRef());
652 llvm::vfs::Status Status;
654 OverriddenFiles[Status.getUniqueID()] = PreambleHash;
656 OverridenFileBuffers[RB.first] = PreambleHash;
659 if (!VFS.makeAbsolute(MappedPath))
660 OverriddenAbsPaths.insert(MappedPath);
664 for (
const auto &F : FilesInPreamble) {
665 auto OverridenFileBuffer = OverridenFileBuffers.find(F.first());
666 if (OverridenFileBuffer != OverridenFileBuffers.end()) {
669 if (OverridenFileBuffer->second != F.second)
674 llvm::vfs::Status Status;
681 std::map<llvm::sys::fs::UniqueID, PreambleFileHash>::iterator Overridden =
682 OverriddenFiles.find(Status.getUniqueID());
683 if (Overridden != OverriddenFiles.end()) {
686 if (Overridden->second != F.second)
693 if (Status.getSize() != uint64_t(F.second.Size) ||
694 llvm::sys::toTimeT(Status.getLastModificationTime()) !=
698 for (
const auto &F : MissingFiles) {
700 if (OverriddenAbsPaths.count(F.getKey()))
704 if (
auto Status = VFS.status(F.getKey())) {
705 if (Status->isRegularFile())
714 llvm::MemoryBuffer *MainFileBuffer)
const {
715 PreambleBounds Bounds(PreambleBytes.size(), PreambleEndsAtStartOfLine);
716 configurePreamble(Bounds, CI, VFS, MainFileBuffer);
721 llvm::MemoryBuffer *MainFileBuffer)
const {
723 configurePreamble(Bounds, CI, VFS, MainFileBuffer);
727 std::unique_ptr<PCHStorage> Storage, std::vector<char> PreambleBytes,
728 bool PreambleEndsAtStartOfLine,
729 llvm::StringMap<PreambleFileHash> FilesInPreamble,
730 llvm::StringSet<> MissingFiles)
731 : Storage(
std::move(Storage)), FilesInPreamble(
std::move(FilesInPreamble)),
732 MissingFiles(
std::move(MissingFiles)),
733 PreambleBytes(
std::move(PreambleBytes)),
734 PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {
735 assert(this->Storage !=
nullptr);
738PrecompiledPreamble::PreambleFileHash
739PrecompiledPreamble::PreambleFileHash::createForFile(off_t Size,
741 PreambleFileHash Result;
743 Result.ModTime = ModTime;
748PrecompiledPreamble::PreambleFileHash
749PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(
750 const llvm::MemoryBufferRef &Buffer) {
752 Result.Size = Buffer.getBufferSize();
756 MD5Ctx.update(Buffer.getBuffer().data());
762void PrecompiledPreamble::configurePreamble(
763 PreambleBounds Bounds, CompilerInvocation &CI,
764 IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS,
765 llvm::MemoryBuffer *MainFileBuffer)
const {
772 PreprocessorOpts.addRemappedFile(MainFilePath, MainFileBuffer);
775 PreprocessorOpts.PrecompiledPreambleBytes.first = Bounds.
Size;
776 PreprocessorOpts.PrecompiledPreambleBytes.second =
778 PreprocessorOpts.DisablePCHOrModuleValidation =
783 PreprocessorOpts.UsePredefines =
false;
785 setupPreambleStorage(*Storage, PreprocessorOpts, VFS);
788void PrecompiledPreamble::setupPreambleStorage(
789 const PCHStorage &Storage, PreprocessorOptions &PreprocessorOpts,
790 IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS) {
791 if (Storage.getKind() == PCHStorage::Kind::TempFile) {
792 llvm::StringRef PCHPath = Storage.filePath();
796 IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS =
797 llvm::vfs::getRealFileSystem();
798 if (VFS == RealFS ||
VFS->exists(PCHPath))
800 auto Buf = RealFS->getBufferForFile(PCHPath);
810 VFS = createVFSOverlayForPreamblePCH(PCHPath, std::move(*Buf), VFS);
812 assert(Storage.getKind() == PCHStorage::Kind::InMemory);
815 StringRef PCHPath = getInMemoryPreamblePath();
818 auto Buf = llvm::MemoryBuffer::getMemBuffer(
819 Storage.memoryContents(), PCHPath,
false);
820 VFS = createVFSOverlayForPreamblePCH(PCHPath, std::move(Buf), VFS);
840 return "build-preamble.error";
846 return "Could not create temporary file for PCH";
848 return "CreateTargetInfo() return null";
850 return "BeginSourceFile() return an error";
852 return "Could not emit PCH";
854 return "Command line arguments must contain exactly one source file";
856 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
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
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.