mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Special-case the standard library to always live relative to the compiler.
Import "swift" will now only find "swift.swiftmodule", and only in the runtime import path. <rdar://problem/15898866> Swift SVN r12932
This commit is contained in:
@@ -37,64 +37,69 @@ SerializedModuleLoader::~SerializedModuleLoader() = default;
|
||||
// the source loader search path should be the same as the module loader search
|
||||
// path.
|
||||
static llvm::error_code findModule(ASTContext &ctx, AccessPathElem moduleID,
|
||||
std::unique_ptr<llvm::MemoryBuffer> &buffer){
|
||||
std::unique_ptr<llvm::MemoryBuffer> &buffer,
|
||||
bool isStdlib) {
|
||||
llvm::SmallString<64> moduleFilename(moduleID.first.str());
|
||||
moduleFilename += '.';
|
||||
moduleFilename += SERIALIZED_MODULE_EXTENSION;
|
||||
|
||||
llvm::SmallString<128> inputFilename;
|
||||
llvm::OwningPtr<llvm::MemoryBuffer> bufferRef;
|
||||
llvm::error_code err;
|
||||
|
||||
// First, search in the directory corresponding to the import location.
|
||||
// FIXME: This screams for a proper FileManager abstraction.
|
||||
if (moduleID.second.isValid()) {
|
||||
unsigned currentBufferID =
|
||||
ctx.SourceMgr.findBufferContainingLoc(moduleID.second);
|
||||
const llvm::MemoryBuffer *importingBuffer
|
||||
= ctx.SourceMgr->getMemoryBuffer(currentBufferID);
|
||||
StringRef currentDirectory
|
||||
= llvm::sys::path::parent_path(importingBuffer->getBufferIdentifier());
|
||||
if (!currentDirectory.empty()) {
|
||||
inputFilename = currentDirectory;
|
||||
if (!isStdlib) {
|
||||
// First, search in the directory corresponding to the import location.
|
||||
// FIXME: This screams for a proper FileManager abstraction.
|
||||
if (moduleID.second.isValid()) {
|
||||
unsigned currentBufferID =
|
||||
ctx.SourceMgr.findBufferContainingLoc(moduleID.second);
|
||||
const llvm::MemoryBuffer *importingBuffer
|
||||
= ctx.SourceMgr->getMemoryBuffer(currentBufferID);
|
||||
StringRef currentDirectory
|
||||
= llvm::sys::path::parent_path(importingBuffer->getBufferIdentifier());
|
||||
if (!currentDirectory.empty()) {
|
||||
inputFilename = currentDirectory;
|
||||
llvm::sys::path::append(inputFilename, moduleFilename.str());
|
||||
llvm::error_code err = llvm::MemoryBuffer::getFile(inputFilename.str(),
|
||||
bufferRef);
|
||||
if (!err || err.value() != llvm::errc::no_such_file_or_directory) {
|
||||
buffer.reset(bufferRef.take());
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second, search in the current directory.
|
||||
err = llvm::MemoryBuffer::getFile(moduleFilename.str(), bufferRef);
|
||||
if (!err || err.value() != llvm::errc::no_such_file_or_directory) {
|
||||
buffer.reset(bufferRef.take());
|
||||
return err;
|
||||
}
|
||||
|
||||
// If we fail, search each import search path.
|
||||
for (auto Path : ctx.SearchPathOpts.ImportSearchPaths) {
|
||||
inputFilename = Path;
|
||||
llvm::sys::path::append(inputFilename, moduleFilename.str());
|
||||
llvm::error_code err = llvm::MemoryBuffer::getFile(inputFilename.str(),
|
||||
bufferRef);
|
||||
if (!err) {
|
||||
err = llvm::MemoryBuffer::getFile(inputFilename.str(), bufferRef);
|
||||
if (!err || err.value() != llvm::errc::no_such_file_or_directory) {
|
||||
buffer.reset(bufferRef.take());
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second, search in the current directory.
|
||||
llvm::error_code err = llvm::MemoryBuffer::getFile(moduleFilename.str(),
|
||||
bufferRef);
|
||||
if (!err) {
|
||||
buffer.reset(bufferRef.take());
|
||||
return err;
|
||||
}
|
||||
|
||||
// If we fail, search each import search path.
|
||||
for (auto Path : ctx.SearchPathOpts.ImportSearchPaths) {
|
||||
inputFilename = Path;
|
||||
llvm::sys::path::append(inputFilename, moduleFilename.str());
|
||||
err = llvm::MemoryBuffer::getFile(inputFilename.str(), bufferRef);
|
||||
if (!err) {
|
||||
buffer.reset(bufferRef.take());
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// Search the runtime import path.
|
||||
inputFilename = ctx.SearchPathOpts.RuntimeImportPath;
|
||||
llvm::sys::path::append(inputFilename, moduleFilename.str());
|
||||
|
||||
err = llvm::MemoryBuffer::getFile(inputFilename.str(), bufferRef);
|
||||
if (!err) {
|
||||
if (!err || err.value() != llvm::errc::no_such_file_or_directory) {
|
||||
buffer.reset(bufferRef.take());
|
||||
return err;
|
||||
}
|
||||
|
||||
// If we get here, we couldn't find the module, so return our most recent err.
|
||||
// If we get here, we couldn't find the module, so return our last
|
||||
// "no such file" error.
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -191,7 +196,8 @@ SerializedModuleLoader::loadAST(Module &M, Optional<SourceLoc> diagLoc,
|
||||
}
|
||||
|
||||
Module *SerializedModuleLoader::loadModule(SourceLoc importLoc,
|
||||
Module::AccessPathTy path) {
|
||||
Module::AccessPathTy path,
|
||||
bool isStdlib) {
|
||||
// FIXME: Swift submodules?
|
||||
if (path.size() > 1)
|
||||
return nullptr;
|
||||
@@ -215,7 +221,7 @@ Module *SerializedModuleLoader::loadModule(SourceLoc importLoc,
|
||||
|
||||
// Otherwise look on disk.
|
||||
if (!inputFile) {
|
||||
if (llvm::error_code err = findModule(Ctx, moduleID, inputFile)) {
|
||||
if (llvm::error_code err = findModule(Ctx, moduleID, inputFile, isStdlib)) {
|
||||
if (err.value() != llvm::errc::no_such_file_or_directory) {
|
||||
Ctx.Diags.diagnose(moduleID.second, diag::sema_opening_import,
|
||||
moduleID.first.str(), err.message());
|
||||
|
||||
Reference in New Issue
Block a user