24 #include "llvm/ADT/StringExtras.h" 25 #include "llvm/ADT/StringSet.h" 26 #include "llvm/Config/llvm-config.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 #include "llvm/Support/VirtualFileSystem.h" 36 using namespace clang;
40 StringRef getInMemoryPreamblePath() {
41 #if defined(LLVM_ON_UNIX) 42 return "/__clang_tmp/___clang_inmemory_preamble___";
44 return "C:\\__clang_tmp\\___clang_inmemory_preamble___";
46 #warning "Unknown platform. Defaulting to UNIX-style paths for in-memory PCHs" 47 return "/__clang_tmp/___clang_inmemory_preamble___";
52 createVFSOverlayForPreamblePCH(StringRef PCHFilename,
53 std::unique_ptr<llvm::MemoryBuffer>
PCHBuffer,
58 new llvm::vfs::InMemoryFileSystem());
59 PCHFS->addFile(PCHFilename, 0, std::move(PCHBuffer));
61 new llvm::vfs::OverlayFileSystem(VFS));
62 Overlay->pushOverlay(PCHFS);
73 bool needSystemDependencies()
override {
return true; }
77 class TemporaryFiles {
80 static TemporaryFiles &getInstance();
84 TemporaryFiles() =
default;
86 TemporaryFiles(
const TemporaryFiles &) =
delete;
92 void addFile(StringRef File);
95 void removeFile(StringRef File);
98 llvm::sys::SmartMutex<false> Mutex;
99 llvm::StringSet<> Files;
102 TemporaryFiles &TemporaryFiles::getInstance() {
103 static TemporaryFiles Instance;
107 TemporaryFiles::~TemporaryFiles() {
108 llvm::MutexGuard Guard(Mutex);
109 for (
const auto &File : Files)
113 void TemporaryFiles::addFile(StringRef File) {
114 llvm::MutexGuard Guard(Mutex);
115 auto IsInserted = Files.insert(File).second;
117 assert(IsInserted &&
"File has already been added");
120 void TemporaryFiles::removeFile(StringRef File) {
121 llvm::MutexGuard Guard(Mutex);
122 auto WasPresent = Files.erase(File);
124 assert(WasPresent &&
"File was not tracked");
130 PrecompilePreambleAction(std::string *InMemStorage,
132 : InMemStorage(InMemStorage), Callbacks(Callbacks) {}
135 StringRef InFile)
override;
137 bool hasEmittedPreamblePCH()
const {
return HasEmittedPreamblePCH; }
139 void setEmittedPreamblePCH(
ASTWriter &Writer) {
140 this->HasEmittedPreamblePCH =
true;
141 Callbacks.AfterPCHEmitted(Writer);
144 bool shouldEraseOutputFiles()
override {
return !hasEmittedPreamblePCH(); }
145 bool hasCodeCompletionSupport()
const override {
return false; }
146 bool hasASTFileSupport()
const override {
return false; }
150 friend class PrecompilePreambleConsumer;
152 bool HasEmittedPreamblePCH =
false;
153 std::string *InMemStorage;
157 class PrecompilePreambleConsumer :
public PCHGenerator {
159 PrecompilePreambleConsumer(PrecompilePreambleAction &Action,
163 std::unique_ptr<raw_ostream> Out)
165 std::make_shared<PCHBuffer>(),
168 Action(Action), Out(
std::move(Out)) {}
171 Action.Callbacks.HandleTopLevelDecl(DG);
175 void HandleTranslationUnit(
ASTContext &Ctx)
override {
177 if (!hasEmittedPCH())
186 getPCH() = std::move(Empty);
188 Action.setEmittedPreamblePCH(getWriter());
192 PrecompilePreambleAction &Action;
193 std::unique_ptr<raw_ostream> Out;
196 std::unique_ptr<ASTConsumer>
203 std::unique_ptr<llvm::raw_ostream>
OS;
205 OS = llvm::make_unique<llvm::raw_string_ostream>(*InMemStorage);
207 std::string OutputFile;
216 return llvm::make_unique<PrecompilePreambleConsumer>(
220 template <
class T>
bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
223 Output = std::move(*Val);
230 llvm::MemoryBuffer *Buffer,
240 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
bool StoreInMemory,
242 assert(VFS &&
"VFS is null");
244 auto PreambleInvocation = std::make_shared<CompilerInvocation>(Invocation);
247 PreambleInvocation->getPreprocessorOpts();
250 if (!StoreInMemory) {
253 llvm::ErrorOr<PrecompiledPreamble::TempPCHFile> PreamblePCHFile =
254 PrecompiledPreamble::TempPCHFile::CreateNewPreamblePCHFile();
255 if (!PreamblePCHFile)
257 TempFile = std::move(*PreamblePCHFile);
260 PCHStorage Storage = StoreInMemory ? PCHStorage(InMemoryPreamble())
261 : PCHStorage(std::move(*TempFile));
265 std::vector<char> PreambleBytes(MainFileBuffer->getBufferStart(),
266 MainFileBuffer->getBufferStart() +
272 FrontendOpts.OutputFile = StoreInMemory ? getInMemoryPreamblePath()
273 : Storage.asFile().getFilePath();
280 std::unique_ptr<CompilerInstance> Clang(
284 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> CICleanup(
287 Clang->setInvocation(std::move(PreambleInvocation));
288 Clang->setDiagnostics(&Diagnostics);
292 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
293 if (!Clang->hasTarget())
300 Clang->getTarget().adjust(Clang->getLangOpts());
302 if (Clang->getFrontendOpts().Inputs.size() != 1 ||
303 Clang->getFrontendOpts().Inputs[0].getKind().getFormat() !=
305 Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() ==
318 Clang->setFileManager(
new FileManager(Clang->getFileSystemOpts(), VFS));
321 Clang->setSourceManager(
324 auto PreambleDepCollector = std::make_shared<PreambleDependencyCollector>();
325 Clang->addDependencyCollector(PreambleDepCollector);
328 StringRef MainFilePath = FrontendOpts.Inputs[0].getFile();
329 auto PreambleInputBuffer = llvm::MemoryBuffer::getMemBufferCopy(
330 MainFileBuffer->getBuffer().slice(0, Bounds.
Size), MainFilePath);
333 PreprocessorOpts.
addRemappedFile(MainFilePath, PreambleInputBuffer.get());
338 PreambleInputBuffer.release());
341 std::unique_ptr<PrecompilePreambleAction> Act;
342 Act.reset(
new PrecompilePreambleAction(
343 StoreInMemory ? &Storage.asMemory().Data :
nullptr, Callbacks));
345 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
348 std::unique_ptr<PPCallbacks> DelegatedPPCallbacks =
350 if (DelegatedPPCallbacks)
351 Clang->getPreprocessor().addPPCallbacks(std::move(DelegatedPPCallbacks));
356 return errorToErrorCode(std::move(Err));
361 Act->EndSourceFile();
363 if (!Act->hasEmittedPreamblePCH())
368 llvm::StringMap<PrecompiledPreamble::PreambleFileHash> FilesInPreamble;
371 for (
auto &
Filename : PreambleDepCollector->getDependencies()) {
376 FilesInPreamble[File->
getName()] =
377 PrecompiledPreamble::PreambleFileHash::createForFile(File->
getSize(),
381 FilesInPreamble[File->
getName()] =
382 PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(Buffer);
387 PreambleEndsAtStartOfLine,
388 std::move(FilesInPreamble));
392 return PreambleBounds(PreambleBytes.size(), PreambleEndsAtStartOfLine);
396 switch (Storage.getKind()) {
397 case PCHStorage::Kind::Empty:
398 assert(
false &&
"Calling getSize() on invalid PrecompiledPreamble. " 399 "Was it std::moved?");
401 case PCHStorage::Kind::InMemory:
402 return Storage.asMemory().Data.size();
403 case PCHStorage::Kind::TempFile: {
405 if (llvm::sys::fs::file_size(Storage.asFile().getFilePath(),
Result))
409 "file size did not fit into size_t");
413 llvm_unreachable(
"Unhandled storage kind");
417 const llvm::MemoryBuffer *MainFileBuffer,
419 llvm::vfs::FileSystem *VFS)
const {
422 Bounds.
Size <= MainFileBuffer->getBufferSize() &&
423 "Buffer is too large. Bounds were calculated from a different buffer?");
425 auto PreambleInvocation = std::make_shared<CompilerInvocation>(Invocation);
427 PreambleInvocation->getPreprocessorOpts();
433 if (PreambleBytes.size() != Bounds.
Size ||
435 !std::equal(PreambleBytes.begin(), PreambleBytes.end(),
436 MainFileBuffer->getBuffer().begin()))
444 std::map<llvm::sys::fs::UniqueID, PreambleFileHash> OverriddenFiles;
445 for (
const auto &R : PreprocessorOpts.RemappedFiles) {
446 llvm::vfs::Status Status;
453 OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForFile(
454 Status.getSize(), llvm::sys::toTimeT(Status.getLastModificationTime()));
458 llvm::StringMap<PreambleFileHash> OverridenFileBuffers;
459 for (
const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
460 const PrecompiledPreamble::PreambleFileHash PreambleHash =
461 PreambleFileHash::createForMemoryBuffer(RB.second);
462 llvm::vfs::Status Status;
464 OverriddenFiles[Status.getUniqueID()] = PreambleHash;
466 OverridenFileBuffers[RB.first] = PreambleHash;
470 for (
const auto &F : FilesInPreamble) {
471 auto OverridenFileBuffer = OverridenFileBuffers.find(F.first());
472 if (OverridenFileBuffer != OverridenFileBuffers.end()) {
475 if (OverridenFileBuffer->second != F.second)
480 llvm::vfs::Status Status;
487 std::map<llvm::sys::fs::UniqueID, PreambleFileHash>::iterator Overridden =
488 OverriddenFiles.find(Status.getUniqueID());
489 if (Overridden != OverriddenFiles.end()) {
492 if (Overridden->second != F.second)
499 if (Status.getSize() != uint64_t(F.second.Size) ||
500 llvm::sys::toTimeT(Status.getLastModificationTime()) !=
509 llvm::MemoryBuffer *MainFileBuffer)
const {
510 PreambleBounds Bounds(PreambleBytes.size(), PreambleEndsAtStartOfLine);
511 configurePreamble(Bounds, CI, VFS, MainFileBuffer);
516 llvm::MemoryBuffer *MainFileBuffer)
const {
518 configurePreamble(Bounds, CI, VFS, MainFileBuffer);
522 PCHStorage Storage, std::vector<char> PreambleBytes,
523 bool PreambleEndsAtStartOfLine,
524 llvm::StringMap<PreambleFileHash> FilesInPreamble)
525 : Storage(std::move(Storage)), FilesInPreamble(std::move(FilesInPreamble)),
526 PreambleBytes(std::move(PreambleBytes)),
527 PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {
528 assert(this->Storage.getKind() != PCHStorage::Kind::Empty);
531 llvm::ErrorOr<PrecompiledPreamble::TempPCHFile>
532 PrecompiledPreamble::TempPCHFile::CreateNewPreamblePCHFile() {
536 const char *TmpFile = ::getenv(
"CINDEXTEST_PREAMBLE_FILE");
538 return TempPCHFile::createFromCustomPath(TmpFile);
539 return TempPCHFile::createInSystemTempDir(
"preamble",
"pch");
542 llvm::ErrorOr<PrecompiledPreamble::TempPCHFile>
543 PrecompiledPreamble::TempPCHFile::createInSystemTempDir(
const Twine &Prefix,
550 auto EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, FD, File);
554 llvm::sys::Process::SafelyCloseFileDescriptor(FD);
555 return TempPCHFile(std::move(File).str());
558 llvm::ErrorOr<PrecompiledPreamble::TempPCHFile>
559 PrecompiledPreamble::TempPCHFile::createFromCustomPath(
const Twine &Path) {
560 return TempPCHFile(Path.str());
563 PrecompiledPreamble::TempPCHFile::TempPCHFile(std::string FilePath)
564 : FilePath(std::move(FilePath)) {
565 TemporaryFiles::getInstance().addFile(*this->FilePath);
568 PrecompiledPreamble::TempPCHFile::TempPCHFile(TempPCHFile &&Other) {
569 FilePath = std::move(Other.FilePath);
570 Other.FilePath =
None;
573 PrecompiledPreamble::TempPCHFile &PrecompiledPreamble::TempPCHFile::
574 operator=(TempPCHFile &&Other) {
575 RemoveFileIfPresent();
577 FilePath = std::move(Other.FilePath);
578 Other.FilePath =
None;
582 PrecompiledPreamble::TempPCHFile::~TempPCHFile() { RemoveFileIfPresent(); }
584 void PrecompiledPreamble::TempPCHFile::RemoveFileIfPresent() {
586 TemporaryFiles::getInstance().removeFile(*FilePath);
591 llvm::StringRef PrecompiledPreamble::TempPCHFile::getFilePath()
const {
592 assert(FilePath &&
"TempPCHFile doesn't have a FilePath. Had it been moved?");
596 PrecompiledPreamble::PCHStorage::PCHStorage(TempPCHFile File)
597 : StorageKind(Kind::TempFile) {
598 new (&asFile()) TempPCHFile(std::move(File));
601 PrecompiledPreamble::PCHStorage::PCHStorage(InMemoryPreamble Memory)
602 : StorageKind(Kind::InMemory) {
603 new (&asMemory()) InMemoryPreamble(std::move(Memory));
606 PrecompiledPreamble::PCHStorage::PCHStorage(PCHStorage &&Other) : PCHStorage() {
607 *
this = std::move(Other);
610 PrecompiledPreamble::PCHStorage &PrecompiledPreamble::PCHStorage::
611 operator=(PCHStorage &&Other) {
614 StorageKind = Other.StorageKind;
615 switch (StorageKind) {
620 new (&asFile()) TempPCHFile(std::move(Other.asFile()));
623 new (&asMemory()) InMemoryPreamble(std::move(Other.asMemory()));
631 PrecompiledPreamble::PCHStorage::~PCHStorage() { destroy(); }
633 PrecompiledPreamble::PCHStorage::Kind
638 PrecompiledPreamble::TempPCHFile &PrecompiledPreamble::PCHStorage::asFile() {
639 assert(
getKind() == Kind::TempFile);
640 return *
reinterpret_cast<TempPCHFile *
>(Storage.buffer);
643 const PrecompiledPreamble::TempPCHFile &
644 PrecompiledPreamble::PCHStorage::asFile()
const {
645 return const_cast<PCHStorage *
>(
this)->asFile();
648 PrecompiledPreamble::InMemoryPreamble &
649 PrecompiledPreamble::PCHStorage::asMemory() {
650 assert(
getKind() == Kind::InMemory);
651 return *
reinterpret_cast<InMemoryPreamble *
>(Storage.buffer);
654 const PrecompiledPreamble::InMemoryPreamble &
655 PrecompiledPreamble::PCHStorage::asMemory()
const {
656 return const_cast<PCHStorage *
>(
this)->asMemory();
659 void PrecompiledPreamble::PCHStorage::destroy() {
660 switch (StorageKind) {
664 asFile().~TempPCHFile();
667 asMemory().~InMemoryPreamble();
672 void PrecompiledPreamble::PCHStorage::setEmpty() {
674 StorageKind = Kind::Empty;
677 PrecompiledPreamble::PreambleFileHash
678 PrecompiledPreamble::PreambleFileHash::createForFile(off_t Size,
682 Result.ModTime = ModTime;
687 PrecompiledPreamble::PreambleFileHash
688 PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(
689 const llvm::MemoryBuffer *Buffer) {
691 Result.Size = Buffer->getBufferSize();
695 MD5Ctx.update(Buffer->getBuffer().data());
696 MD5Ctx.final(Result.MD5);
701 void PrecompiledPreamble::configurePreamble(
704 llvm::MemoryBuffer *MainFileBuffer)
const {
711 PreprocessorOpts.addRemappedFile(MainFilePath, MainFileBuffer);
714 PreprocessorOpts.PrecompiledPreambleBytes.first = Bounds.
Size;
715 PreprocessorOpts.PrecompiledPreambleBytes.second =
717 PreprocessorOpts.DisablePCHValidation =
true;
719 setupPreambleStorage(Storage, PreprocessorOpts, VFS);
722 void PrecompiledPreamble::setupPreambleStorage(
725 if (Storage.getKind() == PCHStorage::Kind::TempFile) {
726 const TempPCHFile &PCHFile = Storage.asFile();
731 llvm::vfs::getRealFileSystem();
732 auto PCHPath = PCHFile.getFilePath();
733 if (VFS == RealFS || VFS->exists(PCHPath))
735 auto Buf = RealFS->getBufferForFile(PCHPath);
745 VFS = createVFSOverlayForPreamblePCH(PCHPath, std::move(*Buf), VFS);
747 assert(Storage.getKind() == PCHStorage::Kind::InMemory);
750 StringRef PCHPath = getInMemoryPreamblePath();
753 auto Buf = llvm::MemoryBuffer::getMemBuffer(Storage.asMemory().Data);
754 VFS = createVFSOverlayForPreamblePCH(PCHPath, std::move(Buf), VFS);
770 return std::error_code(static_cast<int>(Error), *BuildPreambleErrCategory);
774 return "build-preamble.error";
778 switch (static_cast<BuildPreambleError>(condition)) {
780 return "Could not create temporary file for PCH";
782 return "CreateTargetInfo() return null";
784 return "BeginSourceFile() return an error";
786 return "Could not emit PCH";
788 return "Command line arguments must contain exactly one source file";
790 llvm_unreachable(
"unexpected BuildPreambleError");
std::size_t getSize() const
Returns the size, in bytes, that preamble takes on disk or in memory.
Describes the bounds (start, size) of the preamble and a flag required by PreprocessorOptions::Precom...
Implements support for file system lookup, file system caching, and directory search management...
time_t getModificationTime() const
bool CanReuse(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, llvm::vfs::FileSystem *VFS) const
Check whether PrecompiledPreamble can be reused for the new contents(MainFileBuffer) of the main file...
An interface for collecting the dependencies of a compilation.
The translation unit is a prefix to a translation unit, and is not complete.
InMemoryModuleCache & getModuleCache() const
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
void addRemappedFile(StringRef From, StringRef To)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void HandleTranslationUnit(ASTContext &Ctx) override
HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...
static bool moveOnNoError(llvm::ErrorOr< T > Val, T &Output)
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
__DEVICE__ int max(int __a, int __b)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
unsigned RelocatablePCH
When generating PCH files, instruct the AST writer to create relocatable PCH files.
static bool ComputeASTConsumerArguments(CompilerInstance &CI, std::string &Sysroot)
Compute the AST consumer arguments that will be used to create the PCHGenerator instance returned by ...
static llvm::ManagedStatic< BuildPreambleErrorCategory > BuildPreambleErrCategory
std::error_code make_error_code(BuildPreambleError Error)
FrontendOptions & getFrontendOpts()
Concrete class used by the front-end to report problems and issues.
bool RetainRemappedFileBuffers
Whether the compiler instance should retain (i.e., not free) the buffers associated with remapped fil...
void OverridePreamble(CompilerInvocation &CI, IntrusiveRefCntPtr< llvm::vfs::FileSystem > &VFS, llvm::MemoryBuffer *MainFileBuffer) const
Configure CI to use this preamble.
void Reset()
Reset the state of the diagnostic object to its initial configuration.
FrontendOptions & getFrontendOpts()
bool PreambleEndsAtStartOfLine
Whether the preamble ends at the start of a new line.
A set of callbacks to gather useful information while building a preamble.
const char * name() const noexcept override
PreambleBounds getBounds() const
PreambleBounds used to build the preamble.
void AddImplicitPreamble(CompilerInvocation &CI, IntrusiveRefCntPtr< llvm::vfs::FileSystem > &VFS, llvm::MemoryBuffer *MainFileBuffer) const
Changes options inside CI to use PCH from this preamble.
static PreambleBounds ComputePreamble(StringRef Buffer, const LangOptions &LangOpts, unsigned MaxLines=0)
Compute the preamble of the given file.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
Defines the clang::Preprocessor interface.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)
Construct a target for the given options.
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.
In-memory cache for modules.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
StringRef getName() const
virtual CommentHandler * getCommentHandler()
The returned CommentHandler will be added to the preprocessor if not null.
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
std::vector< FrontendInputFile > Inputs
The input files and their types.
Cached information about one file (either on disk or in the virtual file system). ...
void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, bool ReportDiags=true)
ProcessWarningOptions - Initialize the diagnostic client and process the warning options specified on...
Abstract base class to use for AST consumer-based frontend actions.
virtual void BeforeExecute(CompilerInstance &CI)
Called before FrontendAction::BeginSourceFile.
virtual void AfterPCHEmitted(ASTWriter &Writer)
Called after PCH has been emitted.
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()
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
const llvm::MemoryBuffer * getMemoryBufferForFile(const FileEntry *File, bool *Invalid=nullptr)
Retrieve the memory buffer associated with the given file.
FileID getMainFileID() const
Returns the FileID of the main source file.
Helper class for holding the data necessary to invoke the compiler.
FrontendOptions - Options for controlling the behavior of the frontend.
virtual void AfterExecute(CompilerInstance &CI)
Called after FrontendAction::Execute(), but before FrontendAction::EndSourceFile().
static llvm::ErrorOr< PrecompiledPreamble > Build(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, DiagnosticsEngine &Diagnostics, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, bool StoreInMemory, PreambleCallbacks &Callbacks)
Try to build PrecompiledPreamble for Invocation.
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
unsigned Size
Size of the preamble in bytes.
Generate pre-compiled header.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
TranslationUnitKind
Describes the kind of translation unit being processed.
Writes an AST file containing the contents of a translation unit.
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.
static Decl::Kind getKind(const Decl *D)
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...
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.
LangOptions * getLangOpts()
virtual void HandleTopLevelDecl(DeclGroupRef DG)
Called for each TopLevelDecl.
This class handles loading and caching of source files into memory.
virtual std::unique_ptr< PPCallbacks > createPPCallbacks()
Creates wrapper class for PPCallbacks so we can also process information about includes that are insi...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.