void CleanTemporaryFiles();
bool Parse(std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer);
-
- std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> >
- ComputePreamble(CompilerInvocation &Invocation,
- unsigned MaxLines, bool &CreatedBuffer);
+
+ struct ComputedPreamble {
+ llvm::MemoryBuffer *Buffer;
+ std::unique_ptr<llvm::MemoryBuffer> Owner;
+ unsigned Size;
+ bool PreambleEndsAtStartOfLine;
+ ComputedPreamble(llvm::MemoryBuffer *Buffer,
+ std::unique_ptr<llvm::MemoryBuffer> Owner, unsigned Size,
+ bool PreambleEndsAtStartOfLine)
+ : Buffer(Buffer), Owner(std::move(Owner)), Size(Size),
+ PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {}
+ ComputedPreamble(ComputedPreamble &&C)
+ : Buffer(C.Buffer), Owner(std::move(C.Owner)), Size(C.Size),
+ PreambleEndsAtStartOfLine(C.PreambleEndsAtStartOfLine) {}
+ };
+ ComputedPreamble ComputePreamble(CompilerInvocation &Invocation,
+ unsigned MaxLines);
std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble(
const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild = true,
/// \brief Compute the preamble for the main file, providing the source buffer
/// that corresponds to the main file along with a pair (bytes, start-of-line)
/// that describes the preamble.
-std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> >
-ASTUnit::ComputePreamble(CompilerInvocation &Invocation,
- unsigned MaxLines, bool &CreatedBuffer) {
+ASTUnit::ComputedPreamble
+ASTUnit::ComputePreamble(CompilerInvocation &Invocation, unsigned MaxLines) {
FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();
PreprocessorOptions &PreprocessorOpts = Invocation.getPreprocessorOpts();
- CreatedBuffer = false;
// Try to determine if the main file has been remapped, either from the
// command line (to another file) or directly through the compiler invocation
// (to a memory buffer).
llvm::MemoryBuffer *Buffer = nullptr;
+ std::unique_ptr<llvm::MemoryBuffer> BufferOwner;
std::string MainFilePath(FrontendOpts.Inputs[0].getFile());
llvm::sys::fs::UniqueID MainFileID;
if (!llvm::sys::fs::getUniqueID(MainFilePath, MainFileID)) {
if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
if (MainFileID == MID) {
// We found a remapping. Try to load the resulting, remapped source.
- if (CreatedBuffer) {
- delete Buffer;
- CreatedBuffer = false;
- }
-
- Buffer = getBufferForFile(RF.second).release();
- if (!Buffer)
- return std::make_pair(nullptr, std::make_pair(0, true));
- CreatedBuffer = true;
+ BufferOwner = getBufferForFile(RF.second);
+ if (!BufferOwner)
+ return ComputedPreamble(nullptr, nullptr, 0, true);
}
}
}
if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
if (MainFileID == MID) {
// We found a remapping.
- if (CreatedBuffer) {
- delete Buffer;
- CreatedBuffer = false;
- }
-
+ BufferOwner.reset();
Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);
}
}
}
// If the main source file was not remapped, load it now.
- if (!Buffer) {
- Buffer = getBufferForFile(FrontendOpts.Inputs[0].getFile()).release();
- if (!Buffer)
- return std::make_pair(nullptr, std::make_pair(0, true));
-
- CreatedBuffer = true;
+ if (!Buffer && !BufferOwner) {
+ BufferOwner = getBufferForFile(FrontendOpts.Inputs[0].getFile());
+ if (!BufferOwner)
+ return ComputedPreamble(nullptr, nullptr, 0, true);
}
- return std::make_pair(
- Buffer, Lexer::ComputePreamble(Buffer->getBuffer(),
- *Invocation.getLangOpts(), MaxLines));
+ if (!Buffer)
+ Buffer = BufferOwner.get();
+ auto Pre = Lexer::ComputePreamble(Buffer->getBuffer(),
+ *Invocation.getLangOpts(), MaxLines);
+ return ComputedPreamble(Buffer, std::move(BufferOwner), Pre.first,
+ Pre.second);
}
ASTUnit::PreambleFileHash
PreprocessorOptions &PreprocessorOpts
= PreambleInvocation->getPreprocessorOpts();
- bool CreatedPreambleBuffer = false;
- std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble
- = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer);
-
- // If ComputePreamble() Take ownership of the preamble buffer.
- std::unique_ptr<llvm::MemoryBuffer> OwnedPreambleBuffer;
- if (CreatedPreambleBuffer)
- OwnedPreambleBuffer.reset(NewPreamble.first);
+ ComputedPreamble NewPreamble = ComputePreamble(*PreambleInvocation, MaxLines);
- if (!NewPreamble.second.first) {
+ if (!NewPreamble.Size) {
// We couldn't find a preamble in the main source. Clear out the current
// preamble, if we have one. It's obviously no good any more.
Preamble.clear();
// preamble now that we did before, and that there's enough space in
// the main-file buffer within the precompiled preamble to fit the
// new main file.
- if (Preamble.size() == NewPreamble.second.first &&
- PreambleEndsAtStartOfLine == NewPreamble.second.second &&
- memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(),
- NewPreamble.second.first) == 0) {
+ if (Preamble.size() == NewPreamble.Size &&
+ PreambleEndsAtStartOfLine == NewPreamble.PreambleEndsAtStartOfLine &&
+ memcmp(Preamble.getBufferStart(), NewPreamble.Buffer->getBufferStart(),
+ NewPreamble.Size) == 0) {
// The preamble has not changed. We may be able to re-use the precompiled
// preamble.
getDiagnostics().setNumWarnings(NumWarningsInPreamble);
return llvm::MemoryBuffer::getMemBufferCopy(
- NewPreamble.first->getBuffer(), FrontendOpts.Inputs[0].getFile());
+ NewPreamble.Buffer->getBuffer(), FrontendOpts.Inputs[0].getFile());
}
}
// subsequent reparses.
StringRef MainFilename = FrontendOpts.Inputs[0].getFile();
Preamble.assign(FileMgr->getFile(MainFilename),
- NewPreamble.first->getBufferStart(),
- NewPreamble.first->getBufferStart()
- + NewPreamble.second.first);
- PreambleEndsAtStartOfLine = NewPreamble.second.second;
+ NewPreamble.Buffer->getBufferStart(),
+ NewPreamble.Buffer->getBufferStart() + NewPreamble.Size);
+ PreambleEndsAtStartOfLine = NewPreamble.PreambleEndsAtStartOfLine;
PreambleBuffer = llvm::MemoryBuffer::getMemBufferCopy(
- NewPreamble.first->getBuffer().slice(0, Preamble.size()), MainFilename);
+ NewPreamble.Buffer->getBuffer().slice(0, Preamble.size()), MainFilename);
// Remap the main source file to the preamble buffer.
StringRef MainFilePath = FrontendOpts.Inputs[0].getFile();
PreambleTopLevelHashValue = CurrentTopLevelHashValue;
}
- return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.first->getBuffer(),
+ return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.Buffer->getBuffer(),
MainFilename);
}