mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[serialization] Allow references to Clang-imported values.
This unfortunately duplicates the hack of directly referencing the Clang module loader if a cross-reference points to the current module; ideally we'd have some kind of module chain, but I'd settle for a refactoring of the code to share with NameBinding. Additionally, Clang nodes are not actually validated to be from the right module, which could be problematic for extensions or any case of actual name collision. Swift SVN r6519
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "ModuleFile.h"
|
||||
#include "ModuleFormat.h"
|
||||
#include "swift/AST/AST.h"
|
||||
#include "swift/AST/ModuleLoader.h"
|
||||
#include "swift/Basic/STLExtras.h"
|
||||
#include "swift/Serialization/BCReadingExtras.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
@@ -500,12 +501,21 @@ DeclContext *ModuleFile::getDeclContext(DeclID DID) {
|
||||
///
|
||||
/// An empty name represents the builtin module. All other names are looked up
|
||||
/// in the ASTContext.
|
||||
static Module *getModule(ASTContext &ctx, Identifier name) {
|
||||
static Module *getModule(Module *currentModule, Identifier name) {
|
||||
if (name.empty())
|
||||
return ctx.TheBuiltinModule;
|
||||
return currentModule->Ctx.TheBuiltinModule;
|
||||
|
||||
// FIXME: duplicated from NameBinder::getModule
|
||||
// FIXME: provide a real source location.
|
||||
if (name == currentModule->Name)
|
||||
if (auto importer = currentModule->Ctx.getClangModuleLoader())
|
||||
return importer->loadModule(SourceLoc(),
|
||||
std::make_pair(name, SourceLoc()),
|
||||
false);
|
||||
|
||||
// FIXME: provide a real source location.
|
||||
return ctx.getModule(std::make_pair(name, SourceLoc()), false);
|
||||
return currentModule->Ctx.getModule(std::make_pair(name, SourceLoc()),
|
||||
false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1242,7 +1252,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
||||
Identifier moduleName = getIdentifier(rawAccessPath.front());
|
||||
rawAccessPath = rawAccessPath.slice(1);
|
||||
|
||||
Module *M = getModule(ctx, moduleName);
|
||||
Module *M = getModule(ModuleContext, moduleName);
|
||||
assert(M && "missing dependency");
|
||||
|
||||
switch (kind) {
|
||||
@@ -1251,7 +1261,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
||||
// Start by looking up the top-level decl in the module.
|
||||
Module *baseModule = M;
|
||||
if (isWithinExtension) {
|
||||
baseModule = getModule(ctx, getIdentifier(rawAccessPath.front()));
|
||||
baseModule = getModule(ModuleContext,
|
||||
getIdentifier(rawAccessPath.front()));
|
||||
rawAccessPath = rawAccessPath.slice(1);
|
||||
}
|
||||
|
||||
@@ -1286,7 +1297,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
||||
|
||||
ValueDecl *result = nullptr;
|
||||
for (auto value : values) {
|
||||
if (value->getModuleContext() != M)
|
||||
if (!value->hasClangNode() && value->getModuleContext() != M)
|
||||
continue;
|
||||
if (expectedTy && value->getType()->getCanonicalType() != expectedTy)
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user