| // RUN: rm -rf %t |
| // RUN: split-file %s %t |
| // |
| // RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-module-interface -o %t/M.pcm |
| // RUN: %clang_cc1 -std=c++20 %t/use.cpp -fprebuilt-module-path=%t \ |
| // RUN: -fsyntax-only -verify |
| // |
| // RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-obj -fmodules-reduced-bmi \ |
| // RUN: -fmodule-output=%t/M.pcm -o %t/M.o |
| // RUN: %clang_cc1 -std=c++20 %t/use.cpp -fprebuilt-module-path=%t \ |
| // RUN: -fsyntax-only -verify |
| |
| //--- support.h |
| using size_t = decltype(sizeof(0)); |
| |
| struct placement_tag {}; |
| inline void *operator new(size_t, void *p) { return p; } |
| inline void *operator new(size_t, void *p, placement_tag) { return p; } |
| |
| namespace ranges { |
| struct reverse_fn {}; |
| inline constexpr reverse_fn reverse; |
| |
| template <class Range> |
| bool operator|(Range &&, reverse_fn) { |
| return true; |
| } |
| } // namespace ranges |
| |
| //--- M.cppm |
| module; |
| #include "support.h" |
| export module M; |
| |
| export template <class T> |
| struct box { |
| alignas(T) unsigned char storage[sizeof(T)]; |
| |
| void construct(T value) { ::new (static_cast<void *>(storage)) T(value); } |
| |
| void construct_tagged(T value) { |
| ::new (static_cast<void *>(storage), placement_tag{}) T(value); |
| } |
| |
| bool reverse() { return *this | ranges::reverse; } |
| }; |
| |
| //--- use.cpp |
| // expected-no-diagnostics |
| import M; |
| |
| void use() { |
| box<int> b; |
| b.construct(42); |
| b.construct_tagged(43); |
| (void)b.reverse(); |
| } |