@@ -6498,6 +6498,29 @@ static bool hasRequiredValueTypeOperations(const clang::CXXRecordDecl *decl) {
64986498 return true ;
64996499}
65006500
6501+ static bool isSwiftClassType (const clang::CXXRecordDecl *decl) {
6502+ // Swift type must be annotated with external_source_symbol attribute.
6503+ auto essAttr = decl->getAttr <clang::ExternalSourceSymbolAttr>();
6504+ if (!essAttr || essAttr->getLanguage () != " Swift" ||
6505+ essAttr->getDefinedIn ().empty () || essAttr->getUSR ().empty ())
6506+ return false ;
6507+
6508+ // Ensure that the baseclass is swift::RefCountedClass.
6509+ auto baseDecl = decl;
6510+ do {
6511+ if (baseDecl->getNumBases () != 1 )
6512+ return false ;
6513+ auto baseClassSpecifier = *baseDecl->bases_begin ();
6514+ auto Ty = baseClassSpecifier.getType ();
6515+ auto nextBaseDecl = Ty->getAsCXXRecordDecl ();
6516+ if (!nextBaseDecl)
6517+ return false ;
6518+ baseDecl = nextBaseDecl;
6519+ } while (baseDecl->getName () != " RefCountedClass" );
6520+
6521+ return true ;
6522+ }
6523+
65016524CxxRecordSemanticsKind
65026525CxxRecordSemantics::evaluate (Evaluator &evaluator,
65036526 CxxRecordSemanticsDescriptor desc) const {
@@ -6512,6 +6535,9 @@ CxxRecordSemantics::evaluate(Evaluator &evaluator,
65126535 return CxxRecordSemanticsKind::Trivial;
65136536 }
65146537
6538+ if (isSwiftClassType (cxxDecl))
6539+ return CxxRecordSemanticsKind::SwiftClassType;
6540+
65156541 if (!hasRequiredValueTypeOperations (cxxDecl)) {
65166542 if (hasUnsafeAPIAttr (cxxDecl))
65176543 desc.ctx .Diags .diagnose ({}, diag::api_pattern_attr_ignored,
@@ -6549,6 +6575,34 @@ CxxRecordSemantics::evaluate(Evaluator &evaluator,
65496575 return CxxRecordSemanticsKind::Owned;
65506576}
65516577
6578+ ValueDecl *
6579+ CxxRecordAsSwiftType::evaluate (Evaluator &evaluator,
6580+ CxxRecordSemanticsDescriptor desc) const {
6581+ auto cxxDecl = dyn_cast<clang::CXXRecordDecl>(desc.decl );
6582+ if (!cxxDecl)
6583+ return nullptr ;
6584+ if (!isSwiftClassType (cxxDecl))
6585+ return nullptr ;
6586+
6587+ SmallVector<ValueDecl *, 1 > results;
6588+ auto *essaAttr = cxxDecl->getAttr <clang::ExternalSourceSymbolAttr>();
6589+ auto *mod = desc.ctx .getModuleByName (essaAttr->getDefinedIn ());
6590+ if (!mod) {
6591+ // TODO: warn about missing 'import'.
6592+ return nullptr ;
6593+ }
6594+ // FIXME: Support renamed declarations.
6595+ auto swiftName = cxxDecl->getName ();
6596+ // FIXME: handle nested Swift types once they're supported.
6597+ mod->lookupValue (desc.ctx .getIdentifier (swiftName), NLKind::UnqualifiedLookup,
6598+ results);
6599+ if (results.size () == 1 ) {
6600+ if (dyn_cast<ClassDecl>(results[0 ]))
6601+ return results[0 ];
6602+ }
6603+ return nullptr ;
6604+ }
6605+
65526606bool IsSafeUseOfCxxDecl::evaluate (Evaluator &evaluator,
65536607 SafeUseOfCxxDeclDescriptor desc) const {
65546608 const clang::Decl *decl = desc.decl ;
@@ -6577,6 +6631,8 @@ bool IsSafeUseOfCxxDecl::evaluate(Evaluator &evaluator,
65776631 method->getReturnType ().getCanonicalType ())) {
65786632 if (auto cxxRecordReturnType =
65796633 dyn_cast<clang::CXXRecordDecl>(returnType->getDecl ())) {
6634+ if (isSwiftClassType (cxxRecordReturnType))
6635+ return true ;
65806636 if (hasIteratorAPIAttr (cxxRecordReturnType) ||
65816637 isIterator (cxxRecordReturnType)) {
65826638 return false ;
0 commit comments