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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// 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.
#ifndef TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
#define TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
#include <memory>
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceLocation.h"
#include "CheckIPCVisitor.h"
#include "ChromeClassTester.h"
#include "Options.h"
#include "SuppressibleDiagnosticBuilder.h"
namespace chrome_checker {
// Searches for constructs that we know we don't want in the Chromium code base.
class FindBadConstructsConsumer
: public clang::RecursiveASTVisitor<FindBadConstructsConsumer>,
public ChromeClassTester {
public:
FindBadConstructsConsumer(clang::CompilerInstance& instance,
const Options& options);
void Traverse(clang::ASTContext& context);
// RecursiveASTVisitor:
bool TraverseDecl(clang::Decl* decl);
bool VisitTagDecl(clang::TagDecl* tag_decl);
bool VisitVarDecl(clang::VarDecl* var_decl);
bool VisitTemplateSpecializationType(clang::TemplateSpecializationType* spec);
bool VisitCallExpr(clang::CallExpr* call_expr);
// ChromeClassTester overrides:
void CheckChromeClass(clang::SourceLocation record_location,
clang::CXXRecordDecl* record) override;
void CheckChromeEnum(clang::SourceLocation enum_location,
clang::EnumDecl* enum_decl) override;
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);
bool InTestingNamespace(const clang::Decl* record);
bool IsMethodInBannedOrTestingNamespace(const clang::CXXMethodDecl* method);
// Returns a diagnostic builder that only emits the diagnostic if the spelling
// location (the actual characters that make up the token) is not in an
// ignored file. This is useful for situations where the token might originate
// from a macro in a system header: warning isn't useful, since system headers
// generally can't be easily updated.
SuppressibleDiagnosticBuilder ReportIfSpellingLocNotIgnored(
clang::SourceLocation loc,
unsigned diagnostic_id);
void CheckVirtualMethods(clang::SourceLocation record_location,
clang::CXXRecordDecl* record,
bool warn_on_inline_bodies);
void CheckVirtualSpecifiers(const clang::CXXMethodDecl* method);
void CheckVirtualBodies(const clang::CXXMethodDecl* method);
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);
bool IsRefCounted(const clang::CXXBaseSpecifier* base,
clang::CXXBasePath& path);
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);
void CheckVarDecl(clang::VarDecl* decl);
void ParseFunctionTemplates(clang::TranslationUnitDecl* decl);
unsigned diag_method_requires_override_;
unsigned diag_redundant_virtual_specifier_;
unsigned diag_base_method_virtual_and_final_;
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_auto_deduced_to_a_pointer_type_;
unsigned diag_note_inheritance_;
unsigned diag_note_implicit_dtor_;
unsigned diag_note_public_dtor_;
unsigned diag_note_protected_non_virtual_dtor_;
std::unique_ptr<CheckIPCVisitor> ipc_visitor_;
};
} // namespace chrome_checker
#endif // TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
|