@@ -692,7 +692,7 @@ static AccessorDecl *makeStructRawValueGetter(
692
692
assert (storedVar->hasStorage ());
693
693
694
694
ASTContext &C = Impl.SwiftContext ;
695
-
695
+
696
696
auto *params = ParameterList::createEmpty (C);
697
697
698
698
auto computedType = computedVar->getInterfaceType ();
@@ -726,7 +726,7 @@ static AccessorDecl *makeFieldGetterDecl(ClangImporter::Implementation &Impl,
726
726
auto &C = Impl.SwiftContext ;
727
727
728
728
auto *params = ParameterList::createEmpty (C);
729
-
729
+
730
730
auto getterType = importedFieldDecl->getInterfaceType ();
731
731
auto getterDecl = AccessorDecl::create (C,
732
732
/* FuncLoc=*/ importedFieldDecl->getLoc (),
@@ -1152,7 +1152,7 @@ makeBitFieldAccessors(ClangImporter::Implementation &Impl,
1152
1152
cSetterParamTypes,
1153
1153
clang::FunctionProtoType::ExtProtoInfo ());
1154
1154
auto cSetterTypeInfo = Ctx.getTrivialTypeSourceInfo (cSetterType);
1155
-
1155
+
1156
1156
auto cSetterDecl = clang::FunctionDecl::Create (Ctx,
1157
1157
structDecl->getDeclContext (),
1158
1158
clang::SourceLocation (),
@@ -1184,7 +1184,7 @@ makeBitFieldAccessors(ClangImporter::Implementation &Impl,
1184
1184
clang::SC_None,
1185
1185
nullptr );
1186
1186
cGetterDecl->setParams (cGetterSelf);
1187
-
1187
+
1188
1188
auto cGetterSelfExpr = new (Ctx) clang::DeclRefExpr (Ctx, cGetterSelf, false ,
1189
1189
recordType,
1190
1190
clang::VK_PRValue,
@@ -1197,7 +1197,7 @@ makeBitFieldAccessors(ClangImporter::Implementation &Impl,
1197
1197
clang::VK_PRValue,
1198
1198
clang::OK_BitField);
1199
1199
1200
-
1200
+
1201
1201
auto cGetterBody = clang::ReturnStmt::Create (Ctx, clang::SourceLocation (),
1202
1202
cGetterExpr,
1203
1203
nullptr );
@@ -1228,20 +1228,20 @@ makeBitFieldAccessors(ClangImporter::Implementation &Impl,
1228
1228
nullptr );
1229
1229
cSetterParams.push_back (cSetterSelf);
1230
1230
cSetterDecl->setParams (cSetterParams);
1231
-
1231
+
1232
1232
auto cSetterSelfExpr = new (Ctx) clang::DeclRefExpr (Ctx, cSetterSelf, false ,
1233
1233
recordPointerType,
1234
1234
clang::VK_PRValue,
1235
1235
clang::SourceLocation ());
1236
-
1236
+
1237
1237
auto cSetterMemberExpr = clang::MemberExpr::CreateImplicit (Ctx,
1238
1238
cSetterSelfExpr,
1239
1239
/* isarrow=*/ true ,
1240
1240
fieldDecl,
1241
1241
fieldType,
1242
1242
clang::VK_LValue,
1243
1243
clang::OK_BitField);
1244
-
1244
+
1245
1245
auto cSetterValueExpr = new (Ctx) clang::DeclRefExpr (Ctx, cSetterValue, false ,
1246
1246
fieldType,
1247
1247
clang::VK_PRValue,
@@ -1256,7 +1256,7 @@ makeBitFieldAccessors(ClangImporter::Implementation &Impl,
1256
1256
clang::OK_Ordinary,
1257
1257
clang::SourceLocation (),
1258
1258
clang::FPOptionsOverride ());
1259
-
1259
+
1260
1260
cSetterDecl->setBody (cSetterExpr);
1261
1261
}
1262
1262
@@ -2419,7 +2419,7 @@ namespace {
2419
2419
if (auto *typedefForAnon = decl->getTypedefNameForAnonDecl ())
2420
2420
return importFullName (typedefForAnon);
2421
2421
}
2422
-
2422
+
2423
2423
return {ImportedName (), None};
2424
2424
}
2425
2425
@@ -2806,7 +2806,7 @@ namespace {
2806
2806
});
2807
2807
2808
2808
Result->setUnderlyingType (SwiftType);
2809
-
2809
+
2810
2810
// Make Objective-C's 'id' unavailable.
2811
2811
if (Impl.SwiftContext .LangOpts .EnableObjCInterop && isObjCId (Decl)) {
2812
2812
auto attr = AvailableAttr::createPlatformAgnostic (
@@ -2882,7 +2882,7 @@ namespace {
2882
2882
Impl.importDeclContextOf (decl, importedName.getEffectiveContext ());
2883
2883
if (!dc)
2884
2884
return nullptr ;
2885
-
2885
+
2886
2886
auto name = importedName.getDeclName ().getBaseIdentifier ();
2887
2887
2888
2888
// Create the enum declaration and record it.
@@ -2948,7 +2948,7 @@ namespace {
2948
2948
ProtocolDecl *bridgedNSError = nullptr ;
2949
2949
ClassDecl *nsErrorDecl = nullptr ;
2950
2950
ProtocolDecl *errorCodeProto = nullptr ;
2951
- if (enumInfo.isErrorEnum () &&
2951
+ if (enumInfo.isErrorEnum () &&
2952
2952
(bridgedNSError =
2953
2953
C.getProtocol (KnownProtocolKind::BridgedStoredNSError)) &&
2954
2954
(nsErrorDecl = C.getNSErrorDecl ()) &&
@@ -3124,7 +3124,7 @@ namespace {
3124
3124
Impl.ImportedDecls [{canonicalClangDecl, getVersion ()}] = result;
3125
3125
3126
3126
// Import each of the enumerators.
3127
-
3127
+
3128
3128
bool addEnumeratorsAsMembers;
3129
3129
switch (enumKind) {
3130
3130
case EnumKind::Constants:
@@ -3282,7 +3282,7 @@ namespace {
3282
3282
addDecl (result, enumeratorDecl);
3283
3283
for (auto *variant : variantDecls)
3284
3284
addDecl (result, variant);
3285
-
3285
+
3286
3286
// If there is an error wrapper, add an alias within the
3287
3287
// wrapper to the corresponding value within the enumerator
3288
3288
// context.
@@ -3334,7 +3334,7 @@ namespace {
3334
3334
// Track whether this record contains fields we can't reference in Swift
3335
3335
// as stored properties.
3336
3336
bool hasUnreferenceableStorage = false ;
3337
-
3337
+
3338
3338
// Track whether this record contains fields that can't be zero-
3339
3339
// initialized.
3340
3340
bool hasZeroInitializableStorage = true ;
@@ -3576,6 +3576,12 @@ namespace {
3576
3576
3577
3577
const clang::CXXRecordDecl *cxxRecordDecl =
3578
3578
dyn_cast<clang::CXXRecordDecl>(decl);
3579
+ bool hasBaseClasses = cxxRecordDecl && !cxxRecordDecl->bases ().empty ();
3580
+ if (hasBaseClasses) {
3581
+ hasUnreferenceableStorage = true ;
3582
+ hasMemberwiseInitializer = false ;
3583
+ }
3584
+
3579
3585
if (hasZeroInitializableStorage && !cxxRecordDecl) {
3580
3586
// Add default constructor for the struct if compiling in C mode.
3581
3587
// If we're compiling for C++, we'll import the C++ default constructor
@@ -4212,10 +4218,10 @@ namespace {
4212
4218
DeclName ctorName (Impl.SwiftContext , DeclBaseName::createConstructor (),
4213
4219
bodyParams);
4214
4220
result = Impl.createDeclWithClangNode <ConstructorDecl>(
4215
- clangNode, AccessLevel::Public, ctorName, loc,
4221
+ clangNode, AccessLevel::Public, ctorName, loc,
4216
4222
/* failable=*/ false , /* FailabilityLoc=*/ SourceLoc (),
4217
4223
/* Async=*/ false , /* AsyncLoc=*/ SourceLoc (),
4218
- /* Throws=*/ false , /* ThrowsLoc=*/ SourceLoc (),
4224
+ /* Throws=*/ false , /* ThrowsLoc=*/ SourceLoc (),
4219
4225
bodyParams, genericParams, dc);
4220
4226
} else {
4221
4227
auto resultTy = importedType.getType ();
@@ -4592,33 +4598,33 @@ namespace {
4592
4598
// Only import types for now.
4593
4599
if (!isa<clang::TypeDecl>(decl->getUnderlyingDecl ()))
4594
4600
return nullptr ;
4595
-
4601
+
4596
4602
ImportedName importedName;
4597
4603
Optional<ImportedName> correctSwiftName;
4598
4604
std::tie (importedName, correctSwiftName) = importFullName (decl);
4599
4605
auto Name = importedName.getDeclName ().getBaseIdentifier ();
4600
4606
if (Name.empty ())
4601
4607
return nullptr ;
4602
-
4608
+
4603
4609
// If we've been asked to produce a compatibility stub, handle it via a
4604
4610
// typealias.
4605
4611
if (correctSwiftName)
4606
4612
return importCompatibilityTypeAlias (decl, importedName,
4607
4613
*correctSwiftName);
4608
-
4614
+
4609
4615
auto DC =
4610
4616
Impl.importDeclContextOf (decl, importedName.getEffectiveContext ());
4611
4617
if (!DC)
4612
4618
return nullptr ;
4613
-
4619
+
4614
4620
Decl *SwiftDecl = Impl.importDecl (decl->getUnderlyingDecl (), getActiveSwiftVersion ());
4615
4621
if (!SwiftDecl)
4616
4622
return nullptr ;
4617
4623
4618
4624
const TypeDecl *SwiftTypeDecl = dyn_cast<TypeDecl>(SwiftDecl);
4619
4625
if (!SwiftTypeDecl)
4620
4626
return nullptr ;
4621
-
4627
+
4622
4628
auto Loc = Impl.importSourceLoc (decl->getLocation ());
4623
4629
auto Result = Impl.createDeclWithClangNode <TypeAliasDecl>(
4624
4630
decl,
@@ -5286,7 +5292,7 @@ namespace {
5286
5292
objcClass->getDeclaredType ());
5287
5293
Impl.SwiftContext .evaluator .cacheOutput (ExtendedNominalRequest{result},
5288
5294
std::move (objcClass));
5289
-
5295
+
5290
5296
// Determine the type and generic args of the extension.
5291
5297
if (objcClass->getGenericParams ()) {
5292
5298
result->setGenericSignature (objcClass->getGenericSignature ());
@@ -5305,7 +5311,7 @@ namespace {
5305
5311
}
5306
5312
5307
5313
template <typename T, typename U>
5308
- T *resolveSwiftDeclImpl (const U *decl, Identifier name,
5314
+ T *resolveSwiftDeclImpl (const U *decl, Identifier name,
5309
5315
bool hasKnownSwiftName, ModuleDecl *overlay) {
5310
5316
const auto &languageVersion =
5311
5317
Impl.SwiftContext .LangOpts .EffectiveLanguageVersion ;
@@ -6178,7 +6184,7 @@ Decl *SwiftDeclConverter::importCompatibilityTypeAlias(
6178
6184
}
6179
6185
6180
6186
alias->setUnderlyingType (typeDecl->getDeclaredInterfaceType ());
6181
-
6187
+
6182
6188
// Record that this is the official version of this declaration.
6183
6189
Impl.ImportedDecls [{decl->getCanonicalDecl (), getVersion ()}] = alias;
6184
6190
markAsVariant (alias, correctSwiftName);
@@ -9335,7 +9341,7 @@ ClangImporter::Implementation::importMirroredDecl(const clang::NamedDecl *decl,
9335
9341
9336
9342
auto updateMirroredDecl = [&](Decl *result) {
9337
9343
result->setImplicit ();
9338
-
9344
+
9339
9345
// Map the Clang attributes onto Swift attributes.
9340
9346
importAttributes (decl, result);
9341
9347
@@ -9926,10 +9932,10 @@ static void loadAllMembersOfSuperclassIfNeeded(ClassDecl *CD) {
9926
9932
E->loadAllMembers ();
9927
9933
}
9928
9934
9929
- void ClangImporter::Implementation::loadAllMembersOfRecordDecl (
9930
- NominalTypeDecl *recordDecl) {
9931
- auto clangRecord = cast<clang::RecordDecl>(recordDecl->getClangDecl ());
9935
+ ValueDecl *cloneBaseMemberDecl (ValueDecl *decl, DeclContext *newContext);
9932
9936
9937
+ void ClangImporter::Implementation::loadAllMembersOfRecordDecl (
9938
+ NominalTypeDecl *swiftDecl, const clang::RecordDecl *clangRecord) {
9933
9939
// Import all of the members.
9934
9940
llvm::SmallVector<Decl *, 16 > members;
9935
9941
for (const clang::Decl *m : clangRecord->decls ()) {
@@ -9955,12 +9961,36 @@ void ClangImporter::Implementation::loadAllMembersOfRecordDecl(
9955
9961
9956
9962
// Add the members here.
9957
9963
for (auto member: members) {
9964
+ // This means we found a member in a C++ record's base class.
9965
+ if (swiftDecl->getClangDecl () != clangRecord) {
9966
+ // So we need to clone the member into the derived class.
9967
+ if (auto newDecl = cloneBaseMemberDecl (cast<ValueDecl>(member), swiftDecl)) {
9968
+ swiftDecl->addMember (newDecl);
9969
+ }
9970
+ continue ;
9971
+ }
9972
+
9958
9973
// FIXME: constructors are added eagerly, but shouldn't be
9959
9974
// FIXME: subscripts are added eagerly, but shouldn't be
9960
9975
if (!isa<AccessorDecl>(member) &&
9961
9976
!isa<SubscriptDecl>(member) &&
9962
- !isa<ConstructorDecl>(member))
9963
- recordDecl->addMember (member);
9977
+ !isa<ConstructorDecl>(member)) {
9978
+ swiftDecl->addMember (member);
9979
+ }
9980
+ }
9981
+
9982
+ // If this is a C++ record, look through the base classes too.
9983
+ if (auto cxxRecord = dyn_cast<clang::CXXRecordDecl>(clangRecord)) {
9984
+ for (auto base : cxxRecord->bases ()) {
9985
+ clang::QualType baseType = base.getType ();
9986
+ if (auto spectType = dyn_cast<clang::TemplateSpecializationType>(baseType))
9987
+ baseType = spectType->desugar ();
9988
+ if (!isa<clang::RecordType>(baseType))
9989
+ continue ;
9990
+
9991
+ auto *baseRecord = cast<clang::RecordType>(baseType)->getDecl ();
9992
+ loadAllMembersOfRecordDecl (swiftDecl, baseRecord);
9993
+ }
9964
9994
}
9965
9995
}
9966
9996
@@ -9996,7 +10026,8 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) {
9996
10026
}
9997
10027
9998
10028
if (isa_and_nonnull<clang::RecordDecl>(D->getClangDecl ())) {
9999
- loadAllMembersOfRecordDecl (cast<NominalTypeDecl>(D));
10029
+ loadAllMembersOfRecordDecl (cast<NominalTypeDecl>(D),
10030
+ cast<clang::RecordDecl>(D->getClangDecl ()));
10000
10031
return ;
10001
10032
}
10002
10033
0 commit comments