NoDuplicateRefCntMemberChecker.cpp (2627B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "NoDuplicateRefCntMemberChecker.h" 6 #include "CustomMatchers.h" 7 8 void NoDuplicateRefCntMemberChecker::registerMatchers(MatchFinder *AstMatcher) { 9 AstMatcher->addMatcher(cxxRecordDecl().bind("decl"), this); 10 } 11 12 void NoDuplicateRefCntMemberChecker::check( 13 const MatchFinder::MatchResult &Result) { 14 const CXXRecordDecl *D = Result.Nodes.getNodeAs<CXXRecordDecl>("decl"); 15 const FieldDecl *RefCntMember = getClassRefCntMember(D); 16 const FieldDecl *FoundRefCntBase = nullptr; 17 18 if (!D->hasDefinition()) 19 return; 20 D = D->getDefinition(); 21 22 // If we don't have an mRefCnt member, and we have less than 2 superclasses, 23 // we don't have to run this loop, as neither case will ever apply. 24 if (!RefCntMember && D->getNumBases() < 2) { 25 return; 26 } 27 28 // Check every superclass for whether it has a base with a refcnt member, and 29 // warn for those which do 30 for (auto &Base : D->bases()) { 31 // Determine if this base class has an mRefCnt member 32 const FieldDecl *BaseRefCntMember = getBaseRefCntMember(Base.getType()); 33 34 if (BaseRefCntMember) { 35 if (RefCntMember) { 36 // We have an mRefCnt, and superclass has an mRefCnt 37 const char *Error = "Refcounted record %0 has multiple mRefCnt members"; 38 const char *Note1 = "Superclass %0 also has an mRefCnt member"; 39 const char *Note2 = 40 "Consider using the _INHERITED macros for AddRef and Release here"; 41 42 diag(D->getBeginLoc(), Error, DiagnosticIDs::Error) << D; 43 diag(BaseRefCntMember->getBeginLoc(), Note1, DiagnosticIDs::Note) 44 << BaseRefCntMember->getParent(); 45 diag(RefCntMember->getBeginLoc(), Note2, DiagnosticIDs::Note); 46 } 47 48 if (FoundRefCntBase) { 49 const char *Error = "Refcounted record %0 has multiple superclasses " 50 "with mRefCnt members"; 51 const char *Note = "Superclass %0 has an mRefCnt member"; 52 53 // superclass has mRefCnt, and another superclass also has an mRefCnt 54 diag(D->getBeginLoc(), Error, DiagnosticIDs::Error) << D; 55 diag(BaseRefCntMember->getBeginLoc(), Note, DiagnosticIDs::Note) 56 << BaseRefCntMember->getParent(); 57 diag(FoundRefCntBase->getBeginLoc(), Note, DiagnosticIDs::Note) 58 << FoundRefCntBase->getParent(); 59 } 60 61 // Record that we've found a base with a mRefCnt member 62 FoundRefCntBase = BaseRefCntMember; 63 } 64 } 65 }