| // REQUIRES: !system-windows, !system-cygwin | |
| // RUN: rm -rf %t | |
| // RUN: split-file %s %t | |
| // RUN: cd %t | |
| // | |
| // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-module-interface \ | |
| // RUN: %t/Mod.cppm -o %t/Mod.pcm | |
| // | |
| // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/Mod.pcm \ | |
| // RUN: -emit-llvm -o - | FileCheck %t/Mod.cppm | |
| // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fmodule-file=Mod=%t/Mod.pcm \ | |
| // RUN: %t/Use.cpp -emit-llvm -o - | FileCheck %t/Use.cpp | |
| // | |
| // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-module-interface \ | |
| // RUN: %t/Mod.cppm -o %t/Mod.pcm -DKEY_FUNCTION_INLINE | |
| // | |
| // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/Mod.pcm \ | |
| // RUN: -emit-llvm -o - | FileCheck %t/Mod.cppm -check-prefix=CHECK-INLINE | |
| // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fmodule-file=Mod=%t/Mod.pcm \ | |
| // RUN: %t/Use.cpp -emit-llvm -o - | FileCheck %t/Use.cpp -check-prefix=CHECK-INLINE | |
| // | |
| // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-module-interface \ | |
| // 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; | |
| export class Base { | |
| public: | |
| virtual ~Base(); | |
| }; | |
| #ifdef KEY_FUNCTION_INLINE | |
| inline | |
| #endif | |
| Base::~Base() {} | |
| // CHECK: @_ZTVW3Mod4Base = unnamed_addr constant | |
| // CHECK: @_ZTIW3Mod4Base = constant | |
| // CHECK: @_ZTSW3Mod4Base = constant | |
| // With the new Itanium C++ ABI, the linkage of vtables in modules don't need to be linkonce ODR. | |
| // CHECK-INLINE: @_ZTVW3Mod4Base = {{.*}}unnamed_addr constant | |
| // CHECK-INLINE: @_ZTIW3Mod4Base = {{.*}}constant | |
| // CHECK-INLINE: @_ZTSW3Mod4Base = {{.*}}constant | |
| module :private; | |
| int private_use() { | |
| Base base; | |
| return 43; | |
| } | |
| //--- Use.cpp | |
| import Mod; | |
| int use() { | |
| Base* base = new Base(); | |
| return 43; | |
| } | |
| // CHECK-NOT: @_ZTIW3Mod4Base | |
| // CHECK-NOT: @_ZTSW3Mod4Base | |
| // CHECK: @_ZTVW3Mod4Base = external | |
| // CHECK-INLINE-NOT: @_ZTIW3Mod4Base | |
| // CHECK-INLINE-NOT: @_ZTSW3Mod4Base | |
| // 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 | |
| // module unit. | |
| //--- M-A.cppm | |
| export module M:A; | |
| export class C { | |
| public: | |
| virtual ~C(); | |
| }; | |
| int a_use() { | |
| C c; | |
| return 43; | |
| } | |
| // CHECK: @_ZTVW1M1C = unnamed_addr constant | |
| // CHECK: @_ZTIW1M1C = constant | |
| // CHECK: @_ZTSW1M1C = constant | |
| //--- M-B.cppm | |
| export module M:B; | |
| import :A; | |
| C::~C() {} | |
| int b_use() { | |
| C c; | |
| return 43; | |
| } | |
| // CHECK: @_ZTVW1M1C = external | |
| // CHECK-NOT: @_ZTIW1M1C | |
| // CHECK-NOT: @_ZTSW1M1C |