[clang] [clang][modules] Unify "context hash" and "specific module cache path" (PR #176215)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 15 10:34:40 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Jan Svoboda (jansvoboda11)
<details>
<summary>Changes</summary>
This PR unifies the terminology for:
* "context hash" - previously ambiguously referred to as "module hash" or as overly specific "module context hash"
* "specific module cache path" - previously referred to as just "module cache path" - hard to distinguish from the command-line-provided module cache path without the context hash
NFCI
---
Patch is 22.82 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/176215.diff
16 Files Affected:
- (modified) clang/include/clang/Frontend/CompilerInstance.h (+2-2)
- (modified) clang/include/clang/Frontend/CompilerInvocation.h (+5-3)
- (modified) clang/include/clang/Lex/HeaderSearch.h (+15-13)
- (modified) clang/include/clang/Serialization/ASTReader.h (+1-1)
- (modified) clang/lib/DependencyScanning/ModuleDepCollector.cpp (+1-1)
- (modified) clang/lib/Frontend/ASTUnit.cpp (+1-1)
- (modified) clang/lib/Frontend/CompilerInstance.cpp (+24-12)
- (modified) clang/lib/Frontend/CompilerInvocation.cpp (+1-1)
- (modified) clang/lib/Frontend/FrontendAction.cpp (+1-1)
- (modified) clang/lib/Lex/HeaderSearch.cpp (+3-3)
- (modified) clang/lib/Serialization/ASTReader.cpp (+20-19)
- (modified) clang/lib/Serialization/ASTWriter.cpp (+3-1)
- (modified) clang/test/ClangScanDeps/modules-context-hash-module-map-path.c (+1-1)
- (modified) clang/test/ClangScanDeps/modules-context-hash-outputs.c (+1-1)
- (modified) clang/test/Index/pch-from-libclang.c (+1-1)
- (modified) clang/test/Modules/context-hash.c (+1-1)
``````````diff
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index d0b41e9f18a1b..f56da69a05caf 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -738,9 +738,9 @@ class CompilerInstance : public ModuleLoader {
GetDependencyDirectives = std::move(Getter);
}
- std::string getSpecificModuleCachePath(StringRef ModuleHash);
+ std::string getSpecificModuleCachePath(StringRef ContextHash);
std::string getSpecificModuleCachePath() {
- return getSpecificModuleCachePath(getInvocation().getModuleHash());
+ return getSpecificModuleCachePath(getInvocation().computeContextHash());
}
/// Create the AST context.
diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h
index 903583e3fe79c..6fa6cd5d95534 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -308,9 +308,11 @@ class CompilerInvocation : public CompilerInvocationBase {
const LangOptions &LangOpts,
const llvm::Triple &Triple);
- /// Retrieve a module hash string that is suitable for uniquely
- /// identifying the conditions under which the module was built.
- std::string getModuleHash() const;
+ /// Compute the context hash - a string that uniquely identifies compiler
+ /// settings.
+ /// This is currently used mainly for distinguishing different variants of the
+ /// same implicitly-built Clang module.
+ std::string computeContextHash() const;
/// Check that \p Args can be parsed and re-serialized without change,
/// emiting diagnostics for any differences.
diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h
index 5369c872ac1cd..252e421e796f4 100644
--- a/clang/include/clang/Lex/HeaderSearch.h
+++ b/clang/include/clang/Lex/HeaderSearch.h
@@ -276,11 +276,11 @@ class HeaderSearch {
/// a system header.
std::vector<std::pair<std::string, bool>> SystemHeaderPrefixes;
- /// The hash used for module cache paths.
- std::string ModuleHash;
+ /// The context hash used in SpecificModuleCachePath (unless suppressed).
+ std::string ContextHash;
- /// The path to the module cache.
- std::string ModuleCachePath;
+ /// The specific module cache path containing ContextHash (unless suppressed).
+ std::string SpecificModuleCachePath;
/// All of the preprocessor-specific data about files that are
/// included, indexed by the FileEntry's UID.
@@ -433,19 +433,21 @@ class HeaderSearch {
return {};
}
- /// Set the hash to use for module cache paths.
- void setModuleHash(StringRef Hash) { ModuleHash = std::string(Hash); }
+ /// Set the context hash to use for module cache paths.
+ void setContextHash(StringRef Hash) { ContextHash = std::string(Hash); }
- /// Set the path to the module cache.
- void setModuleCachePath(StringRef CachePath) {
- ModuleCachePath = std::string(CachePath);
+ /// Set the module cache path with the context hash (unless suppressed).
+ void setSpecificModuleCachePath(StringRef Path) {
+ SpecificModuleCachePath = std::string(Path);
}
- /// Retrieve the module hash.
- StringRef getModuleHash() const { return ModuleHash; }
+ /// Retrieve the context hash.
+ StringRef getContextHash() const { return ContextHash; }
- /// Retrieve the path to the module cache.
- StringRef getModuleCachePath() const { return ModuleCachePath; }
+ /// Retrieve the module cache path with the context hash (unless suppressed).
+ StringRef getSpecificModuleCachePath() const {
+ return SpecificModuleCachePath;
+ }
/// Forget everything we know about headers so far.
void ClearFileInfo() {
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 2b3fa6d52f163..d1c1b98f78f2c 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -2025,7 +2025,7 @@ class ASTReader
const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts,
const CodeGenOptions &CGOpts, const TargetOptions &TargetOpts,
const PreprocessorOptions &PPOpts, const HeaderSearchOptions &HSOpts,
- StringRef ExistingModuleCachePath,
+ StringRef SpecificModuleCachePath,
bool RequireStrictOptionMatches = false);
/// Returns the suggested contents of the predefines buffer,
diff --git a/clang/lib/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/DependencyScanning/ModuleDepCollector.cpp
index 39bd2e2ab0032..70c94bca10275 100644
--- a/clang/lib/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/DependencyScanning/ModuleDepCollector.cpp
@@ -636,7 +636,7 @@ void ModuleDepCollectorPP::EndOfMainFile() {
handleTopLevelModule(M);
MDC.Consumer.handleContextHash(
- MDC.ScanInstance.getInvocation().getModuleHash());
+ MDC.ScanInstance.getInvocation().computeContextHash());
MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts);
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 0570b8ece24f8..ee22e16bc202d 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -763,7 +763,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
AST->getHeaderSearchOpts(), AST->getSourceManager(),
AST->getDiagnostics(), AST->getLangOpts(),
/*Target=*/nullptr);
- AST->HeaderInfo->setModuleCachePath(SpecificModuleCachePath);
+ AST->HeaderInfo->setSpecificModuleCachePath(SpecificModuleCachePath);
AST->PP = std::make_shared<Preprocessor>(
*AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 088538c7449d2..2cd7888b0d192 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -487,10 +487,10 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {
- std::string ModuleHash = getInvocation().getModuleHash();
- PP->getHeaderSearchInfo().setModuleHash(ModuleHash);
- PP->getHeaderSearchInfo().setModuleCachePath(
- getSpecificModuleCachePath(ModuleHash));
+ std::string ContextHash = getInvocation().computeContextHash();
+ PP->getHeaderSearchInfo().setContextHash(ContextHash);
+ PP->getHeaderSearchInfo().setSpecificModuleCachePath(
+ getSpecificModuleCachePath(ContextHash));
}
// Handle generating dependencies, if requested.
@@ -546,7 +546,8 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
PP->setDependencyDirectivesGetter(*GetDependencyDirectives);
}
-std::string CompilerInstance::getSpecificModuleCachePath(StringRef ModuleHash) {
+std::string
+CompilerInstance::getSpecificModuleCachePath(StringRef ContextHash) {
assert(FileMgr && "Specific module cache path requires a FileManager");
// Set up the module path, including the hash for the module-creation options.
@@ -554,7 +555,7 @@ std::string CompilerInstance::getSpecificModuleCachePath(StringRef ModuleHash) {
normalizeModuleCachePath(*FileMgr, getHeaderSearchOpts().ModuleCachePath,
SpecificModuleCache);
if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash)
- llvm::sys::path::append(SpecificModuleCache, ModuleHash);
+ llvm::sys::path::append(SpecificModuleCache, ContextHash);
return std::string(SpecificModuleCache);
}
@@ -1162,7 +1163,8 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl(
DiagnosticOptions &DiagOpts = Invocation->getDiagnosticOpts();
DiagOpts.VerifyDiagnostics = 0;
- assert(getInvocation().getModuleHash() == Invocation->getModuleHash() &&
+ assert(getInvocation().computeContextHash() ==
+ Invocation->computeContextHash() &&
"Module hash mismatch!");
// Construct a compiler instance that will be used to actually create the
@@ -1621,7 +1623,10 @@ void CompilerInstance::createASTReader() {
// If we're implicitly building modules but not currently recursively
// building a module, check whether we need to prune the module cache.
if (getSourceManager().getModuleBuildStack().empty() &&
- !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())
+ !getPreprocessor()
+ .getHeaderSearchInfo()
+ .getSpecificModuleCachePath()
+ .empty())
ModCache->maybePrune(getHeaderSearchOpts().ModuleCachePath,
getHeaderSearchOpts().ModuleCachePruneInterval,
getHeaderSearchOpts().ModuleCachePruneAfter);
@@ -2176,7 +2181,10 @@ void CompilerInstance::makeModuleVisible(Module *Mod,
GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
SourceLocation TriggerLoc) {
- if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())
+ if (getPreprocessor()
+ .getHeaderSearchInfo()
+ .getSpecificModuleCachePath()
+ .empty())
return nullptr;
if (!TheASTReader)
createASTReader();
@@ -2191,10 +2199,12 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() &&
hasPreprocessor()) {
llvm::sys::fs::create_directories(
- getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
+ getPreprocessor().getHeaderSearchInfo().getSpecificModuleCachePath());
if (llvm::Error Err = GlobalModuleIndex::writeIndex(
getFileManager(), getPCHContainerReader(),
- getPreprocessor().getHeaderSearchInfo().getModuleCachePath())) {
+ getPreprocessor()
+ .getHeaderSearchInfo()
+ .getSpecificModuleCachePath())) {
// FIXME this drops the error on the floor. This code is only used for
// typo correction and drops more than just this one source of errors
// (such as the directory creation failure above). It should handle the
@@ -2228,7 +2238,9 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
if (RecreateIndex) {
if (llvm::Error Err = GlobalModuleIndex::writeIndex(
getFileManager(), getPCHContainerReader(),
- getPreprocessor().getHeaderSearchInfo().getModuleCachePath())) {
+ getPreprocessor()
+ .getHeaderSearchInfo()
+ .getSpecificModuleCachePath())) {
// FIXME As above, this drops the error on the floor.
consumeError(std::move(Err));
return nullptr;
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index ab14661e06e11..5a79634773866 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -5156,7 +5156,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Invocation,
Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);
}
-std::string CompilerInvocation::getModuleHash() const {
+std::string CompilerInvocation::computeContextHash() const {
// FIXME: Consider using SHA1 instead of MD5.
llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 5c2ac862b5e75..7810f0999f7d6 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -1317,7 +1317,7 @@ llvm::Error FrontendAction::Execute() {
if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
CI.hasPreprocessor()) {
StringRef Cache =
- CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
+ CI.getPreprocessor().getHeaderSearchInfo().getSpecificModuleCachePath();
if (!Cache.empty()) {
if (llvm::Error Err = GlobalModuleIndex::writeIndex(
CI.getFileManager(), CI.getPCHContainerReader(), Cache)) {
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index b2ed24f765dab..5f52d62bd36ed 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -243,11 +243,11 @@ std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) {
getModuleMap().getModuleMapFileForUniquing(Module);
StringRef ModuleName = Module->Name;
StringRef ModuleMapPath = ModuleMap->getName();
- StringRef ModuleCacheHash = HSOpts.DisableModuleHash ? "" : getModuleHash();
+ StringRef ContextHash = HSOpts.DisableModuleHash ? "" : getContextHash();
for (const std::string &Dir : HSOpts.PrebuiltModulePaths) {
SmallString<256> CachePath(Dir);
FileMgr.makeAbsolutePath(CachePath);
- llvm::sys::path::append(CachePath, ModuleCacheHash);
+ llvm::sys::path::append(CachePath, ContextHash);
std::string FileName =
getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
if (!FileName.empty() && getFileMgr().getOptionalFileRef(FileName))
@@ -259,7 +259,7 @@ std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) {
std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName,
StringRef ModuleMapPath) {
return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
- getModuleCachePath());
+ getSpecificModuleCachePath());
}
std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 66cf484bb5cb6..5cafcc56871c6 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -944,15 +944,15 @@ bool SimpleASTReaderListener::ReadPreprocessorOptions(
/// \returns true when the module cache paths differ.
static bool checkModuleCachePath(
llvm::vfs::FileSystem &VFS, StringRef SpecificModuleCachePath,
- StringRef ExistingModuleCachePath, StringRef ASTFilename,
+ StringRef ExistingSpecificModuleCachePath, StringRef ASTFilename,
DiagnosticsEngine *Diags, const LangOptions &LangOpts,
const PreprocessorOptions &PPOpts, const HeaderSearchOptions &HSOpts,
const HeaderSearchOptions &ASTFileHSOpts) {
if (!LangOpts.Modules || PPOpts.AllowPCHWithDifferentModulesCachePath ||
- SpecificModuleCachePath == ExistingModuleCachePath)
+ SpecificModuleCachePath == ExistingSpecificModuleCachePath)
return false;
auto EqualOrErr =
- VFS.equivalent(SpecificModuleCachePath, ExistingModuleCachePath);
+ VFS.equivalent(SpecificModuleCachePath, ExistingSpecificModuleCachePath);
if (EqualOrErr && *EqualOrErr)
return false;
if (Diags) {
@@ -965,7 +965,8 @@ static bool checkModuleCachePath(
Diags->Report(clang::diag::warn_ast_file_config_mismatch) << ASTFilename;
else
Diags->Report(diag::err_ast_file_modulecache_mismatch)
- << SpecificModuleCachePath << ExistingModuleCachePath << ASTFilename;
+ << SpecificModuleCachePath << ExistingSpecificModuleCachePath
+ << ASTFilename;
}
return true;
}
@@ -977,7 +978,7 @@ bool PCHValidator::ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
const HeaderSearch &HeaderSearchInfo = PP.getHeaderSearchInfo();
return checkModuleCachePath(
Reader.getFileManager().getVirtualFileSystem(), SpecificModuleCachePath,
- HeaderSearchInfo.getModuleCachePath(), ASTFilename,
+ HeaderSearchInfo.getSpecificModuleCachePath(), ASTFilename,
Complain ? &Reader.Diags : nullptr, PP.getLangOpts(),
PP.getPreprocessorOpts(), HeaderSearchInfo.getHeaderSearchOpts(), HSOpts);
}
@@ -1628,9 +1629,9 @@ bool ASTReader::ReadSpecializations(ModuleFile &M, BitstreamCursor &Cursor,
void ASTReader::Error(StringRef Msg) const {
Error(diag::err_fe_ast_file_malformed, Msg);
if (PP.getLangOpts().Modules &&
- !PP.getHeaderSearchInfo().getModuleCachePath().empty()) {
+ !PP.getHeaderSearchInfo().getSpecificModuleCachePath().empty()) {
Diag(diag::note_module_cache_path)
- << PP.getHeaderSearchInfo().getModuleCachePath();
+ << PP.getHeaderSearchInfo().getSpecificModuleCachePath();
}
}
@@ -4757,10 +4758,10 @@ bool ASTReader::loadGlobalIndex() {
// Try to load the global index.
TriedLoadingGlobalIndex = true;
- StringRef ModuleCachePath
- = getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
+ StringRef SpecificModuleCachePath =
+ getPreprocessor().getHeaderSearchInfo().getSpecificModuleCachePath();
std::pair<GlobalModuleIndex *, llvm::Error> Result =
- GlobalModuleIndex::readIndex(ModuleCachePath);
+ GlobalModuleIndex::readIndex(SpecificModuleCachePath);
if (llvm::Error Err = std::move(Result.second)) {
assert(!Result.first);
consumeError(std::move(Err)); // FIXME this drops errors on the floor.
@@ -5755,7 +5756,7 @@ namespace {
const TargetOptions &ExistingTargetOpts;
const PreprocessorOptions &ExistingPPOpts;
const HeaderSearchOptions &ExistingHSOpts;
- std::string ExistingModuleCachePath;
+ std::string ExistingSpecificModuleCachePath;
FileManager &FileMgr;
bool StrictOptionMatches;
@@ -5765,13 +5766,13 @@ namespace {
const TargetOptions &ExistingTargetOpts,
const PreprocessorOptions &ExistingPPOpts,
const HeaderSearchOptions &ExistingHSOpts,
- StringRef ExistingModuleCachePath, FileManager &FileMgr,
- bool StrictOptionMatches)
+ StringRef ExistingSpecificModuleCachePath,
+ FileManager &FileMgr, bool StrictOptionMatches)
: ExistingLangOpts(ExistingLangOpts), ExistingCGOpts(ExistingCGOpts),
ExistingTargetOpts(ExistingTargetOpts),
ExistingPPOpts(ExistingPPOpts), ExistingHSOpts(ExistingHSOpts),
- ExistingModuleCachePath(ExistingModuleCachePath), FileMgr(FileMgr),
- StrictOptionMatches(StrictOptionMatches) {}
+ ExistingSpecificModuleCachePath(ExistingSpecificModuleCachePath),
+ FileMgr(FileMgr), StrictOptionMatches(StrictOptionMatches) {}
bool ReadLanguageOptions(const LangOptions &LangOpts,
StringRef ModuleFilename, bool Complain,
@@ -5800,8 +5801,8 @@ namespace {
bool Complain) override {
return checkModuleCachePath(
FileMgr.getVirtualFileSystem(), SpecificModuleCachePath,
- ExistingModuleCachePath, ASTFilename, nullptr, ExistingLangOpts,
- ExistingPPOpts, ExistingHSOpts, HSOpts);
+ ExistingSpecificModuleCachePath, ASTFilename, nullptr,
+ ExistingLangOpts, ExistingPPOpts, ExistingHSOpts, HSOpts);
}
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
@@ -6144,9 +6145,9 @@ bool ASTReader::isAcceptableASTFile(
const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts,
const CodeGenOptions &CGOpts, const TargetOptions &TargetOpts,
const PreprocessorOptions &PPOpts, const HeaderSearchOptions &HSOpts,
- StringRef ExistingModuleCachePath, bool RequireStrictOptionMatches) {
+ StringRef SpecificModuleCachePath, bool RequireStrictOptionMatches) {
SimplePCHValidator validator(LangOpts, CGOpts, TargetOpts, PPOpts, HSOpts,
- ExistingModuleCachePath, FileMgr,
+ SpecificModuleCachePath, FileMgr,
RequireStrictOptionMatches);
return !readASTFileControlBlock(Filename, FileMgr, ModCache, PCHContainerRdr,
/*FindModuleFileExtensions=*/false, validator,
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 39104da10d0b7..cd8a843c77305 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1715,7 +1715,9 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
Record.push_back(HSOpts.UseStandardCXXIncludes);
Record.push_back(HSOpts.UseLibcx...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/176215
More information about the cfe-commits
mailing list