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. 4 5 // This file defines a bunch of recurring problems in the Chromium C++ code. 6 // 7 // Checks that are implemented: 8 // - Constructors/Destructors should not be inlined if they are of a complex 9 // class type. 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 16 // member. 17 // - Enum types with a xxxx_LAST or xxxxLast const actually have that constant 18 // have the maximal value for that type. 19 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/TypeLoc.h" 25 #include "clang/Basic/SourceManager.h" 26 27 #include "ChromeClassTester.h" 28 #include "Options.h" 29 30 namespace chrome_checker { 31 32 // Searches for constructs that we know we don't want in the Chromium code base. 33 class FindBadConstructsConsumer : public ChromeClassTester { 34 public: 35 FindBadConstructsConsumer(clang::CompilerInstance& instance, 36 const Options& options); 37 38 // ChromeClassTester overrides: 39 virtual void CheckChromeClass(clang::SourceLocation record_location, 40 clang::CXXRecordDecl* record); 41 virtual void CheckChromeEnum(clang::SourceLocation enum_location, 42 clang::EnumDecl* enum_decl); 43 44 private: 45 // The type of problematic ref-counting pattern that was encountered. 46 enum RefcountIssue { None, ImplicitDestructor, PublicDestructor }; 47 48 void CheckCtorDtorWeight(clang::SourceLocation record_location, 49 clang::CXXRecordDecl* record); 50 51 void CheckVirtualMethod(const clang::CXXMethodDecl* method, 52 bool warn_on_inline_bodies); 53 54 bool InTestingNamespace(const clang::Decl* record); 55 bool IsMethodInBannedOrTestingNamespace(const clang::CXXMethodDecl* method); 56 57 void CheckOverriddenMethod(const clang::CXXMethodDecl* method); 58 void CheckVirtualMethods(clang::SourceLocation record_location, 59 clang::CXXRecordDecl* record, 60 bool warn_on_inline_bodies); 61 62 void CountType(const clang::Type* type, 63 int* trivial_member, 64 int* non_trivial_member, 65 int* templated_non_trivial_member); 66 67 static RefcountIssue CheckRecordForRefcountIssue( 68 const clang::CXXRecordDecl* record, 69 clang::SourceLocation& loc); 70 clang::DiagnosticsEngine::Level getErrorLevel(); 71 static bool IsRefCountedCallback(const clang::CXXBaseSpecifier* base, 72 clang::CXXBasePath& path, 73 void* user_data); 74 static bool HasPublicDtorCallback(const clang::CXXBaseSpecifier* base, 75 clang::CXXBasePath& path, 76 void* user_data); 77 void PrintInheritanceChain(const clang::CXXBasePath& path); 78 unsigned DiagnosticForIssue(RefcountIssue issue); 79 void CheckRefCountedDtors(clang::SourceLocation record_location, 80 clang::CXXRecordDecl* record); 81 82 void CheckWeakPtrFactoryMembers(clang::SourceLocation record_location, 83 clang::CXXRecordDecl* record); 84 85 const Options options_; 86 87 unsigned diag_method_requires_override_; 88 unsigned diag_method_requires_virtual_; 89 unsigned diag_no_explicit_dtor_; 90 unsigned diag_public_dtor_; 91 unsigned diag_protected_non_virtual_dtor_; 92 unsigned diag_weak_ptr_factory_order_; 93 unsigned diag_bad_enum_last_value_; 94 unsigned diag_note_inheritance_; 95 unsigned diag_note_implicit_dtor_; 96 unsigned diag_note_public_dtor_; 97 unsigned diag_note_protected_non_virtual_dtor_; 98 }; 99 100 } // namespace chrome_checker 101