Home | History | Annotate | Download | only in plugins
      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