-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Support C++20 Modules in clang-repl #79261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-modules Author: Chuanqi Xu (ChuanqiXu9) ChangesThis comes from when I playing around clang-repl with moduels : ) I succeeded to import std with https://libcxx.llvm.org/Modules.html and calling I want to put the documentation part to https://clang.llvm.org/docs/StandardCPlusPlusModules.html in a separate commit. Full diff: https://github.com/llvm/llvm-project/pull/79261.diff 4 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fc7511e9136734..db3d74e124e7d1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -191,6 +191,8 @@ Crash and bug fixes
Improvements
^^^^^^^^^^^^
+- Support importing C++20 modules in clang-repl.
+
Moved checkers
^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 8fc75e1cca0399..1e671a7c460163 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -485,7 +485,7 @@ VALUE_LANGOPT(FuchsiaAPILevel, 32, 0, "Fuchsia API level")
// on large _BitInts.
BENIGN_VALUE_LANGOPT(MaxBitIntWidth, 32, 128, "Maximum width of a _BitInt")
-LANGOPT(IncrementalExtensions, 1, 0, " True if we want to process statements"
+COMPATIBLE_LANGOPT(IncrementalExtensions, 1, 0, " True if we want to process statements"
"on the global scope, ignore EOF token and continue later on (thus "
"avoid tearing the Lexer and etc. down). Controlled by "
"-fincremental-extensions.")
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index a149d82153037f..867f4c47eaeceb 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3286,10 +3286,10 @@ DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader,
if (auto *OID = dyn_cast<ObjCInterfaceDecl>(DC))
return OID->getDefinition();
- // We can see the TU here only if we have no Sema object. In that case,
- // there's no TU scope to look in, so using the DC alone is sufficient.
+ // We can see the TU here only if we have no Sema object. It is possible
+ // we're in clang-repl so we still need to get the primary context.
if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
- return TU;
+ return TU->getPrimaryContext();
return nullptr;
}
diff --git a/clang/test/Interpreter/cxx20-modules.cppm b/clang/test/Interpreter/cxx20-modules.cppm
new file mode 100644
index 00000000000000..bc2b722f6b5197
--- /dev/null
+++ b/clang/test/Interpreter/cxx20-modules.cppm
@@ -0,0 +1,31 @@
+// UNSUPPORTED: system-aix
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang -std=c++20 %t/mod.cppm --precompile \
+// RUN: -o %t/mod.pcm
+// RUN: %clang %t/mod.pcm -c -o %t/mod.o
+// RUN: %clang -shared %t/mod.o -o %t/libmod.so
+//
+// RUN: cat %t/import.cpp | env LD_LIBRARY_PATH=%t:$LD_LIBRARY_PATH \
+// RUN: clang-repl -Xcc=-std=c++20 -Xcc=-fmodule-file=M=%t/mod.pcm \
+// RUN: | FileCheck %t/import.cpp
+
+//--- mod.cppm
+export module M;
+export const char* Hello() {
+ return "Hello Interpreter for Modules!";
+}
+
+//--- import.cpp
+
+%lib libmod.so
+
+import M;
+
+extern "C" int printf(const char *, ...);
+printf("%s\n", Hello());
+
+// CHECK: Hello Interpreter for Modules!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm! Thank you @ChuanqiXu9!
Hi @ChuanqiXu9, the test you added is failing on the PS4 bot because for the PS4 target, it requires an external linker which is not present/available. Can the test be rewritten to not require linking? https://lab.llvm.org/buildbot/#/builders/139/builds/57928
|
Oh, maybe I need to add more requires to the test. I tried to handle it in c125965. It shouldn't fail on PS4 any more. |
The previous test can't work on other platforms like PS4. Address the comments in #79261 (comment)
For what it's worth, this test appears to fail when
|
Thanks. But I am not sure how should I change the test. Do you have any idea or suggestion? |
Perhaps we are not propagating the correct triple down to the module build action? |
It looks true but the test does the same thing as other tests to build modules |
This is out of my wheelhouse to debug to be honest but it seems to me that |
We pass the CompilerInstance's notion of the target triple this commit explains it: 49f9532 @nathanchance, can |
@vgvassilev Yes, it appears so, I tried one of the examples from the documentation since I have no prior experience with
|
Normal clang creates a driver using the default target triple here: llvm-project/clang/tools/driver/driver.cpp Line 485 in 754a8ad
clang-repl appears to use IncrementalCompilerBuilder, which uses llvm-project/clang/lib/Interpreter/Interpreter.cpp Lines 165 to 166 in 754a8ad
getProcessTriple() is based on LLVM_HOST_TRIPLE with some fixups. I'm not really sure what the right fix here is. It makes sense that an interpreter uses the host triple by default, but it's also a problem that clang and clang-repl use different default triples. |
@nikic, thanks for the details! Until this change we sailed fairly well. It seems that the pcm rigorously records the clang notion of the triple which is probably what we want. However, if we are building a pcm in the context of |
Looks like it doesn't work when the default host triple is changed: llvm/llvm-project#79261
The pcm here is being generated by clang, not by clang-repl, so I'm not sure how we would know that we need to switch the triple. |
We have a |
But the change itself is to make |
I am wondering if it helps if we specify the target triple in the test, then it won't be so troublesome. |
I mean conditionally if
I was wondering that too. Can we express that in lit? |
I am not sure if it is possible since we don't know the clang fork before we see the import. Even if we can, it is more or less problematic if there are multiple imported module from different fork.
For But due to I can't reproduce the failure, @nathanchance would you like to make this? I don't want to make something that I can't test. |
I can find arguments in changing the clang-repl target triple to match the loaded module… That would have some reasoning but maybe we won’t be able to start the jit if the triples are too different. |
I don't mind submitting something if I have some guidance around how this should be handled (I am a little lost in this thread at the moment). Alternatively, I am able to reproduce this with: ( $ cmake \
-B build \
-G Ninja \
-S llvm \
-Wno-dev \
--log-level=NOTICE \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DLLVM_DEFAULT_TARGET_TRIPLE=$(/usr/bin/clang -print-target-triple) \
-DLLVM_ENABLE_PROJECTS=clang \
-DLLVM_USE_LINKER=lld
$ ninja -C build check-clang
...
error: PCH file was compiled for the target 'x86_64-pc-linux-gnu' but the current translation unit is being compiled for target 'x86_64-unknown-linux-gnu'
error: module file .../tools/clang/test/Interpreter/Output/cxx20-modules.cppm.tmp/mod.pcm cannot be loaded due to a configuration mismatch with the current compilation [-Wmodule-file-config-mismatch]
error: Parsing failed.
... so it should be easy to test and verify the fix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I had in mind
// RUN: %clang -std=c++20 %t/mod.cppm --precompile \ | ||
// RUN: -o %t/mod.pcm | ||
// RUN: %clang %t/mod.pcm -c -o %t/mod.o | ||
// RUN: %clang -shared %t/mod.o -o %t/libmod.so | ||
// | ||
// RUN: cat %t/import.cpp | env LD_LIBRARY_PATH=%t:$LD_LIBRARY_PATH \ | ||
// RUN: clang-repl -Xcc=-std=c++20 -Xcc=-fmodule-file=M=%t/mod.pcm \ | ||
// RUN: | FileCheck %t/import.cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// RUN: %clang -std=c++20 %t/mod.cppm --precompile
// RUN: -o %t/mod.pcm -triple=x86_64-linux-gnu
// RUN: %clang %t/mod.pcm -c -o %t/mod.o -triple=x86_64-linux-gnu
// RUN: %clang -shared %t/mod.o -o %t/libmod.so -triple=x86_64-linux-gnu
//
// RUN: cat %t/import.cpp | env LD_LIBRARY_PATH=%t:$LD_LIBRARY_PATH
// RUN: clang-repl -Xcc=-std=c++20 -Xcc=-fmodule-file=M=%t/mod.pcm
// RUN: -Xcc=-triple=x86_64-linux-gnu | FileCheck %t/import.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nathanchance this is what I expected to test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
diff --git a/clang/test/Interpreter/cxx20-modules.cppm b/clang/test/Interpreter/cxx20-modules.cppm
index 2c6eba525519..cd2b04fdc547 100644
--- a/clang/test/Interpreter/cxx20-modules.cppm
+++ b/clang/test/Interpreter/cxx20-modules.cppm
@@ -6,13 +6,13 @@
// RUN: split-file %s %t
//
// RUN: %clang -std=c++20 %t/mod.cppm --precompile \
-// RUN: -o %t/mod.pcm
-// RUN: %clang %t/mod.pcm -c -o %t/mod.o
-// RUN: %clang -shared %t/mod.o -o %t/libmod.so
+// RUN: -o %t/mod.pcm --target=x86_64-linux-gnu
+// RUN: %clang %t/mod.pcm -c -o %t/mod.o --target=x86_64-linux-gnu
+// RUN: %clang -shared %t/mod.o -o %t/libmod.so --target=x86_64-linux-gnu
//
// RUN: cat %t/import.cpp | env LD_LIBRARY_PATH=%t:$LD_LIBRARY_PATH \
// RUN: clang-repl -Xcc=-std=c++20 -Xcc=-fmodule-file=M=%t/mod.pcm \
-// RUN: | FileCheck %t/import.cpp
+// RUN: -Xcc=--target=x86_64-linux-gnu | FileCheck %t/import.cpp
//--- mod.cppm
export module M;
appears to work for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good, would you like to land it? Or I will do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can land it, thanks for continuing to chase this!
See #79261 for details. It shows that clang-repl uses a different target triple with clang so that it may be problematic if the calng-repl reads the generated BMI from clang in a different target triple. While the underlying issue is not easy to fix, this patch tries to make this test green to not bother developers.
@vgvassilev It appears that this PR added an entry to the Static Analyzer section, and I'm not sure if that's the right one. |
Do you mean the documentation? If so, yes, that’s probably not the right place. I am on my phone but can you suggest a place where we should move this or just move it? I think that was an oversight. |
Thanks. There is nothing urgent. I was just preparing a PR for syncing the release notes with what we actually did in CSA, so I realized this. I wanted to check first if you already have a well established place/section where you would prefer to have this, as I couldn't find one in 3 seconds. (The release branch is supposed to branch off on the 23rd of July) |
Oh, understood. Perhaps would be better if you move it. I am currently on vacation for a while… |
Let's just move these under the `Non-comprehensive list of changes in this release` section. Resolves: - #79261 (comment) - #65484 (comment)
Let's just move these under the `Non-comprehensive list of changes in this release` section. Resolves: - llvm#79261 (comment) - llvm#65484 (comment)
Let's just move these under the `Non-comprehensive list of changes in this release` section. Resolves: - llvm#79261 (comment) - llvm#65484 (comment)
This comes from when I playing around clang-repl with moduels : )
I succeeded to import std with https://libcxx.llvm.org/Modules.html and calling
std::printf
after this patch.I want to put the documentation part to https://clang.llvm.org/docs/StandardCPlusPlusModules.html in a separate commit.