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