Bug 1814798 - pt 1. Add bool to enable/disable PHC at runtime r=glandium
[gecko.git] / build / clang-plugin / NoDuplicateRefCntMemberChecker.cpp
blobeb78a3bd499ae4fd2bffd5b2b8bdc68897cfc437
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/. */
5 #include "NoDuplicateRefCntMemberChecker.h"
6 #include "CustomMatchers.h"
8 void NoDuplicateRefCntMemberChecker::registerMatchers(MatchFinder *AstMatcher) {
9 AstMatcher->addMatcher(cxxRecordDecl().bind("decl"), this);
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;
18 if (!D->hasDefinition())
19 return;
20 D = D->getDefinition();
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;
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());
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";
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);
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";
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();
61 // Record that we've found a base with a mRefCnt member
62 FoundRefCntBase = BaseRefCntMember;