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 #ifndef TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
     21 #define TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
     22 
     23 #include <memory>
     24 
     25 #include "clang/AST/AST.h"
     26 #include "clang/AST/ASTConsumer.h"
     27 #include "clang/AST/Attr.h"
     28 #include "clang/AST/CXXInheritance.h"
     29 #include "clang/AST/RecursiveASTVisitor.h"
     30 #include "clang/AST/TypeLoc.h"
     31 #include "clang/Basic/SourceManager.h"
     32 #include "clang/Basic/SourceLocation.h"
     33 
     34 #include "CheckIPCVisitor.h"
     35 #include "ChromeClassTester.h"
     36 #include "Options.h"
     37 #include "SuppressibleDiagnosticBuilder.h"
     38 
     39 namespace chrome_checker {
     40 
     41 // Searches for constructs that we know we don't want in the Chromium code base.
     42 class FindBadConstructsConsumer
     43     : public clang::RecursiveASTVisitor<FindBadConstructsConsumer>,
     44       public ChromeClassTester {
     45  public:
     46   FindBadConstructsConsumer(clang::CompilerInstance& instance,
     47                             const Options& options);
     48 
     49   void Traverse(clang::ASTContext& context);
     50 
     51   // RecursiveASTVisitor:
     52   bool TraverseDecl(clang::Decl* decl);
     53   bool VisitTagDecl(clang::TagDecl* tag_decl);
     54   bool VisitVarDecl(clang::VarDecl* var_decl);
     55   bool VisitTemplateSpecializationType(clang::TemplateSpecializationType* spec);
     56   bool VisitCallExpr(clang::CallExpr* call_expr);
     57 
     58   // ChromeClassTester overrides:
     59   void CheckChromeClass(clang::SourceLocation record_location,
     60                         clang::CXXRecordDecl* record) override;
     61   void CheckChromeEnum(clang::SourceLocation enum_location,
     62                        clang::EnumDecl* enum_decl) override;
     63 
     64  private:
     65   // The type of problematic ref-counting pattern that was encountered.
     66   enum RefcountIssue { None, ImplicitDestructor, PublicDestructor };
     67 
     68   void CheckCtorDtorWeight(clang::SourceLocation record_location,
     69                            clang::CXXRecordDecl* record);
     70 
     71   bool InTestingNamespace(const clang::Decl* record);
     72   bool IsMethodInBannedOrTestingNamespace(const clang::CXXMethodDecl* method);
     73 
     74   // Returns a diagnostic builder that only emits the diagnostic if the spelling
     75   // location (the actual characters that make up the token) is not in an
     76   // ignored file. This is useful for situations where the token might originate
     77   // from a macro in a system header: warning isn't useful, since system headers
     78   // generally can't be easily updated.
     79   SuppressibleDiagnosticBuilder ReportIfSpellingLocNotIgnored(
     80       clang::SourceLocation loc,
     81       unsigned diagnostic_id);
     82 
     83   void CheckVirtualMethods(clang::SourceLocation record_location,
     84                            clang::CXXRecordDecl* record,
     85                            bool warn_on_inline_bodies);
     86   void CheckVirtualSpecifiers(const clang::CXXMethodDecl* method);
     87   void CheckVirtualBodies(const clang::CXXMethodDecl* method);
     88 
     89   void CountType(const clang::Type* type,
     90                  int* trivial_member,
     91                  int* non_trivial_member,
     92                  int* templated_non_trivial_member);
     93 
     94   static RefcountIssue CheckRecordForRefcountIssue(
     95       const clang::CXXRecordDecl* record,
     96       clang::SourceLocation& loc);
     97   bool IsRefCounted(const clang::CXXBaseSpecifier* base,
     98                     clang::CXXBasePath& path);
     99   static bool HasPublicDtorCallback(const clang::CXXBaseSpecifier* base,
    100                                     clang::CXXBasePath& path,
    101                                     void* user_data);
    102   void PrintInheritanceChain(const clang::CXXBasePath& path);
    103   unsigned DiagnosticForIssue(RefcountIssue issue);
    104   void CheckRefCountedDtors(clang::SourceLocation record_location,
    105                             clang::CXXRecordDecl* record);
    106 
    107   void CheckWeakPtrFactoryMembers(clang::SourceLocation record_location,
    108                                   clang::CXXRecordDecl* record);
    109   void CheckVarDecl(clang::VarDecl* decl);
    110 
    111   void ParseFunctionTemplates(clang::TranslationUnitDecl* decl);
    112 
    113   unsigned diag_method_requires_override_;
    114   unsigned diag_redundant_virtual_specifier_;
    115   unsigned diag_base_method_virtual_and_final_;
    116   unsigned diag_no_explicit_dtor_;
    117   unsigned diag_public_dtor_;
    118   unsigned diag_protected_non_virtual_dtor_;
    119   unsigned diag_weak_ptr_factory_order_;
    120   unsigned diag_bad_enum_last_value_;
    121   unsigned diag_auto_deduced_to_a_pointer_type_;
    122   unsigned diag_note_inheritance_;
    123   unsigned diag_note_implicit_dtor_;
    124   unsigned diag_note_public_dtor_;
    125   unsigned diag_note_protected_non_virtual_dtor_;
    126 
    127   std::unique_ptr<CheckIPCVisitor> ipc_visitor_;
    128 };
    129 
    130 }  // namespace chrome_checker
    131 
    132 #endif  // TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
    133