diff options
Diffstat (limited to 'lib/Sema/SemaExprMember.cpp')
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 95 |
1 files changed, 73 insertions, 22 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 6c84caa..53f22f6 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -115,7 +115,7 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, NamedDecl *D = *I; if (D->isCXXInstanceMember()) { - if (dyn_cast<FieldDecl>(D)) + if (dyn_cast<FieldDecl>(D) || dyn_cast<IndirectFieldDecl>(D)) isField = true; CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext()); @@ -436,8 +436,8 @@ Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType, if (PT && (!getLangOpts().ObjC1 || PT->getPointeeType()->isRecordType())) { assert(BaseExpr && "cannot happen with implicit member accesses"); - Diag(NameInfo.getLoc(), diag::err_typecheck_member_reference_struct_union) - << BaseType << BaseExpr->getSourceRange(); + Diag(OpLoc, diag::err_typecheck_member_reference_struct_union) + << BaseType << BaseExpr->getSourceRange() << NameInfo.getSourceRange(); return ExprError(); } } @@ -548,8 +548,8 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, RecordDecl *RDecl = RTy->getDecl(); if (!SemaRef.isThisOutsideMemberFunctionBody(QualType(RTy, 0)) && SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0), - SemaRef.PDiag(diag::err_typecheck_incomplete_tag) - << BaseRange)) + diag::err_typecheck_incomplete_tag, + BaseRange)) return true; if (HasTemplateArgs) { @@ -813,8 +813,9 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, LookupResult &R, - const TemplateArgumentListInfo *TemplateArgs, - bool SuppressQualifierCheck) { + const TemplateArgumentListInfo *TemplateArgs, + bool SuppressQualifierCheck, + ActOnMemberAccessExtraArgs *ExtraArgs) { QualType BaseType = BaseExprType; if (IsArrow) { assert(BaseType->isPointerType()); @@ -835,6 +836,32 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, ? computeDeclContext(SS, false) : BaseType->getAs<RecordType>()->getDecl()); + if (ExtraArgs) { + ExprResult RetryExpr; + if (!IsArrow && BaseExpr) { + SFINAETrap Trap(*this, true); + ParsedType ObjectType; + bool MayBePseudoDestructor = false; + RetryExpr = ActOnStartCXXMemberReference(getCurScope(), BaseExpr, + OpLoc, tok::arrow, ObjectType, + MayBePseudoDestructor); + if (RetryExpr.isUsable() && !Trap.hasErrorOccurred()) { + CXXScopeSpec TempSS(SS); + RetryExpr = ActOnMemberAccessExpr( + ExtraArgs->S, RetryExpr.get(), OpLoc, tok::arrow, TempSS, + TemplateKWLoc, ExtraArgs->Id, ExtraArgs->ObjCImpDecl, + ExtraArgs->HasTrailingLParen); + } + if (Trap.hasErrorOccurred()) + RetryExpr = ExprError(); + } + if (RetryExpr.isUsable()) { + Diag(OpLoc, diag::err_no_member_overloaded_arrow) + << MemberName << DC << FixItHint::CreateReplacement(OpLoc, "->"); + return RetryExpr; + } + } + Diag(R.getNameLoc(), diag::err_no_member) << MemberName << DC << (BaseExpr ? BaseExpr->getSourceRange() : SourceRange()); @@ -1122,10 +1149,22 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, ObjCImpDecl, HasTemplateArgs); goto fail; } - - if (RequireCompleteType(OpLoc, BaseType, - PDiag(diag::err_typecheck_incomplete_tag) - << BaseExpr.get()->getSourceRange())) + else if (Member && Member->isStr("isa")) { + // If an ivar is (1) the first ivar in a root class and (2) named `isa`, + // then issue the same deprecated warning that id->isa gets. + ObjCInterfaceDecl *ClassDeclared = 0; + if (ObjCIvarDecl *IV = + IDecl->lookupInstanceVariable(Member, ClassDeclared)) { + if (!ClassDeclared->getSuperClass() + && (*ClassDeclared->ivar_begin()) == IV) { + Diag(MemberLoc, diag::warn_objc_isa_use); + Diag(IV->getLocation(), diag::note_ivar_decl); + } + } + } + + if (RequireCompleteType(OpLoc, BaseType, diag::err_typecheck_incomplete_tag, + BaseExpr.get())) return ExprError(); ObjCInterfaceDecl *ClassDeclared = 0; @@ -1211,6 +1250,7 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, << IV->getDeclName(); } } + bool warn = true; if (getLangOpts().ObjCAutoRefCount) { Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts(); if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp)) @@ -1218,10 +1258,20 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, BaseExp = UO->getSubExpr()->IgnoreParenCasts(); if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp)) - if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) + if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { Diag(DE->getLocation(), diag::error_arc_weak_ivar_access); + warn = false; + } + } + if (warn) { + if (ObjCMethodDecl *MD = getCurMethodDecl()) { + ObjCMethodFamily MF = MD->getMethodFamily(); + warn = (MF != OMF_init && MF != OMF_dealloc && + MF != OMF_finalize); + } + if (warn) + Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName(); } - return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr.take(), IsArrow)); @@ -1327,9 +1377,6 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, // methods. Setter = IFace->lookupPrivateMethod(SetterSel, false); } - // Look through local category implementations associated with the class. - if (!Setter) - Setter = IFace->getCategoryClassMethod(SetterSel); if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc)) return ExprError(); @@ -1418,8 +1465,8 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, ObjCImpDecl, HasTemplateArgs); } - Diag(MemberLoc, diag::err_typecheck_member_reference_struct_union) - << BaseType << BaseExpr.get()->getSourceRange(); + Diag(OpLoc, diag::err_typecheck_member_reference_struct_union) + << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc; return ExprError(); } @@ -1434,9 +1481,9 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, /// \param HasTrailingLParen whether the next token is '(', which /// is used to diagnose mis-uses of special members that can /// only be called -/// \param ObjCImpDecl the current ObjC @implementation decl; -/// this is an ugly hack around the fact that ObjC @implementations -/// aren't properly put in the context chain +/// \param ObjCImpDecl the current Objective-C \@implementation +/// decl; this is an ugly hack around the fact that Objective-C +/// \@implementations aren't properly put in the context chain ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, @@ -1506,9 +1553,11 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, return move(Result); } + ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl, HasTrailingLParen}; Result = BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc, - FirstQualifierInScope, R, TemplateArgs); + FirstQualifierInScope, R, TemplateArgs, + false, &ExtraArgs); } return move(Result); @@ -1563,6 +1612,8 @@ BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow, MemberType = S.Context.getQualifiedType(MemberType, Combined); } + S.UnusedPrivateFields.remove(Field); + ExprResult Base = S.PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(), FoundDecl, Field); |