Optional<unsigned> CompilerInstance::getRecordedBufferID(const InputFile &input, bool &failed) { if (!input.buffer()) { if (Optional<unsigned> existingBufferID = SourceMgr.getIDForBufferIdentifier(input.file())) { return existingBufferID; } } std::pair<std::unique_ptr<llvm::MemoryBuffer>, std::unique_ptr<llvm::MemoryBuffer>> buffers = getInputBufferAndModuleDocBufferIfPresent(input); if (!buffers.first) { failed = true; return None; } // FIXME: The fact that this test happens twice, for some cases, // suggests that setupInputs could use another round of refactoring. if (serialization::isSerializedAST(buffers.first->getBuffer())) { PartialModules.push_back( {std::move(buffers.first), std::move(buffers.second)}); return None; } assert(buffers.second.get() == nullptr); // Transfer ownership of the MemoryBuffer to the SourceMgr. unsigned bufferID = SourceMgr.addNewSourceBuffer(std::move(buffers.first)); InputSourceCodeBufferIDs.push_back(bufferID); return bufferID; }
std::pair<std::unique_ptr<llvm::MemoryBuffer>, std::unique_ptr<llvm::MemoryBuffer>> CompilerInstance::getInputBufferAndModuleDocBufferIfPresent( const InputFile &input) { if (auto b = input.buffer()) { return std::make_pair(llvm::MemoryBuffer::getMemBufferCopy( b->getBuffer(), b->getBufferIdentifier()), nullptr); } // FIXME: Working with filenames is fragile, maybe use the real path // or have some kind of FileManager. using FileOrError = llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>; FileOrError inputFileOrErr = llvm::MemoryBuffer::getFileOrSTDIN(input.file()); if (!inputFileOrErr) { Diagnostics.diagnose(SourceLoc(), diag::error_open_input_file, input.file(), inputFileOrErr.getError().message()); return std::make_pair(nullptr, nullptr); } if (!serialization::isSerializedAST((*inputFileOrErr)->getBuffer())) return std::make_pair(std::move(*inputFileOrErr), nullptr); if (Optional<std::unique_ptr<llvm::MemoryBuffer>> moduleDocBuffer = openModuleDoc(input)) { return std::make_pair(std::move(*inputFileOrErr), std::move(*moduleDocBuffer)); } return std::make_pair(nullptr, nullptr); }
bool CompilerInstance::setUpForInput(const InputFile &input) { bool failed = false; Optional<unsigned> bufferID = getRecordedBufferID(input, failed); if (failed) return true; if (!bufferID) return false; if (isInSILMode() || (input.buffer() == nullptr && isInputSwift() && llvm::sys::path::filename(input.file()) == "main.swift")) { assert(MainBufferID == NO_SUCH_BUFFER && "re-setting MainBufferID"); MainBufferID = *bufferID; } if (input.isPrimary()) { assert(PrimaryBufferIDs.empty() && "re-setting PrimaryBufferID"); recordPrimaryInputBuffer(*bufferID); } return false; }