diff --git a/interpreter/llvm-project/clang/include/clang/Serialization/ASTWriter.h b/interpreter/llvm-project/clang/include/clang/Serialization/ASTWriter.h index 079e39a9fb678..a3a78223d131c 100644 --- a/interpreter/llvm-project/clang/include/clang/Serialization/ASTWriter.h +++ b/interpreter/llvm-project/clang/include/clang/Serialization/ASTWriter.h @@ -586,8 +586,6 @@ class ASTWriter : public ASTDeserializationListener, void WriteTypeAbbrevs(); void WriteType(ASTContext &Context, QualType T); - bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC); - void GenerateSpecializationInfoLookupTable( const NamedDecl *D, llvm::SmallVectorImpl &Specializations, llvm::SmallVectorImpl &LookupTable, bool IsPartial); diff --git a/interpreter/llvm-project/clang/lib/Serialization/ASTWriter.cpp b/interpreter/llvm-project/clang/lib/Serialization/ASTWriter.cpp index 4333f0b95b853..5ce05f741b516 100644 --- a/interpreter/llvm-project/clang/lib/Serialization/ASTWriter.cpp +++ b/interpreter/llvm-project/clang/lib/Serialization/ASTWriter.cpp @@ -4493,12 +4493,6 @@ uint64_t ASTWriter::WriteSpecializationInfoLookupTable( return Offset; } -bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result, - DeclContext *DC) { - return Result.hasExternalDecls() && - DC->hasNeedToReconcileExternalVisibleStorage(); -} - /// Returns ture if all of the lookup result are either external, not emitted or /// predefined. In such cases, the lookup result is not interesting and we don't /// need to record the result in the current being written module. Return false @@ -4550,14 +4544,12 @@ void ASTWriter::GenerateNameLookupTable( // order. SmallVector Names; - // We also build up small sets of the constructor and conversion function - // names which are visible. - llvm::SmallPtrSet ConstructorNameSet, ConversionNameSet; - - for (auto &Lookup : *DC->buildLookup()) { - auto &Name = Lookup.first; - auto &Result = Lookup.second; + // We also track whether we're writing out the DeclarationNameKey for + // constructors or conversion functions. + bool IncludeConstructorNames = false; + bool IncludeConversionNames = false; + for (auto &[Name, Result] : *DC->buildLookup()) { // If there are no local declarations in our lookup result, we // don't need to write an entry for the name at all. If we can't // write out a lookup set without performing more deserialization, @@ -4566,15 +4558,8 @@ void ASTWriter::GenerateNameLookupTable( // Also in reduced BMI, we'd like to avoid writing unreachable // declarations in GMF, so we need to avoid writing declarations // that entirely external or unreachable. - // - // FIMXE: It looks sufficient to test - // isLookupResultNotInteresting here. But due to bug we have - // to test isLookupResultExternal here. See - // https://github.com/llvm/llvm-project/issues/61065 for details. - if ((GeneratingReducedBMI || isLookupResultExternal(Result, DC)) && - isLookupResultNotInteresting(*this, Result)) + if (GeneratingReducedBMI && isLookupResultNotInteresting(*this, Result)) continue; - // We also skip empty results. If any of the results could be external and // the currently available results are empty, then all of the results are // external and we skip it above. So the only way we get here with an empty @@ -4589,24 +4574,20 @@ void ASTWriter::GenerateNameLookupTable( // results for them. This in almost certainly a bug in Clang's name lookup, // but that is likely to be hard or impossible to fix and so we tolerate it // here by omitting lookups with empty results. - if (Lookup.second.getLookupResult().empty()) + if (Result.getLookupResult().empty()) continue; - switch (Lookup.first.getNameKind()) { + switch (Name.getNameKind()) { default: - Names.push_back(Lookup.first); + Names.push_back(Name); break; case DeclarationName::CXXConstructorName: - assert(isa(DC) && - "Cannot have a constructor name outside of a class!"); - ConstructorNameSet.insert(Name); + IncludeConstructorNames = true; break; case DeclarationName::CXXConversionFunctionName: - assert(isa(DC) && - "Cannot have a conversion function name outside of a class!"); - ConversionNameSet.insert(Name); + IncludeConversionNames = true; break; } } @@ -4614,57 +4595,34 @@ void ASTWriter::GenerateNameLookupTable( // Sort the names into a stable order. llvm::sort(Names); - if (auto *D = dyn_cast(DC)) { + if (IncludeConstructorNames || IncludeConversionNames) { // We need to establish an ordering of constructor and conversion function - // names, and they don't have an intrinsic ordering. - - // First we try the easy case by forming the current context's constructor - // name and adding that name first. This is a very useful optimization to - // avoid walking the lexical declarations in many cases, and it also - // handles the only case where a constructor name can come from some other - // lexical context -- when that name is an implicit constructor merged from - // another declaration in the redecl chain. Any non-implicit constructor or - // conversion function which doesn't occur in all the lexical contexts - // would be an ODR violation. - auto ImplicitCtorName = Context.DeclarationNames.getCXXConstructorName( - Context.getCanonicalType(Context.getRecordType(D))); - if (ConstructorNameSet.erase(ImplicitCtorName)) - Names.push_back(ImplicitCtorName); - - // If we still have constructors or conversion functions, we walk all the - // names in the decl and add the constructors and conversion functions - // which are visible in the order they lexically occur within the context. - if (!ConstructorNameSet.empty() || !ConversionNameSet.empty()) - for (Decl *ChildD : cast(DC)->decls()) - if (auto *ChildND = dyn_cast(ChildD)) { - auto Name = ChildND->getDeclName(); - switch (Name.getNameKind()) { - default: - continue; - - case DeclarationName::CXXConstructorName: - if (ConstructorNameSet.erase(Name)) - Names.push_back(Name); - break; + // names, and they don't have an intrinsic ordering. We also need to write + // out all constructor and conversion function results if we write out any + // of them, because they're all tracked under the same lookup key. + llvm::SmallPtrSet AddedNames; + for (Decl *ChildD : cast(DC)->decls()) { + if (auto *ChildND = dyn_cast(ChildD)) { + auto Name = ChildND->getDeclName(); + switch (Name.getNameKind()) { + default: + continue; - case DeclarationName::CXXConversionFunctionName: - if (ConversionNameSet.erase(Name)) - Names.push_back(Name); - break; - } + case DeclarationName::CXXConstructorName: + if (!IncludeConstructorNames) + continue; + break; - if (ConstructorNameSet.empty() && ConversionNameSet.empty()) - break; + case DeclarationName::CXXConversionFunctionName: + if (!IncludeConversionNames) + continue; + break; } - - assert(ConstructorNameSet.empty() && "Failed to find all of the visible " - "constructors by walking all the " - "lexical members of the context."); - assert(ConversionNameSet.empty() && "Failed to find all of the visible " - "conversion functions by walking all " - "the lexical members of the context."); + if (AddedNames.insert(Name).second) + Names.push_back(Name); + } + } } - // Next we need to do a lookup with each name into this decl context to fully // populate any results from external sources. We don't actually use the // results of these lookups because we only want to use the results after all diff --git a/interpreter/llvm-project/llvm-project.tag b/interpreter/llvm-project/llvm-project.tag index 7671eec8bada7..d8f26d75d936d 100644 --- a/interpreter/llvm-project/llvm-project.tag +++ b/interpreter/llvm-project/llvm-project.tag @@ -1 +1 @@ -ROOT-llvm20-20260223-01 +ROOT-llvm20-20260408-01