-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[C++20] [Modules] [Itanium ABI] Generate the vtable in the module unit of dynamic classes #75912
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
Changes from all commits
4b595ee
4c654ce
5a65491
de4b842
aecb473
c136838
65524b6
5401fe6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,8 @@ | |
// RUN: %t/M-A.cppm -o %t/M-A.pcm | ||
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fmodule-file=M:A=%t/M-A.pcm \ | ||
// RUN: %t/M-B.cppm -emit-llvm -o - | FileCheck %t/M-B.cppm | ||
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ | ||
// RUN: %t/M-A.pcm -emit-llvm -o - | FileCheck %t/M-A.cppm | ||
|
||
//--- Mod.cppm | ||
export module Mod; | ||
|
@@ -41,9 +43,10 @@ Base::~Base() {} | |
// CHECK: @_ZTSW3Mod4Base = constant | ||
// CHECK: @_ZTIW3Mod4Base = constant | ||
|
||
// CHECK-INLINE: @_ZTVW3Mod4Base = linkonce_odr {{.*}}unnamed_addr constant | ||
// CHECK-INLINE: @_ZTSW3Mod4Base = linkonce_odr {{.*}}constant | ||
// CHECK-INLINE: @_ZTIW3Mod4Base = linkonce_odr {{.*}}constant | ||
// With the new Itanium C++ ABI, the linkage of vtables in modules don't need to be linkonce ODR. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would they benefit from still being linkonce? What if the vtable is never used? Or do we leave that up to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it is linkonce, as long as I understand correctly, if the vtable is not used in the current TU, the middle end is free to remove the unused linkonce entity. But this is not wanted. Since all the things in the module purview is potentially used. Do I misunderstand anything? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right, sorry, was misreading the linkages - I guess
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While I agree |
||
// CHECK-INLINE: @_ZTVW3Mod4Base = {{.*}}unnamed_addr constant | ||
// CHECK-INLINE: @_ZTSW3Mod4Base = {{.*}}constant | ||
// CHECK-INLINE: @_ZTIW3Mod4Base = {{.*}}constant | ||
|
||
module :private; | ||
int private_use() { | ||
|
@@ -58,13 +61,13 @@ int use() { | |
return 43; | ||
} | ||
|
||
// CHECK-NOT: @_ZTSW3Mod4Base = constant | ||
// CHECK-NOT: @_ZTIW3Mod4Base = constant | ||
// CHECK: @_ZTVW3Mod4Base = external unnamed_addr | ||
// CHECK-NOT: @_ZTSW3Mod4Base | ||
// CHECK-NOT: @_ZTIW3Mod4Base | ||
// CHECK: @_ZTVW3Mod4Base = external | ||
|
||
// CHECK-INLINE: @_ZTVW3Mod4Base = linkonce_odr {{.*}}unnamed_addr constant | ||
// CHECK-INLINE: @_ZTSW3Mod4Base = linkonce_odr {{.*}}constant | ||
// CHECK-INLINE: @_ZTIW3Mod4Base = linkonce_odr {{.*}}constant | ||
// CHECK-INLINE-NOT: @_ZTSW3Mod4Base | ||
// CHECK-INLINE-NOT: @_ZTIW3Mod4Base | ||
// CHECK-INLINE: @_ZTVW3Mod4Base = external | ||
|
||
// Check the case that the declaration of the key function comes from another | ||
// module unit but the definition of the key function comes from the current | ||
|
@@ -82,6 +85,10 @@ int a_use() { | |
return 43; | ||
} | ||
|
||
// CHECK: @_ZTVW1M1C = unnamed_addr constant | ||
// CHECK: @_ZTSW1M1C = constant | ||
// CHECK: @_ZTIW1M1C = constant | ||
|
||
//--- M-B.cppm | ||
export module M:B; | ||
import :A; | ||
|
@@ -93,6 +100,6 @@ int b_use() { | |
return 43; | ||
} | ||
|
||
// CHECK: @_ZTVW1M1C = unnamed_addr constant | ||
// CHECK: @_ZTSW1M1C = constant | ||
// CHECK: @_ZTIW1M1C = constant | ||
// CHECK: @_ZTVW1M1C = external | ||
// CHECK-NOT: @_ZTSW1M1C | ||
// CHECK-NOT: @_ZTIW1M1C |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't need to test "isInNamedModule" here, though? Would it be adequate to do:
Ah, I geuss you want to return false ASAP too - I guess looking at some of the implementation details of
shouldEmitInExternalSource
and using those APIs directly here - Always -> true, Never -> false, I think?Like
adjustGVALinkageForExternalDefinitionKind
already does? Or even reusing some of that functionality somehow.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried. But it can't work the case we compile the AST directly to the object file. In this case,
hasExternalDefinitions
returns EK_ReplyHazy, but we need to return false directly here. I think it looks good now. If we want to extend this to header modules with object files, it will be easy.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems unfortunate - having these things work through different codepaths/states when compiling directly rather than via a pcm. It'd be good to make those paths converge (making
hasExternalDefinitions
provide the same answers/do the right thing when compiling directly without the intermediate pcm).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we would have to maintain both the one phase compilation and two phase compilation path. Maybe we can make it better by refining the API.