132 lines
5.3 KiB
C++
132 lines
5.3 KiB
C++
// 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_
|