summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/tools/clang/lib/AST/CXXInheritance.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2017-10-04 20:27:34 +0000
committerpatrick <patrick@openbsd.org>2017-10-04 20:27:34 +0000
commit31eb748944903b7f4f38afda9851951ca9dfc1ae (patch)
tree9b95b6ea45d0874d75eb05b90c0840e191416439 /gnu/llvm/tools/clang/lib/AST/CXXInheritance.cpp
parentDon't try to handle IPv4-compatible IPv6 addresses (diff)
downloadwireguard-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.cpp126
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