@@ -1241,6 +1241,10 @@ synthesizeStructDefaultConstructorBody(AbstractFunctionDecl *afd,
1241
1241
ASTContext &ctx = constructor->getASTContext ();
1242
1242
auto structDecl = static_cast <StructDecl *>(context);
1243
1243
1244
+ // We should call into C++ constructors directly.
1245
+ assert (!isa<clang::CXXRecordDecl>(structDecl->getClangDecl ()) &&
1246
+ " Should not synthesize a C++ object constructor." );
1247
+
1244
1248
// Use a builtin to produce a zero initializer, and assign it to self.
1245
1249
1246
1250
// Construct the left-hand reference to self.
@@ -3378,6 +3382,11 @@ namespace {
3378
3382
continue ;
3379
3383
}
3380
3384
3385
+ if (auto CD = dyn_cast<ConstructorDecl>(member)) {
3386
+ ctors.push_back (CD);
3387
+ continue ;
3388
+ }
3389
+
3381
3390
if (auto MD = dyn_cast<FuncDecl>(member)) {
3382
3391
methods.push_back (MD);
3383
3392
continue ;
@@ -3434,12 +3443,17 @@ namespace {
3434
3443
3435
3444
bool hasReferenceableFields = !members.empty ();
3436
3445
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.
3439
3452
ctors.push_back (createDefaultConstructor (Impl, result));
3440
3453
}
3441
3454
3442
- if (hasReferenceableFields && hasMemberwiseInitializer) {
3455
+ bool isAggregate = !cxxRecordDecl || cxxRecordDecl->isAggregate ();
3456
+ if (hasReferenceableFields && hasMemberwiseInitializer && isAggregate) {
3443
3457
// The default zero initializer suppresses the implicit value
3444
3458
// constructor that would normally be formed, so we have to add that
3445
3459
// explicitly as well.
@@ -3470,7 +3484,7 @@ namespace {
3470
3484
3471
3485
result->setHasUnreferenceableStorage (hasUnreferenceableStorage);
3472
3486
3473
- if (auto cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(decl) ) {
3487
+ if (cxxRecordDecl) {
3474
3488
result->setIsCxxNonTrivial (!cxxRecordDecl->isTriviallyCopyable ());
3475
3489
3476
3490
for (auto ctor : cxxRecordDecl->ctors ()) {
@@ -3491,6 +3505,34 @@ namespace {
3491
3505
return result;
3492
3506
}
3493
3507
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
+
3494
3536
Decl *VisitClassTemplateSpecializationDecl (
3495
3537
const clang::ClassTemplateSpecializationDecl *decl) {
3496
3538
// `Sema::isCompleteType` will try to instantiate the class template as a
@@ -3514,7 +3556,7 @@ namespace {
3514
3556
Impl.getClangSema ().InstantiateClassTemplateSpecializationMembers (
3515
3557
def->getLocation (), def, clang::TSK_ExplicitInstantiationDefinition);
3516
3558
3517
- return VisitRecordDecl (def);
3559
+ return VisitCXXRecordDecl (def);
3518
3560
}
3519
3561
3520
3562
Decl *VisitClassTemplatePartialSpecializationDecl (
@@ -3745,6 +3787,9 @@ namespace {
3745
3787
ImportedName importedName,
3746
3788
Optional<ImportedName> correctSwiftName,
3747
3789
Optional<AccessorInfo> accessorInfo) {
3790
+ if (decl->isDeleted ())
3791
+ return nullptr ;
3792
+
3748
3793
auto dc =
3749
3794
Impl.importDeclContextOf (decl, importedName.getEffectiveContext ());
3750
3795
if (!dc)
@@ -3753,7 +3798,6 @@ namespace {
3753
3798
DeclName name = accessorInfo ? DeclName () : importedName.getDeclName ();
3754
3799
auto selfIdx = importedName.getSelfIndex ();
3755
3800
3756
- FuncDecl *result = nullptr ;
3757
3801
ImportedType importedType;
3758
3802
bool selfIsInOut = false ;
3759
3803
ParameterList *bodyParams = nullptr ;
@@ -3855,27 +3899,48 @@ namespace {
3855
3899
if (!importedType)
3856
3900
return nullptr ;
3857
3901
3858
- auto resultTy = importedType.getType ();
3859
3902
auto loc = Impl.importSourceLoc (decl->getLocation ());
3860
3903
3861
3904
// FIXME: Poor location info.
3862
3905
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
+ }
3878
3941
}
3942
+ // Someday, maybe this will need to be 'open' for C++ virtual methods.
3943
+ func->setAccess (AccessLevel::Public);
3879
3944
}
3880
3945
3881
3946
result->setIsObjC (false );
@@ -3889,8 +3954,6 @@ namespace {
3889
3954
result->getAttrs ().add (new (Impl.SwiftContext )
3890
3955
FinalAttr (/* IsImplicit=*/ true ));
3891
3956
3892
- // Someday, maybe this will need to be 'open' for C++ virtual methods.
3893
- result->setAccess (AccessLevel::Public);
3894
3957
finishFuncDecl (decl, result);
3895
3958
3896
3959
// If this is a compatibility stub, mark it as such.
0 commit comments