aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-03-30 21:47:33 +0000
committerJohn McCall <rjmccall@apple.com>2010-03-30 21:47:33 +0000
commit6bb8017bb9e828d118e15e59d71c66bba323c364 (patch)
treec642fbc5f1f809b4e97bc13e5b663d78b4f94200 /lib/Sema/SemaStmt.cpp
parent366ed48c52dc813c82c3d780ee35a195ec05b3f4 (diff)
Propagate the "found declaration" (i.e. the using declaration instead of
the underlying/instantiated decl) through a lot of API, including "intermediate" MemberExprs required for (e.g.) template instantiation. This is necessary because of the access semantics of member accesses to using declarations: only the base class *containing the using decl* need be accessible from the naming class. This allows us to complete an access-controlled selfhost, if there are no recent regressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99936 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r--lib/Sema/SemaStmt.cpp41
1 files changed, 25 insertions, 16 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 1e37bb00c4..fd30a5360e 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -437,32 +437,35 @@ static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc,
<< CondExpr->getSourceRange()))
return true;
- llvm::SmallVector<CXXConversionDecl *, 4> ViableConversions;
- llvm::SmallVector<CXXConversionDecl *, 4> ExplicitConversions;
+ UnresolvedSet<4> ViableConversions;
+ UnresolvedSet<4> ExplicitConversions;
if (const RecordType *RecordTy = CondType->getAs<RecordType>()) {
const UnresolvedSetImpl *Conversions
= cast<CXXRecordDecl>(RecordTy->getDecl())
->getVisibleConversionFunctions();
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
- if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(*I))
+ if (CXXConversionDecl *Conversion
+ = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl()))
if (Conversion->getConversionType().getNonReferenceType()
->isIntegralType()) {
if (Conversion->isExplicit())
- ExplicitConversions.push_back(Conversion);
+ ExplicitConversions.addDecl(I.getDecl(), I.getAccess());
else
- ViableConversions.push_back(Conversion);
+ ViableConversions.addDecl(I.getDecl(), I.getAccess());
}
}
switch (ViableConversions.size()) {
case 0:
if (ExplicitConversions.size() == 1) {
+ DeclAccessPair Found = ExplicitConversions[0];
+ CXXConversionDecl *Conversion =
+ cast<CXXConversionDecl>(Found->getUnderlyingDecl());
// The user probably meant to invoke the given explicit
// conversion; use it.
QualType ConvTy
- = ExplicitConversions[0]->getConversionType()
- .getNonReferenceType();
+ = Conversion->getConversionType().getNonReferenceType();
std::string TypeStr;
ConvTy.getAsStringInternal(TypeStr, S.Context.PrintingPolicy);
@@ -473,8 +476,7 @@ static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc,
<< CodeModificationHint::CreateInsertion(
S.PP.getLocForEndOfToken(CondExpr->getLocEnd()),
")");
- S.Diag(ExplicitConversions[0]->getLocation(),
- diag::note_switch_conversion)
+ S.Diag(Conversion->getLocation(), diag::note_switch_conversion)
<< ConvTy->isEnumeralType() << ConvTy;
// If we aren't in a SFINAE context, build a call to the
@@ -482,25 +484,32 @@ static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc,
if (S.isSFINAEContext())
return true;
- CondExpr = S.BuildCXXMemberCallExpr(CondExpr, ExplicitConversions[0]);
+ S.CheckMemberOperatorAccess(CondExpr->getExprLoc(),
+ CondExpr, 0, Found);
+ CondExpr = S.BuildCXXMemberCallExpr(CondExpr, Found, Conversion);
}
// We'll complain below about a non-integral condition type.
break;
- case 1:
+ case 1: {
// Apply this conversion.
- CondExpr = S.BuildCXXMemberCallExpr(CondExpr, ViableConversions[0]);
+ DeclAccessPair Found = ViableConversions[0];
+ S.CheckMemberOperatorAccess(CondExpr->getExprLoc(),
+ CondExpr, 0, Found);
+ CondExpr = S.BuildCXXMemberCallExpr(CondExpr, Found,
+ cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
break;
+ }
default:
S.Diag(SwitchLoc, diag::err_switch_multiple_conversions)
<< CondType << CondExpr->getSourceRange();
for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
- QualType ConvTy
- = ViableConversions[I]->getConversionType().getNonReferenceType();
- S.Diag(ViableConversions[I]->getLocation(),
- diag::note_switch_conversion)
+ CXXConversionDecl *Conv
+ = cast<CXXConversionDecl>(ViableConversions[I]->getUnderlyingDecl());
+ QualType ConvTy = Conv->getConversionType().getNonReferenceType();
+ S.Diag(Conv->getLocation(), diag::note_switch_conversion)
<< ConvTy->isEnumeralType() << ConvTy;
}
return true;