File: FindBadConstructsConsumer.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (156 lines) | stat: -rw-r--r-- 6,408 bytes parent folder | download | duplicates (8)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2012 The Chromium Authors
// 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 "BlinkDataMemberTypeChecker.h"
#include "CheckIPCVisitor.h"
#include "CheckLayoutObjectMethodsVisitor.h"
#include "ChromeClassTester.h"
#include "Options.h"
#include "StackAllocatedChecker.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 VisitCXXConstructExpr(clang::CXXConstructExpr* expr);
  bool VisitCXXRecordDecl(clang::CXXRecordDecl* cxx_record_decl);
  bool VisitEnumDecl(clang::EnumDecl* enum_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(LocationType location_type,
                        clang::SourceLocation record_location,
                        clang::CXXRecordDecl* record) 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);

  // 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);

  enum class TypeClassification {
    kTrivial,
    kNonTrivial,
    kTrivialTemplate,
    kNonTrivialTemplate,
    kNonTrivialExternTemplate
  };
  TypeClassification ClassifyType(const clang::Type* type);

  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 CheckEnumMaxValue(clang::EnumDecl* decl);
  void CheckDeducedAutoPointer(clang::VarDecl* decl);
  void CheckConstructingSpanFromStringLiteral(
      clang::CXXConstructorDecl* ctor_decl,
      llvm::ArrayRef<const clang::Expr*> args,
      clang::SourceLocation loc);

  void ParseFunctionTemplates(clang::TranslationUnitDecl* decl);

  unsigned diag_method_requires_override_;
  unsigned diag_redundant_virtual_specifier_;
  unsigned diag_will_be_redundant_virtual_specifier_;
  unsigned diag_base_method_virtual_and_final_;
  unsigned diag_virtual_with_inline_body_;
  unsigned diag_no_explicit_ctor_;
  unsigned diag_no_explicit_copy_ctor_;
  unsigned diag_inline_complex_ctor_;
  unsigned diag_no_explicit_dtor_;
  unsigned diag_inline_complex_dtor_;
  unsigned diag_refcounted_needs_explicit_dtor_;
  unsigned diag_refcounted_with_public_dtor_;
  unsigned diag_refcounted_with_protected_non_virtual_dtor_;
  unsigned diag_weak_ptr_factory_order_;
  unsigned diag_bad_enum_max_value_;
  unsigned diag_enum_max_value_unique_;
  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_;
  unsigned diag_span_from_string_literal_;
  unsigned diag_note_span_from_string_literal1_;

  std::unique_ptr<BlinkDataMemberTypeChecker> blink_data_member_type_checker_;
  std::unique_ptr<CheckIPCVisitor> ipc_visitor_;
  std::unique_ptr<CheckLayoutObjectMethodsVisitor> layout_visitor_;
  std::unique_ptr<StackAllocatedChecker> stack_allocated_checker_;
};

}  // namespace chrome_checker

#endif  // TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_