brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 077f69e Raw
150 lines · cpp
1// RUN: rm -fR %t2// RUN: split-file %s %t3// RUN: cd %t4// RUN: %clang_cc1 -std=c++20 -xc++ -emit-module -fmodules foo.cppmap -fmodule-name=foo -fmodule-name=foo -o foo.pcm5// RUN: %clang_cc1 -std=c++20 -xc++ -emit-module -fmodules bar.cppmap -fmodule-name=bar -o bar.pcm6// RUN: %clang_cc1 -std=c++20 -xc++ -emit-module -fmodules experiment_context.cppmap -fmodule-name=experiment_context -fmodule-file=foo.pcm -fmodule-file=bar.pcm -o experiment_context.pcm7// RUN: %clang_cc1 -verify -std=c++20 -xc++ -fmodule-file=experiment_context.pcm experiment_context_test.cc -o experiment_context_test.o8 9// https://github.com/llvm/llvm-project/issues/14158210//--- bar.cppmap11module "bar" {12  export *13  header "co.h"14}15 16//--- foo.cppmap17module "foo" {18  export *19  header "co.h"20}21 22//--- experiment_context.cppmap23module "experiment_context" {24  export *25  header "lazy.h"26 27  use "foo"28  use "bar"29}30 31//--- experiment_context_test.cc32// expected-no-diagnostics33#include "lazy.h"34 35namespace c9 {36 37template <typename T>38void WaitForCoroutine() {39  MakeCo<T>([]() -> Co<void> {40    co_return;41  });42}43 44void test() {45  c9::WaitForCoroutine<void>();46}47}48 49//--- lazy.h50#pragma once51 52#include "co.h"53 54namespace c9 {55template <typename T, typename F>56Co<T> MakeCo(F f)57{58  co_return co_await f();59}60}61 62inline c9::Co<void> DoNothing() { co_return; }63 64 65//--- co.h66#pragma  once67namespace std {68 69template <class _Ret, class... _Args>70struct coroutine_traits {};71 72template <typename Ret, typename... Args>73  requires requires { typename Ret::promise_type; }74struct coroutine_traits<Ret, Args...> {75  using promise_type = typename Ret::promise_type;76};77 78template <typename Promise = void>79struct coroutine_handle;80 81template <>82struct coroutine_handle<void> {};83 84template <typename Promise = void>85struct coroutine_handle : coroutine_handle<> {86  static coroutine_handle from_address(void *addr);87};88 89struct suspend_always {90  bool await_ready() noexcept;91  void await_suspend(coroutine_handle<>) noexcept;92  void await_resume() noexcept;93};94 95}  // namespace std96 97namespace c9 {98 99template <typename T>100class Co;101 102namespace internal {103 104template <typename T>105class CoroutinePromise {106 public:107  template <typename... Args>108  explicit CoroutinePromise(Args&&... args) {109    // Ensure that the 'dummy_color' VarDecl referenced by the inner DeclRefExpr110    // is the same declaration as the one outside the lambda.111    // This is guaranteed because both CoroutinePromise and the lambda's call operator112    // (CXXMethodDecl) are loaded from the same module.113    const int dummy_color = 1;114    [&]{ (void)dummy_color; }();115  }116 117  ~CoroutinePromise();118  void return_void();119  auto get_return_object() {120    return Co<T>();121  }122  void unhandled_exception();123  std::suspend_always  initial_suspend();124 125  struct result_t {126    ~result_t();127    bool await_ready() const noexcept;128    void await_suspend(std::coroutine_handle<void>) noexcept;129    void await_resume() const noexcept;130  };131 132  template <typename U>133  result_t await_transform(Co<U> co);134 135  std::suspend_always final_suspend() noexcept;136};137}  // namespace internal138 139template <typename T>140class Co {141 public:142  using promise_type = internal::CoroutinePromise<void>;143};144 145class CoIncomingModuleBase {146 public:147    Co<void> CoAfterFinish() { co_return; }148};149}  // namespace c9150