diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp | 401 |
1 files changed, 188 insertions, 213 deletions
diff --git a/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp b/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp index af82ab3f5558..62373b23b82e 100644 --- a/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -11,10 +11,8 @@ //===----------------------------------------------------------------------===// #include "clang/Frontend/PrecompiledPreamble.h" -#include "clang/AST/DeclObjC.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangStandard.h" -#include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" @@ -25,7 +23,6 @@ #include "clang/Lex/PreprocessorOptions.h" #include "clang/Serialization/ASTWriter.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Config/llvm-config.h" @@ -99,13 +96,13 @@ public: void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, - CharSourceRange FilenameRange, const FileEntry *File, - StringRef SearchPath, StringRef RelativePath, - const Module *Imported, + CharSourceRange FilenameRange, + OptionalFileEntryRef File, StringRef SearchPath, + StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { - // File is null if it wasn't found. + // File is std::nullopt if it wasn't found. // (We have some false negatives if PP recovered e.g. <foo> -> "foo") - if (File != nullptr) + if (File) return; // If it's a rare absolute include, we know the full path already. @@ -116,16 +113,16 @@ public: // Reconstruct the filenames that would satisfy this directive... llvm::SmallString<256> Buf; - auto NotFoundRelativeTo = [&](const DirectoryEntry *DE) { - Buf = DE->getName(); + auto NotFoundRelativeTo = [&](DirectoryEntryRef DE) { + Buf = DE.getName(); llvm::sys::path::append(Buf, FileName); llvm::sys::path::remove_dots(Buf, /*remove_dot_dot=*/true); Out.insert(Buf); }; // ...relative to the including file. if (!IsAngled) { - if (const FileEntry *IncludingFile = - SM.getFileEntryForID(SM.getFileID(IncludeTok.getLocation()))) + if (OptionalFileEntryRef IncludingFile = + SM.getFileEntryRefForID(SM.getFileID(IncludeTok.getLocation()))) if (IncludingFile->getDir()) NotFoundRelativeTo(IncludingFile->getDir()); } @@ -135,7 +132,7 @@ public: Search.search_dir_end())) { // No support for frameworks or header maps yet. if (Dir.isNormalDir()) - NotFoundRelativeTo(Dir.getDir()); + NotFoundRelativeTo(*Dir.getDirRef()); } } }; @@ -192,11 +189,67 @@ void TemporaryFiles::removeFile(StringRef File) { llvm::sys::fs::remove(File); } +// A temp file that would be deleted on destructor call. If destructor is not +// called for any reason, the file will be deleted at static objects' +// destruction. +// An assertion will fire if two TempPCHFiles are created with the same name, +// so it's not intended to be used outside preamble-handling. +class TempPCHFile { +public: + // A main method used to construct TempPCHFile. + static std::unique_ptr<TempPCHFile> create(StringRef StoragePath) { + // FIXME: This is a hack so that we can override the preamble file during + // crash-recovery testing, which is the only case where the preamble files + // are not necessarily cleaned up. + if (const char *TmpFile = ::getenv("CINDEXTEST_PREAMBLE_FILE")) + return std::unique_ptr<TempPCHFile>(new TempPCHFile(TmpFile)); + + llvm::SmallString<128> File; + // Using the versions of createTemporaryFile() and + // createUniqueFile() with a file descriptor guarantees + // that we would never get a race condition in a multi-threaded setting + // (i.e., multiple threads getting the same temporary path). + int FD; + std::error_code EC; + if (StoragePath.empty()) + EC = llvm::sys::fs::createTemporaryFile("preamble", "pch", FD, File); + else { + llvm::SmallString<128> TempPath = StoragePath; + // Use the same filename model as fs::createTemporaryFile(). + llvm::sys::path::append(TempPath, "preamble-%%%%%%.pch"); + namespace fs = llvm::sys::fs; + // Use the same owner-only file permissions as fs::createTemporaryFile(). + EC = fs::createUniqueFile(TempPath, FD, File, fs::OF_None, + fs::owner_read | fs::owner_write); + } + if (EC) + return nullptr; + // We only needed to make sure the file exists, close the file right away. + llvm::sys::Process::SafelyCloseFileDescriptor(FD); + return std::unique_ptr<TempPCHFile>(new TempPCHFile(File.str().str())); + } + + TempPCHFile &operator=(const TempPCHFile &) = delete; + TempPCHFile(const TempPCHFile &) = delete; + ~TempPCHFile() { TemporaryFiles::getInstance().removeFile(FilePath); }; + + /// A path where temporary file is stored. + llvm::StringRef getFilePath() const { return FilePath; }; + +private: + TempPCHFile(std::string FilePath) : FilePath(std::move(FilePath)) { + TemporaryFiles::getInstance().addFile(this->FilePath); + } + + std::string FilePath; +}; + class PrecompilePreambleAction : public ASTFrontendAction { public: - PrecompilePreambleAction(std::string *InMemStorage, + PrecompilePreambleAction(std::shared_ptr<PCHBuffer> Buffer, bool WritePCHFile, PreambleCallbacks &Callbacks) - : InMemStorage(InMemStorage), Callbacks(Callbacks) {} + : Buffer(std::move(Buffer)), WritePCHFile(WritePCHFile), + Callbacks(Callbacks) {} std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override; @@ -204,6 +257,12 @@ public: bool hasEmittedPreamblePCH() const { return HasEmittedPreamblePCH; } void setEmittedPreamblePCH(ASTWriter &Writer) { + if (FileOS) { + *FileOS << Buffer->Data; + // Make sure it hits disk now. + FileOS.reset(); + } + this->HasEmittedPreamblePCH = true; Callbacks.AfterPCHEmitted(Writer); } @@ -222,7 +281,9 @@ private: friend class PrecompilePreambleConsumer; bool HasEmittedPreamblePCH = false; - std::string *InMemStorage; + std::shared_ptr<PCHBuffer> Buffer; + bool WritePCHFile; // otherwise the PCH is written into the PCHBuffer only. + std::unique_ptr<llvm::raw_pwrite_stream> FileOS; // null if in-memory PreambleCallbacks &Callbacks; }; @@ -232,12 +293,11 @@ public: const Preprocessor &PP, InMemoryModuleCache &ModuleCache, StringRef isysroot, - std::unique_ptr<raw_ostream> Out) - : PCHGenerator(PP, ModuleCache, "", isysroot, - std::make_shared<PCHBuffer>(), + std::shared_ptr<PCHBuffer> Buffer) + : PCHGenerator(PP, ModuleCache, "", isysroot, std::move(Buffer), ArrayRef<std::shared_ptr<ModuleFileExtension>>(), /*AllowASTWithErrors=*/true), - Action(Action), Out(std::move(Out)) {} + Action(Action) {} bool HandleTopLevelDecl(DeclGroupRef DG) override { Action.Callbacks.HandleTopLevelDecl(DG); @@ -248,15 +308,6 @@ public: PCHGenerator::HandleTranslationUnit(Ctx); if (!hasEmittedPCH()) return; - - // Write the generated bitstream to "Out". - *Out << getPCH(); - // Make sure it hits disk now. - Out->flush(); - // Free the buffer. - llvm::SmallVector<char, 0> Empty; - getPCH() = std::move(Empty); - Action.setEmittedPreamblePCH(getWriter()); } @@ -266,7 +317,6 @@ public: private: PrecompilePreambleAction &Action; - std::unique_ptr<raw_ostream> Out; }; std::unique_ptr<ASTConsumer> @@ -276,21 +326,18 @@ PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, if (!GeneratePCHAction::ComputeASTConsumerArguments(CI, Sysroot)) return nullptr; - std::unique_ptr<llvm::raw_ostream> OS; - if (InMemStorage) { - OS = std::make_unique<llvm::raw_string_ostream>(*InMemStorage); - } else { - std::string OutputFile; - OS = GeneratePCHAction::CreateOutputFile(CI, InFile, OutputFile); + if (WritePCHFile) { + std::string OutputFile; // unused + FileOS = GeneratePCHAction::CreateOutputFile(CI, InFile, OutputFile); + if (!FileOS) + return nullptr; } - if (!OS) - return nullptr; if (!CI.getFrontendOpts().RelocatablePCH) Sysroot.clear(); return std::make_unique<PrecompilePreambleConsumer>( - *this, CI.getPreprocessor(), CI.getModuleCache(), Sysroot, std::move(OS)); + *this, CI.getPreprocessor(), CI.getModuleCache(), Sysroot, Buffer); } template <class T> bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) { @@ -308,13 +355,67 @@ PreambleBounds clang::ComputePreambleBounds(const LangOptions &LangOpts, return Lexer::ComputePreamble(Buffer.getBuffer(), LangOpts, MaxLines); } +class PrecompiledPreamble::PCHStorage { +public: + static std::unique_ptr<PCHStorage> file(std::unique_ptr<TempPCHFile> File) { + assert(File); + std::unique_ptr<PCHStorage> S(new PCHStorage()); + S->File = std::move(File); + return S; + } + static std::unique_ptr<PCHStorage> inMemory(std::shared_ptr<PCHBuffer> Buf) { + std::unique_ptr<PCHStorage> S(new PCHStorage()); + S->Memory = std::move(Buf); + return S; + } + + enum class Kind { InMemory, TempFile }; + Kind getKind() const { + if (Memory) + return Kind::InMemory; + if (File) + return Kind::TempFile; + llvm_unreachable("Neither Memory nor File?"); + } + llvm::StringRef filePath() const { + assert(getKind() == Kind::TempFile); + return File->getFilePath(); + } + llvm::StringRef memoryContents() const { + assert(getKind() == Kind::InMemory); + return StringRef(Memory->Data.data(), Memory->Data.size()); + } + + // Shrink in-memory buffers to fit. + // This incurs a copy, but preambles tend to be long-lived. + // Only safe to call once nothing can alias the buffer. + void shrink() { + if (!Memory) + return; + Memory->Data = decltype(Memory->Data)(Memory->Data); + } + +private: + PCHStorage() = default; + PCHStorage(const PCHStorage &) = delete; + PCHStorage &operator=(const PCHStorage &) = delete; + + std::shared_ptr<PCHBuffer> Memory; + std::unique_ptr<TempPCHFile> File; +}; + +PrecompiledPreamble::~PrecompiledPreamble() = default; +PrecompiledPreamble::PrecompiledPreamble(PrecompiledPreamble &&) = default; +PrecompiledPreamble & +PrecompiledPreamble::operator=(PrecompiledPreamble &&) = default; + llvm::ErrorOr<PrecompiledPreamble> 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) { + StringRef StoragePath, PreambleCallbacks &Callbacks) { assert(VFS && "VFS is null"); auto PreambleInvocation = std::make_shared<CompilerInvocation>(Invocation); @@ -322,20 +423,20 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( PreprocessorOptions &PreprocessorOpts = PreambleInvocation->getPreprocessorOpts(); - llvm::Optional<TempPCHFile> TempFile; - if (!StoreInMemory) { + std::shared_ptr<PCHBuffer> Buffer = std::make_shared<PCHBuffer>(); + std::unique_ptr<PCHStorage> Storage; + if (StoreInMemory) { + Storage = PCHStorage::inMemory(Buffer); + } else { // Create a temporary file for the precompiled preamble. In rare // circumstances, this can fail. - llvm::ErrorOr<PrecompiledPreamble::TempPCHFile> PreamblePCHFile = - PrecompiledPreamble::TempPCHFile::CreateNewPreamblePCHFile(); + std::unique_ptr<TempPCHFile> PreamblePCHFile = + TempPCHFile::create(StoragePath); if (!PreamblePCHFile) return BuildPreambleError::CouldntCreateTempFile; - TempFile = std::move(*PreamblePCHFile); + Storage = PCHStorage::file(std::move(PreamblePCHFile)); } - PCHStorage Storage = StoreInMemory ? PCHStorage(InMemoryPreamble()) - : PCHStorage(std::move(*TempFile)); - // Save the preamble text for later; we'll need to compare against it for // subsequent reparses. std::vector<char> PreambleBytes(MainFileBuffer->getBufferStart(), @@ -345,9 +446,8 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( // Tell the compiler invocation to generate a temporary precompiled header. FrontendOpts.ProgramAction = frontend::GeneratePCH; - FrontendOpts.OutputFile = - std::string(StoreInMemory ? getInMemoryPreamblePath() - : Storage.asFile().getFilePath()); + FrontendOpts.OutputFile = std::string( + StoreInMemory ? getInMemoryPreamblePath() : Storage->filePath()); PreprocessorOpts.PrecompiledPreambleBytes.first = 0; PreprocessorOpts.PrecompiledPreambleBytes.second = false; // Inform preprocessor to record conditional stack when building the preamble. @@ -409,13 +509,17 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( PreambleInputBuffer.release()); } - std::unique_ptr<PrecompilePreambleAction> Act; - Act.reset(new PrecompilePreambleAction( - StoreInMemory ? &Storage.asMemory().Data : nullptr, Callbacks)); - Callbacks.BeforeExecute(*Clang); + auto Act = std::make_unique<PrecompilePreambleAction>( + std::move(Buffer), + /*WritePCHFile=*/Storage->getKind() == PCHStorage::Kind::TempFile, + Callbacks); if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) return BuildPreambleError::BeginSourceFileFailed; + // Performed after BeginSourceFile to ensure Clang->Preprocessor can be + // referenced in the callback. + Callbacks.BeforeExecute(*Clang); + std::unique_ptr<PPCallbacks> DelegatedPPCallbacks = Callbacks.createPPCallbacks(); if (DelegatedPPCallbacks) @@ -438,6 +542,7 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( if (!Act->hasEmittedPreamblePCH()) return BuildPreambleError::CouldntEmitPCH; + Act.reset(); // Frees the PCH buffer, unless Storage keeps it in memory. // Keep track of all of the files that the source manager knows about, // so we can verify whether they have changed or not. @@ -445,23 +550,28 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( SourceManager &SourceMgr = Clang->getSourceManager(); for (auto &Filename : PreambleDepCollector->getDependencies()) { - auto FileOrErr = Clang->getFileManager().getFile(Filename); - if (!FileOrErr || - *FileOrErr == SourceMgr.getFileEntryForID(SourceMgr.getMainFileID())) + auto MaybeFile = Clang->getFileManager().getOptionalFileRef(Filename); + if (!MaybeFile || + MaybeFile == SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID())) continue; - auto File = *FileOrErr; - if (time_t ModTime = File->getModificationTime()) { - FilesInPreamble[File->getName()] = - PrecompiledPreamble::PreambleFileHash::createForFile(File->getSize(), + auto File = *MaybeFile; + if (time_t ModTime = File.getModificationTime()) { + FilesInPreamble[File.getName()] = + PrecompiledPreamble::PreambleFileHash::createForFile(File.getSize(), ModTime); } else { llvm::MemoryBufferRef Buffer = SourceMgr.getMemoryBufferForFileOrFake(File); - FilesInPreamble[File->getName()] = + FilesInPreamble[File.getName()] = PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(Buffer); } } + // Shrinking the storage requires extra temporary memory. + // Destroying clang first reduces peak memory usage. + CICleanup.unregister(); + Clang.reset(); + Storage->shrink(); return PrecompiledPreamble( std::move(Storage), std::move(PreambleBytes), PreambleEndsAtStartOfLine, std::move(FilesInPreamble), std::move(MissingFiles)); @@ -472,16 +582,12 @@ PreambleBounds PrecompiledPreamble::getBounds() const { } std::size_t PrecompiledPreamble::getSize() const { - switch (Storage.getKind()) { - case PCHStorage::Kind::Empty: - assert(false && "Calling getSize() on invalid PrecompiledPreamble. " - "Was it std::moved?"); - return 0; + switch (Storage->getKind()) { case PCHStorage::Kind::InMemory: - return Storage.asMemory().Data.size(); + return Storage->memoryContents().size(); case PCHStorage::Kind::TempFile: { uint64_t Result; - if (llvm::sys::fs::file_size(Storage.asFile().getFilePath(), Result)) + if (llvm::sys::fs::file_size(Storage->filePath(), Result)) return 0; assert(Result <= std::numeric_limits<std::size_t>::max() && @@ -613,12 +719,12 @@ void PrecompiledPreamble::AddImplicitPreamble( void PrecompiledPreamble::OverridePreamble( CompilerInvocation &CI, IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS, llvm::MemoryBuffer *MainFileBuffer) const { - auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), *MainFileBuffer, 0); + auto Bounds = ComputePreambleBounds(CI.getLangOpts(), *MainFileBuffer, 0); configurePreamble(Bounds, CI, VFS, MainFileBuffer); } PrecompiledPreamble::PrecompiledPreamble( - PCHStorage Storage, std::vector<char> PreambleBytes, + std::unique_ptr<PCHStorage> Storage, std::vector<char> PreambleBytes, bool PreambleEndsAtStartOfLine, llvm::StringMap<PreambleFileHash> FilesInPreamble, llvm::StringSet<> MissingFiles) @@ -626,142 +732,7 @@ PrecompiledPreamble::PrecompiledPreamble( MissingFiles(std::move(MissingFiles)), PreambleBytes(std::move(PreambleBytes)), PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) { - assert(this->Storage.getKind() != PCHStorage::Kind::Empty); -} - -llvm::ErrorOr<PrecompiledPreamble::TempPCHFile> -PrecompiledPreamble::TempPCHFile::CreateNewPreamblePCHFile() { - // FIXME: This is a hack so that we can override the preamble file during - // crash-recovery testing, which is the only case where the preamble files - // are not necessarily cleaned up. - if (const char *TmpFile = ::getenv("CINDEXTEST_PREAMBLE_FILE")) - return TempPCHFile(TmpFile); - - llvm::SmallString<64> File; - // Using a version of createTemporaryFile with a file descriptor guarantees - // that we would never get a race condition in a multi-threaded setting - // (i.e., multiple threads getting the same temporary path). - int FD; - auto EC = llvm::sys::fs::createTemporaryFile("preamble", "pch", FD, File); - if (EC) - return EC; - // We only needed to make sure the file exists, close the file right away. - llvm::sys::Process::SafelyCloseFileDescriptor(FD); - return TempPCHFile(std::string(std::move(File).str())); -} - -PrecompiledPreamble::TempPCHFile::TempPCHFile(std::string FilePath) - : FilePath(std::move(FilePath)) { - TemporaryFiles::getInstance().addFile(*this->FilePath); -} - -PrecompiledPreamble::TempPCHFile::TempPCHFile(TempPCHFile &&Other) { - FilePath = std::move(Other.FilePath); - Other.FilePath = None; -} - -PrecompiledPreamble::TempPCHFile &PrecompiledPreamble::TempPCHFile:: -operator=(TempPCHFile &&Other) { - RemoveFileIfPresent(); - - FilePath = std::move(Other.FilePath); - Other.FilePath = None; - return *this; -} - -PrecompiledPreamble::TempPCHFile::~TempPCHFile() { RemoveFileIfPresent(); } - -void PrecompiledPreamble::TempPCHFile::RemoveFileIfPresent() { - if (FilePath) { - TemporaryFiles::getInstance().removeFile(*FilePath); - FilePath = None; - } -} - -llvm::StringRef PrecompiledPreamble::TempPCHFile::getFilePath() const { - assert(FilePath && "TempPCHFile doesn't have a FilePath. Had it been moved?"); - return *FilePath; -} - -PrecompiledPreamble::PCHStorage::PCHStorage(TempPCHFile File) - : StorageKind(Kind::TempFile) { - new (&asFile()) TempPCHFile(std::move(File)); -} - -PrecompiledPreamble::PCHStorage::PCHStorage(InMemoryPreamble Memory) - : StorageKind(Kind::InMemory) { - new (&asMemory()) InMemoryPreamble(std::move(Memory)); -} - -PrecompiledPreamble::PCHStorage::PCHStorage(PCHStorage &&Other) : PCHStorage() { - *this = std::move(Other); -} - -PrecompiledPreamble::PCHStorage &PrecompiledPreamble::PCHStorage:: -operator=(PCHStorage &&Other) { - destroy(); - - StorageKind = Other.StorageKind; - switch (StorageKind) { - case Kind::Empty: - // do nothing; - break; - case Kind::TempFile: - new (&asFile()) TempPCHFile(std::move(Other.asFile())); - break; - case Kind::InMemory: - new (&asMemory()) InMemoryPreamble(std::move(Other.asMemory())); - break; - } - - Other.setEmpty(); - return *this; -} - -PrecompiledPreamble::PCHStorage::~PCHStorage() { destroy(); } - -PrecompiledPreamble::PCHStorage::Kind -PrecompiledPreamble::PCHStorage::getKind() const { - return StorageKind; -} - -PrecompiledPreamble::TempPCHFile &PrecompiledPreamble::PCHStorage::asFile() { - assert(getKind() == Kind::TempFile); - return *reinterpret_cast<TempPCHFile *>(&Storage); -} - -const PrecompiledPreamble::TempPCHFile & -PrecompiledPreamble::PCHStorage::asFile() const { - return const_cast<PCHStorage *>(this)->asFile(); -} - -PrecompiledPreamble::InMemoryPreamble & -PrecompiledPreamble::PCHStorage::asMemory() { - assert(getKind() == Kind::InMemory); - return *reinterpret_cast<InMemoryPreamble *>(&Storage); -} - -const PrecompiledPreamble::InMemoryPreamble & -PrecompiledPreamble::PCHStorage::asMemory() const { - return const_cast<PCHStorage *>(this)->asMemory(); -} - -void PrecompiledPreamble::PCHStorage::destroy() { - switch (StorageKind) { - case Kind::Empty: - return; - case Kind::TempFile: - asFile().~TempPCHFile(); - return; - case Kind::InMemory: - asMemory().~InMemoryPreamble(); - return; - } -} - -void PrecompiledPreamble::PCHStorage::setEmpty() { - destroy(); - StorageKind = Kind::Empty; + assert(this->Storage != nullptr); } PrecompiledPreamble::PreambleFileHash @@ -807,20 +778,23 @@ void PrecompiledPreamble::configurePreamble( PreprocessorOpts.DisablePCHOrModuleValidation = DisableValidationForModuleKind::PCH; - setupPreambleStorage(Storage, PreprocessorOpts, VFS); + // Don't bother generating the long version of the predefines buffer. + // The preamble is going to overwrite it anyway. + PreprocessorOpts.UsePredefines = false; + + setupPreambleStorage(*Storage, PreprocessorOpts, VFS); } void PrecompiledPreamble::setupPreambleStorage( const PCHStorage &Storage, PreprocessorOptions &PreprocessorOpts, IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS) { if (Storage.getKind() == PCHStorage::Kind::TempFile) { - const TempPCHFile &PCHFile = Storage.asFile(); - PreprocessorOpts.ImplicitPCHInclude = std::string(PCHFile.getFilePath()); + llvm::StringRef PCHPath = Storage.filePath(); + PreprocessorOpts.ImplicitPCHInclude = PCHPath.str(); // Make sure we can access the PCH file even if we're using a VFS IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS = llvm::vfs::getRealFileSystem(); - auto PCHPath = PCHFile.getFilePath(); if (VFS == RealFS || VFS->exists(PCHPath)) return; auto Buf = RealFS->getBufferForFile(PCHPath); @@ -841,7 +815,8 @@ void PrecompiledPreamble::setupPreambleStorage( StringRef PCHPath = getInMemoryPreamblePath(); PreprocessorOpts.ImplicitPCHInclude = std::string(PCHPath); - auto Buf = llvm::MemoryBuffer::getMemBuffer(Storage.asMemory().Data); + auto Buf = llvm::MemoryBuffer::getMemBuffer( + Storage.memoryContents(), PCHPath, /*RequiresNullTerminator=*/false); VFS = createVFSOverlayForPreamblePCH(PCHPath, std::move(Buf), VFS); } } |