diff options
author | Richard Smith <richard@metafoo.co.uk> | 2020-11-25 15:22:51 -0800 |
---|---|---|
committer | Richard Smith <richard@metafoo.co.uk> | 2020-11-25 16:25:33 -0800 |
commit | 3fb0879867d7039cb61ffb6287ac17ac949adfa9 (patch) | |
tree | 5b96af6b5b8db644781b334a4ac0130c27ffab7d /clang/lib/AST/CXXInheritance.cpp | |
parent | 1363dfaf3105470e1724ed1f17c6d9c0713f442e (diff) | |
download | llvm-3fb0879867d7039cb61ffb6287ac17ac949adfa9.zip llvm-3fb0879867d7039cb61ffb6287ac17ac949adfa9.tar.gz llvm-3fb0879867d7039cb61ffb6287ac17ac949adfa9.tar.bz2 |
Refactor and simplify class scope name lookup.
This is partly in preparation for an upcoming change that can change the
order in which DeclContext lookup results are presented.
In passing, fix some obvious errors where name lookup's notion of a
"static member function" missed static member function templates, and
where its notion of "same set of declarations" was confused by the same
declarations appearing in a different order.
Diffstat (limited to 'clang/lib/AST/CXXInheritance.cpp')
-rw-r--r-- | clang/lib/AST/CXXInheritance.cpp | 127 |
1 files changed, 35 insertions, 92 deletions
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp index 8af9711..816b5d1 100644 --- a/clang/lib/AST/CXXInheritance.cpp +++ b/clang/lib/AST/CXXInheritance.cpp @@ -402,54 +402,45 @@ bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, ->getCanonicalDecl() == BaseRecord; } -bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, - DeclarationName Name) { - RecordDecl *BaseRecord = - Specifier->getType()->castAs<RecordType>()->getDecl(); - - for (Path.Decls = BaseRecord->lookup(Name); - !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - if (Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) - return true; - } - - return false; +static bool isOrdinaryMember(const NamedDecl *ND) { + return ND->isInIdentifierNamespace(Decl::IDNS_Ordinary | Decl::IDNS_Tag | + Decl::IDNS_Member); } -static bool findOrdinaryMember(RecordDecl *BaseRecord, CXXBasePath &Path, +static bool findOrdinaryMember(const CXXRecordDecl *RD, CXXBasePath &Path, DeclarationName Name) { - const unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | - Decl::IDNS_Member; - for (Path.Decls = BaseRecord->lookup(Name); - !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - if (Path.Decls.front()->isInIdentifierNamespace(IDNS)) + Path.Decls = RD->lookup(Name); + for (NamedDecl *ND : Path.Decls) + if (isOrdinaryMember(ND)) return true; - } return false; } -bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, - DeclarationName Name) { - RecordDecl *BaseRecord = - Specifier->getType()->castAs<RecordType>()->getDecl(); - return findOrdinaryMember(BaseRecord, Path, Name); +bool CXXRecordDecl::hasMemberName(DeclarationName Name) const { + CXXBasePath P; + if (findOrdinaryMember(this, P, Name)) + return true; + + CXXBasePaths Paths(false, false, false); + return lookupInBases( + [Name](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { + return findOrdinaryMember(Specifier->getType()->getAsCXXRecordDecl(), + Path, Name); + }, + Paths); } -bool CXXRecordDecl::FindOrdinaryMemberInDependentClasses( - const CXXBaseSpecifier *Specifier, CXXBasePath &Path, - DeclarationName Name) { +static bool +findOrdinaryMemberInDependentClasses(const CXXBaseSpecifier *Specifier, + CXXBasePath &Path, DeclarationName Name) { const TemplateSpecializationType *TST = Specifier->getType()->getAs<TemplateSpecializationType>(); if (!TST) { auto *RT = Specifier->getType()->getAs<RecordType>(); if (!RT) return false; - return findOrdinaryMember(RT->getDecl(), Path, Name); + return findOrdinaryMember(cast<CXXRecordDecl>(RT->getDecl()), Path, Name); } TemplateName TN = TST->getTemplateName(); const auto *TD = dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()); @@ -461,80 +452,32 @@ bool CXXRecordDecl::FindOrdinaryMemberInDependentClasses( return findOrdinaryMember(RD, Path, Name); } -bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, - DeclarationName Name) { - RecordDecl *BaseRecord = - Specifier->getType()->castAs<RecordType>()->getDecl(); - - for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPReduction)) - return true; - } - - return false; -} - -bool CXXRecordDecl::FindOMPMapperMember(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, - DeclarationName Name) { - RecordDecl *BaseRecord = - Specifier->getType()->castAs<RecordType>()->getDecl(); - - for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPMapper)) - return true; - } - - return false; -} - -bool CXXRecordDecl:: -FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, - DeclarationName Name) { - RecordDecl *BaseRecord = - Specifier->getType()->castAs<RecordType>()->getDecl(); - - for (Path.Decls = BaseRecord->lookup(Name); - !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - // FIXME: Refactor the "is it a nested-name-specifier?" check - if (isa<TypedefNameDecl>(Path.Decls.front()) || - Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag)) - return true; - } - - return false; -} - std::vector<const NamedDecl *> CXXRecordDecl::lookupDependentName( - const DeclarationName &Name, + DeclarationName Name, llvm::function_ref<bool(const NamedDecl *ND)> Filter) { std::vector<const NamedDecl *> Results; // Lookup in the class. - DeclContext::lookup_result DirectResult = lookup(Name); - if (!DirectResult.empty()) { - for (const NamedDecl *ND : DirectResult) { - if (Filter(ND)) - Results.push_back(ND); - } - return Results; + bool AnyOrdinaryMembers = false; + for (const NamedDecl *ND : lookup(Name)) { + if (isOrdinaryMember(ND)) + AnyOrdinaryMembers = true; + if (Filter(ND)) + Results.push_back(ND); } + if (AnyOrdinaryMembers) + return Results; + // Perform lookup into our base classes. CXXBasePaths Paths; Paths.setOrigin(this); if (!lookupInBases( [&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { - return CXXRecordDecl::FindOrdinaryMemberInDependentClasses( - Specifier, Path, Name); + return findOrdinaryMemberInDependentClasses(Specifier, Path, Name); }, Paths, /*LookupInDependent=*/true)) return Results; for (const NamedDecl *ND : Paths.front().Decls) { - if (Filter(ND)) + if (isOrdinaryMember(ND) && Filter(ND)) Results.push_back(ND); } return Results; |