mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Mangle imported declarations using their C names.
This makes them consistent no matter what shenanigans are pulled by the importer, particularly NS_ENUM vs. NS_OPTIONS and NS_SWIFT_NAME. The 'NSErrorDomain' API note /nearly/ works with this, but the synthesized error struct is still mangled as a Swift declaration, which means it's not rename-stable. See follow-up commits. The main place where this still falls down is NS_STRING_ENUM: when this is applied, a typedef is imported as a unique struct, but without it it's just a typealias for the underlying type. There's also still a problem with synthesized conformances, which have a module mangled into the witness table symbol even though that symbol is linkonce_odr. rdar://problem/31616162
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "swift/AST/TypeRepr.h"
|
||||
#include "swift/Basic/Mangler.h"
|
||||
#include "swift/ClangImporter/ClangImporter.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
|
||||
// TODO: Develop a proper interface for this.
|
||||
#include "swift/AST/IRGenOptions.h"
|
||||
@@ -419,7 +420,8 @@ public:
|
||||
Type createObjCClassType(StringRef name) {
|
||||
Identifier ident = Ctx.getIdentifier(name);
|
||||
auto typeDecl =
|
||||
findForeignNominalTypeDecl(ident, Demangle::Node::Kind::Class);
|
||||
findForeignNominalTypeDecl(ident, ForeignModuleKind::Imported,
|
||||
Demangle::Node::Kind::Class);
|
||||
if (!typeDecl) return Type();
|
||||
return createNominalType(typeDecl, /*parent*/ Type());
|
||||
}
|
||||
@@ -462,13 +464,21 @@ private:
|
||||
DeclContext *findDeclContext(const Demangle::NodePointer &node);
|
||||
ModuleDecl *findModule(const Demangle::NodePointer &node);
|
||||
Demangle::NodePointer findModuleNode(const Demangle::NodePointer &node);
|
||||
bool isForeignModule(const Demangle::NodePointer &node);
|
||||
|
||||
enum class ForeignModuleKind {
|
||||
Imported,
|
||||
SynthesizedByImporter
|
||||
};
|
||||
|
||||
Optional<ForeignModuleKind>
|
||||
getForeignModuleKind(const Demangle::NodePointer &node);
|
||||
|
||||
NominalTypeDecl *findNominalTypeDecl(DeclContext *dc,
|
||||
Identifier name,
|
||||
Identifier privateDiscriminator,
|
||||
Demangle::Node::Kind kind);
|
||||
NominalTypeDecl *findForeignNominalTypeDecl(Identifier name,
|
||||
ForeignModuleKind lookupKind,
|
||||
Demangle::Node::Kind kind);
|
||||
|
||||
Type checkTypeRepr(TypeRepr *repr) {
|
||||
@@ -558,15 +568,19 @@ RemoteASTTypeBuilder::findModuleNode(const Demangle::NodePointer &node) {
|
||||
return findModuleNode(child->getFirstChild());
|
||||
}
|
||||
|
||||
bool RemoteASTTypeBuilder::isForeignModule(const Demangle::NodePointer &node) {
|
||||
Optional<RemoteASTTypeBuilder::ForeignModuleKind>
|
||||
RemoteASTTypeBuilder::getForeignModuleKind(const Demangle::NodePointer &node) {
|
||||
if (node->getKind() == Demangle::Node::Kind::DeclContext)
|
||||
return isForeignModule(node->getFirstChild());
|
||||
return getForeignModuleKind(node->getFirstChild());
|
||||
|
||||
if (node->getKind() != Demangle::Node::Kind::Module)
|
||||
return false;
|
||||
return None;
|
||||
|
||||
return (node->getText() == MANGLING_MODULE_OBJC ||
|
||||
node->getText() == MANGLING_MODULE_CLANG_IMPORTER);
|
||||
return llvm::StringSwitch<Optional<ForeignModuleKind>>(node->getText())
|
||||
.Case(MANGLING_MODULE_OBJC, ForeignModuleKind::Imported)
|
||||
.Case(MANGLING_MODULE_CLANG_IMPORTER,
|
||||
ForeignModuleKind::SynthesizedByImporter)
|
||||
.Default(None);
|
||||
}
|
||||
|
||||
DeclContext *
|
||||
@@ -582,7 +596,8 @@ RemoteASTTypeBuilder::findDeclContext(const Demangle::NodePointer &node) {
|
||||
case Demangle::Node::Kind::Class:
|
||||
case Demangle::Node::Kind::Enum:
|
||||
case Demangle::Node::Kind::Protocol:
|
||||
case Demangle::Node::Kind::Structure: {
|
||||
case Demangle::Node::Kind::Structure:
|
||||
case Demangle::Node::Kind::TypeAlias: {
|
||||
const auto &declNameNode = node->getChild(1);
|
||||
|
||||
// Handle local declarations.
|
||||
@@ -620,12 +635,13 @@ RemoteASTTypeBuilder::findDeclContext(const Demangle::NodePointer &node) {
|
||||
DeclContext *dc = findDeclContext(node->getChild(0));
|
||||
if (!dc) {
|
||||
// Do some backup logic for foreign type declarations.
|
||||
if (privateDiscriminator.empty() &&
|
||||
isForeignModule(node->getChild(0))) {
|
||||
return findForeignNominalTypeDecl(name, node->getKind());
|
||||
} else {
|
||||
return nullptr;
|
||||
if (privateDiscriminator.empty()) {
|
||||
if (auto foreignModuleKind = getForeignModuleKind(node->getChild(0))) {
|
||||
return findForeignNominalTypeDecl(name, foreignModuleKind.getValue(),
|
||||
node->getKind());
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return findNominalTypeDecl(dc, name, privateDiscriminator, node->getKind());
|
||||
@@ -675,6 +691,7 @@ RemoteASTTypeBuilder::findNominalTypeDecl(DeclContext *dc,
|
||||
|
||||
NominalTypeDecl *
|
||||
RemoteASTTypeBuilder::findForeignNominalTypeDecl(Identifier name,
|
||||
ForeignModuleKind foreignKind,
|
||||
Demangle::Node::Kind kind) {
|
||||
// Check to see if we have an importer loaded.
|
||||
auto importer = static_cast<ClangImporter *>(Ctx.getClangModuleLoader());
|
||||
@@ -690,11 +707,9 @@ RemoteASTTypeBuilder::findForeignNominalTypeDecl(Identifier name,
|
||||
|
||||
void foundDecl(ValueDecl *decl, DeclVisibilityKind reason) override {
|
||||
if (HadError) return;
|
||||
auto typeDecl = getAcceptableNominalTypeCandidate(decl, ExpectedKind);
|
||||
if (!typeDecl) return;
|
||||
if (typeDecl == Result) return;
|
||||
if (decl == Result) return;
|
||||
if (!Result) {
|
||||
Result = typeDecl;
|
||||
Result = cast<NominalTypeDecl>(decl);
|
||||
} else {
|
||||
HadError = true;
|
||||
Result = nullptr;
|
||||
@@ -702,7 +717,36 @@ RemoteASTTypeBuilder::findForeignNominalTypeDecl(Identifier name,
|
||||
}
|
||||
} consumer(kind);
|
||||
|
||||
importer->lookupValue(name, consumer);
|
||||
switch (foreignKind) {
|
||||
case ForeignModuleKind::SynthesizedByImporter:
|
||||
importer->lookupValue(name, consumer);
|
||||
if (consumer.Result)
|
||||
consumer.Result = getAcceptableNominalTypeCandidate(consumer.Result,kind);
|
||||
break;
|
||||
case ForeignModuleKind::Imported: {
|
||||
ClangTypeKind lookupKind;
|
||||
switch (kind) {
|
||||
case Demangle::Node::Kind::Protocol:
|
||||
lookupKind = ClangTypeKind::ObjCProtocol;
|
||||
break;
|
||||
case Demangle::Node::Kind::Class:
|
||||
lookupKind = ClangTypeKind::ObjCClass;
|
||||
break;
|
||||
case Demangle::Node::Kind::TypeAlias:
|
||||
lookupKind = ClangTypeKind::Typedef;
|
||||
break;
|
||||
case Demangle::Node::Kind::Structure:
|
||||
case Demangle::Node::Kind::Enum:
|
||||
lookupKind = ClangTypeKind::Tag;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
importer->lookupTypeDecl(name.str(), lookupKind, [&](TypeDecl *found) {
|
||||
consumer.foundDecl(found, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return consumer.Result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user