Skip to content

[clang] Extract CompilerInstance creation out of compileModuleImpl() #134887

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

Merged
merged 7 commits into from
Apr 11, 2025

Conversation

jansvoboda11
Copy link
Contributor

This PR extracts the creation of CompilerInstance for compiling an implicitly-discovered module out of compileModuleImpl() into its own separate function and passes it into compileModuleImpl() from the outside. This makes the instance creation logic reusable (useful for my experiments) and also simplifies the API, removing the PreBuildStep and PostBuildStep hooks from compileModuleImpl().

@jansvoboda11
Copy link
Contributor Author

The only non-NFC change I'm aware of is that the err_module_rebuild_finalized diagnostic is now only emitted by compileModule() and not by CompilerInstance::createModuleFromSource(). I believe that's fine, since that's only used from #pragma clang module build/endbuild intended for debugging, but I can copy it around to remove that difference too.

@llvmbot llvmbot added the clang Clang issues not falling into any other category label Apr 8, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 8, 2025

@llvm/pr-subscribers-clang

Author: Jan Svoboda (jansvoboda11)

Changes

This PR extracts the creation of CompilerInstance for compiling an implicitly-discovered module out of compileModuleImpl() into its own separate function and passes it into compileModuleImpl() from the outside. This makes the instance creation logic reusable (useful for my experiments) and also simplifies the API, removing the PreBuildStep and PostBuildStep hooks from compileModuleImpl().


Full diff: https://github.com/llvm/llvm-project/pull/134887.diff

1 Files Affected:

  • (modified) clang/lib/Frontend/CompilerInstance.cpp (+155-127)
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 9cab17ae70eeb..62fff9e2397a1 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1138,41 +1138,16 @@ void CompilerInstance::LoadRequestedPlugins() {
   }
 }
 
-/// Determine the appropriate source input kind based on language
-/// options.
-static Language getLanguageFromOptions(const LangOptions &LangOpts) {
-  if (LangOpts.OpenCL)
-    return Language::OpenCL;
-  if (LangOpts.CUDA)
-    return Language::CUDA;
-  if (LangOpts.ObjC)
-    return LangOpts.CPlusPlus ? Language::ObjCXX : Language::ObjC;
-  return LangOpts.CPlusPlus ? Language::CXX : Language::C;
-}
-
-/// Compile a module file for the given module, using the options
-/// provided by the importing compiler instance. Returns true if the module
-/// was built without errors.
-static bool
-compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
-                  StringRef ModuleName, FrontendInputFile Input,
-                  StringRef OriginalModuleMapFile, StringRef ModuleFileName,
-                  llvm::function_ref<void(CompilerInstance &)> PreBuildStep =
-                      [](CompilerInstance &) {},
-                  llvm::function_ref<void(CompilerInstance &)> PostBuildStep =
-                      [](CompilerInstance &) {}) {
-  llvm::TimeTraceScope TimeScope("Module Compile", ModuleName);
-
-  // Never compile a module that's already finalized - this would cause the
-  // existing module to be freed, causing crashes if it is later referenced
-  if (ImportingInstance.getModuleCache().getInMemoryModuleCache().isPCMFinal(
-          ModuleFileName)) {
-    ImportingInstance.getDiagnostics().Report(
-        ImportLoc, diag::err_module_rebuild_finalized)
-        << ModuleName;
-    return false;
-  }
-
+/// Creates a \c CompilerInstance for compiling a module.
+///
+/// This expects a properly initialized \c FrontendInputFile.
+static std::unique_ptr<CompilerInstance>
+createCompilerInstanceForModuleCompileImpl(CompilerInstance &ImportingInstance,
+                                           SourceLocation ImportLoc,
+                                           StringRef ModuleName,
+                                           FrontendInputFile Input,
+                                           StringRef OriginalModuleMapFile,
+                                           StringRef ModuleFileName) {
   // Construct a compiler invocation for creating this module.
   auto Invocation =
       std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation());
@@ -1226,8 +1201,11 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
   // module.  Since we're sharing an in-memory module cache,
   // CompilerInstance::CompilerInstance is responsible for finalizing the
   // buffers to prevent use-after-frees.
-  CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),
-                            &ImportingInstance.getModuleCache());
+  auto InstancePtr = std::make_unique<CompilerInstance>(
+      ImportingInstance.getPCHContainerOperations(),
+      &ImportingInstance.getModuleCache());
+  auto &Instance = *InstancePtr;
+
   auto &Inv = *Invocation;
   Instance.setInvocation(std::move(Invocation));
 
@@ -1267,45 +1245,19 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
   Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector());
   Inv.getDependencyOutputOpts() = DependencyOutputOptions();
 
-  ImportingInstance.getDiagnostics().Report(ImportLoc,
-                                            diag::remark_module_build)
-    << ModuleName << ModuleFileName;
-
-  PreBuildStep(Instance);
-
-  // Execute the action to actually build the module in-place. Use a separate
-  // thread so that we get a stack large enough.
-  bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnThread(
-      [&]() {
-        GenerateModuleFromModuleMapAction Action;
-        Instance.ExecuteAction(Action);
-      },
-      DesiredStackSize);
-
-  PostBuildStep(Instance);
-
-  ImportingInstance.getDiagnostics().Report(ImportLoc,
-                                            diag::remark_module_build_done)
-    << ModuleName;
-
-  // Propagate the statistics to the parent FileManager.
-  if (!FrontendOpts.ModulesShareFileManager)
-    ImportingInstance.getFileManager().AddStats(Instance.getFileManager());
-
-  if (Crashed) {
-    // Clear the ASTConsumer if it hasn't been already, in case it owns streams
-    // that must be closed before clearing output files.
-    Instance.setSema(nullptr);
-    Instance.setASTConsumer(nullptr);
-
-    // Delete any remaining temporary files related to Instance.
-    Instance.clearOutputFiles(/*EraseFiles=*/true);
-  }
+  return InstancePtr;
+}
 
-  // If \p AllowPCMWithCompilerErrors is set return 'success' even if errors
-  // occurred.
-  return !Instance.getDiagnostics().hasErrorOccurred() ||
-         Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
+/// Determine the appropriate source input kind based on language
+/// options.
+static Language getLanguageFromOptions(const LangOptions &LangOpts) {
+  if (LangOpts.OpenCL)
+    return Language::OpenCL;
+  if (LangOpts.CUDA)
+    return Language::CUDA;
+  if (LangOpts.ObjC)
+    return LangOpts.CPlusPlus ? Language::ObjCXX : Language::ObjC;
+  return LangOpts.CPlusPlus ? Language::CXX : Language::C;
 }
 
 static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File,
@@ -1321,20 +1273,24 @@ static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File,
   return FileMgr.getOptionalFileRef(PublicFilename);
 }
 
-/// Compile a module file for the given module in a separate compiler instance,
-/// using the options provided by the importing compiler instance. Returns true
-/// if the module was built without errors.
-static bool compileModule(CompilerInstance &ImportingInstance,
-                          SourceLocation ImportLoc, Module *Module,
-                          StringRef ModuleFileName) {
+/// Creates a \c CompilerInstance for compiling a module.
+///
+/// This takes care of creating appropriate \c FrontendInputFile for
+/// public/private frameworks, inferred modules and such.
+static std::unique_ptr<CompilerInstance>
+createCompilerInstanceForModuleCompile(CompilerInstance &ImportingInstance,
+                                       SourceLocation ImportLoc, Module *Module,
+                                       StringRef ModuleFileName) {
+  StringRef ModuleName = Module->getTopLevelModuleName();
+
   InputKind IK(getLanguageFromOptions(ImportingInstance.getLangOpts()),
                InputKind::ModuleMap);
 
   // Get or create the module map that we'll use to build this module.
-  ModuleMap &ModMap
-    = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
+  ModuleMap &ModMap =
+      ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
   SourceManager &SourceMgr = ImportingInstance.getSourceManager();
-  bool Result;
+
   if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID(Module);
       ModuleMapFID.isValid()) {
     // We want to use the top-level module map. If we don't, the compiling
@@ -1368,44 +1324,115 @@ static bool compileModule(CompilerInstance &ImportingInstance,
     bool IsSystem = isSystem(SLoc.getFile().getFileCharacteristic());
 
     // Use the module map where this module resides.
-    Result = compileModuleImpl(
-        ImportingInstance, ImportLoc, Module->getTopLevelModuleName(),
+    return createCompilerInstanceForModuleCompileImpl(
+        ImportingInstance, ImportLoc, ModuleName,
         FrontendInputFile(ModuleMapFilePath, IK, IsSystem),
         ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName);
-  } else {
-    // FIXME: We only need to fake up an input file here as a way of
-    // transporting the module's directory to the module map parser. We should
-    // be able to do that more directly, and parse from a memory buffer without
-    // inventing this file.
-    SmallString<128> FakeModuleMapFile(Module->Directory->getName());
-    llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map");
-
-    std::string InferredModuleMapContent;
-    llvm::raw_string_ostream OS(InferredModuleMapContent);
-    Module->print(OS);
-
-    Result = compileModuleImpl(
-        ImportingInstance, ImportLoc, Module->getTopLevelModuleName(),
-        FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem),
-        ModMap.getModuleMapFileForUniquing(Module)->getName(),
-        ModuleFileName,
-        [&](CompilerInstance &Instance) {
-      std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
-          llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
-      FileEntryRef ModuleMapFile = Instance.getFileManager().getVirtualFileRef(
-          FakeModuleMapFile, InferredModuleMapContent.size(), 0);
-      Instance.getSourceManager().overrideFileContents(
-          ModuleMapFile, std::move(ModuleMapBuffer));
-    });
   }
 
+  // FIXME: We only need to fake up an input file here as a way of
+  // transporting the module's directory to the module map parser. We should
+  // be able to do that more directly, and parse from a memory buffer without
+  // inventing this file.
+  SmallString<128> FakeModuleMapFile(Module->Directory->getName());
+  llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map");
+
+  std::string InferredModuleMapContent;
+  llvm::raw_string_ostream OS(InferredModuleMapContent);
+  Module->print(OS);
+
+  auto Instance = createCompilerInstanceForModuleCompileImpl(
+      ImportingInstance, ImportLoc, ModuleName,
+      FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem),
+      ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName);
+
+  std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
+      llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent);
+  FileEntryRef ModuleMapFile = Instance->getFileManager().getVirtualFileRef(
+      FakeModuleMapFile, InferredModuleMapContent.size(), 0);
+  Instance->getSourceManager().overrideFileContents(ModuleMapFile,
+                                                    std::move(ModuleMapBuffer));
+
+  return Instance;
+}
+
+/// Compile a module file for the given module, using the options
+/// provided by the importing compiler instance. Returns true if the module
+/// was built without errors.
+static bool compileModuleImpl(CompilerInstance &ImportingInstance,
+                              SourceLocation ImportLoc, StringRef ModuleName,
+                              StringRef ModuleFileName,
+                              CompilerInstance &Instance) {
+  llvm::TimeTraceScope TimeScope("Module Compile", ModuleName);
+
+  ImportingInstance.getDiagnostics().Report(ImportLoc,
+                                            diag::remark_module_build)
+    << ModuleName << ModuleFileName;
+
+  // Execute the action to actually build the module in-place. Use a separate
+  // thread so that we get a stack large enough.
+  bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnThread(
+      [&]() {
+        GenerateModuleFromModuleMapAction Action;
+        Instance.ExecuteAction(Action);
+      },
+      DesiredStackSize);
+
+  ImportingInstance.getDiagnostics().Report(ImportLoc,
+                                            diag::remark_module_build_done)
+    << ModuleName;
+
+  // Propagate the statistics to the parent FileManager.
+  if (ImportingInstance.getFileManagerPtr() != Instance.getFileManagerPtr())
+    ImportingInstance.getFileManager().AddStats(Instance.getFileManager());
+
+  if (Crashed) {
+    // Clear the ASTConsumer if it hasn't been already, in case it owns streams
+    // that must be closed before clearing output files.
+    Instance.setSema(nullptr);
+    Instance.setASTConsumer(nullptr);
+
+    // Delete any remaining temporary files related to Instance.
+    Instance.clearOutputFiles(/*EraseFiles=*/true);
+  }
+
+  // If \p AllowPCMWithCompilerErrors is set return 'success' even if errors
+  // occurred.
+  return !Instance.getDiagnostics().hasErrorOccurred() ||
+         Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
+}
+
+/// Compile a module file for the given module in a separate compiler instance,
+/// using the options provided by the importing compiler instance. Returns true
+/// if the module was built without errors.
+static bool compileModule(CompilerInstance &ImportingInstance,
+                          SourceLocation ImportLoc, Module *Module,
+                          StringRef ModuleFileName) {
+  StringRef ModuleName = Module->getTopLevelModuleName();
+
+  // Never compile a module that's already finalized - this would cause the
+  // existing module to be freed, causing crashes if it is later referenced
+  if (ImportingInstance.getModuleCache().getInMemoryModuleCache().isPCMFinal(
+          ModuleFileName)) {
+    ImportingInstance.getDiagnostics().Report(
+        ImportLoc, diag::err_module_rebuild_finalized)
+        << ModuleName;
+    return false;
+  }
+
+  auto Instance = createCompilerInstanceForModuleCompile(
+      ImportingInstance, ImportLoc, Module, ModuleFileName);
+
+  bool Success = compileModuleImpl(ImportingInstance, ImportLoc, ModuleName,
+                                   ModuleFileName, *Instance);
+
   // We've rebuilt a module. If we're allowed to generate or update the global
   // module index, record that fact in the importing compiler instance.
   if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) {
     ImportingInstance.setBuildGlobalModuleIndex(true);
   }
 
-  return Result;
+  return Success;
 }
 
 /// Read the AST right after compiling the module.
@@ -2232,25 +2259,26 @@ void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc,
 
   std::string NullTerminatedSource(Source.str());
 
-  auto PreBuildStep = [&](CompilerInstance &Other) {
-    // Create a virtual file containing our desired source.
-    // FIXME: We shouldn't need to do this.
-    FileEntryRef ModuleMapFile = Other.getFileManager().getVirtualFileRef(
-        ModuleMapFileName, NullTerminatedSource.size(), 0);
-    Other.getSourceManager().overrideFileContents(
-        ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));
+  auto Other = createCompilerInstanceForModuleCompileImpl(
+      *this, ImportLoc, ModuleName, Input, StringRef(), ModuleFileName);
 
-    Other.BuiltModules = std::move(BuiltModules);
-    Other.DeleteBuiltModules = false;
-  };
+  // Create a virtual file containing our desired source.
+  // FIXME: We shouldn't need to do this.
+  FileEntryRef ModuleMapFile = Other->getFileManager().getVirtualFileRef(
+      ModuleMapFileName, NullTerminatedSource.size(), 0);
+  Other->getSourceManager().overrideFileContents(
+      ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));
 
-  auto PostBuildStep = [this](CompilerInstance &Other) {
-    BuiltModules = std::move(Other.BuiltModules);
-  };
+  Other->BuiltModules = std::move(BuiltModules);
+  Other->DeleteBuiltModules = false;
 
   // Build the module, inheriting any modules that we've built locally.
-  if (compileModuleImpl(*this, ImportLoc, ModuleName, Input, StringRef(),
-                        ModuleFileName, PreBuildStep, PostBuildStep)) {
+  bool Success =
+      compileModuleImpl(*this, ImportLoc, ModuleName, ModuleFileName, *Other);
+
+  BuiltModules = std::move(Other->BuiltModules);
+
+  if (Success) {
     BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName);
     llvm::sys::RemoveFileOnSignal(ModuleFileName);
   }

Copy link

github-actions bot commented Apr 8, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@Bigcheese
Copy link
Contributor

Can you not just move the err_module_rebuild_finalized diagnostic into compileModuleImpl? It has access to everything it needs there.

@jansvoboda11
Copy link
Contributor Author

Can you not just move the err_module_rebuild_finalized diagnostic into compileModuleImpl? It has access to everything it needs there.

I didn't want to do it there to avoid unnecessarily creating the CompilerInstance when we're about to hit the error. But I tried moving the diagnostic into compileModuleImpl() and it nicely allows for collapsing compileModule() and compileModuleImpl() together, if we're fine with this running for the #pragma clang module build/endbuild case too:

  // We've rebuilt a module. If we're allowed to generate or update the global
  // module index, record that fact in the importing compiler instance.
  if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) {
    ImportingInstance.setBuildGlobalModuleIndex(true);
  }

Copy link
Contributor

@Bigcheese Bigcheese left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that's fine to run, it just may build the index again.

@jansvoboda11 jansvoboda11 merged commit 8d2f091 into llvm:main Apr 11, 2025
11 checks passed
@jansvoboda11 jansvoboda11 deleted the compile-module-impl-refactor branch April 11, 2025 16:39
@llvm-ci
Copy link
Collaborator

llvm-ci commented Apr 11, 2025

LLVM Buildbot has detected a new failure on builder lldb-arm-ubuntu running on linaro-lldb-arm-ubuntu while building clang at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/18/builds/14360

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: terminal/TestSTTYBeforeAndAfter.py (1142 of 2953)
PASS: lldb-api :: test_utils/TestDecorators.py (1143 of 2953)
PASS: lldb-api :: test_utils/TestInlineTest.py (1144 of 2953)
PASS: lldb-api :: test_utils/TestPExpectTest.py (1145 of 2953)
PASS: lldb-api :: test_utils/base/TestBaseTest.py (1146 of 2953)
PASS: lldb-api :: python_api/watchpoint/watchlocation/TestTargetWatchAddress.py (1147 of 2953)
PASS: lldb-api :: terminal/TestEditline.py (1148 of 2953)
UNSUPPORTED: lldb-api :: tools/lldb-dap/breakpoint-events/TestDAP_breakpointEvents.py (1149 of 2953)
PASS: lldb-api :: tools/lldb-dap/breakpoint/TestDAP_breakpointLocations.py (1150 of 2953)
PASS: lldb-api :: tools/lldb-dap/attach/TestDAP_attachByPortNum.py (1151 of 2953)
FAIL: lldb-api :: tools/lldb-dap/attach/TestDAP_attach.py (1152 of 2953)
******************** TEST 'lldb-api :: tools/lldb-dap/attach/TestDAP_attach.py' FAILED ********************
Script:
--
/usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin --arch armv8l --build-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./lib /home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/test/API/tools/lldb-dap/attach -p TestDAP_attach.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 8d2f0911ce8dddb37d064b3065b3be71e3233c2c)
  clang revision 8d2f0911ce8dddb37d064b3065b3be71e3233c2c
  llvm revision 8d2f0911ce8dddb37d064b3065b3be71e3233c2c
Skipping the following test categories: ['libc++', 'dsym', 'gmodules', 'debugserver', 'objc']

--
Command Output (stderr):
--
========= DEBUG ADAPTER PROTOCOL LOGS =========
1744390495.955542803 --> (stdin/stdout) {"command":"initialize","type":"request","arguments":{"adapterID":"lldb-native","clientID":"vscode","columnsStartAt1":true,"linesStartAt1":true,"locale":"en-us","pathFormat":"path","supportsRunInTerminalRequest":true,"supportsVariablePaging":true,"supportsVariableType":true,"supportsStartDebuggingRequest":true,"supportsProgressReporting":true,"$__lldb_sourceInitFile":false},"seq":1}
1744390495.960146666 <-- (stdin/stdout) {"body":{"$__lldb_version":"lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 8d2f0911ce8dddb37d064b3065b3be71e3233c2c)\n  clang revision 8d2f0911ce8dddb37d064b3065b3be71e3233c2c\n  llvm revision 8d2f0911ce8dddb37d064b3065b3be71e3233c2c","completionTriggerCharacters":["."," ","\t"],"exceptionBreakpointFilters":[{"default":false,"filter":"cpp_catch","label":"C++ Catch"},{"default":false,"filter":"cpp_throw","label":"C++ Throw"},{"default":false,"filter":"objc_catch","label":"Objective-C Catch"},{"default":false,"filter":"objc_throw","label":"Objective-C Throw"}],"supportTerminateDebuggee":true,"supportsBreakpointLocationsRequest":true,"supportsCompletionsRequest":true,"supportsConditionalBreakpoints":true,"supportsConfigurationDoneRequest":true,"supportsDataBreakpoints":true,"supportsDelayedStackTraceLoading":true,"supportsDisassembleRequest":true,"supportsEvaluateForHovers":true,"supportsExceptionInfoRequest":true,"supportsExceptionOptions":true,"supportsFunctionBreakpoints":true,"supportsHitConditionalBreakpoints":true,"supportsInstructionBreakpoints":true,"supportsLogPoints":true,"supportsModulesRequest":true,"supportsReadMemoryRequest":true,"supportsRestartRequest":true,"supportsSetVariable":true,"supportsStepInTargetsRequest":true,"supportsSteppingGranularity":true,"supportsValueFormattingOptions":true},"command":"initialize","request_seq":1,"seq":0,"success":true,"type":"response"}
1744390495.961159706 --> (stdin/stdout) {"command":"attach","type":"request","arguments":{"program":"/tmp/lit-tmp-pnifl7pg/tmppd0sik7z","initCommands":["settings clear -all","settings set symbols.enable-external-lookup false","settings set target.inherit-tcc true","settings set target.disable-aslr false","settings set target.detach-on-error false","settings set target.auto-apply-fixits false","settings set plugin.process.gdb-remote.packet-timeout 60","settings set symbols.clang-modules-cache-path \"/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api\"","settings set use-color false","settings set show-statusline false"]},"seq":2}
1744390495.961512566 <-- (stdin/stdout) {"body":{"category":"console","output":"Running initCommands:\n"},"event":"output","seq":0,"type":"event"}
1744390495.961573601 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings clear -all\n"},"event":"output","seq":0,"type":"event"}
1744390495.961587667 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings set symbols.enable-external-lookup false\n"},"event":"output","seq":0,"type":"event"}
1744390495.961600304 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings set target.inherit-tcc true\n"},"event":"output","seq":0,"type":"event"}
1744390495.961612463 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings set target.disable-aslr false\n"},"event":"output","seq":0,"type":"event"}
1744390495.961623907 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings set target.detach-on-error false\n"},"event":"output","seq":0,"type":"event"}
1744390495.961635113 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings set target.auto-apply-fixits false\n"},"event":"output","seq":0,"type":"event"}
1744390495.961646318 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings set plugin.process.gdb-remote.packet-timeout 60\n"},"event":"output","seq":0,"type":"event"}
1744390495.961659431 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings set symbols.clang-modules-cache-path \"/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api\"\n"},"event":"output","seq":0,"type":"event"}
1744390495.961725950 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings set use-color false\n"},"event":"output","seq":0,"type":"event"}
1744390495.961738348 <-- (stdin/stdout) {"body":{"category":"console","output":"(lldb) settings set show-statusline false\n"},"event":"output","seq":0,"type":"event"}
1744390496.153091669 <-- (stdin/stdout) {"command":"attach","request_seq":2,"seq":0,"success":true,"type":"response"}
1744390496.153301716 <-- (stdin/stdout) {"body":{"isLocalProcess":true,"name":"/tmp/lit-tmp-pnifl7pg/tmppd0sik7z","startMethod":"attach","systemProcessId":2626338},"event":"process","seq":0,"type":"event"}
1744390496.153342247 <-- (stdin/stdout) {"event":"initialized","seq":0,"type":"event"}
1744390496.154325962 --> (stdin/stdout) {"command":"setBreakpoints","type":"request","arguments":{"source":{"name":"main.c","path":"main.c"},"sourceModified":false,"lines":[28],"breakpoints":[{"line":28}]},"seq":3}
1744390496.165861368 <-- (stdin/stdout) {"body":{"breakpoints":[{"column":3,"id":1,"instructionReference":"0xA007D8","line":28,"source":{"name":"main.c","path":"main.c"},"verified":true}]},"command":"setBreakpoints","request_seq":3,"seq":0,"success":true,"type":"response"}
1744390496.166342258 <-- (stdin/stdout) {"body":{"breakpoint":{"column":3,"id":1,"instructionReference":"0xA007D8","line":28,"verified":true},"reason":"changed"},"event":"breakpoint","seq":0,"type":"event"}

@llvm-ci
Copy link
Collaborator

llvm-ci commented Apr 11, 2025

LLVM Buildbot has detected a new failure on builder arc-builder running on arc-worker while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/3/builds/14412

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: 1200 seconds without output running [b'ninja', b'check-all'], attempting to kill
...
6.771 [56/18/5] Linking CXX executable tools/clang/unittests/AST/ByteCode/InterpTests
6.829 [55/18/6] Linking CXX executable tools/clang/unittests/CrossTU/CrossTUTests
7.018 [54/18/7] Linking CXX executable tools/clang/unittests/Analysis/ClangAnalysisTests
7.187 [53/18/8] Linking CXX executable tools/clang/unittests/libclang/libclangTests
7.339 [52/18/9] Linking CXX executable tools/clang/unittests/libclang/CrashTests/libclangCrashTests
7.351 [51/18/10] Linking CXX executable tools/clang/unittests/Rewrite/RewriteTests
7.687 [50/18/11] Linking CXX executable tools/clang/unittests/Analysis/FlowSensitive/ClangAnalysisFlowSensitiveTests
7.840 [49/18/12] Linking CXX executable tools/clang/unittests/InstallAPI/InstallAPITests
7.857 [48/18/13] Linking CXX executable tools/clang/unittests/ASTMatchers/Dynamic/DynamicASTMatchersTests
8.123 [47/18/14] Preparing lit tests
command timed out: 1200 seconds without output running [b'ninja', b'check-all'], attempting to kill
process killed by signal 9
program finished with exit code -1
elapsedTime=1208.882938

var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
…()` (llvm#134887)

This PR extracts the creation of `CompilerInstance` for compiling an
implicitly-discovered module out of `compileModuleImpl()` into its own
separate function and passes it into `compileModuleImpl()` from the
outside. This makes the instance creation logic reusable (useful for my
experiments) and also simplifies the API, removing the `PreBuildStep`
and `PostBuildStep` hooks from `compileModuleImpl()`.
bnbarham added a commit to swiftlang/llvm-project that referenced this pull request Jul 3, 2025
llvm#134887 added a clone for the
compiler instance in `compileModuleAndReadASTImpl`, which would then be
destroyed *after* the corresponding read in the importing instance.

Swift has a `SwiftNameLookupExtension` module extension which updates
(effectively) global state - populating the lookup table for a
module on read and removing it when the module is destroyed.

With newly cloned instance, we would then see:
  - Module compiled with cloned instance
  - Module read with importing instance
  - Lookup table for that module added
  - Cloned instance destroyed
  - Module from that cloned instance destroyed
  - Lookup table for that module name removed

Depending on the original semantics is incredibly fragile, but for now
it's good enough to ensure that the read in the importing instance is
after the cloned instanced is destroyed. Ideally we'd only ever add to
the lookup tables in the original importing instance, never its clones.
AnthonyLatsis pushed a commit to swiftlang/llvm-project that referenced this pull request Jul 18, 2025
llvm#134887 added a clone for the
compiler instance in `compileModuleAndReadASTImpl`, which would then be
destroyed *after* the corresponding read in the importing instance.

Swift has a `SwiftNameLookupExtension` module extension which updates
(effectively) global state - populating the lookup table for a
module on read and removing it when the module is destroyed.

With newly cloned instance, we would then see:
  - Module compiled with cloned instance
  - Module read with importing instance
  - Lookup table for that module added
  - Cloned instance destroyed
  - Module from that cloned instance destroyed
  - Lookup table for that module name removed

Depending on the original semantics is incredibly fragile, but for now
it's good enough to ensure that the read in the importing instance is
after the cloned instanced is destroyed. Ideally we'd only ever add to
the lookup tables in the original importing instance, never its clones.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants