xref: /llvm-project/clang/test/Modules/lambda-in-variable.cpp (revision bc73ef0031b50f7443615fef614fb4ecaaa4bd11)
1*bc73ef00SRichard Smith // RUN: rm -rf %t
2*bc73ef00SRichard Smith // RUN: mkdir -p %t
3*bc73ef00SRichard Smith // RUN: split-file %s %t
4*bc73ef00SRichard Smith //
5*bc73ef00SRichard Smith // RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%t/module.modulemap %t/use.cpp -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s
6*bc73ef00SRichard Smith // RUN: %clang_cc1 -DDEFINE_LOCALLY -std=c++20 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%t/module.modulemap %t/use.cpp -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s
7*bc73ef00SRichard Smith 
8*bc73ef00SRichard Smith //--- module.modulemap
9*bc73ef00SRichard Smith module a { header "a.h" export * }
10*bc73ef00SRichard Smith module b { header "b.h" export * }
11*bc73ef00SRichard Smith module c { header "c.h" export * }
12*bc73ef00SRichard Smith 
13*bc73ef00SRichard Smith //--- nonmodular.h
14*bc73ef00SRichard Smith void not_constant();
15*bc73ef00SRichard Smith 
16*bc73ef00SRichard Smith template<typename T> struct A {
__anond5ec2cd60102A17*bc73ef00SRichard Smith   template<T M> static inline T N = [] { not_constant(); return M; } ();
18*bc73ef00SRichard Smith };
19*bc73ef00SRichard Smith 
__anond5ec2cd60202null20*bc73ef00SRichard Smith template<typename T, T M> inline T N = [] { not_constant(); return M; } ();
21*bc73ef00SRichard Smith 
__anond5ec2cd60302null22*bc73ef00SRichard Smith template<typename T, T M> inline auto L = [] {};
23*bc73ef00SRichard Smith 
24*bc73ef00SRichard Smith template<typename T> int Z;
25*bc73ef00SRichard Smith 
26*bc73ef00SRichard Smith // These lambdas should not be merged, despite having the same context decl and
27*bc73ef00SRichard Smith // mangling number (but different signatures).
__anond5ec2cd60402(int*) 28*bc73ef00SRichard Smith inline auto MultipleLambdas = ((void)[](int*) { return 1; }, [] { return 2; });
29*bc73ef00SRichard Smith 
30*bc73ef00SRichard Smith //--- a.h
31*bc73ef00SRichard Smith #include "nonmodular.h"
32*bc73ef00SRichard Smith 
33*bc73ef00SRichard Smith //--- b.h
34*bc73ef00SRichard Smith #include "a.h"
35*bc73ef00SRichard Smith 
b1()36*bc73ef00SRichard Smith int b1() { return A<int>::N<1>; }
b2()37*bc73ef00SRichard Smith int b2() { return N<int, 1>; }
38*bc73ef00SRichard Smith 
39*bc73ef00SRichard Smith inline auto x1 = L<int, 1>;
40*bc73ef00SRichard Smith inline auto x2 = L<int, 2>;
41*bc73ef00SRichard Smith 
__anond5ec2cd60602null42*bc73ef00SRichard Smith inline constexpr int *P = &Z<decltype([] { static int n; return &n; }())>;
43*bc73ef00SRichard Smith inline constexpr int *xP = P;
44*bc73ef00SRichard Smith 
45*bc73ef00SRichard Smith static_assert(!__is_same(decltype(x1), decltype(x2)));
46*bc73ef00SRichard Smith 
47*bc73ef00SRichard Smith //--- c.h
48*bc73ef00SRichard Smith #include "a.h"
49*bc73ef00SRichard Smith 
c1()50*bc73ef00SRichard Smith int c1() { return A<int>::N<2>; }
c2()51*bc73ef00SRichard Smith int c2() { return N<int, 2>; }
52*bc73ef00SRichard Smith 
53*bc73ef00SRichard Smith inline auto y2 = L<int, 2>;
54*bc73ef00SRichard Smith inline auto y1 = L<int, 1>;
55*bc73ef00SRichard Smith 
__anond5ec2cd60702null56*bc73ef00SRichard Smith inline constexpr int *P = &Z<decltype([] { static int n; return &n; }())>;
57*bc73ef00SRichard Smith inline constexpr int *yP = P;
58*bc73ef00SRichard Smith 
59*bc73ef00SRichard Smith //--- use.cpp
60*bc73ef00SRichard Smith #ifdef DEFINE_LOCALLY
61*bc73ef00SRichard Smith #include "nonmodular.h"
62*bc73ef00SRichard Smith 
__anond5ec2cd60802null63*bc73ef00SRichard Smith inline constexpr int *P = &Z<decltype([] { static int n; return &n; }())>;
64*bc73ef00SRichard Smith inline constexpr int *zP = P;
65*bc73ef00SRichard Smith 
66*bc73ef00SRichard Smith auto z0 = L<int, 0>;
67*bc73ef00SRichard Smith auto z2 = L<int, 2>;
68*bc73ef00SRichard Smith auto z1 = L<int, 1>;
69*bc73ef00SRichard Smith #endif
70*bc73ef00SRichard Smith 
71*bc73ef00SRichard Smith #include "b.h"
72*bc73ef00SRichard Smith #include "c.h"
73*bc73ef00SRichard Smith 
74*bc73ef00SRichard Smith int b1v = b1();
75*bc73ef00SRichard Smith int b2v = b2();
76*bc73ef00SRichard Smith int c1v = c1();
77*bc73ef00SRichard Smith int c2v = c2();
78*bc73ef00SRichard Smith 
79*bc73ef00SRichard Smith // We should merge together matching lambdas.
80*bc73ef00SRichard Smith static_assert(__is_same(decltype(x1), decltype(y1)));
81*bc73ef00SRichard Smith static_assert(__is_same(decltype(x2), decltype(y2)));
82*bc73ef00SRichard Smith static_assert(!__is_same(decltype(x1), decltype(x2)));
83*bc73ef00SRichard Smith static_assert(!__is_same(decltype(y1), decltype(y2)));
84*bc73ef00SRichard Smith static_assert(!__is_same(decltype(x1), decltype(y2)));
85*bc73ef00SRichard Smith static_assert(!__is_same(decltype(x2), decltype(y1)));
86*bc73ef00SRichard Smith static_assert(xP == yP);
87*bc73ef00SRichard Smith #ifdef DEFINE_LOCALLY
88*bc73ef00SRichard Smith static_assert(!__is_same(decltype(x1), decltype(z0)));
89*bc73ef00SRichard Smith static_assert(!__is_same(decltype(x2), decltype(z0)));
90*bc73ef00SRichard Smith static_assert(__is_same(decltype(x1), decltype(z1)));
91*bc73ef00SRichard Smith static_assert(__is_same(decltype(x2), decltype(z2)));
92*bc73ef00SRichard Smith static_assert(xP == zP);
93*bc73ef00SRichard Smith #endif
94*bc73ef00SRichard Smith 
95*bc73ef00SRichard Smith static_assert(MultipleLambdas() == 2);
96*bc73ef00SRichard Smith 
97*bc73ef00SRichard Smith // We should not merge the instantiated lambdas from `b.h` and `c.h` together,
98*bc73ef00SRichard Smith // even though they will both have anonymous declaration number #1 within
99*bc73ef00SRichard Smith // A<int> and within the TU, respectively.
100*bc73ef00SRichard Smith 
101*bc73ef00SRichard Smith // CHECK-LABEL: define {{.*}}global_var_init{{.*}} comdat($_Z1NIiLi1EE) {
102*bc73ef00SRichard Smith // CHECK: load i8, ptr @_ZGV1NIiLi1EE, align 8
103*bc73ef00SRichard Smith // CHECK: call {{.*}} i32 @_ZNK1NIiLi1EEMUlvE_clEv(
104*bc73ef00SRichard Smith // CHECK: store i32 {{.*}}, ptr @_Z1NIiLi1EE
105*bc73ef00SRichard Smith 
106*bc73ef00SRichard Smith // CHECK-LABEL: define {{.*}}global_var_init{{.*}} comdat($_ZN1AIiE1NILi1EEE) {
107*bc73ef00SRichard Smith // CHECK: load i8, ptr @_ZGVN1AIiE1NILi1EEE, align 8
108*bc73ef00SRichard Smith // CHECK: call {{.*}} i32 @_ZNK1AIiE1NILi1EEMUlvE_clEv(
109*bc73ef00SRichard Smith // CHECK: store i32 {{.*}}, ptr @_ZN1AIiE1NILi1EEE
110*bc73ef00SRichard Smith 
111*bc73ef00SRichard Smith // CHECK-LABEL: define {{.*}}global_var_init{{.*}} comdat($_Z1NIiLi2EE) {
112*bc73ef00SRichard Smith // CHECK: load i8, ptr @_ZGV1NIiLi2EE, align 8
113*bc73ef00SRichard Smith // CHECK: call {{.*}} i32 @_ZNK1NIiLi2EEMUlvE_clEv(
114*bc73ef00SRichard Smith // CHECK: store i32 {{.*}}, ptr @_Z1NIiLi2EE
115*bc73ef00SRichard Smith 
116*bc73ef00SRichard Smith // CHECK-LABEL: define {{.*}}global_var_init{{.*}} comdat($_ZN1AIiE1NILi2EEE) {
117*bc73ef00SRichard Smith // CHECK: load i8, ptr @_ZGVN1AIiE1NILi2EEE, align 8
118*bc73ef00SRichard Smith // CHECK: call {{.*}} i32 @_ZNK1AIiE1NILi2EEMUlvE_clEv(
119*bc73ef00SRichard Smith // CHECK: store i32 {{.*}}, ptr @_ZN1AIiE1NILi2EEE
120*bc73ef00SRichard Smith 
121