• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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