This is an archive of the discontinued LLVM Phabricator instance.

[Draft] [libcxx] introducing std modules
AbandonedPublic

Authored by ChuanqiXu on Oct 7 2022, 7:41 PM.

Details

Reviewers
ldionne
philnik
Mordante
Group Reviewers
Restricted Project
Summary

This is only a draft for asking questions due to I am not familiar with testing infrastructure. No reviewing is required. We need some higher level discussion now.

The main problem I meet now is how can I add another test mode with new macro definitions (or new compiler options).

See test/std_modules/language.support/support.coroutines/end.to.end/generator.pass.cpp and https://github.com/llvm/llvm-project/blob/main/libcxx/test/std/language.support/support.coroutines/end.to.end/generator.pass.cpp, there two differences only:

  • the modules version add another unsupported testing mode: c++20
  • the modules version uses import std; while the original one includes <vector> and <coroutine>.

What I want to achieve is the following one:

// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-coroutines

// See https://llvm.org/PR33271
// UNSUPPORTED: ubsan

#include <cassert>
#include "test_macros.h"

#ifdef USE_STD_MODULES
import std;
#else
#include <coroutine>
#include <vector>
#endif

Then for every testing mode with std version higher than C++20, it will test the file twice. One with the macro USE_STD_MODULES and one without it. But I failed to make it so I am wondering if it is better to ask questions here.

(I updated the discussion in https://discourse.llvm.org/t/maybe-we-could-start-to-play-with-std-modules/64093/15. And the question here should be independent with the concrete implementation methods.)

Diff Detail

Event Timeline

ChuanqiXu created this revision.Oct 7 2022, 7:41 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 7 2022, 7:41 PM
ChuanqiXu requested review of this revision.Oct 7 2022, 7:41 PM
ChuanqiXu edited the summary of this revision. (Show Details)Oct 7 2022, 7:53 PM
ChuanqiXu added reviewers: ldionne, philnik, Mordante, Restricted Project.
ChuanqiXu edited the summary of this revision. (Show Details)Oct 7 2022, 8:36 PM

I think it would be a lot easier to generate dummy headers, which just import std;. These can be used instead of the actual headers in the tests, so we don't have to add an #ifdef for every single test.

libcxx/modules/CMakeLists.txt
18
libcxx/modules/std-coroutine.cppm
1–14

I think it would be nice if we add the sections like this:

module;

#include <coroutine>

export module std:coroutine;

export namespace std {
  // [coroutine.traits]
  using std::coroutine_traits;

  // [coroutine.handle]
  using std::coroutine_handle;

  // [coroutine.handle.compare]
  using std::operator==;
  using std::operator<=>;

  // [coroutine.handle.hash]
  using std::hash;

  // [coroutine.noop]
  using std::noop_coroutine_promise;
  using std::noop_coroutine_handle;
  using std::noop_coroutine;

  // [coroutine.trivial.awaitables]
  using std::suspend_always;
  using std::suspend_never;
}

This makes it a lot easier to compare to the standard, since we already know in which section to look. This will be especially useful for large headers like <algorithm> or <type_traits>.

ChuanqiXu added a comment.EditedOct 8 2022, 2:23 AM

I think it would be a lot easier to generate dummy headers, which just import std;. These can be used instead of the actual headers in the tests, so we don't have to add an #ifdef for every single test.

I don't get your point.. May you elaborate more? The reason why I stopped at the current state is that I feel it is bad to copy the test files. So I can move on if I avoid the copyings.

libcxx/modules/std-coroutine.cppm
1–14

Yeah, I'll follow when this one is not draft.

I think it would be a lot easier to generate dummy headers, which just import std;. These can be used instead of the actual headers in the tests, so we don't have to add an #ifdef for every single test.

I don't get your point.. May you elaborate more? The reason why I stopped at the current state is that I feel it is bad to copy the test files. So I can move on if I avoid the copyings.

The idea is that you generate the public headers, which just import std; instead of the actual headers. i.e. you build the modules with the normal headers. Then you generate all the public headers, which just contain import std;. These get used by the tests. That way as soon as a test #include <public-header> the std module gets imported.

For example, you have an <algorithm> header which contains all the actual stuff and you generate an <algorithm> header which is just:

algorithm
import std;

Then you have a test:

test.pass.cpp
#include <algorithm>

...

That test uses the generated header, so it just imports std instead of including the implementation header. Does that explanation make sense?

I think it would be a lot easier to generate dummy headers, which just import std;. These can be used instead of the actual headers in the tests, so we don't have to add an #ifdef for every single test.

I don't get your point.. May you elaborate more? The reason why I stopped at the current state is that I feel it is bad to copy the test files. So I can move on if I avoid the copyings.

The idea is that you generate the public headers, which just import std; instead of the actual headers. i.e. you build the modules with the normal headers. Then you generate all the public headers, which just contain import std;. These get used by the tests. That way as soon as a test #include <public-header> the std module gets imported.

For example, you have an <algorithm> header which contains all the actual stuff and you generate an <algorithm> header which is just:

algorithm
import std;

Then you have a test:

test.pass.cpp
#include <algorithm>

...

That test uses the generated header, so it just imports std instead of including the implementation header. Does that explanation make sense?

I got your point. It makes sense. The only problem I have now is how to make it.. do you have any ideas?

I got your point. It makes sense. The only problem I have now is how to make it.. do you have any ideas?

I also don't have an immediate solution. But maybe post on our Discord channel @ldionne is more active there and he often has some suggestions.

I got your point. It makes sense. The only problem I have now is how to make it.. do you have any ideas?

I also don't have an immediate solution. But maybe post on our Discord channel @ldionne is more active there and he often has some suggestions.

Oh, I got it. Thanks.

I think it would be a lot easier to generate dummy headers, which just import std;. These can be used instead of the actual headers in the tests, so we don't have to add an #ifdef for every single test.

I don't get your point.. May you elaborate more? The reason why I stopped at the current state is that I feel it is bad to copy the test files. So I can move on if I avoid the copyings.

The idea is that you generate the public headers, which just import std; instead of the actual headers. i.e. you build the modules with the normal headers. Then you generate all the public headers, which just contain import std;. These get used by the tests. That way as soon as a test #include <public-header> the std module gets imported.

For example, you have an <algorithm> header which contains all the actual stuff and you generate an <algorithm> header which is just:

algorithm
import std;

Then you have a test:

test.pass.cpp
#include <algorithm>

...

That test uses the generated header, so it just imports std instead of including the implementation header. Does that explanation make sense?

@philnik Now I have a different idea. I think my proposed solution is better. Since it has higher readability and consistently. The codes behaves the same with its look. And in your suggestion, it may be confusing. Although it saves a little bit typing, I feel the readability may be more important.

ChuanqiXu abandoned this revision.Mar 1 2023, 7:27 PM

Deprecated since we prefer D144994