Skip to content

Commit 3dedfda

Browse files
authored
Merge pull request #41655 from zoecarver/spec-as-base-class
[cxx-interop] Make sure to use the cannonical base class type.
2 parents 4c62dae + fc1e4df commit 3dedfda

File tree

5 files changed

+43
-5
lines changed

5 files changed

+43
-5
lines changed

lib/IRGen/GenStruct.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,16 +338,18 @@ namespace {
338338

339339
if (auto cxxRecord = dyn_cast<clang::CXXRecordDecl>(ClangDecl)) {
340340
for (auto base : cxxRecord->bases()) {
341-
auto baseRecord = cast<clang::RecordType>(base.getType())->getDecl();
341+
auto baseType = base.getType().getCanonicalType();
342+
343+
auto baseRecord = cast<clang::RecordType>(baseType)->getDecl();
342344
auto baseCxxRecord = cast<clang::CXXRecordDecl>(baseRecord);
343345

344346
if (baseCxxRecord->isEmpty())
345347
continue;
346348

347349
auto offset = layout.getBaseClassOffset(baseCxxRecord);
348350
auto size =
349-
ClangDecl->getASTContext().getTypeSizeInChars(base.getType());
350-
fn(base.getType(), offset, size);
351+
ClangDecl->getASTContext().getTypeSizeInChars(baseType);
352+
fn(baseType, offset, size);
351353
}
352354
}
353355
}
@@ -458,8 +460,14 @@ namespace {
458460

459461
unsigned baseOffset = 0;
460462
if (auto cxxRecord = dyn_cast<clang::CXXRecordDecl>(ClangDecl)) {
461-
baseOffset =
462-
std::distance(cxxRecord->bases().begin(), cxxRecord->bases().end());
463+
baseOffset = llvm::count_if(cxxRecord->bases(), [](auto base) {
464+
auto baseType = base.getType().getCanonicalType();
465+
466+
auto baseRecord = cast<clang::RecordType>(baseType)->getDecl();
467+
auto baseCxxRecord = cast<clang::CXXRecordDecl>(baseRecord);
468+
469+
return !baseCxxRecord->isEmpty();
470+
});
463471
}
464472

465473
// Otherwise, project from the base.

test/Interop/Cxx/class/inheritance/Inputs/fields.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,12 @@ struct NonTrivialHasOneField {
4646
struct NonTrivialDerivedFromAll : NonTrivialHasOneField, NonTrivialDerivedWithOneField {
4747
int f = 6;
4848
};
49+
50+
// Templates:
51+
52+
template<class T>
53+
struct ClassTemplate {
54+
T value;
55+
};
56+
57+
struct DerivedFromClassTemplate : ClassTemplate<int> {};

test/Interop/Cxx/class/inheritance/Inputs/functions.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,12 @@ struct DerivedFromDerived : Derived {
4949
};
5050

5151
struct DerivedFromNonTrivial : NonTrivial {};
52+
53+
struct EmptyBaseClass {
54+
const char *inBase() const { return "EmptyBaseClass::inBase"; }
55+
};
56+
57+
struct DerivedFromEmptyBaseClass : EmptyBaseClass {
58+
int a = 42;
59+
int b = 42;
60+
};

test/Interop/Cxx/class/inheritance/fields.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,10 @@ FieldsTestSuite.test("Fields from derived from non trivial") {
5252
expectEqual(mutable.f, 48)
5353
}
5454

55+
FieldsTestSuite.test("Derived from class template") {
56+
var derived = DerivedFromClassTemplate()
57+
derived.value = 42
58+
expectEqual(derived.value, 42)
59+
}
60+
5561
runAllTests()

test/Interop/Cxx/class/inheritance/functions.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,10 @@ FunctionsTestSuite.test("base member from derived from non trivial") {
6969
expectEqual(String(cString: dnt.inNonTrivialWithArgs(0, 1)!), "NonTrivial::inNonTrivialWithArgs")
7070
}
7171

72+
FunctionsTestSuite.test("non-empty derived from empty class") {
73+
let derived = DerivedFromEmptyBaseClass()
74+
expectEqual(String(cString: derived.inBase()!), "EmptyBaseClass::inBase")
75+
expectEqual(derived.b, 42)
76+
}
77+
7278
runAllTests()

0 commit comments

Comments
 (0)