@@ -3940,12 +3940,6 @@ class ASTDeclContextNameLookupTrait {
3940
3940
3941
3941
} // namespace
3942
3942
3943
- bool ASTWriter::isLookupResultExternal (StoredDeclsList &Result,
3944
- DeclContext *DC) {
3945
- return Result.hasExternalDecls () &&
3946
- DC->hasNeedToReconcileExternalVisibleStorage ();
3947
- }
3948
-
3949
3943
bool ASTWriter::isLookupResultEntirelyExternal (StoredDeclsList &Result,
3950
3944
DeclContext *DC) {
3951
3945
for (auto *D : Result.getLookupResult ())
@@ -3976,20 +3970,17 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
3976
3970
// order.
3977
3971
SmallVector<DeclarationName, 16 > Names;
3978
3972
3979
- // We also build up small sets of the constructor and conversion function
3980
- // names which are visible.
3981
- llvm::SmallPtrSet<DeclarationName, 8 > ConstructorNameSet, ConversionNameSet;
3982
-
3983
- for (auto &Lookup : *DC->buildLookup ()) {
3984
- auto &Name = Lookup.first ;
3985
- auto &Result = Lookup.second ;
3973
+ // We also track whether we're writing out the DeclarationNameKey for
3974
+ // constructors or conversion functions.
3975
+ bool IncludeConstructorNames = false ;
3976
+ bool IncludeConversionNames = false ;
3986
3977
3978
+ for (auto &[Name, Result] : *DC->buildLookup ()) {
3987
3979
// If there are no local declarations in our lookup result, we
3988
3980
// don't need to write an entry for the name at all. If we can't
3989
3981
// write out a lookup set without performing more deserialization,
3990
3982
// just skip this entry.
3991
- if (isLookupResultExternal (Result, DC) &&
3992
- isLookupResultEntirelyExternal (Result, DC))
3983
+ if (isLookupResultEntirelyExternal (Result, DC))
3993
3984
continue ;
3994
3985
3995
3986
// We also skip empty results. If any of the results could be external and
@@ -4006,80 +3997,55 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
4006
3997
// results for them. This in almost certainly a bug in Clang's name lookup,
4007
3998
// but that is likely to be hard or impossible to fix and so we tolerate it
4008
3999
// here by omitting lookups with empty results.
4009
- if (Lookup. second .getLookupResult ().empty ())
4000
+ if (Result .getLookupResult ().empty ())
4010
4001
continue ;
4011
4002
4012
- switch (Lookup. first .getNameKind ()) {
4003
+ switch (Name .getNameKind ()) {
4013
4004
default :
4014
- Names.push_back (Lookup. first );
4005
+ Names.push_back (Name );
4015
4006
break ;
4016
4007
4017
4008
case DeclarationName::CXXConstructorName:
4018
- assert (isa<CXXRecordDecl>(DC) &&
4019
- " Cannot have a constructor name outside of a class!" );
4020
- ConstructorNameSet.insert (Name);
4009
+ IncludeConstructorNames = true ;
4021
4010
break ;
4022
4011
4023
4012
case DeclarationName::CXXConversionFunctionName:
4024
- assert (isa<CXXRecordDecl>(DC) &&
4025
- " Cannot have a conversion function name outside of a class!" );
4026
- ConversionNameSet.insert (Name);
4013
+ IncludeConversionNames = true ;
4027
4014
break ;
4028
4015
}
4029
4016
}
4030
4017
4031
4018
// Sort the names into a stable order.
4032
4019
llvm::sort (Names);
4033
4020
4034
- if (auto *D = dyn_cast<CXXRecordDecl>(DC) ) {
4021
+ if (IncludeConstructorNames || IncludeConversionNames ) {
4035
4022
// We need to establish an ordering of constructor and conversion function
4036
- // names, and they don't have an intrinsic ordering.
4037
-
4038
- // First we try the easy case by forming the current context's constructor
4039
- // name and adding that name first. This is a very useful optimization to
4040
- // avoid walking the lexical declarations in many cases, and it also
4041
- // handles the only case where a constructor name can come from some other
4042
- // lexical context -- when that name is an implicit constructor merged from
4043
- // another declaration in the redecl chain. Any non-implicit constructor or
4044
- // conversion function which doesn't occur in all the lexical contexts
4045
- // would be an ODR violation.
4046
- auto ImplicitCtorName = Context->DeclarationNames .getCXXConstructorName (
4047
- Context->getCanonicalType (Context->getRecordType (D)));
4048
- if (ConstructorNameSet.erase (ImplicitCtorName))
4049
- Names.push_back (ImplicitCtorName);
4050
-
4051
- // If we still have constructors or conversion functions, we walk all the
4052
- // names in the decl and add the constructors and conversion functions
4053
- // which are visible in the order they lexically occur within the context.
4054
- if (!ConstructorNameSet.empty () || !ConversionNameSet.empty ())
4055
- for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls ())
4056
- if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
4057
- auto Name = ChildND->getDeclName ();
4058
- switch (Name.getNameKind ()) {
4059
- default :
4060
- continue ;
4061
-
4062
- case DeclarationName::CXXConstructorName:
4063
- if (ConstructorNameSet.erase (Name))
4064
- Names.push_back (Name);
4065
- break ;
4023
+ // names, and they don't have an intrinsic ordering. We also need to write
4024
+ // out all constructor and conversion function results if we write out any
4025
+ // of them, because they're all tracked under the same lookup key.
4026
+ llvm::SmallPtrSet<DeclarationName, 8 > AddedNames;
4027
+ for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls ()) {
4028
+ if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
4029
+ auto Name = ChildND->getDeclName ();
4030
+ switch (Name.getNameKind ()) {
4031
+ default :
4032
+ continue ;
4066
4033
4067
- case DeclarationName::CXXConversionFunctionName:
4068
- if (ConversionNameSet.erase (Name))
4069
- Names.push_back (Name);
4070
- break ;
4071
- }
4034
+ case DeclarationName::CXXConstructorName:
4035
+ if (!IncludeConstructorNames)
4036
+ continue ;
4037
+ break ;
4072
4038
4073
- if (ConstructorNameSet.empty () && ConversionNameSet.empty ())
4074
- break ;
4039
+ case DeclarationName::CXXConversionFunctionName:
4040
+ if (!IncludeConversionNames)
4041
+ continue ;
4042
+ break ;
4075
4043
}
4076
-
4077
- assert (ConstructorNameSet.empty () && " Failed to find all of the visible "
4078
- " constructors by walking all the "
4079
- " lexical members of the context." );
4080
- assert (ConversionNameSet.empty () && " Failed to find all of the visible "
4081
- " conversion functions by walking all "
4082
- " the lexical members of the context." );
4044
+ // We should include lookup results for this name.
4045
+ if (AddedNames.insert (Name).second )
4046
+ Names.push_back (Name);
4047
+ }
4048
+ }
4083
4049
}
4084
4050
4085
4051
// Next we need to do a lookup with each name into this decl context to fully
0 commit comments