| Index: tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
|
| diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
|
| index 21ef6e3e73f46ee718ad6e16ab96ca2dbb640b18..1a32defcc42698ae7c32cf92dc3264dcc9c7d66e 100644
|
| --- a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
|
| +++ b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
|
| @@ -8,6 +8,9 @@
|
| #include <set>
|
|
|
| #include "CheckDispatchVisitor.h"
|
| +#include "CheckFieldsVisitor.h"
|
| +#include "CheckFinalizerVisitor.h"
|
| +#include "CheckGCRootsVisitor.h"
|
| #include "CheckTraceVisitor.h"
|
| #include "CollectVisitor.h"
|
| #include "JsonWriter.h"
|
| @@ -19,136 +22,6 @@ using namespace clang;
|
|
|
| namespace {
|
|
|
| -const char kClassMustLeftMostlyDeriveGC[] =
|
| - "[blink-gc] Class %0 must derive its GC base in the left-most position.";
|
| -
|
| -const char kClassRequiresTraceMethod[] =
|
| - "[blink-gc] Class %0 requires a trace method.";
|
| -
|
| -const char kBaseRequiresTracing[] =
|
| - "[blink-gc] Base class %0 of derived class %1 requires tracing.";
|
| -
|
| -const char kBaseRequiresTracingNote[] =
|
| - "[blink-gc] Untraced base class %0 declared here:";
|
| -
|
| -const char kFieldsRequireTracing[] =
|
| - "[blink-gc] Class %0 has untraced fields that require tracing.";
|
| -
|
| -const char kFieldRequiresTracingNote[] =
|
| - "[blink-gc] Untraced field %0 declared here:";
|
| -
|
| -const char kClassContainsInvalidFields[] =
|
| - "[blink-gc] Class %0 contains invalid fields.";
|
| -
|
| -const char kClassContainsGCRoot[] =
|
| - "[blink-gc] Class %0 contains GC root in field %1.";
|
| -
|
| -const char kClassRequiresFinalization[] =
|
| - "[blink-gc] Class %0 requires finalization.";
|
| -
|
| -const char kClassDoesNotRequireFinalization[] =
|
| - "[blink-gc] Class %0 may not require finalization.";
|
| -
|
| -const char kFinalizerAccessesFinalizedField[] =
|
| - "[blink-gc] Finalizer %0 accesses potentially finalized field %1.";
|
| -
|
| -const char kFinalizerAccessesEagerlyFinalizedField[] =
|
| - "[blink-gc] Finalizer %0 accesses eagerly finalized field %1.";
|
| -
|
| -const char kRawPtrToGCManagedClassNote[] =
|
| - "[blink-gc] Raw pointer field %0 to a GC managed class declared here:";
|
| -
|
| -const char kRefPtrToGCManagedClassNote[] =
|
| - "[blink-gc] RefPtr field %0 to a GC managed class declared here:";
|
| -
|
| -const char kReferencePtrToGCManagedClassNote[] =
|
| - "[blink-gc] Reference pointer field %0 to a GC managed class"
|
| - " declared here:";
|
| -
|
| -const char kOwnPtrToGCManagedClassNote[] =
|
| - "[blink-gc] OwnPtr field %0 to a GC managed class declared here:";
|
| -
|
| -const char kMemberToGCUnmanagedClassNote[] =
|
| - "[blink-gc] Member field %0 to non-GC managed class declared here:";
|
| -
|
| -const char kStackAllocatedFieldNote[] =
|
| - "[blink-gc] Stack-allocated field %0 declared here:";
|
| -
|
| -const char kMemberInUnmanagedClassNote[] =
|
| - "[blink-gc] Member field %0 in unmanaged class declared here:";
|
| -
|
| -const char kPartObjectToGCDerivedClassNote[] =
|
| - "[blink-gc] Part-object field %0 to a GC derived class declared here:";
|
| -
|
| -const char kPartObjectContainsGCRootNote[] =
|
| - "[blink-gc] Field %0 with embedded GC root in %1 declared here:";
|
| -
|
| -const char kFieldContainsGCRootNote[] =
|
| - "[blink-gc] Field %0 defining a GC root declared here:";
|
| -
|
| -const char kOverriddenNonVirtualTrace[] =
|
| - "[blink-gc] Class %0 overrides non-virtual trace of base class %1.";
|
| -
|
| -const char kOverriddenNonVirtualTraceNote[] =
|
| - "[blink-gc] Non-virtual trace method declared here:";
|
| -
|
| -const char kMissingTraceDispatchMethod[] =
|
| - "[blink-gc] Class %0 is missing manual trace dispatch.";
|
| -
|
| -const char kMissingFinalizeDispatchMethod[] =
|
| - "[blink-gc] Class %0 is missing manual finalize dispatch.";
|
| -
|
| -const char kVirtualAndManualDispatch[] =
|
| - "[blink-gc] Class %0 contains or inherits virtual methods"
|
| - " but implements manual dispatching.";
|
| -
|
| -const char kMissingTraceDispatch[] =
|
| - "[blink-gc] Missing dispatch to class %0 in manual trace dispatch.";
|
| -
|
| -const char kMissingFinalizeDispatch[] =
|
| - "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch.";
|
| -
|
| -const char kFinalizedFieldNote[] =
|
| - "[blink-gc] Potentially finalized field %0 declared here:";
|
| -
|
| -const char kEagerlyFinalizedFieldNote[] =
|
| - "[blink-gc] Field %0 having eagerly finalized value, declared here:";
|
| -
|
| -const char kUserDeclaredDestructorNote[] =
|
| - "[blink-gc] User-declared destructor declared here:";
|
| -
|
| -const char kUserDeclaredFinalizerNote[] =
|
| - "[blink-gc] User-declared finalizer declared here:";
|
| -
|
| -const char kBaseRequiresFinalizationNote[] =
|
| - "[blink-gc] Base class %0 requiring finalization declared here:";
|
| -
|
| -const char kFieldRequiresFinalizationNote[] =
|
| - "[blink-gc] Field %0 requiring finalization declared here:";
|
| -
|
| -const char kManualDispatchMethodNote[] =
|
| - "[blink-gc] Manual dispatch %0 declared here:";
|
| -
|
| -const char kDerivesNonStackAllocated[] =
|
| - "[blink-gc] Stack-allocated class %0 derives class %1"
|
| - " which is not stack allocated.";
|
| -
|
| -const char kClassOverridesNew[] =
|
| - "[blink-gc] Garbage collected class %0"
|
| - " is not permitted to override its new operator.";
|
| -
|
| -const char kClassDeclaresPureVirtualTrace[] =
|
| - "[blink-gc] Garbage collected class %0"
|
| - " is not permitted to declare a pure-virtual trace method.";
|
| -
|
| -const char kLeftMostBaseMustBePolymorphic[] =
|
| - "[blink-gc] Left-most base class %0 of derived class %1"
|
| - " must be polymorphic.";
|
| -
|
| -const char kBaseClassMustDeclareVirtualTrace[] =
|
| - "[blink-gc] Left-most base class %0 of derived class %1"
|
| - " must define a virtual trace method.";
|
| -
|
| // Use a local RAV implementation to simply collect all FunctionDecls marked for
|
| // late template parsing. This happens with the flag -fdelayed-template-parsing,
|
| // which is on by default in MSVC-compatible mode.
|
| @@ -193,7 +66,7 @@ BlinkGCPluginConsumer::BlinkGCPluginConsumer(
|
| clang::CompilerInstance& instance,
|
| const BlinkGCPluginOptions& options)
|
| : instance_(instance),
|
| - diagnostic_(instance.getDiagnostics()),
|
| + reporter_(instance),
|
| options_(options),
|
| json_(0) {
|
| // Only check structures in the blink and WebKit namespaces.
|
| @@ -201,97 +74,11 @@ BlinkGCPluginConsumer::BlinkGCPluginConsumer(
|
|
|
| // Ignore GC implementation files.
|
| options_.ignored_directories.push_back("/heap/");
|
| -
|
| - // Register warning/error messages.
|
| - diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kClassMustLeftMostlyDeriveGC);
|
| - diag_class_requires_trace_method_ =
|
| - diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod);
|
| - diag_base_requires_tracing_ =
|
| - diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing);
|
| - diag_fields_require_tracing_ =
|
| - diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing);
|
| - diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kClassContainsInvalidFields);
|
| - diag_class_contains_gc_root_ =
|
| - diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot);
|
| - diag_class_requires_finalization_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kClassRequiresFinalization);
|
| - diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization);
|
| - diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kFinalizerAccessesFinalizedField);
|
| - diag_finalizer_eagerly_finalized_field_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kFinalizerAccessesEagerlyFinalizedField);
|
| - diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kOverriddenNonVirtualTrace);
|
| - diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kMissingTraceDispatchMethod);
|
| - diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kMissingFinalizeDispatchMethod);
|
| - diag_virtual_and_manual_dispatch_ =
|
| - diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch);
|
| - diag_missing_trace_dispatch_ =
|
| - diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch);
|
| - diag_missing_finalize_dispatch_ =
|
| - diagnostic_.getCustomDiagID(getErrorLevel(), kMissingFinalizeDispatch);
|
| - diag_derives_non_stack_allocated_ =
|
| - diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated);
|
| - diag_class_overrides_new_ =
|
| - diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew);
|
| - diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kClassDeclaresPureVirtualTrace);
|
| - diag_left_most_base_must_be_polymorphic_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kLeftMostBaseMustBePolymorphic);
|
| - diag_base_class_must_declare_virtual_trace_ = diagnostic_.getCustomDiagID(
|
| - getErrorLevel(), kBaseClassMustDeclareVirtualTrace);
|
| -
|
| - // Register note messages.
|
| - diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kBaseRequiresTracingNote);
|
| - diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kFieldRequiresTracingNote);
|
| - diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote);
|
| - diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote);
|
| - diag_reference_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kReferencePtrToGCManagedClassNote);
|
| - diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote);
|
| - diag_member_to_gc_unmanaged_class_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kMemberToGCUnmanagedClassNote);
|
| - diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kStackAllocatedFieldNote);
|
| - diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kMemberInUnmanagedClassNote);
|
| - diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote);
|
| - diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kPartObjectContainsGCRootNote);
|
| - diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kFieldContainsGCRootNote);
|
| - diag_finalized_field_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kFinalizedFieldNote);
|
| - diag_eagerly_finalized_field_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kEagerlyFinalizedFieldNote);
|
| - diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kUserDeclaredDestructorNote);
|
| - diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kUserDeclaredFinalizerNote);
|
| - diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kBaseRequiresFinalizationNote);
|
| - diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kFieldRequiresFinalizationNote);
|
| - diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote);
|
| - diag_manual_dispatch_method_note_ = diagnostic_.getCustomDiagID(
|
| - DiagnosticsEngine::Note, kManualDispatchMethodNote);
|
| }
|
|
|
| void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) {
|
| // Don't run the plugin if the compilation unit is already invalid.
|
| - if (diagnostic_.hasErrorOccurred())
|
| + if (reporter_.hasErrorOccurred())
|
| return;
|
|
|
| ParseFunctionTemplates(context.getTranslationUnitDecl());
|
| @@ -393,14 +180,14 @@ void BlinkGCPluginConsumer::CheckClass(RecordInfo* info) {
|
| if (info->IsStackAllocated()) {
|
| for (auto& base : info->GetBases())
|
| if (!base.second.info()->IsStackAllocated())
|
| - ReportDerivesNonStackAllocated(info, &base.second);
|
| + reporter_.DerivesNonStackAllocated(info, &base.second);
|
| }
|
|
|
| if (CXXMethodDecl* trace = info->GetTraceMethod()) {
|
| if (trace->isPure())
|
| - ReportClassDeclaresPureVirtualTrace(info, trace);
|
| + reporter_.ClassDeclaresPureVirtualTrace(info, trace);
|
| } else if (info->RequiresTraceMethod()) {
|
| - ReportClassRequiresTraceMethod(info);
|
| + reporter_.ClassRequiresTraceMethod(info);
|
| }
|
|
|
| // Check polymorphic classes that are GC-derived or have a trace method.
|
| @@ -412,9 +199,9 @@ void BlinkGCPluginConsumer::CheckClass(RecordInfo* info) {
|
| }
|
|
|
| {
|
| - CheckFieldsVisitor visitor(options_);
|
| + CheckFieldsVisitor visitor;
|
| if (visitor.ContainsInvalidFields(info))
|
| - ReportClassContainsInvalidFields(info, visitor.invalid_fields());
|
| + reporter_.ClassContainsInvalidFields(info, visitor.invalid_fields());
|
| }
|
|
|
| if (info->IsGCDerived()) {
|
| @@ -423,13 +210,13 @@ void BlinkGCPluginConsumer::CheckClass(RecordInfo* info) {
|
| CheckDispatch(info);
|
| if (CXXMethodDecl* newop = info->DeclaresNewOperator())
|
| if (!Config::IsIgnoreAnnotated(newop))
|
| - ReportClassOverridesNew(info, newop);
|
| + reporter_.ClassOverridesNew(info, newop);
|
| }
|
|
|
| {
|
| CheckGCRootsVisitor visitor;
|
| if (visitor.ContainsGCRoots(info))
|
| - ReportClassContainsGCRoots(info, visitor.gc_roots());
|
| + reporter_.ClassContainsGCRoots(info, visitor.gc_roots());
|
| }
|
|
|
| if (info->NeedsFinalization())
|
| @@ -513,7 +300,7 @@ void BlinkGCPluginConsumer::CheckPolymorphicClass(
|
| if (trace->isVirtual())
|
| return;
|
| }
|
| - ReportBaseClassMustDeclareVirtualTrace(info, left_most);
|
| + reporter_.BaseClassMustDeclareVirtualTrace(info, left_most);
|
| return;
|
| }
|
|
|
| @@ -529,13 +316,13 @@ void BlinkGCPluginConsumer::CheckPolymorphicClass(
|
| if (CXXRecordDecl* next_left_most = GetLeftMostBase(next_base)) {
|
| if (DeclaresVirtualMethods(next_left_most))
|
| return;
|
| - ReportLeftMostBaseMustBePolymorphic(info, next_left_most);
|
| + reporter_.LeftMostBaseMustBePolymorphic(info, next_left_most);
|
| return;
|
| }
|
| }
|
| }
|
| }
|
| - ReportLeftMostBaseMustBePolymorphic(info, left_most);
|
| + reporter_.LeftMostBaseMustBePolymorphic(info, left_most);
|
| }
|
| }
|
|
|
| @@ -567,7 +354,7 @@ void BlinkGCPluginConsumer::CheckLeftMostDerived(RecordInfo* info) {
|
| if (!left_most)
|
| return;
|
| if (!Config::IsGCBase(left_most->getName()))
|
| - ReportClassMustLeftMostlyDeriveGC(info);
|
| + reporter_.ClassMustLeftMostlyDeriveGC(info);
|
| }
|
|
|
| void BlinkGCPluginConsumer::CheckDispatch(RecordInfo* info) {
|
| @@ -583,18 +370,18 @@ void BlinkGCPluginConsumer::CheckDispatch(RecordInfo* info) {
|
| // Check that dispatch methods are defined at the base.
|
| if (base == info->record()) {
|
| if (!trace_dispatch)
|
| - ReportMissingTraceDispatchMethod(info);
|
| + reporter_.MissingTraceDispatchMethod(info);
|
| if (finalized && !finalize_dispatch)
|
| - ReportMissingFinalizeDispatchMethod(info);
|
| + reporter_.MissingFinalizeDispatchMethod(info);
|
| if (!finalized && finalize_dispatch) {
|
| - ReportClassRequiresFinalization(info);
|
| - NoteUserDeclaredFinalizer(finalize_dispatch);
|
| + reporter_.ClassRequiresFinalization(info);
|
| + reporter_.NoteUserDeclaredFinalizer(finalize_dispatch);
|
| }
|
| }
|
|
|
| // Check that classes implementing manual dispatch do not have vtables.
|
| if (info->record()->isPolymorphic()) {
|
| - ReportVirtualAndManualDispatch(
|
| + reporter_.VirtualAndManualDispatch(
|
| info, trace_dispatch ? trace_dispatch : finalize_dispatch);
|
| }
|
|
|
| @@ -610,14 +397,14 @@ void BlinkGCPluginConsumer::CheckDispatch(RecordInfo* info) {
|
| CheckDispatchVisitor visitor(info);
|
| visitor.TraverseStmt(defn->getBody());
|
| if (!visitor.dispatched_to_receiver())
|
| - ReportMissingTraceDispatch(defn, info);
|
| + reporter_.MissingTraceDispatch(defn, info);
|
| }
|
|
|
| if (finalized && finalize_dispatch && finalize_dispatch->isDefined(defn)) {
|
| CheckDispatchVisitor visitor(info);
|
| visitor.TraverseStmt(defn->getBody());
|
| if (!visitor.dispatched_to_receiver())
|
| - ReportMissingFinalizeDispatch(defn, info);
|
| + reporter_.MissingFinalizeDispatch(defn, info);
|
| }
|
| }
|
|
|
| @@ -631,7 +418,7 @@ void BlinkGCPluginConsumer::CheckFinalization(RecordInfo* info) {
|
| CheckFinalizerVisitor visitor(&cache_, info->IsEagerlyFinalized());
|
| visitor.TraverseCXXMethodDecl(dtor);
|
| if (!visitor.finalized_fields().empty()) {
|
| - ReportFinalizerAccessesFinalizedFields(
|
| + reporter_.FinalizerAccessesFinalizedFields(
|
| dtor, visitor.finalized_fields());
|
| }
|
| }
|
| @@ -644,23 +431,23 @@ void BlinkGCPluginConsumer::CheckFinalization(RecordInfo* info) {
|
|
|
| // Report the finalization error, and proceed to print possible causes for
|
| // the finalization requirement.
|
| - ReportClassRequiresFinalization(info);
|
| + reporter_.ClassRequiresFinalization(info);
|
|
|
| if (dtor && dtor->isUserProvided())
|
| - NoteUserDeclaredDestructor(dtor);
|
| + reporter_.NoteUserDeclaredDestructor(dtor);
|
|
|
| for (auto& base : info->GetBases())
|
| if (base.second.info()->NeedsFinalization())
|
| - NoteBaseRequiresFinalization(&base.second);
|
| + reporter_.NoteBaseRequiresFinalization(&base.second);
|
|
|
| for (auto& field : info->GetFields())
|
| if (field.second.edge()->NeedsFinalization())
|
| - NoteField(&field.second, diag_field_requires_finalization_note_);
|
| + reporter_.NoteFieldRequiresFinalization(&field.second);
|
| }
|
|
|
| void BlinkGCPluginConsumer::CheckUnneededFinalization(RecordInfo* info) {
|
| if (!HasNonEmptyFinalizer(info))
|
| - ReportClassDoesNotRequireFinalization(info);
|
| + reporter_.ClassDoesNotRequireFinalization(info);
|
| }
|
|
|
| bool BlinkGCPluginConsumer::HasNonEmptyFinalizer(RecordInfo* info) {
|
| @@ -748,7 +535,7 @@ void BlinkGCPluginConsumer::CheckTraceMethod(
|
| if (trace_type == Config::TRACE_METHOD) {
|
| for (auto& base : parent->GetBases())
|
| if (CXXMethodDecl* other = base.second.info()->InheritsNonVirtualTrace())
|
| - ReportOverriddenNonVirtualTrace(parent, trace, other);
|
| + reporter_.OverriddenNonVirtualTrace(parent, trace, other);
|
| }
|
|
|
| CheckTraceVisitor visitor(trace, parent, &cache_);
|
| @@ -762,12 +549,12 @@ void BlinkGCPluginConsumer::CheckTraceMethod(
|
|
|
| for (auto& base : parent->GetBases())
|
| if (!base.second.IsProperlyTraced())
|
| - ReportBaseRequiresTracing(parent, trace, base.first);
|
| + reporter_.BaseRequiresTracing(parent, trace, base.first);
|
|
|
| for (auto& field : parent->GetFields()) {
|
| if (!field.second.IsProperlyTraced()) {
|
| // Discontinue once an untraced-field error is found.
|
| - ReportFieldsRequireTracing(parent, trace);
|
| + reporter_.FieldsRequireTracing(parent, trace);
|
| break;
|
| }
|
| }
|
| @@ -858,11 +645,6 @@ void BlinkGCPluginConsumer::DumpClass(RecordInfo* info) {
|
| GetLocString(field.second.field()->getLocStart()));
|
| }
|
|
|
| -DiagnosticsEngine::Level BlinkGCPluginConsumer::getErrorLevel() {
|
| - return diagnostic_.getWarningsAsErrors() ? DiagnosticsEngine::Error
|
| - : DiagnosticsEngine::Warning;
|
| -}
|
| -
|
| std::string BlinkGCPluginConsumer::GetLocString(SourceLocation loc) {
|
| const SourceManager& source_manager = instance_.getSourceManager();
|
| PresumedLoc ploc = source_manager.getPresumedLoc(loc);
|
| @@ -937,283 +719,3 @@ bool BlinkGCPluginConsumer::GetFilename(SourceLocation loc,
|
| *filename = ploc.getFilename();
|
| return true;
|
| }
|
| -
|
| -DiagnosticBuilder BlinkGCPluginConsumer::ReportDiagnostic(
|
| - SourceLocation location,
|
| - unsigned diag_id) {
|
| - SourceManager& manager = instance_.getSourceManager();
|
| - FullSourceLoc full_loc(location, manager);
|
| - return diagnostic_.Report(full_loc, diag_id);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportClassMustLeftMostlyDeriveGC(
|
| - RecordInfo* info) {
|
| - ReportDiagnostic(info->record()->getInnerLocStart(),
|
| - diag_class_must_left_mostly_derive_gc_)
|
| - << info->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportClassRequiresTraceMethod(RecordInfo* info) {
|
| - ReportDiagnostic(info->record()->getInnerLocStart(),
|
| - diag_class_requires_trace_method_)
|
| - << info->record();
|
| -
|
| - for (auto& base : info->GetBases())
|
| - if (base.second.NeedsTracing().IsNeeded())
|
| - NoteBaseRequiresTracing(&base.second);
|
| -
|
| - for (auto& field : info->GetFields())
|
| - if (!field.second.IsProperlyTraced())
|
| - NoteFieldRequiresTracing(info, field.first);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportBaseRequiresTracing(
|
| - RecordInfo* derived,
|
| - CXXMethodDecl* trace,
|
| - CXXRecordDecl* base) {
|
| - ReportDiagnostic(trace->getLocStart(), diag_base_requires_tracing_)
|
| - << base << derived->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportFieldsRequireTracing(
|
| - RecordInfo* info,
|
| - CXXMethodDecl* trace) {
|
| - ReportDiagnostic(trace->getLocStart(), diag_fields_require_tracing_)
|
| - << info->record();
|
| - for (auto& field : info->GetFields())
|
| - if (!field.second.IsProperlyTraced())
|
| - NoteFieldRequiresTracing(info, field.first);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportClassContainsInvalidFields(
|
| - RecordInfo* info,
|
| - const CheckFieldsVisitor::Errors& errors) {
|
| -
|
| - ReportDiagnostic(info->record()->getLocStart(),
|
| - diag_class_contains_invalid_fields_)
|
| - << info->record();
|
| -
|
| - for (auto& error : errors) {
|
| - unsigned note;
|
| - if (error.second == CheckFieldsVisitor::kRawPtrToGCManaged) {
|
| - note = diag_raw_ptr_to_gc_managed_class_note_;
|
| - } else if (error.second == CheckFieldsVisitor::kRefPtrToGCManaged) {
|
| - note = diag_ref_ptr_to_gc_managed_class_note_;
|
| - } else if (error.second == CheckFieldsVisitor::kReferencePtrToGCManaged) {
|
| - note = diag_reference_ptr_to_gc_managed_class_note_;
|
| - } else if (error.second == CheckFieldsVisitor::kOwnPtrToGCManaged) {
|
| - note = diag_own_ptr_to_gc_managed_class_note_;
|
| - } else if (error.second == CheckFieldsVisitor::kMemberToGCUnmanaged) {
|
| - note = diag_member_to_gc_unmanaged_class_note_;
|
| - } else if (error.second == CheckFieldsVisitor::kMemberInUnmanaged) {
|
| - note = diag_member_in_unmanaged_class_note_;
|
| - } else if (error.second == CheckFieldsVisitor::kPtrFromHeapToStack) {
|
| - note = diag_stack_allocated_field_note_;
|
| - } else if (error.second == CheckFieldsVisitor::kGCDerivedPartObject) {
|
| - note = diag_part_object_to_gc_derived_class_note_;
|
| - } else {
|
| - assert(false && "Unknown field error");
|
| - }
|
| - NoteField(error.first, note);
|
| - }
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportClassContainsGCRoots(
|
| - RecordInfo* info,
|
| - const CheckGCRootsVisitor::Errors& errors) {
|
| - for (auto& error : errors) {
|
| - FieldPoint* point = nullptr;
|
| - for (FieldPoint* path : error) {
|
| - if (!point) {
|
| - point = path;
|
| - ReportDiagnostic(info->record()->getLocStart(),
|
| - diag_class_contains_gc_root_)
|
| - << info->record() << point->field();
|
| - continue;
|
| - }
|
| - NotePartObjectContainsGCRoot(point);
|
| - point = path;
|
| - }
|
| - NoteFieldContainsGCRoot(point);
|
| - }
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportFinalizerAccessesFinalizedFields(
|
| - CXXMethodDecl* dtor,
|
| - const CheckFinalizerVisitor::Errors& errors) {
|
| - for (auto& error : errors) {
|
| - bool as_eagerly_finalized = error.as_eagerly_finalized;
|
| - unsigned diag_error = as_eagerly_finalized ?
|
| - diag_finalizer_eagerly_finalized_field_ :
|
| - diag_finalizer_accesses_finalized_field_;
|
| - unsigned diag_note = as_eagerly_finalized ?
|
| - diag_eagerly_finalized_field_note_ :
|
| - diag_finalized_field_note_;
|
| - ReportDiagnostic(error.member->getLocStart(), diag_error)
|
| - << dtor << error.field->field();
|
| - NoteField(error.field, diag_note);
|
| - }
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportClassRequiresFinalization(RecordInfo* info) {
|
| - ReportDiagnostic(info->record()->getInnerLocStart(),
|
| - diag_class_requires_finalization_)
|
| - << info->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportClassDoesNotRequireFinalization(
|
| - RecordInfo* info) {
|
| - ReportDiagnostic(info->record()->getInnerLocStart(),
|
| - diag_class_does_not_require_finalization_)
|
| - << info->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportOverriddenNonVirtualTrace(
|
| - RecordInfo* info,
|
| - CXXMethodDecl* trace,
|
| - CXXMethodDecl* overridden) {
|
| - ReportDiagnostic(trace->getLocStart(), diag_overridden_non_virtual_trace_)
|
| - << info->record() << overridden->getParent();
|
| - NoteOverriddenNonVirtualTrace(overridden);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportMissingTraceDispatchMethod(RecordInfo* info) {
|
| - ReportMissingDispatchMethod(info, diag_missing_trace_dispatch_method_);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportMissingFinalizeDispatchMethod(
|
| - RecordInfo* info) {
|
| - ReportMissingDispatchMethod(info, diag_missing_finalize_dispatch_method_);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportMissingDispatchMethod(
|
| - RecordInfo* info,
|
| - unsigned error) {
|
| - ReportDiagnostic(info->record()->getInnerLocStart(), error)
|
| - << info->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportVirtualAndManualDispatch(
|
| - RecordInfo* info,
|
| - CXXMethodDecl* dispatch) {
|
| - ReportDiagnostic(info->record()->getInnerLocStart(),
|
| - diag_virtual_and_manual_dispatch_)
|
| - << info->record();
|
| - NoteManualDispatchMethod(dispatch);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportMissingTraceDispatch(
|
| - const FunctionDecl* dispatch,
|
| - RecordInfo* receiver) {
|
| - ReportMissingDispatch(dispatch, receiver, diag_missing_trace_dispatch_);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportMissingFinalizeDispatch(
|
| - const FunctionDecl* dispatch,
|
| - RecordInfo* receiver) {
|
| - ReportMissingDispatch(dispatch, receiver, diag_missing_finalize_dispatch_);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportMissingDispatch(
|
| - const FunctionDecl* dispatch,
|
| - RecordInfo* receiver,
|
| - unsigned error) {
|
| - ReportDiagnostic(dispatch->getLocStart(), error) << receiver->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportDerivesNonStackAllocated(
|
| - RecordInfo* info,
|
| - BasePoint* base) {
|
| - ReportDiagnostic(base->spec().getLocStart(),
|
| - diag_derives_non_stack_allocated_)
|
| - << info->record() << base->info()->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportClassOverridesNew(
|
| - RecordInfo* info,
|
| - CXXMethodDecl* newop) {
|
| - ReportDiagnostic(newop->getLocStart(), diag_class_overrides_new_)
|
| - << info->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportClassDeclaresPureVirtualTrace(
|
| - RecordInfo* info,
|
| - CXXMethodDecl* trace) {
|
| - ReportDiagnostic(trace->getLocStart(),
|
| - diag_class_declares_pure_virtual_trace_)
|
| - << info->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportLeftMostBaseMustBePolymorphic(
|
| - RecordInfo* derived,
|
| - CXXRecordDecl* base) {
|
| - ReportDiagnostic(base->getLocStart(),
|
| - diag_left_most_base_must_be_polymorphic_)
|
| - << base << derived->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::ReportBaseClassMustDeclareVirtualTrace(
|
| - RecordInfo* derived,
|
| - CXXRecordDecl* base) {
|
| - ReportDiagnostic(base->getLocStart(),
|
| - diag_base_class_must_declare_virtual_trace_)
|
| - << base << derived->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteManualDispatchMethod(CXXMethodDecl* dispatch) {
|
| - ReportDiagnostic(dispatch->getLocStart(),
|
| - diag_manual_dispatch_method_note_)
|
| - << dispatch;
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteBaseRequiresTracing(BasePoint* base) {
|
| - ReportDiagnostic(base->spec().getLocStart(),
|
| - diag_base_requires_tracing_note_)
|
| - << base->info()->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteFieldRequiresTracing(
|
| - RecordInfo* holder,
|
| - FieldDecl* field) {
|
| - NoteField(field, diag_field_requires_tracing_note_);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NotePartObjectContainsGCRoot(FieldPoint* point) {
|
| - FieldDecl* field = point->field();
|
| - ReportDiagnostic(field->getLocStart(),
|
| - diag_part_object_contains_gc_root_note_)
|
| - << field << field->getParent();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteFieldContainsGCRoot(FieldPoint* point) {
|
| - NoteField(point, diag_field_contains_gc_root_note_);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteUserDeclaredDestructor(CXXMethodDecl* dtor) {
|
| - ReportDiagnostic(dtor->getLocStart(), diag_user_declared_destructor_note_);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteUserDeclaredFinalizer(CXXMethodDecl* dtor) {
|
| - ReportDiagnostic(dtor->getLocStart(), diag_user_declared_finalizer_note_);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteBaseRequiresFinalization(BasePoint* base) {
|
| - ReportDiagnostic(base->spec().getLocStart(),
|
| - diag_base_requires_finalization_note_)
|
| - << base->info()->record();
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteField(FieldPoint* point, unsigned note) {
|
| - NoteField(point->field(), note);
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteField(FieldDecl* field, unsigned note) {
|
| - ReportDiagnostic(field->getLocStart(), note) << field;
|
| -}
|
| -
|
| -void BlinkGCPluginConsumer::NoteOverriddenNonVirtualTrace(
|
| - CXXMethodDecl* overridden) {
|
| - ReportDiagnostic(overridden->getLocStart(),
|
| - diag_overridden_non_virtual_trace_note_)
|
| - << overridden;
|
| -}
|
|
|