Skip to content

[cxx-interop][IRGen] Walk initializer decls when walking constructor decls #41584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lib/IRGen/GenClangDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ class ClangDeclFinder
return true;
}

bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *CXXCD) {
callback(CXXCD);
for (clang::CXXCtorInitializer *CXXCI : CXXCD->inits()) {
if (clang::FieldDecl *FD = CXXCI->getMember())
callback(FD);
}
return true;
}

bool VisitCXXConstructExpr(clang::CXXConstructExpr *CXXCE) {
callback(CXXCE->getConstructor());
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef TEST_INTEROP_CXX_CLASS_INLINE_FUNCTION_CODEGEN_INPUTS_CONSTRUCTOR_CALLS_FUNCTION_FROM_NESTED_CALLS_H
#define TEST_INTEROP_CXX_CLASS_INLINE_FUNCTION_CODEGEN_INPUTS_CONSTRUCTOR_CALLS_FUNCTION_FROM_NESTED_CALLS_H

inline int get42Level4() { return 42; }
inline int get42Level3() { return get42Level4(); }
inline int get42Level2() { return get42Level3(); }
inline int get42Level1() { return get42Level2(); }

struct Hold42WithLongInitCallGraph {
int m = get42Level1();
};

#endif // TEST_INTEROP_CXX_CLASS_INLINE_FUNCTION_THROUGH_MEMBER_INPUTS_CONSTRUCTOR_CALLS_FUNCTION_FROM_NESTED_STRUCT_H
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,18 @@ inline int callConstructor(int value) {
return IncrementUser::Incrementor(value).value;
}

inline int get42() { return 42; }

struct HoldMemberThatHolds42 {
struct Hold42 {
int m = get42();
};

Hold42 holder;
};

struct HoldMemberThatHoldsMemberThatHolds42 {
HoldMemberThatHolds42 holder;
};

#endif // TEST_INTEROP_CXX_CLASS_INLINE_FUNCTION_THROUGH_MEMBER_INPUTS_CONSTRUCTOR_CALLS_FUNCTION_FROM_NESTED_STRUCT_H
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,19 @@ struct Incrementor {

inline int callConstructor(int value) { return Incrementor(value).incrementee; }

inline int get42() { return 42; }

template <typename T>
T passThroughArgT(T t) {
return t;
}

struct Hold42 {
int m = get42();
};

struct Hold23 {
int m = passThroughArgT<int>(23);
};

#endif // TEST_INTEROP_CXX_CLASS_INLINE_FUNCTION_THROUGH_MEMBER_INPUTS_CONSTRUCTOR_CALLS_FUNCTION_H
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ module ConstructorCallsFunctionFromNestedStruct {
requires cplusplus
}

module ConstructorCallsFunctionFromNestedCalls {
header "constructor-calls-function-from-nested-calls.h"
requires cplusplus
}

module ConstructorCallsMethod {
header "constructor-calls-method.h"
requires cplusplus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@ import StdlibUnittest

var MembersTestSuite = TestSuite("MembersTestSuite")

MembersTestSuite.test("constructor calls function") {
MembersTestSuite.test("constructor calls function (explicit)") {
expectEqual(42, callConstructor(41))
}

MembersTestSuite.test("constructor calls function (implicit)") {
let holder = Hold42()
expectEqual(42, holder.m)
}

MembersTestSuite.test("constructor calls template function (implicit)") {
let holder = Hold23()
expectEqual(23, holder.m)
}

runAllTests()
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-cxx-interop)
//
// REQUIRES: executable_test

import ConstructorCallsFunctionFromNestedCalls
import StdlibUnittest

var MembersTestSuite = TestSuite("MembersTestSuite")

MembersTestSuite.test("constructor calls function from nested calls") {
let holder = Hold42WithLongInitCallGraph()
expectEqual(42, holder.m)
}

runAllTests()
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %target-swift-emit-ir %s -I %S/Inputs -enable-cxx-interop | %FileCheck %s

import ConstructorCallsFunctionFromNestedCalls

let a = Hold42WithLongInitCallGraph()

// CHECK-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z11get42Level1v|"\?get42Level1@@YAHXZ"}}
// CHECK-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z11get42Level2v|"\?get42Level2@@YAHXZ"}}
// CHECK-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z11get42Level3v|"\?get42Level3@@YAHXZ"}}
// CHECK-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z11get42Level4v|"\?get42Level4@@YAHXZ"}}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ import StdlibUnittest

var MembersTestSuite = TestSuite("MembersTestSuite")

MembersTestSuite.test("constructor calls function from nested struct") {
MembersTestSuite.test("constructor calls function from nested struct (explicit)") {
expectEqual(42, callConstructor(41))
}

MembersTestSuite.test("constructor calls function from nested struct (implicit)") {
let holder = HoldMemberThatHolds42()
expectEqual(42, holder.holder.m)
}

runAllTests()
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,10 @@ public func getIncrementorValue() -> CInt {
return callConstructor(41)
}

// CHECK: define linkonce_odr{{( dso_local)?}} i32 @{{_Z9incrementi|"\?increment@@YAHH@Z"}}(i32 %t)
let a = HoldMemberThatHolds42()
let b = HoldMemberThatHoldsMemberThatHolds42()

let sum = a.holder.m + b.holder.holder.m

// CHECK-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z9incrementi|"\?increment@@YAHH@Z"}}(i32 %t)
// CHECK-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z5get42v|"\?get42@@YAHXZ"}}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ public func getIncrementorValue() -> CInt {
return callConstructor(41)
}

// CHECK: define linkonce_odr{{( dso_local)?}} i32 @{{_Z9incrementi|"\?increment@@YAHH@Z"}}(i32 %t)
let a = Hold42()
let b = Hold23()

let sum = a.m + b.m

// CHECK-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z9incrementi|"\?increment@@YAHH@Z"}}(i32 %t)
// CHECK-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z5get42v|"\?get42@@YAHXZ"}}
// CHECK-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z15passThroughArgTIiET_S0_|"\?\?\$passThroughArgT@H@@YAHH@Z"}}