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