@@ -1241,6 +1241,10 @@ synthesizeStructDefaultConstructorBody(AbstractFunctionDecl *afd,
12411241 ASTContext &ctx = constructor->getASTContext ();
12421242 auto structDecl = static_cast <StructDecl *>(context);
12431243
1244+ // We should call into C++ constructors directly.
1245+ assert (!isa<clang::CXXRecordDecl>(structDecl->getClangDecl ()) &&
1246+ " Should not synthesize a C++ object constructor." );
1247+
12441248 // Use a builtin to produce a zero initializer, and assign it to self.
12451249
12461250 // Construct the left-hand reference to self.
@@ -3378,6 +3382,11 @@ namespace {
33783382 continue ;
33793383 }
33803384
3385+ if (auto CD = dyn_cast<ConstructorDecl>(member)) {
3386+ ctors.push_back (CD);
3387+ continue ;
3388+ }
3389+
33813390 if (auto MD = dyn_cast<FuncDecl>(member)) {
33823391 methods.push_back (MD);
33833392 continue ;
@@ -3434,12 +3443,17 @@ namespace {
34343443
34353444 bool hasReferenceableFields = !members.empty ();
34363445
3437- if (hasZeroInitializableStorage) {
3438- // Add constructors for the struct.
3446+ const clang::CXXRecordDecl *cxxRecordDecl =
3447+ dyn_cast<clang::CXXRecordDecl>(decl);
3448+ if (hasZeroInitializableStorage && !cxxRecordDecl) {
3449+ // Add default constructor for the struct if compiling in C mode.
3450+ // If we're compiling for C++, we'll import the C++ default constructor
3451+ // (if there is one), so we don't need to synthesize one here.
34393452 ctors.push_back (createDefaultConstructor (Impl, result));
34403453 }
34413454
3442- if (hasReferenceableFields && hasMemberwiseInitializer) {
3455+ bool isAggregate = !cxxRecordDecl || cxxRecordDecl->isAggregate ();
3456+ if (hasReferenceableFields && hasMemberwiseInitializer && isAggregate) {
34433457 // The default zero initializer suppresses the implicit value
34443458 // constructor that would normally be formed, so we have to add that
34453459 // explicitly as well.
@@ -3470,7 +3484,7 @@ namespace {
34703484
34713485 result->setHasUnreferenceableStorage (hasUnreferenceableStorage);
34723486
3473- if (auto cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(decl) ) {
3487+ if (cxxRecordDecl) {
34743488 result->setIsCxxNonTrivial (!cxxRecordDecl->isTriviallyCopyable ());
34753489
34763490 for (auto ctor : cxxRecordDecl->ctors ()) {
@@ -3491,6 +3505,34 @@ namespace {
34913505 return result;
34923506 }
34933507
3508+ Decl *VisitCXXRecordDecl (const clang::CXXRecordDecl *decl) {
3509+ // This can be called from lldb without C++ interop being enabled: There
3510+ // may be C++ declarations in imported modules, but the interface for
3511+ // those modules may be a pure C or Objective-C interface.
3512+ // To avoid crashing in Clang's Sema, fall back to importing this as a
3513+ // plain RecordDecl.
3514+ if (!Impl.SwiftContext .LangOpts .EnableCXXInterop )
3515+ return VisitRecordDecl (decl);
3516+
3517+ auto &clangSema = Impl.getClangSema ();
3518+ // Make Clang define the implicit default constructor if the class needs
3519+ // it. Make sure we only do this if the class has been fully defined and
3520+ // we're not in a dependent context (this is equivalent to the logic in
3521+ // CanDeclareSpecialMemberFunction in Clang's SemaLookup.cpp).
3522+ if (decl->getDefinition () && !decl->isBeingDefined () &&
3523+ !decl->isDependentContext () &&
3524+ decl->needsImplicitDefaultConstructor ()) {
3525+ clang::CXXConstructorDecl *ctor =
3526+ clangSema.DeclareImplicitDefaultConstructor (
3527+ const_cast <clang::CXXRecordDecl *>(decl));
3528+ if (!ctor->isDeleted ())
3529+ clangSema.DefineImplicitDefaultConstructor (clang::SourceLocation (),
3530+ ctor);
3531+ }
3532+
3533+ return VisitRecordDecl (decl);
3534+ }
3535+
34943536 Decl *VisitClassTemplateSpecializationDecl (
34953537 const clang::ClassTemplateSpecializationDecl *decl) {
34963538 // `Sema::isCompleteType` will try to instantiate the class template as a
@@ -3514,7 +3556,7 @@ namespace {
35143556 Impl.getClangSema ().InstantiateClassTemplateSpecializationMembers (
35153557 def->getLocation (), def, clang::TSK_ExplicitInstantiationDefinition);
35163558
3517- return VisitRecordDecl (def);
3559+ return VisitCXXRecordDecl (def);
35183560 }
35193561
35203562 Decl *VisitClassTemplatePartialSpecializationDecl (
@@ -3745,6 +3787,9 @@ namespace {
37453787 ImportedName importedName,
37463788 Optional<ImportedName> correctSwiftName,
37473789 Optional<AccessorInfo> accessorInfo) {
3790+ if (decl->isDeleted ())
3791+ return nullptr ;
3792+
37483793 auto dc =
37493794 Impl.importDeclContextOf (decl, importedName.getEffectiveContext ());
37503795 if (!dc)
@@ -3753,7 +3798,6 @@ namespace {
37533798 DeclName name = accessorInfo ? DeclName () : importedName.getDeclName ();
37543799 auto selfIdx = importedName.getSelfIndex ();
37553800
3756- FuncDecl *result = nullptr ;
37573801 ImportedType importedType;
37583802 bool selfIsInOut = false ;
37593803 ParameterList *bodyParams = nullptr ;
@@ -3855,27 +3899,48 @@ namespace {
38553899 if (!importedType)
38563900 return nullptr ;
38573901
3858- auto resultTy = importedType.getType ();
38593902 auto loc = Impl.importSourceLoc (decl->getLocation ());
38603903
38613904 // FIXME: Poor location info.
38623905 auto nameLoc = Impl.importSourceLoc (decl->getLocation ());
3863- result = createFuncOrAccessor (
3864- Impl.SwiftContext , loc, accessorInfo, name,
3865- nameLoc, bodyParams, resultTy,
3866- /* async*/ false , /* throws*/ false , dc, decl);
3867-
3868- if (!dc->isModuleScopeContext ()) {
3869- if (selfIsInOut)
3870- result->setSelfAccessKind (SelfAccessKind::Mutating);
3871- else
3872- result->setSelfAccessKind (SelfAccessKind::NonMutating);
3873- if (selfIdx) {
3874- result->setSelfIndex (selfIdx.getValue ());
3875- } else {
3876- result->setStatic ();
3877- result->setImportAsStaticMember ();
3906+
3907+ AbstractFunctionDecl *result = nullptr ;
3908+ if (auto *ctordecl = dyn_cast<clang::CXXConstructorDecl>(decl)) {
3909+ // Don't import copy constructor or move constructor -- these will be
3910+ // provided through the value witness table.
3911+ if (ctordecl->isCopyConstructor () || ctordecl->isMoveConstructor ())
3912+ return nullptr ;
3913+
3914+ DeclName ctorName (Impl.SwiftContext , DeclBaseName::createConstructor (),
3915+ bodyParams);
3916+ result = Impl.createDeclWithClangNode <ConstructorDecl>(
3917+ decl, AccessLevel::Public, ctorName, loc, /* failable=*/ false ,
3918+ /* FailabilityLoc=*/ SourceLoc (), /* Throws=*/ false ,
3919+ /* ThrowsLoc=*/ SourceLoc (), bodyParams, /* GenericParams=*/ nullptr ,
3920+ dc);
3921+ } else {
3922+ auto resultTy = importedType.getType ();
3923+
3924+ FuncDecl *func =
3925+ createFuncOrAccessor (Impl.SwiftContext , loc, accessorInfo, name,
3926+ nameLoc, bodyParams, resultTy,
3927+ /* async=*/ false , /* throws=*/ false , dc, decl);
3928+ result = func;
3929+
3930+ if (!dc->isModuleScopeContext ()) {
3931+ if (selfIsInOut)
3932+ func->setSelfAccessKind (SelfAccessKind::Mutating);
3933+ else
3934+ func->setSelfAccessKind (SelfAccessKind::NonMutating);
3935+ if (selfIdx) {
3936+ func->setSelfIndex (selfIdx.getValue ());
3937+ } else {
3938+ func->setStatic ();
3939+ func->setImportAsStaticMember ();
3940+ }
38783941 }
3942+ // Someday, maybe this will need to be 'open' for C++ virtual methods.
3943+ func->setAccess (AccessLevel::Public);
38793944 }
38803945
38813946 result->setIsObjC (false );
@@ -3889,8 +3954,6 @@ namespace {
38893954 result->getAttrs ().add (new (Impl.SwiftContext )
38903955 FinalAttr (/* IsImplicit=*/ true ));
38913956
3892- // Someday, maybe this will need to be 'open' for C++ virtual methods.
3893- result->setAccess (AccessLevel::Public);
38943957 finishFuncDecl (decl, result);
38953958
38963959 // If this is a compatibility stub, mark it as such.
0 commit comments