diff --git a/clang/tools/CMakeLists.txt b/clang/tools/CMakeLists.txt index ae3414e177192..e488112f2ca2d 100644 --- a/clang/tools/CMakeLists.txt +++ b/clang/tools/CMakeLists.txt @@ -15,6 +15,7 @@ add_clang_subdirectory(clang-nvlink-wrapper) add_clang_subdirectory(clang-offload-packager) add_clang_subdirectory(clang-offload-bundler) add_clang_subdirectory(clang-scan-deps) +add_clang_subdirectory(cpp-modules-from-driver) add_clang_subdirectory(clang-sycl-linker) add_clang_subdirectory(clang-installapi) if(HAVE_CLANG_REPL_SUPPORT) diff --git a/clang/tools/cpp-modules-from-driver/CMakeLists.txt b/clang/tools/cpp-modules-from-driver/CMakeLists.txt new file mode 100644 index 0000000000000..ebede8adcb786 --- /dev/null +++ b/clang/tools/cpp-modules-from-driver/CMakeLists.txt @@ -0,0 +1,30 @@ +set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + Core + Option + Support + TargetParser +) + +add_clang_tool(cpp-modules-from-driver + CPPModulesFromDriver.cpp + + DEPENDS + GENERATE_DRIVER +) + +set(CPP_MODULES_FROM_DRIVER_LIB_DEPS + clangAST + clangBasic + clangDependencyScanning + clangDriver + clangFrontend + clangLex + clangSerialization + clangTooling +) + +clang_target_link_libraries(cpp-modules-from-driver + PRIVATE + ${CPP_MODULES_FROM_DRIVER_LIB_DEPS} +) diff --git a/clang/tools/cpp-modules-from-driver/CPPModulesFromDriver.cpp b/clang/tools/cpp-modules-from-driver/CPPModulesFromDriver.cpp new file mode 100644 index 0000000000000..eb2de806cd760 --- /dev/null +++ b/clang/tools/cpp-modules-from-driver/CPPModulesFromDriver.cpp @@ -0,0 +1,90 @@ +#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h" +#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/LLVMDriver.h" + +#include +#include +#include + +using namespace clang; +using namespace clang::tooling; +using namespace clang::tooling::dependencies; +using namespace llvm; + +struct EnsureFinishedConsumer : public DiagnosticConsumer { + bool Finished = false; + void finish() override { Finished = true; } +}; + +int cpp_modules_from_driver_main(int argc, char **, const llvm::ToolContext &) { + StringRef CWD = "/root"; + + auto VFS = new llvm::vfs::InMemoryFileSystem(); + VFS->setCurrentWorkingDirectory(CWD); + auto Sept = llvm::sys::path::get_separator(); + + std::vector Files = { + std::string(llvm::formatv("{0}root{0}header.h", Sept)), + std::string(llvm::formatv("{0}root{0}test.cpp", Sept)), + std::string(llvm::formatv("{0}root{0}test.s", Sept)), + std::string(llvm::formatv("{0}root{0}module.cppm", Sept)), + std::string(llvm::formatv("{0}root{0}main.cpp", Sept)) + }; + + VFS->addFile(Files[0], 0, llvm::MemoryBuffer::getMemBuffer("\n")); + VFS->addFile(Files[1], 0, llvm::MemoryBuffer::getMemBuffer("#include \"header.h\"\n")); + VFS->addFile(Files[2], 0, llvm::MemoryBuffer::getMemBuffer("")); + VFS->addFile(Files[3], 0, llvm::MemoryBuffer::getMemBuffer("export module M;\nexport int foo();\n")); + VFS->addFile(Files[4], 0, llvm::MemoryBuffer::getMemBuffer("#include \"header.h\"\nimport M;\nint main() { return foo(); }\n")); + + DependencyScanningService Service(ScanningMode::DependencyDirectivesScan, + ScanningOutputFormat::Make); + DependencyScanningWorker Worker(Service, VFS); + + for (const auto &File : Files) { + + if (File == Files[2]) { + llvm::outs() << "Skipping assembly file: " << File << "\n"; + continue; + } + + llvm::DenseSet AlreadySeen; + FullDependencyConsumer DC(AlreadySeen); + CallbackActionController AC(nullptr); + + std::vector Args = { + "clang++", + "-target", + "x86_64-unknown-linux-gnu", + "-c", + File, + "-o", + File + ".o" + }; + + EnsureFinishedConsumer DiagConsumer; + bool Success = Worker.computeDependencies(CWD, Args, DC, AC, DiagConsumer); + + if (Success) { + TranslationUnitDeps TU = DC.takeTranslationUnitDeps(); + llvm::outs() << "Dependencies for " << File << ":\n"; + llvm::outs() << " File Dependencies:\n"; + for (const auto &FileDep : TU.FileDeps) { + llvm::outs() << " - " << FileDep << "\n"; + } + llvm::outs() << " Module Dependencies:\n"; + for (const auto &ModuleDep : TU.ClangModuleDeps) { + llvm::outs() << "[log] inside the Module Dependencies loop : "; + llvm::outs() << " - " << "ModuleID{ModuleName: " << ModuleDep.ModuleName + << ", ContextHash: " << ModuleDep.ContextHash << "}" << "\n"; + } + } else { + llvm::errs() << "Failed to compute dependencies for " << File << ".\n"; + } + + llvm::outs() << "Success: " << Success << "\n"; + llvm::outs() << "Diagnostic Consumer Finished: " << DiagConsumer.Finished << "\n"; + } + return 0; +} \ No newline at end of file diff --git a/llvm/utils/gn/secondary/clang/test/BUILD.gn b/llvm/utils/gn/secondary/clang/test/BUILD.gn index 926407fbea2af..f355a8944259e 100644 --- a/llvm/utils/gn/secondary/clang/test/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/test/BUILD.gn @@ -168,6 +168,7 @@ group("test") { "//clang/tools/clang-refactor", "//clang/tools/clang-repl", "//clang/tools/clang-scan-deps", + "//clang/tools/cpp-modules-from-driver", "//clang/tools/clang-sycl-linker", "//clang/tools/diagtool", "//clang/tools/driver:symlinks",