diff options
| author | 2017-10-04 20:27:34 +0000 | |
|---|---|---|
| committer | 2017-10-04 20:27:34 +0000 | |
| commit | 31eb748944903b7f4f38afda9851951ca9dfc1ae (patch) | |
| tree | 9b95b6ea45d0874d75eb05b90c0840e191416439 /gnu/llvm/tools/clang/lib/AST/CXXInheritance.cpp | |
| parent | Don't try to handle IPv4-compatible IPv6 addresses (diff) | |
| download | wireguard-openbsd-31eb748944903b7f4f38afda9851951ca9dfc1ae.tar.xz wireguard-openbsd-31eb748944903b7f4f38afda9851951ca9dfc1ae.zip | |
Import LLVM 5.0.0 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/AST/CXXInheritance.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/AST/CXXInheritance.cpp | 126 |
1 files changed, 106 insertions, 20 deletions
diff --git a/gnu/llvm/tools/clang/lib/AST/CXXInheritance.cpp b/gnu/llvm/tools/clang/lib/AST/CXXInheritance.cpp index a97d6a22e7b..fc4d8b13733 100644 --- a/gnu/llvm/tools/clang/lib/AST/CXXInheritance.cpp +++ b/gnu/llvm/tools/clang/lib/AST/CXXInheritance.cpp @@ -13,6 +13,7 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/RecordLayout.h" #include "llvm/ADT/SetVector.h" #include <algorithm> @@ -56,6 +57,7 @@ bool CXXBasePaths::isAmbiguous(CanQualType BaseType) { void CXXBasePaths::clear() { Paths.clear(); ClassSubobjects.clear(); + VisitedDependentRecords.clear(); ScratchPath.clear(); DetectedVirtual = nullptr; } @@ -66,6 +68,7 @@ void CXXBasePaths::swap(CXXBasePaths &Other) { std::swap(Origin, Other.Origin); Paths.swap(Other.Paths); ClassSubobjects.swap(Other.ClassSubobjects); + VisitedDependentRecords.swap(Other.VisitedDependentRecords); std::swap(FindAmbiguities, Other.FindAmbiguities); std::swap(RecordPaths, Other.RecordPaths); std::swap(DetectVirtual, Other.DetectVirtual); @@ -88,7 +91,7 @@ bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base, const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl(); // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7. return lookupInBases( - [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { + [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { return FindBaseClass(Specifier, Path, BaseDecl); }, Paths); @@ -109,7 +112,7 @@ bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const { const CXXRecordDecl *BaseDecl = Base->getCanonicalDecl(); // FIXME: Capturing 'this' is a workaround for name lookup bugs in GCC 4.7. return lookupInBases( - [this, BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { + [BaseDecl](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { return FindVirtualBaseClass(Specifier, Path, BaseDecl); }, Paths); @@ -174,9 +177,10 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches, return AllMatches; } -bool CXXBasePaths::lookupInBases( - ASTContext &Context, const CXXRecordDecl *Record, - CXXRecordDecl::BaseMatchesCallback BaseMatches) { +bool CXXBasePaths::lookupInBases(ASTContext &Context, + const CXXRecordDecl *Record, + CXXRecordDecl::BaseMatchesCallback BaseMatches, + bool LookupInDependent) { bool FoundPath = false; // The access of the path down to this record. @@ -194,7 +198,7 @@ bool CXXBasePaths::lookupInBases( // the base class scope is not examined during unqualified name lookup // either at the point of definition of the class template or member or // during an instantiation of the class tem- plate or member. - if (BaseType->isDependentType()) + if (!LookupInDependent && BaseType->isDependentType()) continue; // Determine whether we need to visit this base class at all, @@ -262,10 +266,34 @@ bool CXXBasePaths::lookupInBases( return FoundPath; } } else if (VisitBase) { - CXXRecordDecl *BaseRecord - = cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>() - ->getDecl()); - if (lookupInBases(Context, BaseRecord, BaseMatches)) { + CXXRecordDecl *BaseRecord; + if (LookupInDependent) { + BaseRecord = nullptr; + const TemplateSpecializationType *TST = + BaseSpec.getType()->getAs<TemplateSpecializationType>(); + if (!TST) { + if (auto *RT = BaseSpec.getType()->getAs<RecordType>()) + BaseRecord = cast<CXXRecordDecl>(RT->getDecl()); + } else { + TemplateName TN = TST->getTemplateName(); + if (auto *TD = + dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl())) + BaseRecord = TD->getTemplatedDecl(); + } + if (BaseRecord) { + if (!BaseRecord->hasDefinition() || + VisitedDependentRecords.count(BaseRecord)) { + BaseRecord = nullptr; + } else { + VisitedDependentRecords.insert(BaseRecord); + } + } + } else { + BaseRecord = cast<CXXRecordDecl>( + BaseSpec.getType()->castAs<RecordType>()->getDecl()); + } + if (BaseRecord && + lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) { // C++ [class.member.lookup]p2: // A member name f in one sub-object B hides a member name f in // a sub-object A if A is a base class sub-object of B. Any @@ -299,9 +327,11 @@ bool CXXBasePaths::lookupInBases( } bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches, - CXXBasePaths &Paths) const { + CXXBasePaths &Paths, + bool LookupInDependent) const { // If we didn't find anything, report that. - if (!Paths.lookupInBases(getASTContext(), this, BaseMatches)) + if (!Paths.lookupInBases(getASTContext(), this, BaseMatches, + LookupInDependent)) return false; // If we're not recording paths or we won't ever find ambiguities, @@ -387,23 +417,49 @@ bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, return false; } -bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, - DeclarationName Name) { - RecordDecl *BaseRecord = - Specifier->getType()->castAs<RecordType>()->getDecl(); - - const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member; +static bool findOrdinaryMember(RecordDecl *BaseRecord, CXXBasePath &Path, + DeclarationName Name) { + const unsigned IDNS = clang::Decl::IDNS_Ordinary | clang::Decl::IDNS_Tag | + clang::Decl::IDNS_Member; for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); Path.Decls = Path.Decls.slice(1)) { if (Path.Decls.front()->isInIdentifierNamespace(IDNS)) 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::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); + } + TemplateName TN = TST->getTemplateName(); + const auto *TD = dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()); + if (!TD) + return false; + CXXRecordDecl *RD = TD->getTemplatedDecl(); + if (!RD) + return false; + return findOrdinaryMember(RD, Path, Name); +} + bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, DeclarationName Name) { @@ -438,6 +494,36 @@ FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, return false; } +std::vector<const NamedDecl *> CXXRecordDecl::lookupDependentName( + const 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; + } + // Perform lookup into our base classes. + CXXBasePaths Paths; + Paths.setOrigin(this); + if (!lookupInBases( + [&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { + return CXXRecordDecl::FindOrdinaryMemberInDependentClasses( + Specifier, Path, Name); + }, + Paths, /*LookupInDependent=*/true)) + return Results; + for (const NamedDecl *ND : Paths.front().Decls) { + if (Filter(ND)) + Results.push_back(ND); + } + return Results; +} + void OverridingMethods::add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding) { SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides |
