1 // Copyright 2016 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 #ifndef TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_ 6 #define TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_ 7 8 #include "CheckFieldsVisitor.h" 9 #include "CheckFinalizerVisitor.h" 10 #include "CheckGCRootsVisitor.h" 11 #include "Config.h" 12 #include "clang/AST/AST.h" 13 #include "clang/AST/ASTConsumer.h" 14 #include "clang/Basic/Diagnostic.h" 15 #include "clang/Frontend/CompilerInstance.h" 16 17 class RecordInfo; 18 19 // All error/warning reporting methods under one roof. 20 // 21 class DiagnosticsReporter { 22 public: 23 explicit DiagnosticsReporter(clang::CompilerInstance&); 24 25 bool hasErrorOccurred() const; 26 clang::DiagnosticsEngine::Level getErrorLevel() const; 27 28 void ClassMustLeftMostlyDeriveGC(RecordInfo* info); 29 void ClassRequiresTraceMethod(RecordInfo* info); 30 void BaseRequiresTracing(RecordInfo* derived, 31 clang::CXXMethodDecl* trace, 32 clang::CXXRecordDecl* base); 33 void FieldsImproperlyTraced(RecordInfo* info, 34 clang::CXXMethodDecl* trace); 35 void ClassContainsInvalidFields( 36 RecordInfo* info, 37 const CheckFieldsVisitor::Errors& errors); 38 void ClassContainsGCRoots(RecordInfo* info, 39 const CheckGCRootsVisitor::Errors& errors); 40 void FinalizerAccessesFinalizedFields( 41 clang::CXXMethodDecl* dtor, 42 const CheckFinalizerVisitor::Errors& errors); 43 void ClassRequiresFinalization(RecordInfo* info); 44 void ClassDoesNotRequireFinalization(RecordInfo* info); 45 void ClassMustDeclareGCMixinTraceMethod(RecordInfo* info); 46 void OverriddenNonVirtualTrace(RecordInfo* info, 47 clang::CXXMethodDecl* trace, 48 clang::CXXMethodDecl* overridden); 49 void MissingTraceDispatchMethod(RecordInfo* info); 50 void MissingFinalizeDispatchMethod(RecordInfo* info); 51 void VirtualAndManualDispatch(RecordInfo* info, 52 clang::CXXMethodDecl* dispatch); 53 void MissingTraceDispatch(const clang::FunctionDecl* dispatch, 54 RecordInfo* receiver); 55 void MissingFinalizeDispatch(const clang::FunctionDecl* dispatch, 56 RecordInfo* receiver); 57 void StackAllocatedDerivesGarbageCollected(RecordInfo* info, BasePoint* base); 58 void ClassOverridesNew(RecordInfo* info, clang::CXXMethodDecl* newop); 59 void ClassDeclaresPureVirtualTrace(RecordInfo* info, 60 clang::CXXMethodDecl* trace); 61 void LeftMostBaseMustBePolymorphic(RecordInfo* derived, 62 clang::CXXRecordDecl* base); 63 void BaseClassMustDeclareVirtualTrace(RecordInfo* derived, 64 clang::CXXRecordDecl* base); 65 void TraceMethodForStackAllocatedClass(RecordInfo* parent, 66 clang::CXXMethodDecl* trace); 67 68 void NoteManualDispatchMethod(clang::CXXMethodDecl* dispatch); 69 void NoteBaseRequiresTracing(BasePoint* base); 70 void NoteFieldRequiresTracing(RecordInfo* holder, clang::FieldDecl* field); 71 void NoteFieldShouldNotBeTraced(RecordInfo* holder, clang::FieldDecl* field); 72 void NotePartObjectContainsGCRoot(FieldPoint* point); 73 void NoteFieldContainsGCRoot(FieldPoint* point); 74 void NoteUserDeclaredDestructor(clang::CXXMethodDecl* dtor); 75 void NoteUserDeclaredFinalizer(clang::CXXMethodDecl* dtor); 76 void NoteBaseRequiresFinalization(BasePoint* base); 77 void NoteFieldRequiresFinalization(FieldPoint* field); 78 void NoteField(FieldPoint* point, unsigned note); 79 void NoteField(clang::FieldDecl* field, unsigned note); 80 void NoteOverriddenNonVirtualTrace(clang::CXXMethodDecl* overridden); 81 82 // Used by FindBadPatterns. 83 void UniquePtrUsedWithGC(const clang::Expr* expr, 84 const clang::FunctionDecl* bad_function, 85 const clang::CXXRecordDecl* gc_type); 86 void OptionalUsedWithGC(const clang::Expr* expr, 87 const clang::CXXRecordDecl* optional, 88 const clang::CXXRecordDecl* gc_type); 89 90 private: 91 clang::DiagnosticBuilder ReportDiagnostic( 92 clang::SourceLocation location, 93 unsigned diag_id); 94 95 void ReportMissingDispatchMethod(RecordInfo* info, unsigned error); 96 void ReportMissingDispatch(const clang::FunctionDecl* dispatch, 97 RecordInfo* receiver, 98 unsigned error); 99 100 clang::CompilerInstance& instance_; 101 clang::DiagnosticsEngine& diagnostic_; 102 103 unsigned diag_class_must_left_mostly_derive_gc_; 104 unsigned diag_class_requires_trace_method_; 105 unsigned diag_base_requires_tracing_; 106 unsigned diag_fields_require_tracing_; 107 unsigned diag_fields_improperly_traced_; 108 unsigned diag_class_contains_invalid_fields_; 109 unsigned diag_class_contains_gc_root_; 110 unsigned diag_class_requires_finalization_; 111 unsigned diag_class_does_not_require_finalization_; 112 unsigned diag_finalizer_accesses_finalized_field_; 113 unsigned diag_finalizer_eagerly_finalized_field_; 114 unsigned diag_overridden_non_virtual_trace_; 115 unsigned diag_missing_trace_dispatch_method_; 116 unsigned diag_missing_finalize_dispatch_method_; 117 unsigned diag_virtual_and_manual_dispatch_; 118 unsigned diag_missing_trace_dispatch_; 119 unsigned diag_missing_finalize_dispatch_; 120 unsigned diag_stack_allocated_derives_gc_; 121 unsigned diag_class_overrides_new_; 122 unsigned diag_class_declares_pure_virtual_trace_; 123 unsigned diag_left_most_base_must_be_polymorphic_; 124 unsigned diag_base_class_must_declare_virtual_trace_; 125 126 unsigned diag_base_requires_tracing_note_; 127 unsigned diag_field_requires_tracing_note_; 128 unsigned diag_field_should_not_be_traced_note_; 129 unsigned diag_raw_ptr_to_gc_managed_class_note_; 130 unsigned diag_ref_ptr_to_gc_managed_class_note_; 131 unsigned diag_reference_ptr_to_gc_managed_class_note_; 132 unsigned diag_own_ptr_to_gc_managed_class_note_; 133 unsigned diag_unique_ptr_to_gc_managed_class_note_; 134 unsigned diag_member_to_gc_unmanaged_class_note_; 135 unsigned diag_stack_allocated_field_note_; 136 unsigned diag_member_in_unmanaged_class_note_; 137 unsigned diag_part_object_to_gc_derived_class_note_; 138 unsigned diag_part_object_contains_gc_root_note_; 139 unsigned diag_field_contains_gc_root_note_; 140 unsigned diag_finalized_field_note_; 141 unsigned diag_eagerly_finalized_field_note_; 142 unsigned diag_user_declared_destructor_note_; 143 unsigned diag_user_declared_finalizer_note_; 144 unsigned diag_base_requires_finalization_note_; 145 unsigned diag_field_requires_finalization_note_; 146 unsigned diag_overridden_non_virtual_trace_note_; 147 unsigned diag_manual_dispatch_method_note_; 148 unsigned diag_iterator_to_gc_managed_collection_note_; 149 unsigned diag_trace_method_of_stack_allocated_parent_; 150 151 unsigned diag_unique_ptr_used_with_gc_; 152 unsigned diag_optional_used_with_gc_; 153 }; 154 155 #endif // TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_ 156