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 66 void NoteManualDispatchMethod(clang::CXXMethodDecl* dispatch); 67 void NoteBaseRequiresTracing(BasePoint* base); 68 void NoteFieldRequiresTracing(RecordInfo* holder, clang::FieldDecl* field); 69 void NoteFieldShouldNotBeTraced(RecordInfo* holder, clang::FieldDecl* field); 70 void NotePartObjectContainsGCRoot(FieldPoint* point); 71 void NoteFieldContainsGCRoot(FieldPoint* point); 72 void NoteUserDeclaredDestructor(clang::CXXMethodDecl* dtor); 73 void NoteUserDeclaredFinalizer(clang::CXXMethodDecl* dtor); 74 void NoteBaseRequiresFinalization(BasePoint* base); 75 void NoteFieldRequiresFinalization(FieldPoint* field); 76 void NoteField(FieldPoint* point, unsigned note); 77 void NoteField(clang::FieldDecl* field, unsigned note); 78 void NoteOverriddenNonVirtualTrace(clang::CXXMethodDecl* overridden); 79 80 private: 81 clang::DiagnosticBuilder ReportDiagnostic( 82 clang::SourceLocation location, 83 unsigned diag_id); 84 85 void ReportMissingDispatchMethod(RecordInfo* info, unsigned error); 86 void ReportMissingDispatch(const clang::FunctionDecl* dispatch, 87 RecordInfo* receiver, 88 unsigned error); 89 90 clang::CompilerInstance& instance_; 91 clang::DiagnosticsEngine& diagnostic_; 92 93 unsigned diag_class_must_left_mostly_derive_gc_; 94 unsigned diag_class_requires_trace_method_; 95 unsigned diag_base_requires_tracing_; 96 unsigned diag_fields_require_tracing_; 97 unsigned diag_fields_improperly_traced_; 98 unsigned diag_class_contains_invalid_fields_; 99 unsigned diag_class_contains_gc_root_; 100 unsigned diag_class_requires_finalization_; 101 unsigned diag_class_does_not_require_finalization_; 102 unsigned diag_finalizer_accesses_finalized_field_; 103 unsigned diag_finalizer_eagerly_finalized_field_; 104 unsigned diag_overridden_non_virtual_trace_; 105 unsigned diag_missing_trace_dispatch_method_; 106 unsigned diag_missing_finalize_dispatch_method_; 107 unsigned diag_virtual_and_manual_dispatch_; 108 unsigned diag_missing_trace_dispatch_; 109 unsigned diag_missing_finalize_dispatch_; 110 unsigned diag_stack_allocated_derives_gc_; 111 unsigned diag_class_overrides_new_; 112 unsigned diag_class_declares_pure_virtual_trace_; 113 unsigned diag_left_most_base_must_be_polymorphic_; 114 unsigned diag_base_class_must_declare_virtual_trace_; 115 116 unsigned diag_base_requires_tracing_note_; 117 unsigned diag_field_requires_tracing_note_; 118 unsigned diag_field_should_not_be_traced_note_; 119 unsigned diag_raw_ptr_to_gc_managed_class_note_; 120 unsigned diag_ref_ptr_to_gc_managed_class_note_; 121 unsigned diag_reference_ptr_to_gc_managed_class_note_; 122 unsigned diag_own_ptr_to_gc_managed_class_note_; 123 unsigned diag_unique_ptr_to_gc_managed_class_note_; 124 unsigned diag_member_to_gc_unmanaged_class_note_; 125 unsigned diag_stack_allocated_field_note_; 126 unsigned diag_member_in_unmanaged_class_note_; 127 unsigned diag_part_object_to_gc_derived_class_note_; 128 unsigned diag_part_object_contains_gc_root_note_; 129 unsigned diag_field_contains_gc_root_note_; 130 unsigned diag_finalized_field_note_; 131 unsigned diag_eagerly_finalized_field_note_; 132 unsigned diag_user_declared_destructor_note_; 133 unsigned diag_user_declared_finalizer_note_; 134 unsigned diag_base_requires_finalization_note_; 135 unsigned diag_field_requires_finalization_note_; 136 unsigned diag_overridden_non_virtual_trace_note_; 137 unsigned diag_manual_dispatch_method_note_; 138 unsigned diag_iterator_to_gc_managed_collection_note_; 139 }; 140 141 #endif // TOOLS_BLINK_GC_PLUGIN_DIAGNOSTICS_REPORTER_H_ 142