@@ -4504,12 +4504,6 @@ uint64_t ASTWriter::WriteSpecializationInfoLookupTable(
4504
4504
return Offset;
4505
4505
}
4506
4506
4507
- bool ASTWriter::isLookupResultExternal (StoredDeclsList &Result,
4508
- DeclContext *DC) {
4509
- return Result.hasExternalDecls () &&
4510
- DC->hasNeedToReconcileExternalVisibleStorage ();
4511
- }
4512
-
4513
4507
// / Returns ture if all of the lookup result are either external, not emitted or
4514
4508
// / predefined. In such cases, the lookup result is not interesting and we don't
4515
4509
// / need to record the result in the current being written module. Return false
@@ -4561,14 +4555,12 @@ void ASTWriter::GenerateNameLookupTable(
4561
4555
// order.
4562
4556
SmallVector<DeclarationName, 16 > Names;
4563
4557
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 ;
4571
4562
4563
+ for (auto &[Name, Result] : *DC->buildLookup ()) {
4572
4564
// If there are no local declarations in our lookup result, we
4573
4565
// don't need to write an entry for the name at all. If we can't
4574
4566
// write out a lookup set without performing more deserialization,
@@ -4577,15 +4569,8 @@ void ASTWriter::GenerateNameLookupTable(
4577
4569
// Also in reduced BMI, we'd like to avoid writing unreachable
4578
4570
// declarations in GMF, so we need to avoid writing declarations
4579
4571
// 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))
4587
4573
continue ;
4588
-
4589
4574
// We also skip empty results. If any of the results could be external and
4590
4575
// the currently available results are empty, then all of the results are
4591
4576
// external and we skip it above. So the only way we get here with an empty
@@ -4600,82 +4585,55 @@ void ASTWriter::GenerateNameLookupTable(
4600
4585
// results for them. This in almost certainly a bug in Clang's name lookup,
4601
4586
// but that is likely to be hard or impossible to fix and so we tolerate it
4602
4587
// here by omitting lookups with empty results.
4603
- if (Lookup. second .getLookupResult ().empty ())
4588
+ if (Result .getLookupResult ().empty ())
4604
4589
continue ;
4605
4590
4606
- switch (Lookup. first .getNameKind ()) {
4591
+ switch (Name .getNameKind ()) {
4607
4592
default :
4608
- Names.push_back (Lookup. first );
4593
+ Names.push_back (Name );
4609
4594
break ;
4610
4595
4611
4596
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 ;
4615
4598
break ;
4616
4599
4617
4600
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 ;
4621
4602
break ;
4622
4603
}
4623
4604
}
4624
4605
4625
4606
// Sort the names into a stable order.
4626
4607
llvm::sort (Names);
4627
4608
4628
- if (auto *D = dyn_cast<CXXRecordDecl>(DC) ) {
4609
+ if (IncludeConstructorNames || IncludeConversionNames ) {
4629
4610
// 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 ;
4660
4621
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 ;
4666
4626
4667
- if (ConstructorNameSet.empty () && ConversionNameSet.empty ())
4668
- break ;
4627
+ case DeclarationName::CXXConversionFunctionName:
4628
+ if (!IncludeConversionNames)
4629
+ continue ;
4630
+ break ;
4669
4631
}
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
+ }
4677
4636
}
4678
-
4679
4637
// Next we need to do a lookup with each name into this decl context to fully
4680
4638
// populate any results from external sources. We don't actually use the
4681
4639
// results of these lookups because we only want to use the results after all
0 commit comments