@@ -4493,12 +4493,6 @@ uint64_t ASTWriter::WriteSpecializationInfoLookupTable(
44934493 return Offset;
44944494}
44954495
4496- bool ASTWriter::isLookupResultExternal (StoredDeclsList &Result,
4497- DeclContext *DC) {
4498- return Result.hasExternalDecls () &&
4499- DC->hasNeedToReconcileExternalVisibleStorage ();
4500- }
4501-
45024496// / Returns ture if all of the lookup result are either external, not emitted or
45034497// / predefined. In such cases, the lookup result is not interesting and we don't
45044498// / need to record the result in the current being written module. Return false
@@ -4550,14 +4544,12 @@ void ASTWriter::GenerateNameLookupTable(
45504544 // order.
45514545 SmallVector<DeclarationName, 16 > Names;
45524546
4553- // We also build up small sets of the constructor and conversion function
4554- // names which are visible.
4555- llvm::SmallPtrSet<DeclarationName, 8 > ConstructorNameSet, ConversionNameSet;
4556-
4557- for (auto &Lookup : *DC->buildLookup ()) {
4558- auto &Name = Lookup.first ;
4559- auto &Result = Lookup.second ;
4547+ // We also track whether we're writing out the DeclarationNameKey for
4548+ // constructors or conversion functions.
4549+ bool IncludeConstructorNames = false ;
4550+ bool IncludeConversionNames = false ;
45604551
4552+ for (auto &[Name, Result] : *DC->buildLookup ()) {
45614553 // If there are no local declarations in our lookup result, we
45624554 // don't need to write an entry for the name at all. If we can't
45634555 // write out a lookup set without performing more deserialization,
@@ -4566,15 +4558,8 @@ void ASTWriter::GenerateNameLookupTable(
45664558 // Also in reduced BMI, we'd like to avoid writing unreachable
45674559 // declarations in GMF, so we need to avoid writing declarations
45684560 // that entirely external or unreachable.
4569- //
4570- // FIMXE: It looks sufficient to test
4571- // isLookupResultNotInteresting here. But due to bug we have
4572- // to test isLookupResultExternal here. See
4573- // https://github.com/llvm/llvm-project/issues/61065 for details.
4574- if ((GeneratingReducedBMI || isLookupResultExternal (Result, DC)) &&
4575- isLookupResultNotInteresting (*this , Result))
4561+ if (GeneratingReducedBMI && isLookupResultNotInteresting (*this , Result))
45764562 continue ;
4577-
45784563 // We also skip empty results. If any of the results could be external and
45794564 // the currently available results are empty, then all of the results are
45804565 // external and we skip it above. So the only way we get here with an empty
@@ -4589,82 +4574,55 @@ void ASTWriter::GenerateNameLookupTable(
45894574 // results for them. This in almost certainly a bug in Clang's name lookup,
45904575 // but that is likely to be hard or impossible to fix and so we tolerate it
45914576 // here by omitting lookups with empty results.
4592- if (Lookup. second .getLookupResult ().empty ())
4577+ if (Result .getLookupResult ().empty ())
45934578 continue ;
45944579
4595- switch (Lookup. first .getNameKind ()) {
4580+ switch (Name .getNameKind ()) {
45964581 default :
4597- Names.push_back (Lookup. first );
4582+ Names.push_back (Name );
45984583 break ;
45994584
46004585 case DeclarationName::CXXConstructorName:
4601- assert (isa<CXXRecordDecl>(DC) &&
4602- " Cannot have a constructor name outside of a class!" );
4603- ConstructorNameSet.insert (Name);
4586+ IncludeConstructorNames = true ;
46044587 break ;
46054588
46064589 case DeclarationName::CXXConversionFunctionName:
4607- assert (isa<CXXRecordDecl>(DC) &&
4608- " Cannot have a conversion function name outside of a class!" );
4609- ConversionNameSet.insert (Name);
4590+ IncludeConversionNames = true ;
46104591 break ;
46114592 }
46124593 }
46134594
46144595 // Sort the names into a stable order.
46154596 llvm::sort (Names);
46164597
4617- if (auto *D = dyn_cast<CXXRecordDecl>(DC) ) {
4598+ if (IncludeConstructorNames || IncludeConversionNames ) {
46184599 // We need to establish an ordering of constructor and conversion function
4619- // names, and they don't have an intrinsic ordering.
4620-
4621- // First we try the easy case by forming the current context's constructor
4622- // name and adding that name first. This is a very useful optimization to
4623- // avoid walking the lexical declarations in many cases, and it also
4624- // handles the only case where a constructor name can come from some other
4625- // lexical context -- when that name is an implicit constructor merged from
4626- // another declaration in the redecl chain. Any non-implicit constructor or
4627- // conversion function which doesn't occur in all the lexical contexts
4628- // would be an ODR violation.
4629- auto ImplicitCtorName = Context.DeclarationNames .getCXXConstructorName (
4630- Context.getCanonicalType (Context.getRecordType (D)));
4631- if (ConstructorNameSet.erase (ImplicitCtorName))
4632- Names.push_back (ImplicitCtorName);
4633-
4634- // If we still have constructors or conversion functions, we walk all the
4635- // names in the decl and add the constructors and conversion functions
4636- // which are visible in the order they lexically occur within the context.
4637- if (!ConstructorNameSet.empty () || !ConversionNameSet.empty ())
4638- for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls ())
4639- if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
4640- auto Name = ChildND->getDeclName ();
4641- switch (Name.getNameKind ()) {
4642- default :
4643- continue ;
4644-
4645- case DeclarationName::CXXConstructorName:
4646- if (ConstructorNameSet.erase (Name))
4647- Names.push_back (Name);
4648- break ;
4600+ // names, and they don't have an intrinsic ordering. We also need to write
4601+ // out all constructor and conversion function results if we write out any
4602+ // of them, because they're all tracked under the same lookup key.
4603+ llvm::SmallPtrSet<DeclarationName, 8 > AddedNames;
4604+ for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls ()) {
4605+ if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
4606+ auto Name = ChildND->getDeclName ();
4607+ switch (Name.getNameKind ()) {
4608+ default :
4609+ continue ;
46494610
4650- case DeclarationName::CXXConversionFunctionName:
4651- if (ConversionNameSet.erase (Name))
4652- Names.push_back (Name);
4653- break ;
4654- }
4611+ case DeclarationName::CXXConstructorName:
4612+ if (!IncludeConstructorNames)
4613+ continue ;
4614+ break ;
46554615
4656- if (ConstructorNameSet.empty () && ConversionNameSet.empty ())
4657- break ;
4616+ case DeclarationName::CXXConversionFunctionName:
4617+ if (!IncludeConversionNames)
4618+ continue ;
4619+ break ;
46584620 }
4659-
4660- assert (ConstructorNameSet.empty () && " Failed to find all of the visible "
4661- " constructors by walking all the "
4662- " lexical members of the context." );
4663- assert (ConversionNameSet.empty () && " Failed to find all of the visible "
4664- " conversion functions by walking all "
4665- " the lexical members of the context." );
4621+ if (AddedNames.insert (Name).second )
4622+ Names.push_back (Name);
4623+ }
4624+ }
46664625 }
4667-
46684626 // Next we need to do a lookup with each name into this decl context to fully
46694627 // populate any results from external sources. We don't actually use the
46704628 // results of these lookups because we only want to use the results after all
0 commit comments