Pull out conversion on LHS of -> and . into its own function. This happens

implicitly in LookupMemberExpr and explicitly in cases where template
instantiation doesn't redo the lookup.

llvm-svn: 143046
This commit is contained in:
Richard Smith 2011-10-26 19:06:56 +00:00
parent 16133782dc
commit cab9a7d51c
3 changed files with 28 additions and 42 deletions

View File

@ -2443,6 +2443,7 @@ public:
const TemplateArgumentListInfo *TemplateArgs,
bool SuppressQualifierCheck = false);
ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow);
ExprResult LookupMemberExpr(LookupResult &R, ExprResult &Base,
bool &IsArrow, SourceLocation OpLoc,
CXXScopeSpec &SS,

View File

@ -970,6 +970,17 @@ static bool isPointerToRecordType(QualType T) {
return false;
}
/// Perform conversions on the LHS of a member access expression.
ExprResult
Sema::PerformMemberExprBaseConversion(Expr *Base, bool IsArrow) {
ExprResult BaseResult = DefaultFunctionArrayConversion(Base);
if (!BaseResult.isInvalid() && IsArrow)
BaseResult = DefaultLvalueConversion(BaseResult.take());
return BaseResult;
}
/// Look up the given member of the given non-type-dependent
/// expression. This can return in one of two ways:
/// * If it returns a sentinel null-but-valid result, the caller will
@ -988,16 +999,10 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
assert(BaseExpr.get() && "no base expression");
// Perform default conversions.
BaseExpr = DefaultFunctionArrayConversion(BaseExpr.take());
BaseExpr = PerformMemberExprBaseConversion(BaseExpr.take(), IsArrow);
if (BaseExpr.isInvalid())
return ExprError();
if (IsArrow) {
BaseExpr = DefaultLvalueConversion(BaseExpr.take());
if (BaseExpr.isInvalid())
return ExprError();
}
QualType BaseType = BaseExpr.get()->getType();
assert(!BaseType->isDependentType());

View File

@ -1468,6 +1468,8 @@ public:
NamedDecl *FoundDecl,
const TemplateArgumentListInfo *ExplicitTemplateArgs,
NamedDecl *FirstQualifierInScope) {
ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
isArrow);
if (!Member->getDeclName()) {
// We have a reference to an unnamed field. This is always the
// base of an anonymous struct/union member access, i.e. the
@ -1476,17 +1478,12 @@ public:
assert(Member->getType()->isRecordType() &&
"unnamed member not of record type?");
ExprResult BaseResult =
getSema().PerformObjectMemberConversion(Base,
BaseResult =
getSema().PerformObjectMemberConversion(BaseResult.take(),
QualifierLoc.getNestedNameSpecifier(),
FoundDecl, Member);
if (BaseResult.isInvalid())
return ExprError();
if (isArrow) {
BaseResult = getSema().DefaultLvalueConversion(BaseResult.take());
if (BaseResult.isInvalid())
return ExprError();
}
Base = BaseResult.take();
ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind();
MemberExpr *ME =
@ -1500,14 +1497,6 @@ public:
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
ExprResult BaseResult = getSema().DefaultFunctionArrayConversion(Base);
if (BaseResult.isInvalid())
return ExprError();
if (isArrow) {
BaseResult = getSema().DefaultLvalueConversion(BaseResult.get());
if (BaseResult.isInvalid())
return ExprError();
}
Base = BaseResult.take();
QualType BaseType = Base->getType();
@ -2134,30 +2123,16 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE,
QualType BaseType,
SourceLocation OperatorLoc,
bool IsArrow,
NestedNameSpecifierLoc QualifierLoc,
NamedDecl *FirstQualifierInScope,
LookupResult &R,
ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
SourceLocation OperatorLoc,
bool IsArrow,
NestedNameSpecifierLoc QualifierLoc,
NamedDecl *FirstQualifierInScope,
LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs) {
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
if (BaseE) {
ExprResult BaseResult = getSema().DefaultFunctionArrayConversion(BaseE);
if (BaseResult.isInvalid())
return ExprError();
if (IsArrow) {
BaseResult = getSema().DefaultLvalueConversion(BaseResult.take());
if (BaseResult.isInvalid())
return ExprError();
}
BaseE = BaseResult.take();
BaseType = BaseE->getType();
}
return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
OperatorLoc, IsArrow,
SS, FirstQualifierInScope,
@ -7707,6 +7682,11 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
Base = getDerived().TransformExpr(Old->getBase());
if (Base.isInvalid())
return ExprError();
Base = getSema().PerformMemberExprBaseConversion(Base.take(),
Old->isArrow());
if (Base.isInvalid())
return ExprError();
BaseType = Base.get()->getType();
} else {
BaseType = getDerived().TransformType(Old->getBaseType());
}