xref: /llvm-project/clang/test/Modules/friend-inline-function-body.cpp (revision 38b3d87bd384a469a6618ec6a971352cb4f813ba)
1 // RUN: rm -fR %t
2 // RUN: split-file %s %t
3 // RUN: cd %t
4 // RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -xc++ -emit-module -fmodule-name=internal modules.map -o internal.pcm
5 // RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -xc++ -emit-module -fmodule-name=interface modules.map -o interface.pcm
6 // RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -xc++ -emit-module -fmodule-name=foo modules.map -o foo.pcm -fmodule-file=interface.pcm -fmodule-file=internal.pcm
7 // RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -O1 -emit-obj main.cc -verify -fmodule-file=foo.pcm
8 
9 //--- modules.map
10 module "interface" {
11   export *
12   module "interface.h" {
13     export *
14     header "interface.h"
15   }
16 }
17 
18 module "internal" {
19   export *
20   module "internal.h" {
21     export *
22     header "internal.h"
23   }
24 }
25 
26 module "foo" {
27   export *
28   module "foo.h" {
29     export *
30     header "foo.h"
31   }
32 }
33 
34 //--- foo.h
35 #ifndef FOO_H
36 #define FOO_H
37 
38 #include "strong_int.h"
39 
40 DEFINE_STRONG_INT_TYPE(CallbackId, int);
41 
42 #define CALL_HASH(id) \
43   (void)[&]() { AbslHashValue(0, id); };
44 
45 void test(CallbackId id) {
46   CALL_HASH(id);
47 }
48 
49 #include "internal.h"
50 #include "interface.h"
51 
52 #endif
53 
54 //--- interface.h
55 #ifndef INTERFACE_H
56 #define INTERFACE_H
57 
58 #include "strong_int.h"
59 
60 DEFINE_STRONG_INT_TYPE(EndpointToken, int);
61 
62 #endif
63 
64 //--- internal.h
65 #ifndef INTERNAL_H
66 #define INTERNAL_H
67 
68 #include "strong_int.h"
69 
70 DEFINE_STRONG_INT_TYPE(OrderedListSortKey, int);
71 DEFINE_STRONG_INT_TYPE(OrderedListId, int);
72 
73 #endif
74 
75 //--- strong_int.h
76 #ifndef STRONG_INT_H
77 #define STRONG_INT_H
78 
79 namespace util_intops {
80 
81 template <typename TagType, typename NativeType>
82 class StrongInt2;
83 
84 template <typename TagType, typename NativeType>
85 class StrongInt2 {
86  public:
87   template <typename H>
88   friend H AbslHashValue(H h, const StrongInt2& i) {
89     return h;
90   }
91 };
92 
93 }  // namespace util_intops
94 
95 #define DEFINE_STRONG_INT_TYPE(type_name, value_type)                        \
96   struct type_name##_strong_int_tag_ {};                                     \
97   typedef ::util_intops::StrongInt2<type_name##_strong_int_tag_, value_type> \
98       type_name;
99 
100 #endif
101 
102 //--- main.cc
103 // expected-no-diagnostics
104 #include "foo.h"
105 
106 #include "strong_int.h"
107 
108 DEFINE_STRONG_INT_TYPE(ArchiveId2, int);
109 void partial(ArchiveId2 id) {
110   CALL_HASH(id);
111 }
112