@@ -3849,12 +3849,6 @@ class ASTDeclContextNameLookupTrait {
3849
3849
3850
3850
} // namespace
3851
3851
3852
- bool ASTWriter::isLookupResultExternal (StoredDeclsList &Result,
3853
- DeclContext *DC) {
3854
- return Result.hasExternalDecls () &&
3855
- DC->hasNeedToReconcileExternalVisibleStorage ();
3856
- }
3857
-
3858
3852
bool ASTWriter::isLookupResultEntirelyExternal (StoredDeclsList &Result,
3859
3853
DeclContext *DC) {
3860
3854
for (auto *D : Result.getLookupResult ())
@@ -3885,20 +3879,17 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
3885
3879
// order.
3886
3880
SmallVector<DeclarationName, 16 > Names;
3887
3881
3888
- // We also build up small sets of the constructor and conversion function
3889
- // names which are visible.
3890
- llvm::SmallPtrSet<DeclarationName, 8 > ConstructorNameSet, ConversionNameSet;
3891
-
3892
- for (auto &Lookup : *DC->buildLookup ()) {
3893
- auto &Name = Lookup.first ;
3894
- auto &Result = Lookup.second ;
3882
+ // We also track whether we're writing out the DeclarationNameKey for
3883
+ // constructors or conversion functions.
3884
+ bool IncludeConstructorNames = false ;
3885
+ bool IncludeConversionNames = false ;
3895
3886
3887
+ for (auto &[Name, Result] : *DC->buildLookup ()) {
3896
3888
// If there are no local declarations in our lookup result, we
3897
3889
// don't need to write an entry for the name at all. If we can't
3898
3890
// write out a lookup set without performing more deserialization,
3899
3891
// just skip this entry.
3900
- if (isLookupResultExternal (Result, DC) &&
3901
- isLookupResultEntirelyExternal (Result, DC))
3892
+ if (isLookupResultEntirelyExternal (Result, DC))
3902
3893
continue ;
3903
3894
3904
3895
// We also skip empty results. If any of the results could be external and
@@ -3915,80 +3906,55 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
3915
3906
// results for them. This in almost certainly a bug in Clang's name lookup,
3916
3907
// but that is likely to be hard or impossible to fix and so we tolerate it
3917
3908
// here by omitting lookups with empty results.
3918
- if (Lookup. second .getLookupResult ().empty ())
3909
+ if (Result .getLookupResult ().empty ())
3919
3910
continue ;
3920
3911
3921
- switch (Lookup. first .getNameKind ()) {
3912
+ switch (Name .getNameKind ()) {
3922
3913
default :
3923
- Names.push_back (Lookup. first );
3914
+ Names.push_back (Name );
3924
3915
break ;
3925
3916
3926
3917
case DeclarationName::CXXConstructorName:
3927
- assert (isa<CXXRecordDecl>(DC) &&
3928
- " Cannot have a constructor name outside of a class!" );
3929
- ConstructorNameSet.insert (Name);
3918
+ IncludeConstructorNames = true ;
3930
3919
break ;
3931
3920
3932
3921
case DeclarationName::CXXConversionFunctionName:
3933
- assert (isa<CXXRecordDecl>(DC) &&
3934
- " Cannot have a conversion function name outside of a class!" );
3935
- ConversionNameSet.insert (Name);
3922
+ IncludeConversionNames = true ;
3936
3923
break ;
3937
3924
}
3938
3925
}
3939
3926
3940
3927
// Sort the names into a stable order.
3941
3928
llvm::sort (Names);
3942
3929
3943
- if (auto *D = dyn_cast<CXXRecordDecl>(DC) ) {
3930
+ if (IncludeConstructorNames || IncludeConversionNames ) {
3944
3931
// We need to establish an ordering of constructor and conversion function
3945
- // names, and they don't have an intrinsic ordering.
3946
-
3947
- // First we try the easy case by forming the current context's constructor
3948
- // name and adding that name first. This is a very useful optimization to
3949
- // avoid walking the lexical declarations in many cases, and it also
3950
- // handles the only case where a constructor name can come from some other
3951
- // lexical context -- when that name is an implicit constructor merged from
3952
- // another declaration in the redecl chain. Any non-implicit constructor or
3953
- // conversion function which doesn't occur in all the lexical contexts
3954
- // would be an ODR violation.
3955
- auto ImplicitCtorName = Context->DeclarationNames .getCXXConstructorName (
3956
- Context->getCanonicalType (Context->getRecordType (D)));
3957
- if (ConstructorNameSet.erase (ImplicitCtorName))
3958
- Names.push_back (ImplicitCtorName);
3959
-
3960
- // If we still have constructors or conversion functions, we walk all the
3961
- // names in the decl and add the constructors and conversion functions
3962
- // which are visible in the order they lexically occur within the context.
3963
- if (!ConstructorNameSet.empty () || !ConversionNameSet.empty ())
3964
- for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls ())
3965
- if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
3966
- auto Name = ChildND->getDeclName ();
3967
- switch (Name.getNameKind ()) {
3968
- default :
3969
- continue ;
3970
-
3971
- case DeclarationName::CXXConstructorName:
3972
- if (ConstructorNameSet.erase (Name))
3973
- Names.push_back (Name);
3974
- break ;
3932
+ // names, and they don't have an intrinsic ordering. We also need to write
3933
+ // out all constructor and conversion function results if we write out any
3934
+ // of them, because they're all tracked under the same lookup key.
3935
+ llvm::SmallPtrSet<DeclarationName, 8 > AddedNames;
3936
+ for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls ()) {
3937
+ if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
3938
+ auto Name = ChildND->getDeclName ();
3939
+ switch (Name.getNameKind ()) {
3940
+ default :
3941
+ continue ;
3975
3942
3976
- case DeclarationName::CXXConversionFunctionName:
3977
- if (ConversionNameSet.erase (Name))
3978
- Names.push_back (Name);
3979
- break ;
3980
- }
3943
+ case DeclarationName::CXXConstructorName:
3944
+ if (!IncludeConstructorNames)
3945
+ continue ;
3946
+ break ;
3981
3947
3982
- if (ConstructorNameSet.empty () && ConversionNameSet.empty ())
3983
- break ;
3948
+ case DeclarationName::CXXConversionFunctionName:
3949
+ if (!IncludeConversionNames)
3950
+ continue ;
3951
+ break ;
3984
3952
}
3985
-
3986
- assert (ConstructorNameSet.empty () && " Failed to find all of the visible "
3987
- " constructors by walking all the "
3988
- " lexical members of the context." );
3989
- assert (ConversionNameSet.empty () && " Failed to find all of the visible "
3990
- " conversion functions by walking all "
3991
- " the lexical members of the context." );
3953
+ // We should include lookup results for this name.
3954
+ if (AddedNames.insert (Name).second )
3955
+ Names.push_back (Name);
3956
+ }
3957
+ }
3992
3958
}
3993
3959
3994
3960
// Next we need to do a lookup with each name into this decl context to fully
0 commit comments