Implement access control for overloaded functions. Suppress access control
diagnostics in "early" lookups, such as during typename checks and when building
unresolved lookup expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94647 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index a6574ef..475dcf2 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -116,6 +116,7 @@
// UnresolvedLookupExpr
UnresolvedLookupExpr *
UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
+ CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange, DeclarationName Name,
SourceLocation NameLoc, bool ADL,
@@ -125,7 +126,8 @@
ExplicitTemplateArgumentList::sizeFor(Args));
UnresolvedLookupExpr *ULE
= new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
- Dependent, Qualifier, QualifierRange,
+ Dependent, NamingClass,
+ Qualifier, QualifierRange,
Name, NameLoc, ADL,
/*Overload*/ true,
/*ExplicitTemplateArgs*/ true);
@@ -651,6 +653,35 @@
Member, MemberLoc, TemplateArgs);
}
+CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
+ // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
+
+ // If there was a nested name specifier, it names the naming class.
+ // It can't be dependent: after all, we were actually able to do the
+ // lookup.
+ const RecordType *RT;
+ if (Qualifier) {
+ Type *T = Qualifier->getAsType();
+ assert(T && "qualifier in member expression does not name type");
+ RT = T->getAs<RecordType>();
+ assert(RT && "qualifier in member expression does not name record");
+
+ // Otherwise the naming class must have been the base class.
+ } else {
+ QualType BaseType = getBaseType().getNonReferenceType();
+ if (isArrow()) {
+ const PointerType *PT = BaseType->getAs<PointerType>();
+ assert(PT && "base of arrow member access is not pointer");
+ BaseType = PT->getPointeeType();
+ }
+
+ RT = BaseType->getAs<RecordType>();
+ assert(RT && "base of member expression does not name record");
+ }
+
+ return cast<CXXRecordDecl>(RT->getDecl());
+}
+
Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
return child_iterator(&Base);
}