1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // This file defines a bunch of recurring problems in the Chromium C++ code.
7 // Checks that are implemented:
8 // - Constructors/Destructors should not be inlined if they are of a complex
10 // - Missing "virtual" keywords on methods that should be virtual.
11 // - Non-annotated overriding virtual methods.
12 // - Virtual methods with nonempty implementations in their headers.
13 // - Classes that derive from base::RefCounted / base::RefCountedThreadSafe
14 // should have protected or private destructors.
15 // - WeakPtrFactory members that refer to their outer class should be the last
17 // - Enum types with a xxxx_LAST or xxxxLast const actually have that constant
18 // have the maximal value for that type.
20 #include "clang/AST/AST.h"
21 #include "clang/AST/ASTConsumer.h"
22 #include "clang/AST/Attr.h"
23 #include "clang/AST/CXXInheritance.h"
24 #include "clang/AST/RecursiveASTVisitor.h"
25 #include "clang/AST/TypeLoc.h"
26 #include "clang/Basic/SourceManager.h"
28 #include "ChromeClassTester.h"
31 namespace chrome_checker
{
33 // Searches for constructs that we know we don't want in the Chromium code base.
34 class FindBadConstructsConsumer
35 : public clang::RecursiveASTVisitor
<FindBadConstructsConsumer
>,
36 public ChromeClassTester
{
38 FindBadConstructsConsumer(clang::CompilerInstance
& instance
,
39 const Options
& options
);
41 // RecursiveASTVisitor:
42 bool VisitDecl(clang::Decl
* decl
);
44 // ChromeClassTester overrides:
45 void CheckChromeClass(clang::SourceLocation record_location
,
46 clang::CXXRecordDecl
* record
) override
;
47 void CheckChromeEnum(clang::SourceLocation enum_location
,
48 clang::EnumDecl
* enum_decl
) override
;
51 // The type of problematic ref-counting pattern that was encountered.
52 enum RefcountIssue
{ None
, ImplicitDestructor
, PublicDestructor
};
54 void CheckCtorDtorWeight(clang::SourceLocation record_location
,
55 clang::CXXRecordDecl
* record
);
57 bool InTestingNamespace(const clang::Decl
* record
);
58 bool IsMethodInBannedOrTestingNamespace(const clang::CXXMethodDecl
* method
);
60 void CheckVirtualMethods(clang::SourceLocation record_location
,
61 clang::CXXRecordDecl
* record
,
62 bool warn_on_inline_bodies
);
63 void CheckVirtualSpecifiers(const clang::CXXMethodDecl
* method
);
64 void CheckVirtualBodies(const clang::CXXMethodDecl
* method
);
66 void CountType(const clang::Type
* type
,
68 int* non_trivial_member
,
69 int* templated_non_trivial_member
);
71 static RefcountIssue
CheckRecordForRefcountIssue(
72 const clang::CXXRecordDecl
* record
,
73 clang::SourceLocation
& loc
);
74 clang::DiagnosticsEngine::Level
getErrorLevel();
75 static bool IsRefCountedCallback(const clang::CXXBaseSpecifier
* base
,
76 clang::CXXBasePath
& path
,
78 static bool HasPublicDtorCallback(const clang::CXXBaseSpecifier
* base
,
79 clang::CXXBasePath
& path
,
81 void PrintInheritanceChain(const clang::CXXBasePath
& path
);
82 unsigned DiagnosticForIssue(RefcountIssue issue
);
83 void CheckRefCountedDtors(clang::SourceLocation record_location
,
84 clang::CXXRecordDecl
* record
);
86 void CheckWeakPtrFactoryMembers(clang::SourceLocation record_location
,
87 clang::CXXRecordDecl
* record
);
89 const Options options_
;
91 unsigned diag_method_requires_override_
;
92 unsigned diag_redundant_virtual_specifier_
;
93 unsigned diag_base_method_virtual_and_final_
;
94 unsigned diag_no_explicit_dtor_
;
95 unsigned diag_public_dtor_
;
96 unsigned diag_protected_non_virtual_dtor_
;
97 unsigned diag_weak_ptr_factory_order_
;
98 unsigned diag_bad_enum_last_value_
;
99 unsigned diag_note_inheritance_
;
100 unsigned diag_note_implicit_dtor_
;
101 unsigned diag_note_public_dtor_
;
102 unsigned diag_note_protected_non_virtual_dtor_
;
105 } // namespace chrome_checker