1// REQUIRES: !system-windows 2 3// RUN: rm -rf %t 4// RUN: split-file %s %t 5// RUN: cd %t 6// 7// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-module-interface \ 8// RUN: %t/Mod.cppm -o %t/Mod.pcm 9// 10// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/Mod.pcm \ 11// RUN: -emit-llvm -o - | FileCheck %t/Mod.cppm 12// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fmodule-file=Mod=%t/Mod.pcm \ 13// RUN: %t/Use.cpp -emit-llvm -o - | FileCheck %t/Use.cpp 14// 15// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-module-interface \ 16// RUN: %t/Mod.cppm -o %t/Mod.pcm -DKEY_FUNCTION_INLINE 17// 18// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/Mod.pcm \ 19// RUN: -emit-llvm -o - | FileCheck %t/Mod.cppm -check-prefix=CHECK-INLINE 20// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fmodule-file=Mod=%t/Mod.pcm \ 21// RUN: %t/Use.cpp -emit-llvm -o - | FileCheck %t/Use.cpp -check-prefix=CHECK-INLINE 22// 23// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-module-interface \ 24// RUN: %t/M-A.cppm -o %t/M-A.pcm 25// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fmodule-file=M:A=%t/M-A.pcm \ 26// RUN: %t/M-B.cppm -emit-llvm -o - | FileCheck %t/M-B.cppm 27// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ 28// RUN: %t/M-A.pcm -emit-llvm -o - | FileCheck %t/M-A.cppm 29 30//--- Mod.cppm 31export module Mod; 32 33export class Base { 34public: 35 virtual ~Base(); 36}; 37#ifdef KEY_FUNCTION_INLINE 38inline 39#endif 40Base::~Base() {} 41 42// CHECK: @_ZTVW3Mod4Base = unnamed_addr constant 43// CHECK: @_ZTIW3Mod4Base = constant 44// CHECK: @_ZTSW3Mod4Base = constant 45 46// With the new Itanium C++ ABI, the linkage of vtables in modules don't need to be linkonce ODR. 47// CHECK-INLINE: @_ZTVW3Mod4Base = {{.*}}unnamed_addr constant 48// CHECK-INLINE: @_ZTIW3Mod4Base = {{.*}}constant 49// CHECK-INLINE: @_ZTSW3Mod4Base = {{.*}}constant 50 51module :private; 52int private_use() { 53 Base base; 54 return 43; 55} 56 57//--- Use.cpp 58import Mod; 59int use() { 60 Base* base = new Base(); 61 return 43; 62} 63 64// CHECK-NOT: @_ZTIW3Mod4Base 65// CHECK-NOT: @_ZTSW3Mod4Base 66// CHECK: @_ZTVW3Mod4Base = external 67 68// CHECK-INLINE-NOT: @_ZTIW3Mod4Base 69// CHECK-INLINE-NOT: @_ZTSW3Mod4Base 70// CHECK-INLINE: @_ZTVW3Mod4Base = external 71 72// Check the case that the declaration of the key function comes from another 73// module unit but the definition of the key function comes from the current 74// module unit. 75 76//--- M-A.cppm 77export module M:A; 78export class C { 79public: 80 virtual ~C(); 81}; 82 83int a_use() { 84 C c; 85 return 43; 86} 87 88// CHECK: @_ZTVW1M1C = unnamed_addr constant 89// CHECK: @_ZTIW1M1C = constant 90// CHECK: @_ZTSW1M1C = constant 91 92//--- M-B.cppm 93export module M:B; 94import :A; 95 96C::~C() {} 97 98int b_use() { 99 C c; 100 return 43; 101} 102 103// CHECK: @_ZTVW1M1C = external 104// CHECK-NOT: @_ZTIW1M1C 105// CHECK-NOT: @_ZTSW1M1C 106