@@ -7999,6 +7999,18 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
7999
7999
8000
8000
QualType BaseType = Base->getType();
8001
8001
MayBePseudoDestructor = false;
8002
+ if (BaseType->isDependentType()) {
8003
+ // If we have a pointer to a dependent type and are using the -> operator,
8004
+ // the object type is the type that the pointer points to. We might still
8005
+ // have enough information about that type to do something useful.
8006
+ if (OpKind == tok::arrow)
8007
+ if (const PointerType *Ptr = BaseType->getAs<PointerType>())
8008
+ BaseType = Ptr->getPointeeType();
8009
+
8010
+ ObjectType = ParsedType::make(BaseType);
8011
+ MayBePseudoDestructor = true;
8012
+ return Base;
8013
+ }
8002
8014
8003
8015
// C++ [over.match.oper]p8:
8004
8016
// [...] When operator->returns, the operator-> is applied to the value
@@ -8013,7 +8025,7 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
8013
8025
SmallVector<FunctionDecl*, 8> OperatorArrows;
8014
8026
CTypes.insert(Context.getCanonicalType(BaseType));
8015
8027
8016
- while (BaseType->getAsRecordDecl ()) {
8028
+ while (BaseType->isRecordType ()) {
8017
8029
if (OperatorArrows.size() >= getLangOpts().ArrowDepth) {
8018
8030
Diag(OpLoc, diag::err_operator_arrow_depth_exceeded)
8019
8031
<< StartingType << getLangOpts().ArrowDepth << Base->getSourceRange();
@@ -8024,7 +8036,7 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
8024
8036
}
8025
8037
8026
8038
Result = BuildOverloadedArrowExpr(
8027
- Base, OpLoc,
8039
+ S, Base, OpLoc,
8028
8040
// When in a template specialization and on the first loop iteration,
8029
8041
// potentially give the default diagnostic (with the fixit in a
8030
8042
// separate note) instead of having the error reported back to here
@@ -8088,7 +8100,7 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
8088
8100
// it's legal for the type to be incomplete if this is a pseudo-destructor
8089
8101
// call. We'll do more incomplete-type checks later in the lookup process,
8090
8102
// so just skip this check for ObjC types.
8091
- if (BaseType->isDependentType() || !BaseType->isRecordType()) {
8103
+ if (!BaseType->isRecordType()) {
8092
8104
ObjectType = ParsedType::make(BaseType);
8093
8105
MayBePseudoDestructor = true;
8094
8106
return Base;
@@ -8099,7 +8111,8 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
8099
8111
// Unlike the object expression in other contexts, *this is not required to
8100
8112
// be of complete type for purposes of class member access (5.2.5) outside
8101
8113
// the member function body.
8102
- if (!isThisOutsideMemberFunctionBody(BaseType) &&
8114
+ if (!BaseType->isDependentType() &&
8115
+ !isThisOutsideMemberFunctionBody(BaseType) &&
8103
8116
RequireCompleteType(OpLoc, BaseType,
8104
8117
diag::err_incomplete_member_access)) {
8105
8118
return CreateRecoveryExpr(Base->getBeginLoc(), Base->getEndLoc(), {Base});
0 commit comments