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
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());
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
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 =
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();
///
/// 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,
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());
}