forked from OSchip/llvm-project
[Frontend] Simplify PrecompiledPreamble::PCHStorage. NFC
- Remove fiddly union, preambles are heavyweight - Remove fiddly move constructors in TempPCHFile and PCHStorage, use unique_ptr - Remove unneccesary accessors on PCHStorage - Remove trivial InMemoryStorage - Move implementation details into cpp file This is a prefactoring, followup change will change the in-memory PCHStorage to avoid extra string copies while creating it. Differential Revision: https://reviews.llvm.org/D124177
This commit is contained in:
parent
889847922d
commit
af3fb07154
|
@ -17,7 +17,6 @@
|
|||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/Support/MD5.h"
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
@ -86,8 +85,9 @@ public:
|
|||
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
bool StoreInMemory, PreambleCallbacks &Callbacks);
|
||||
|
||||
PrecompiledPreamble(PrecompiledPreamble &&) = default;
|
||||
PrecompiledPreamble &operator=(PrecompiledPreamble &&) = default;
|
||||
PrecompiledPreamble(PrecompiledPreamble &&);
|
||||
PrecompiledPreamble &operator=(PrecompiledPreamble &&);
|
||||
~PrecompiledPreamble();
|
||||
|
||||
/// PreambleBounds used to build the preamble.
|
||||
PreambleBounds getBounds() const;
|
||||
|
@ -128,79 +128,12 @@ public:
|
|||
llvm::MemoryBuffer *MainFileBuffer) const;
|
||||
|
||||
private:
|
||||
PrecompiledPreamble(PCHStorage Storage, std::vector<char> PreambleBytes,
|
||||
PrecompiledPreamble(std::unique_ptr<PCHStorage> Storage,
|
||||
std::vector<char> PreambleBytes,
|
||||
bool PreambleEndsAtStartOfLine,
|
||||
llvm::StringMap<PreambleFileHash> FilesInPreamble,
|
||||
llvm::StringSet<> MissingFiles);
|
||||
|
||||
/// 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 llvm::ErrorOr<TempPCHFile> CreateNewPreamblePCHFile();
|
||||
|
||||
private:
|
||||
TempPCHFile(std::string FilePath);
|
||||
|
||||
public:
|
||||
TempPCHFile(TempPCHFile &&Other);
|
||||
TempPCHFile &operator=(TempPCHFile &&Other);
|
||||
|
||||
TempPCHFile(const TempPCHFile &) = delete;
|
||||
~TempPCHFile();
|
||||
|
||||
/// A path where temporary file is stored.
|
||||
llvm::StringRef getFilePath() const;
|
||||
|
||||
private:
|
||||
void RemoveFileIfPresent();
|
||||
|
||||
private:
|
||||
llvm::Optional<std::string> FilePath;
|
||||
};
|
||||
|
||||
class InMemoryPreamble {
|
||||
public:
|
||||
std::string Data;
|
||||
};
|
||||
|
||||
class PCHStorage {
|
||||
public:
|
||||
enum class Kind { Empty, InMemory, TempFile };
|
||||
|
||||
PCHStorage() = default;
|
||||
PCHStorage(TempPCHFile File);
|
||||
PCHStorage(InMemoryPreamble Memory);
|
||||
|
||||
PCHStorage(const PCHStorage &) = delete;
|
||||
PCHStorage &operator=(const PCHStorage &) = delete;
|
||||
|
||||
PCHStorage(PCHStorage &&Other);
|
||||
PCHStorage &operator=(PCHStorage &&Other);
|
||||
|
||||
~PCHStorage();
|
||||
|
||||
Kind getKind() const;
|
||||
|
||||
TempPCHFile &asFile();
|
||||
const TempPCHFile &asFile() const;
|
||||
|
||||
InMemoryPreamble &asMemory();
|
||||
const InMemoryPreamble &asMemory() const;
|
||||
|
||||
private:
|
||||
void destroy();
|
||||
void setEmpty();
|
||||
|
||||
private:
|
||||
Kind StorageKind = Kind::Empty;
|
||||
llvm::AlignedCharArrayUnion<TempPCHFile, InMemoryPreamble> Storage = {};
|
||||
};
|
||||
|
||||
/// Data used to determine if a file used in the preamble has been changed.
|
||||
struct PreambleFileHash {
|
||||
/// All files have size set.
|
||||
|
@ -245,7 +178,7 @@ private:
|
|||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS);
|
||||
|
||||
/// Manages the memory buffer or temporary file that stores the PCH.
|
||||
PCHStorage Storage;
|
||||
std::unique_ptr<PCHStorage> Storage;
|
||||
/// Keeps track of the files that were used when computing the
|
||||
/// preamble, with both their buffer size and their modification time.
|
||||
///
|
||||
|
|
|
@ -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"
|
||||
|
@ -192,6 +189,49 @@ 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() {
|
||||
// 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<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;
|
||||
if (auto EC =
|
||||
llvm::sys::fs::createTemporaryFile("preamble", "pch", FD, File))
|
||||
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,
|
||||
|
@ -308,6 +348,55 @@ 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::unique_ptr<PCHStorage> S(new PCHStorage());
|
||||
S->Memory.emplace();
|
||||
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 *Memory;
|
||||
}
|
||||
std::string &memoryBufferForWrite() {
|
||||
assert(getKind() == Kind::InMemory);
|
||||
return *Memory;
|
||||
}
|
||||
|
||||
private:
|
||||
PCHStorage() = default;
|
||||
PCHStorage(const PCHStorage &) = delete;
|
||||
PCHStorage &operator=(const PCHStorage &) = delete;
|
||||
|
||||
llvm::Optional<std::string> 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,
|
||||
|
@ -322,20 +411,18 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build(
|
|||
PreprocessorOptions &PreprocessorOpts =
|
||||
PreambleInvocation->getPreprocessorOpts();
|
||||
|
||||
llvm::Optional<TempPCHFile> TempFile;
|
||||
if (!StoreInMemory) {
|
||||
std::unique_ptr<PCHStorage> Storage;
|
||||
if (StoreInMemory) {
|
||||
Storage = PCHStorage::inMemory();
|
||||
} 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();
|
||||
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 +432,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.
|
||||
|
@ -411,7 +497,7 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build(
|
|||
|
||||
std::unique_ptr<PrecompilePreambleAction> Act;
|
||||
Act.reset(new PrecompilePreambleAction(
|
||||
StoreInMemory ? &Storage.asMemory().Data : nullptr, Callbacks));
|
||||
StoreInMemory ? &Storage->memoryBufferForWrite() : nullptr, Callbacks));
|
||||
if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
|
||||
return BuildPreambleError::BeginSourceFileFailed;
|
||||
|
||||
|
@ -475,16 +561,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() &&
|
||||
|
@ -621,7 +703,7 @@ void PrecompiledPreamble::OverridePreamble(
|
|||
}
|
||||
|
||||
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)
|
||||
|
@ -629,142 +711,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
|
||||
|
@ -810,20 +757,19 @@ void PrecompiledPreamble::configurePreamble(
|
|||
PreprocessorOpts.DisablePCHOrModuleValidation =
|
||||
DisableValidationForModuleKind::PCH;
|
||||
|
||||
setupPreambleStorage(Storage, PreprocessorOpts, VFS);
|
||||
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);
|
||||
|
@ -844,7 +790,7 @@ 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());
|
||||
VFS = createVFSOverlayForPreamblePCH(PCHPath, std::move(Buf), VFS);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue