@@ -7999,6 +7999,18 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
79997999
80008000 QualType BaseType = Base->getType ();
80018001 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+ }
80028014
80038015 // C++ [over.match.oper]p8:
80048016 // [...] When operator->returns, the operator-> is applied to the value
@@ -8013,7 +8025,7 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
80138025 SmallVector<FunctionDecl*, 8 > OperatorArrows;
80148026 CTypes.insert (Context.getCanonicalType (BaseType));
80158027
8016- while (BaseType->getAsRecordDecl ()) {
8028+ while (BaseType->isRecordType ()) {
80178029 if (OperatorArrows.size () >= getLangOpts ().ArrowDepth ) {
80188030 Diag (OpLoc, diag::err_operator_arrow_depth_exceeded)
80198031 << StartingType << getLangOpts ().ArrowDepth << Base->getSourceRange ();
@@ -8024,7 +8036,7 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
80248036 }
80258037
80268038 Result = BuildOverloadedArrowExpr (
8027- Base, OpLoc,
8039+ S, Base, OpLoc,
80288040 // When in a template specialization and on the first loop iteration,
80298041 // potentially give the default diagnostic (with the fixit in a
80308042 // separate note) instead of having the error reported back to here
@@ -8088,7 +8100,7 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
80888100 // it's legal for the type to be incomplete if this is a pseudo-destructor
80898101 // call. We'll do more incomplete-type checks later in the lookup process,
80908102 // so just skip this check for ObjC types.
8091- if (BaseType-> isDependentType () || !BaseType->isRecordType ()) {
8103+ if (!BaseType->isRecordType ()) {
80928104 ObjectType = ParsedType::make (BaseType);
80938105 MayBePseudoDestructor = true ;
80948106 return Base;
@@ -8099,7 +8111,8 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
80998111 // Unlike the object expression in other contexts, *this is not required to
81008112 // be of complete type for purposes of class member access (5.2.5) outside
81018113 // the member function body.
8102- if (!isThisOutsideMemberFunctionBody (BaseType) &&
8114+ if (!BaseType->isDependentType () &&
8115+ !isThisOutsideMemberFunctionBody (BaseType) &&
81038116 RequireCompleteType (OpLoc, BaseType,
81048117 diag::err_incomplete_member_access)) {
81058118 return CreateRecoveryExpr (Base->getBeginLoc (), Base->getEndLoc (), {Base});
0 commit comments