#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 {
class FindBadConstructsConsumer
: public clang::RecursiveASTVisitor<FindBadConstructsConsumer>,
public ChromeClassTester {
public:
FindBadConstructsConsumer(clang::CompilerInstance& instance,
const Options& options);
void Traverse(clang::ASTContext& context);
bool TraverseDecl(clang::Decl* 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);
void CheckChromeClass(LocationType location_type,
clang::SourceLocation record_location,
clang::CXXRecordDecl* record) override;
private:
enum RefcountIssue { None, ImplicitDestructor, PublicDestructor };
void CheckCtorDtorWeight(clang::SourceLocation record_location,
clang::CXXRecordDecl* record);
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 CheckEnumMaxValue(clang::EnumDecl* decl);
void CheckVarDecl(clang::VarDecl* decl);
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_;
std::unique_ptr<CheckIPCVisitor> ipc_visitor_;
};
}
#endif