@@ -646,6 +646,31 @@ namespace {
646
646
return nullptr ;
647
647
}
648
648
649
+ // / Map the Clang swift_bridge attribute to a specific type.
650
+ Type mapSwiftBridgeAttr (const clang::NamedDecl *clangDecl) {
651
+ // Check whether there is a swift_bridge attribute.
652
+ auto bridgeAttr = clangDecl->getAttr <clang::SwiftBridgeAttr>();
653
+ if (!bridgeAttr) return Type ();
654
+
655
+ // Determine the module and Swift declaration names.
656
+ StringRef moduleName;
657
+ StringRef name = bridgeAttr->getSwiftType ();
658
+ auto dotPos = name.find (' .' );
659
+ if (dotPos == StringRef::npos) {
660
+ // Determine the module name from the Clang declaration.
661
+ if (auto module = clangDecl->getImportedOwningModule ())
662
+ moduleName = module->getTopLevelModuleName ();
663
+ else
664
+ moduleName = clangDecl->getASTContext ().getLangOpts ().CurrentModule ;
665
+ } else {
666
+ // The string is ModuleName.TypeName.
667
+ moduleName = name.substr (0 , dotPos);
668
+ name = name.substr (dotPos + 1 );
669
+ }
670
+
671
+ return Impl.getNamedSwiftType (moduleName, name);
672
+ }
673
+
649
674
ImportResult
650
675
VisitObjCObjectPointerType (const clang::ObjCObjectPointerType *type) {
651
676
// If this object pointer refers to an Objective-C class (possibly
@@ -684,20 +709,11 @@ namespace {
684
709
685
710
// Determine whether this Objective-C class type is bridged to
686
711
// a Swift type.
687
- NominalTypeDecl *bridgedTypeDecl = nullptr ;
688
- StringRef objcClassName = objcClass->getName ();
689
- if (objcClassName == " NSString" )
690
- bridgedTypeDecl = Impl.SwiftContext .getStringDecl ();
691
- else if (objcClassName == " NSArray" )
692
- bridgedTypeDecl = Impl.SwiftContext .getArrayDecl ();
693
- else if (objcClassName == " NSDictionary" )
694
- bridgedTypeDecl = Impl.SwiftContext .getDictionaryDecl ();
695
- else if (objcClassName == " NSSet" )
696
- bridgedTypeDecl = Impl.SwiftContext .getSetDecl ();
697
-
698
712
Type bridgedType;
699
- if (bridgedTypeDecl)
700
- bridgedType = bridgedTypeDecl->getDeclaredType ();
713
+ if (auto objcClassDef = objcClass->getDefinition ())
714
+ bridgedType = mapSwiftBridgeAttr (objcClassDef);
715
+ else
716
+ bridgedType = mapSwiftBridgeAttr (objcClass);
701
717
702
718
if (bridgedType) {
703
719
// Gather the type arguments.
@@ -2214,29 +2230,36 @@ Module *ClangImporter::Implementation::getNamedModule(StringRef name) {
2214
2230
}
2215
2231
2216
2232
static Module *tryLoadModule (ASTContext &C,
2217
- Identifier name ,
2233
+ Identifier moduleName ,
2218
2234
bool importForwardDeclarations,
2219
- Optional<Module *> &cache) {
2220
- if (!cache.hasValue ()) {
2221
- // If we're synthesizing forward declarations, we don't want to pull in
2222
- // the module too eagerly.
2223
- if (importForwardDeclarations)
2224
- cache = C.getLoadedModule (name);
2225
- else
2226
- cache = C.getModule ({ {name, SourceLoc ()} });
2227
- }
2235
+ llvm::DenseMap<Identifier, Module *>
2236
+ &checkedModules) {
2237
+ // If we've already done this check, return the cached result.
2238
+ auto known = checkedModules.find (moduleName);
2239
+ if (known != checkedModules.end ())
2240
+ return known->second ;
2241
+
2242
+ Module *module;
2243
+
2244
+ // If we're synthesizing forward declarations, we don't want to pull in
2245
+ // the module too eagerly.
2246
+ if (importForwardDeclarations)
2247
+ module = C.getLoadedModule (moduleName);
2248
+ else
2249
+ module = C.getModule ({ {moduleName, SourceLoc ()} });
2228
2250
2229
- return cache.getValue ();
2251
+ checkedModules[moduleName] = module;
2252
+ return module;
2230
2253
}
2231
2254
2232
2255
Module *ClangImporter::Implementation::tryLoadFoundationModule () {
2233
2256
return tryLoadModule (SwiftContext, SwiftContext.Id_Foundation ,
2234
- ImportForwardDeclarations, checkedFoundationModule );
2257
+ ImportForwardDeclarations, checkedModules );
2235
2258
}
2236
2259
2237
2260
Module *ClangImporter::Implementation::tryLoadSIMDModule () {
2238
2261
return tryLoadModule (SwiftContext, SwiftContext.Id_simd ,
2239
- ImportForwardDeclarations, checkedSIMDModule );
2262
+ ImportForwardDeclarations, checkedModules );
2240
2263
}
2241
2264
2242
2265
Type ClangImporter::Implementation::getNamedSwiftType (Module *module,
@@ -2277,6 +2300,17 @@ Type ClangImporter::Implementation::getNamedSwiftType(Module *module,
2277
2300
return type->getDeclaredType ();
2278
2301
}
2279
2302
2303
+ Type ClangImporter::Implementation::getNamedSwiftType (StringRef moduleName,
2304
+ StringRef name) {
2305
+ // Try to load the module.
2306
+ auto module = tryLoadModule (SwiftContext,
2307
+ SwiftContext.getIdentifier (moduleName),
2308
+ ImportForwardDeclarations, checkedModules);
2309
+ if (!module) return Type ();
2310
+
2311
+ return getNamedSwiftType (module, name);
2312
+ }
2313
+
2280
2314
Type
2281
2315
ClangImporter::Implementation::
2282
2316
getNamedSwiftTypeSpecialization (Module *module, StringRef name,
0 commit comments