clangd seems to be unable to properly deserialize a source file that has both include and import declarations, therefore it assumes that there are ODR violations in my code. Nevertheless, code compiles and runs properly without any warnings, how do I fix clangd comments?
As a dummy model, imagine that I have this simple module:
// some_module.cpp
module;
#include <string>
export module SomeModule;
export std::string HelloWorld() {
return "Hello, World!";
}
Now I want to use it, but clangd keeps complaining that I broke ODR:
// main.cpp
#include <iostream>
import SomeModule; // clangd complaint:
// in included file: 'std::basic_string' has different definitions
// in different modules; first difference is definition in
// module 'SomeModule.<global>' found template parameter
// with no default argument (module_odr_violation_template_parameter)
int main() {
std::cout << HelloWorld() << std::endl;
return 0;
}
How do I fix this issue? Where do I look?
[EDIT] Includes in both primary module interface and in main are done properly and according to LLVM recommendations (e.g. includes only in global module fragments and includes before imports):Hence the question is not about how to properly use includes with imports (clang-17 compiles provided code perfectly), but rather how to configure clangd to stop emitting odr errors
P.S.
Here is my CMakeLists.txt (whole code is available on github)
# CMakeLists.txt
cmake_minimum_required(VERSION 3.28)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(example CXX)
add_executable(main
main.cpp
)
target_sources(main
PUBLIC FILE_SET modules TYPE CXX_MODULES FILES
some_module.cpp
)
Here is response of standalone clangd diagnostics:
~: clangd --compile-commands-dir=build --check=main.cpp I[13:41:01.950] clangd version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
I[13:41:01.950] Features: linux
I[13:41:01.950] PID: 14364
I[13:41:01.950] Working directory: /home/zhantaram/Prog/example
I[13:41:01.950] argv[0]: clangd
I[13:41:01.950] argv[1]: --compile-commands-dir=build
I[13:41:01.950] argv[2]: --check=main.cpp
I[13:41:01.950] Entering check mode (no LSP server)
I[13:41:01.950] Testing on source file /home/zhantaram/Prog/example/main.cpp
I[13:41:01.951] Loading compilation database...
I[13:41:01.951] Loaded compilation database from /home/zhantaram/Prog/example/build/compile_commands.json
I[13:41:01.952] Compile command from CDB is: [/home/zhantaram/Prog/example/build] /home/zhantaram/.installer/clang/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04/bin/clang++ --driver-mode=g++ -std=gnu++20 -fmodule-file=SomeModule=CMakeFiles/main.dir/SomeModule.pcm -o CMakeFiles/main.dir/main.cpp.o -c -std=c++20 -resource-dir=/home/zhantaram/.installer/clang/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04/lib/clang/17 -- /home/zhantaram/Prog/example/main.cpp
I[13:41:01.952] Parsing command...
I[13:41:01.955] internal (cc1) args are: -cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/zhantaram/Prog/example/build -resource-dir /home/zhantaram/.installer/clang/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04/lib/clang/17 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/backward -internal-isystem /home/zhantaram/.installer/clang/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c++20 -fdeprecated-macro -fdebug-compilation-dir=/home/zhantaram/Prog/example/build -ferror-limit 19 -fgnuc-version=4.2.1 -fno-implicit-modules -fmodule-file=SomeModule=CMakeFiles/main.dir/SomeModule.pcm -fcxx-exceptions -fexceptions -no-round-trip-args -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -x c++ /home/zhantaram/Prog/example/main.cpp
I[13:41:01.956] Building preamble...
I[13:41:02.356] Built preamble of size 5050620 for file /home/zhantaram/Prog/example/main.cpp version null in 0.40 seconds
I[13:41:02.356] Indexing headers...
I[13:41:02.424] Building AST...
E[13:41:02.445] [module_odr_violation_template_parameter] Line 3: in included file: 'std::basic_string' has different definitions in different modules; first difference is definition in module 'SomeModule.<global>' found template parameter with no default argument
I[13:41:02.445] Indexing AST...
I[13:41:02.445] Building inlay hints
I[13:41:02.445] Building semantic highlighting
I[13:41:02.445] Testing features at each token (may be slow in large files)
I[13:41:02.451] All checks completed, 1 errors
Here is compilation database dumped by cmake:
# compile_commands.json
[
{
"directory": "/home/zhantaram/Prog/example/build",
"command": "/home/zhantaram/.installer/clang/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04/bin/clang++ -std=gnu++20 @CMakeFiles/main.dir/main.cpp.o.modmap -o CMakeFiles/main.dir/main.cpp.o -c /home/zhantaram/Prog/example/main.cpp",
"file": "/home/zhantaram/Prog/example/main.cpp",
"output": "CMakeFiles/main.dir/main.cpp.o"
},
{
"directory": "/home/zhantaram/Prog/example/build",
"command": "/home/zhantaram/.installer/clang/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04/bin/clang++ -std=gnu++20 @CMakeFiles/main.dir/some_module.cpp.o.modmap -o CMakeFiles/main.dir/some_module.cpp.o -c /home/zhantaram/Prog/example/some_module.cpp",
"file": "/home/zhantaram/Prog/example/some_module.cpp",
"output": "CMakeFiles/main.dir/some_module.cpp.o"
}
]
2
Answers
So apparently, as of version 17.0.6 of clangd, module support is not complete:
https://github.com/clangd/clangd/issues/1892#issuecomment-1875850961
Problem in question may or may not be solved with upcoming releases or even in development branch, when this umbrella task gets resolved:
https://github.com/clangd/clangd/issues/1293
You need to encapsulates C++ standard library into a new module. You may check this project: infinity, which already fully adopted C++20 Modules. This file shows how to encapsulates C++ standard library. This file show how to encapsulates third_party source code.