Index: lit/Reproducer/Inputs/ModuleCapture.in =================================================================== --- lit/Reproducer/Inputs/ModuleCapture.in +++ lit/Reproducer/Inputs/ModuleCapture.in @@ -0,0 +1,2 @@ +expr -- @import Cocoa +reproducer generate Index: lit/Reproducer/TestClangFileRepro.test =================================================================== --- lit/Reproducer/TestClangFileRepro.test +++ lit/Reproducer/TestClangFileRepro.test @@ -0,0 +1,8 @@ +# REQUIRES: system-darwin +# +# This tests that modules files from clang end up in the reproducer. +# +# RUN: %lldb -x -b -s %S/Inputs/ModuleCapture.in --capture %t.repro +# cat %t.repro/files.yaml | FileCheck %s +# +# CHECK: Cocoa.h Index: source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -54,15 +54,15 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Signals.h" -#include "ClangDiagnostic.h" -#include "ClangExpressionParser.h" - #include "ClangASTSource.h" +#include "ClangDiagnostic.h" #include "ClangExpressionDeclMap.h" #include "ClangExpressionHelper.h" +#include "ClangExpressionParser.h" #include "ClangModulesDeclVendor.h" #include "ClangPersistentVariables.h" #include "IRForTarget.h" +#include "ModuleDependencyCollector.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" @@ -84,6 +84,7 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Reproducer.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringList.h" @@ -250,6 +251,19 @@ // 1. Create a new compiler instance. m_compiler.reset(new CompilerInstance()); + + // When capturing a reproducer, hook up the file collector with clang to + // collector modules and headers. + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { + repro::FileProvider &fp = g->GetOrCreate(); + m_compiler->setModuleDepCollector( + std::make_shared( + fp.GetFileCollector())); + DependencyOutputOptions &opts = m_compiler->getDependencyOutputOpts(); + opts.IncludeSystemHeaders = true; + opts.IncludeModuleFiles = true; + } + lldb::LanguageType frame_lang = expr.Language(); // defaults to lldb::eLanguageTypeUnknown bool overridden_target_opts = false; Index: source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -22,6 +22,7 @@ #include "ClangHost.h" #include "ClangModulesDeclVendor.h" +#include "ModuleDependencyCollector.h" #include "lldb/Core/ModuleList.h" #include "lldb/Host/Host.h" @@ -31,6 +32,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Reproducer.h" #include "lldb/Utility/StreamString.h" using namespace lldb_private; @@ -631,6 +633,18 @@ std::unique_ptr instance( new clang::CompilerInstance); + // When capturing a reproducer, hook up the file collector with clang to + // collector modules and headers. + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { + repro::FileProvider &fp = g->GetOrCreate(); + instance->setModuleDepCollector( + std::make_shared( + fp.GetFileCollector())); + clang::DependencyOutputOptions &opts = instance->getDependencyOutputOpts(); + opts.IncludeSystemHeaders = true; + opts.IncludeModuleFiles = true; + } + instance->setDiagnostics(diagnostics_engine.get()); instance->setInvocation(invocation); Index: source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h =================================================================== --- source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h +++ source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h @@ -0,0 +1,38 @@ +//===-- ModuleDependencyCollector.h -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ModuleDependencyCollector_h_ +#define liblldb_ModuleDependencyCollector_h_ + +#include "lldb/Utility/FileCollector.h" +#include "clang/Frontend/Utils.h" +#include "llvm/ADT/StringRef.h" + +namespace lldb_private { +class ModuleDependencyCollectorAdaptor + : public clang::ModuleDependencyCollector { +public: + ModuleDependencyCollectorAdaptor(FileCollector &file_collector) + : clang::ModuleDependencyCollector(""), m_file_collector(file_collector) { + } + + void addFile(llvm::StringRef Filename, + llvm::StringRef FileDst = {}) override { + m_file_collector.AddFile(Filename); + } + + bool insertSeen(llvm::StringRef Filename) override { return false; } + void addFileMapping(llvm::StringRef VPath, llvm::StringRef RPath) override {} + void writeFileMap() override {} + +private: + FileCollector &m_file_collector; +}; +} // namespace lldb_private + +#endif