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.