@@ -4504,12 +4504,6 @@ uint64_t ASTWriter::WriteSpecializationInfoLookupTable(
45044504 return Offset;
45054505}
45064506
4507- bool ASTWriter::isLookupResultExternal (StoredDeclsList &Result,
4508- DeclContext *DC) {
4509- return Result.hasExternalDecls () &&
4510- DC->hasNeedToReconcileExternalVisibleStorage ();
4511- }
4512-
45134507// / Returns ture if all of the lookup result are either external, not emitted or
45144508// / predefined. In such cases, the lookup result is not interesting and we don't
45154509// / need to record the result in the current being written module. Return false
@@ -4561,14 +4555,12 @@ void ASTWriter::GenerateNameLookupTable(
45614555 // order.
45624556 SmallVector<DeclarationName, 16 > Names;
45634557
4564- // We also build up small sets of the constructor and conversion function
4565- // names which are visible.
4566- llvm::SmallPtrSet<DeclarationName, 8 > ConstructorNameSet, ConversionNameSet;
4567-
4568- for (auto &Lookup : *DC->buildLookup ()) {
4569- auto &Name = Lookup.first ;
4570- auto &Result = Lookup.second ;
4558+ // We also track whether we're writing out the DeclarationNameKey for
4559+ // constructors or conversion functions.
4560+ bool IncludeConstructorNames = false ;
4561+ bool IncludeConversionNames = false ;
45714562
4563+ for (auto &[Name, Result] : *DC->buildLookup ()) {
45724564 // If there are no local declarations in our lookup result, we
45734565 // don't need to write an entry for the name at all. If we can't
45744566 // write out a lookup set without performing more deserialization,
@@ -4577,15 +4569,8 @@ void ASTWriter::GenerateNameLookupTable(
45774569 // Also in reduced BMI, we'd like to avoid writing unreachable
45784570 // declarations in GMF, so we need to avoid writing declarations
45794571 // that entirely external or unreachable.
4580- //
4581- // FIMXE: It looks sufficient to test
4582- // isLookupResultNotInteresting here. But due to bug we have
4583- // to test isLookupResultExternal here. See
4584- // https://github.com/llvm/llvm-project/issues/61065 for details.
4585- if ((GeneratingReducedBMI || isLookupResultExternal (Result, DC)) &&
4586- isLookupResultNotInteresting (*this , Result))
4572+ if (GeneratingReducedBMI && isLookupResultNotInteresting (*this , Result))
45874573 continue ;
4588-
45894574 // We also skip empty results. If any of the results could be external and
45904575 // the currently available results are empty, then all of the results are
45914576 // external and we skip it above. So the only way we get here with an empty
@@ -4600,82 +4585,55 @@ void ASTWriter::GenerateNameLookupTable(
46004585 // results for them. This in almost certainly a bug in Clang's name lookup,
46014586 // but that is likely to be hard or impossible to fix and so we tolerate it
46024587 // here by omitting lookups with empty results.
4603- if (Lookup. second .getLookupResult ().empty ())
4588+ if (Result .getLookupResult ().empty ())
46044589 continue ;
46054590
4606- switch (Lookup. first .getNameKind ()) {
4591+ switch (Name .getNameKind ()) {
46074592 default :
4608- Names.push_back (Lookup. first );
4593+ Names.push_back (Name );
46094594 break ;
46104595
46114596 case DeclarationName::CXXConstructorName:
4612- assert (isa<CXXRecordDecl>(DC) &&
4613- " Cannot have a constructor name outside of a class!" );
4614- ConstructorNameSet.insert (Name);
4597+ IncludeConstructorNames = true ;
46154598 break ;
46164599
46174600 case DeclarationName::CXXConversionFunctionName:
4618- assert (isa<CXXRecordDecl>(DC) &&
4619- " Cannot have a conversion function name outside of a class!" );
4620- ConversionNameSet.insert (Name);
4601+ IncludeConversionNames = true ;
46214602 break ;
46224603 }
46234604 }
46244605
46254606 // Sort the names into a stable order.
46264607 llvm::sort (Names);
46274608
4628- if (auto *D = dyn_cast<CXXRecordDecl>(DC) ) {
4609+ if (IncludeConstructorNames || IncludeConversionNames ) {
46294610 // We need to establish an ordering of constructor and conversion function
4630- // names, and they don't have an intrinsic ordering.
4631-
4632- // First we try the easy case by forming the current context's constructor
4633- // name and adding that name first. This is a very useful optimization to
4634- // avoid walking the lexical declarations in many cases, and it also
4635- // handles the only case where a constructor name can come from some other
4636- // lexical context -- when that name is an implicit constructor merged from
4637- // another declaration in the redecl chain. Any non-implicit constructor or
4638- // conversion function which doesn't occur in all the lexical contexts
4639- // would be an ODR violation.
4640- auto ImplicitCtorName = Context.DeclarationNames .getCXXConstructorName (
4641- Context.getCanonicalType (Context.getRecordType (D)));
4642- if (ConstructorNameSet.erase (ImplicitCtorName))
4643- Names.push_back (ImplicitCtorName);
4644-
4645- // If we still have constructors or conversion functions, we walk all the
4646- // names in the decl and add the constructors and conversion functions
4647- // which are visible in the order they lexically occur within the context.
4648- if (!ConstructorNameSet.empty () || !ConversionNameSet.empty ())
4649- for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls ())
4650- if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
4651- auto Name = ChildND->getDeclName ();
4652- switch (Name.getNameKind ()) {
4653- default :
4654- continue ;
4655-
4656- case DeclarationName::CXXConstructorName:
4657- if (ConstructorNameSet.erase (Name))
4658- Names.push_back (Name);
4659- break ;
4611+ // names, and they don't have an intrinsic ordering. We also need to write
4612+ // out all constructor and conversion function results if we write out any
4613+ // of them, because they're all tracked under the same lookup key.
4614+ llvm::SmallPtrSet<DeclarationName, 8 > AddedNames;
4615+ for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls ()) {
4616+ if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
4617+ auto Name = ChildND->getDeclName ();
4618+ switch (Name.getNameKind ()) {
4619+ default :
4620+ continue ;
46604621
4661- case DeclarationName::CXXConversionFunctionName:
4662- if (ConversionNameSet.erase (Name))
4663- Names.push_back (Name);
4664- break ;
4665- }
4622+ case DeclarationName::CXXConstructorName:
4623+ if (!IncludeConstructorNames)
4624+ continue ;
4625+ break ;
46664626
4667- if (ConstructorNameSet.empty () && ConversionNameSet.empty ())
4668- break ;
4627+ case DeclarationName::CXXConversionFunctionName:
4628+ if (!IncludeConversionNames)
4629+ continue ;
4630+ break ;
46694631 }
4670-
4671- assert (ConstructorNameSet.empty () && " Failed to find all of the visible "
4672- " constructors by walking all the "
4673- " lexical members of the context." );
4674- assert (ConversionNameSet.empty () && " Failed to find all of the visible "
4675- " conversion functions by walking all "
4676- " the lexical members of the context." );
4632+ if (AddedNames.insert (Name).second )
4633+ Names.push_back (Name);
4634+ }
4635+ }
46774636 }
4678-
46794637 // Next we need to do a lookup with each name into this decl context to fully
46804638 // populate any results from external sources. We don't actually use the
46814639 // results of these lookups because we only want to use the results after all
0 commit comments