OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This clang plugin checks various invariants of the Blink garbage | 5 // This clang plugin checks various invariants of the Blink garbage |
6 // collection infrastructure. | 6 // collection infrastructure. |
7 // | 7 // |
8 // Errors are described at: | 8 // Errors are described at: |
9 // http://www.chromium.org/developers/blink-gc-plugin-errors | 9 // http://www.chromium.org/developers/blink-gc-plugin-errors |
10 | 10 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 | 49 |
50 const char kRawPtrToGCManagedClassNote[] = | 50 const char kRawPtrToGCManagedClassNote[] = |
51 "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; | 51 "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; |
52 | 52 |
53 const char kRefPtrToGCManagedClassNote[] = | 53 const char kRefPtrToGCManagedClassNote[] = |
54 "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; | 54 "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; |
55 | 55 |
56 const char kOwnPtrToGCManagedClassNote[] = | 56 const char kOwnPtrToGCManagedClassNote[] = |
57 "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; | 57 "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; |
58 | 58 |
| 59 const char kStackAllocatedFieldNote[] = |
| 60 "[blink-gc] Stack-allocated field %0 declared here:"; |
| 61 |
59 const char kPartObjectContainsGCRoot[] = | 62 const char kPartObjectContainsGCRoot[] = |
60 "[blink-gc] Field %0 with embedded GC root in %1 declared here:"; | 63 "[blink-gc] Field %0 with embedded GC root in %1 declared here:"; |
61 | 64 |
62 const char kFieldContainsGCRoot[] = | 65 const char kFieldContainsGCRoot[] = |
63 "[blink-gc] Field %0 defining a GC root declared here:"; | 66 "[blink-gc] Field %0 defining a GC root declared here:"; |
64 | 67 |
65 const char kOverriddenNonVirtualTrace[] = | 68 const char kOverriddenNonVirtualTrace[] = |
66 "[blink-gc] Class %0 overrides non-virtual trace of base class %1."; | 69 "[blink-gc] Class %0 overrides non-virtual trace of base class %1."; |
67 | 70 |
68 const char kOverriddenNonVirtualTraceNote[] = | 71 const char kOverriddenNonVirtualTraceNote[] = |
(...skipping 21 matching lines...) Expand all Loading... |
90 | 93 |
91 const char kUserDeclaredDestructorNote[] = | 94 const char kUserDeclaredDestructorNote[] = |
92 "[blink-gc] User-declared destructor declared here:"; | 95 "[blink-gc] User-declared destructor declared here:"; |
93 | 96 |
94 const char kBaseRequiresFinalizationNote[] = | 97 const char kBaseRequiresFinalizationNote[] = |
95 "[blink-gc] Base class %0 requiring finalization declared here:"; | 98 "[blink-gc] Base class %0 requiring finalization declared here:"; |
96 | 99 |
97 const char kFieldRequiresFinalizationNote[] = | 100 const char kFieldRequiresFinalizationNote[] = |
98 "[blink-gc] Field %0 requiring finalization declared here:"; | 101 "[blink-gc] Field %0 requiring finalization declared here:"; |
99 | 102 |
| 103 const char kDerivesNonStackAllocated[] = |
| 104 "[blink-gc] Stack-allocated class %0 derives class %1" |
| 105 " which is not stack allocated."; |
| 106 |
| 107 const char kDerivesStackAllocated[] = |
| 108 "[blink-gc] Class %0 derives stack-allocated class %1" |
| 109 " but is not itself stack allocated"; |
| 110 |
100 struct BlinkGCPluginOptions { | 111 struct BlinkGCPluginOptions { |
101 BlinkGCPluginOptions() : enable_oilpan(false) {} | 112 BlinkGCPluginOptions() : enable_oilpan(false) {} |
102 bool enable_oilpan; | 113 bool enable_oilpan; |
103 std::set<std::string> ignored_classes; | 114 std::set<std::string> ignored_classes; |
104 std::set<std::string> checked_namespaces; | 115 std::set<std::string> checked_namespaces; |
105 std::vector<std::string> ignored_directories; | 116 std::vector<std::string> ignored_directories; |
106 }; | 117 }; |
107 | 118 |
108 typedef std::vector<CXXRecordDecl*> RecordVector; | 119 typedef std::vector<CXXRecordDecl*> RecordVector; |
109 typedef std::vector<CXXMethodDecl*> MethodVector; | 120 typedef std::vector<CXXMethodDecl*> MethodVector; |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 }; | 423 }; |
413 | 424 |
414 // This visitor checks that the fields of a class are "well formed". | 425 // This visitor checks that the fields of a class are "well formed". |
415 // - OwnPtr, RefPtr and RawPtr must not point to a GC derived types. | 426 // - OwnPtr, RefPtr and RawPtr must not point to a GC derived types. |
416 // - An on-heap class must never contain GC roots. | 427 // - An on-heap class must never contain GC roots. |
417 class CheckFieldsVisitor : public RecursiveEdgeVisitor { | 428 class CheckFieldsVisitor : public RecursiveEdgeVisitor { |
418 public: | 429 public: |
419 typedef std::vector<std::pair<FieldPoint*, Edge*> > Errors; | 430 typedef std::vector<std::pair<FieldPoint*, Edge*> > Errors; |
420 | 431 |
421 CheckFieldsVisitor(const BlinkGCPluginOptions& options) | 432 CheckFieldsVisitor(const BlinkGCPluginOptions& options) |
422 : options_(options), current_(0) {} | 433 : options_(options), current_(0), stack_allocated_host_(false) {} |
423 | 434 |
424 Errors& invalid_fields() { return invalid_fields_; } | 435 Errors& invalid_fields() { return invalid_fields_; } |
425 | 436 |
426 bool ContainsInvalidFields(RecordInfo* info) { | 437 bool ContainsInvalidFields(RecordInfo* info) { |
| 438 stack_allocated_host_ = info->IsStackAllocated(); |
427 for (RecordInfo::Fields::iterator it = info->GetFields().begin(); | 439 for (RecordInfo::Fields::iterator it = info->GetFields().begin(); |
428 it != info->GetFields().end(); | 440 it != info->GetFields().end(); |
429 ++it) { | 441 ++it) { |
430 context().clear(); | 442 context().clear(); |
431 current_ = &it->second; | 443 current_ = &it->second; |
432 current_->edge()->Accept(this); | 444 current_->edge()->Accept(this); |
433 } | 445 } |
434 return !invalid_fields_.empty(); | 446 return !invalid_fields_.empty(); |
435 } | 447 } |
436 | 448 |
437 void VisitValue(Value* edge) { | 449 void VisitValue(Value* edge) { |
438 // TODO: what should we do to check unions? | 450 // TODO: what should we do to check unions? |
439 if (edge->value()->record()->isUnion()) | 451 if (edge->value()->record()->isUnion()) |
440 return; | 452 return; |
441 | 453 |
| 454 if (!stack_allocated_host_ && edge->value()->IsStackAllocated()) |
| 455 invalid_fields_.push_back(std::make_pair(current_, edge)); |
| 456 |
442 if (!Parent() || !edge->value()->IsGCAllocated()) | 457 if (!Parent() || !edge->value()->IsGCAllocated()) |
443 return; | 458 return; |
444 | 459 |
445 if (Parent()->IsOwnPtr()) | 460 if (Parent()->IsOwnPtr()) |
446 invalid_fields_.push_back(std::make_pair(current_, Parent())); | 461 invalid_fields_.push_back(std::make_pair(current_, Parent())); |
447 | 462 |
448 // Don't check raw and ref pointers in transition mode. | 463 // Don't check raw and ref pointers in transition mode. |
449 if (options_.enable_oilpan) | 464 if (options_.enable_oilpan) |
450 return; | 465 return; |
451 | 466 |
452 if (Parent()->IsRawPtr() || Parent()->IsRefPtr()) | 467 if ((!stack_allocated_host_ && Parent()->IsRawPtr()) || |
| 468 Parent()->IsRefPtr()) |
453 invalid_fields_.push_back(std::make_pair(current_, Parent())); | 469 invalid_fields_.push_back(std::make_pair(current_, Parent())); |
454 } | 470 } |
455 | 471 |
456 private: | 472 private: |
457 const BlinkGCPluginOptions& options_; | 473 const BlinkGCPluginOptions& options_; |
458 FieldPoint* current_; | 474 FieldPoint* current_; |
| 475 bool stack_allocated_host_; |
459 Errors invalid_fields_; | 476 Errors invalid_fields_; |
460 }; | 477 }; |
461 | 478 |
462 // Main class containing checks for various invariants of the Blink | 479 // Main class containing checks for various invariants of the Blink |
463 // garbage collection infrastructure. | 480 // garbage collection infrastructure. |
464 class BlinkGCPluginConsumer : public ASTConsumer { | 481 class BlinkGCPluginConsumer : public ASTConsumer { |
465 public: | 482 public: |
466 BlinkGCPluginConsumer(CompilerInstance& instance, | 483 BlinkGCPluginConsumer(CompilerInstance& instance, |
467 const BlinkGCPluginOptions& options) | 484 const BlinkGCPluginOptions& options) |
468 : instance_(instance), | 485 : instance_(instance), |
(...skipping 27 matching lines...) Expand all Loading... |
496 diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( | 513 diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( |
497 getErrorLevel(), kOverriddenNonVirtualTrace); | 514 getErrorLevel(), kOverriddenNonVirtualTrace); |
498 diag_virtual_and_manual_dispatch_ = diagnostic_.getCustomDiagID( | 515 diag_virtual_and_manual_dispatch_ = diagnostic_.getCustomDiagID( |
499 getErrorLevel(), kVirtualAndManualDispatch); | 516 getErrorLevel(), kVirtualAndManualDispatch); |
500 diag_missing_trace_dispatch_ = diagnostic_.getCustomDiagID( | 517 diag_missing_trace_dispatch_ = diagnostic_.getCustomDiagID( |
501 getErrorLevel(), kMissingTraceDispatch); | 518 getErrorLevel(), kMissingTraceDispatch); |
502 diag_missing_finalize_ = diagnostic_.getCustomDiagID( | 519 diag_missing_finalize_ = diagnostic_.getCustomDiagID( |
503 getErrorLevel(), kMissingFinalize); | 520 getErrorLevel(), kMissingFinalize); |
504 diag_missing_finalize_dispatch_ = diagnostic_.getCustomDiagID( | 521 diag_missing_finalize_dispatch_ = diagnostic_.getCustomDiagID( |
505 getErrorLevel(), kMissingFinalizeDispatch); | 522 getErrorLevel(), kMissingFinalizeDispatch); |
| 523 diag_derives_non_stack_allocated_ = diagnostic_.getCustomDiagID( |
| 524 getErrorLevel(), kDerivesNonStackAllocated); |
| 525 diag_derives_stack_allocated_ = diagnostic_.getCustomDiagID( |
| 526 getErrorLevel(), kDerivesStackAllocated); |
506 | 527 |
507 // Register note messages. | 528 // Register note messages. |
508 diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( | 529 diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( |
509 DiagnosticsEngine::Note, kFieldRequiresTracingNote); | 530 DiagnosticsEngine::Note, kFieldRequiresTracingNote); |
510 diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( | 531 diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( |
511 DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); | 532 DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); |
512 diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( | 533 diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( |
513 DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); | 534 DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); |
514 diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( | 535 diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( |
515 DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); | 536 DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); |
| 537 diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID( |
| 538 DiagnosticsEngine::Note, kStackAllocatedFieldNote); |
516 diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 539 diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( |
517 DiagnosticsEngine::Note, kPartObjectContainsGCRoot); | 540 DiagnosticsEngine::Note, kPartObjectContainsGCRoot); |
518 diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 541 diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( |
519 DiagnosticsEngine::Note, kFieldContainsGCRoot); | 542 DiagnosticsEngine::Note, kFieldContainsGCRoot); |
520 diag_finalized_field_note_ = diagnostic_.getCustomDiagID( | 543 diag_finalized_field_note_ = diagnostic_.getCustomDiagID( |
521 DiagnosticsEngine::Note, kFinalizedFieldNote); | 544 DiagnosticsEngine::Note, kFinalizedFieldNote); |
522 diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( | 545 diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( |
523 DiagnosticsEngine::Note, kUserDeclaredDestructorNote); | 546 DiagnosticsEngine::Note, kUserDeclaredDestructorNote); |
524 diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( | 547 diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( |
525 DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); | 548 DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 CheckClass(cache_.Lookup(*it)); | 590 CheckClass(cache_.Lookup(*it)); |
568 } | 591 } |
569 return; | 592 return; |
570 } | 593 } |
571 | 594 |
572 CheckClass(info); | 595 CheckClass(info); |
573 } | 596 } |
574 | 597 |
575 // Check a class-like object (eg, class, specialization, instantiation). | 598 // Check a class-like object (eg, class, specialization, instantiation). |
576 void CheckClass(RecordInfo* info) { | 599 void CheckClass(RecordInfo* info) { |
577 // Don't enforce tracing of stack allocated objects. | 600 if (!info) |
578 if (!info || info->IsStackAllocated()) | |
579 return; | 601 return; |
580 | 602 |
| 603 // Check consistency of stack-allocated hierarchies. |
| 604 bool stack_allocated = info->IsStackAllocated(); |
| 605 for (RecordInfo::Bases::iterator it = info->GetBases().begin(); |
| 606 it != info->GetBases().end(); |
| 607 ++it) { |
| 608 bool stack_allocated_base = it->second.info()->IsStackAllocated(); |
| 609 if (stack_allocated && !stack_allocated_base) |
| 610 ReportDerivesNonStackAllocated(info, &it->second); |
| 611 |
| 612 if (!stack_allocated && stack_allocated_base) |
| 613 ReportDerivesStackAllocated(info, &it->second); |
| 614 } |
| 615 |
581 if (info->RequiresTraceMethod() && !info->GetTraceMethod()) | 616 if (info->RequiresTraceMethod() && !info->GetTraceMethod()) |
582 ReportClassRequiresTraceMethod(info); | 617 ReportClassRequiresTraceMethod(info); |
583 | 618 |
584 if (CXXMethodDecl* dispatch = info->GetTraceDispatchMethod()) | 619 if (CXXMethodDecl* dispatch = info->GetTraceDispatchMethod()) |
585 CheckDispatch(info, dispatch); | 620 CheckDispatch(info, dispatch); |
586 | 621 |
587 { | 622 { |
588 CheckFieldsVisitor visitor(options_); | 623 CheckFieldsVisitor visitor(options_); |
589 if (visitor.ContainsInvalidFields(info)) | 624 if (visitor.ContainsInvalidFields(info)) |
590 ReportClassContainsInvalidFields(info, &visitor.invalid_fields()); | 625 ReportClassContainsInvalidFields(info, &visitor.invalid_fields()); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 << info->record(); | 908 << info->record(); |
874 for (CheckFieldsVisitor::Errors::iterator it = errors->begin(); | 909 for (CheckFieldsVisitor::Errors::iterator it = errors->begin(); |
875 it != errors->end(); | 910 it != errors->end(); |
876 ++it) { | 911 ++it) { |
877 if (it->second->IsRawPtr()) { | 912 if (it->second->IsRawPtr()) { |
878 NoteField(it->first, diag_raw_ptr_to_gc_managed_class_note_); | 913 NoteField(it->first, diag_raw_ptr_to_gc_managed_class_note_); |
879 } else if (it->second->IsRefPtr()) { | 914 } else if (it->second->IsRefPtr()) { |
880 NoteField(it->first, diag_ref_ptr_to_gc_managed_class_note_); | 915 NoteField(it->first, diag_ref_ptr_to_gc_managed_class_note_); |
881 } else if (it->second->IsOwnPtr()) { | 916 } else if (it->second->IsOwnPtr()) { |
882 NoteField(it->first, diag_own_ptr_to_gc_managed_class_note_); | 917 NoteField(it->first, diag_own_ptr_to_gc_managed_class_note_); |
| 918 } else if (it->second->IsValue()) { |
| 919 NoteField(it->first, diag_stack_allocated_field_note_); |
883 } | 920 } |
884 } | 921 } |
885 } | 922 } |
886 | 923 |
887 void ReportClassContainsGCRoots(RecordInfo* info, | 924 void ReportClassContainsGCRoots(RecordInfo* info, |
888 CheckGCRootsVisitor::Errors* errors) { | 925 CheckGCRootsVisitor::Errors* errors) { |
889 SourceLocation loc = info->record()->getLocStart(); | 926 SourceLocation loc = info->record()->getLocStart(); |
890 SourceManager& manager = instance_.getSourceManager(); | 927 SourceManager& manager = instance_.getSourceManager(); |
891 FullSourceLoc full_loc(loc, manager); | 928 FullSourceLoc full_loc(loc, manager); |
892 for (CheckGCRootsVisitor::Errors::iterator it = errors->begin(); | 929 for (CheckGCRootsVisitor::Errors::iterator it = errors->begin(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 | 1003 |
967 void ReportMissingDispatch(const FunctionDecl* dispatch, | 1004 void ReportMissingDispatch(const FunctionDecl* dispatch, |
968 RecordInfo* receiver, | 1005 RecordInfo* receiver, |
969 unsigned error) { | 1006 unsigned error) { |
970 SourceLocation loc = dispatch->getLocStart(); | 1007 SourceLocation loc = dispatch->getLocStart(); |
971 SourceManager& manager = instance_.getSourceManager(); | 1008 SourceManager& manager = instance_.getSourceManager(); |
972 FullSourceLoc full_loc(loc, manager); | 1009 FullSourceLoc full_loc(loc, manager); |
973 diagnostic_.Report(full_loc, error) << receiver->record(); | 1010 diagnostic_.Report(full_loc, error) << receiver->record(); |
974 } | 1011 } |
975 | 1012 |
| 1013 void ReportDerivesNonStackAllocated(RecordInfo* info, BasePoint* base) { |
| 1014 SourceLocation loc = base->spec().getLocStart(); |
| 1015 SourceManager& manager = instance_.getSourceManager(); |
| 1016 FullSourceLoc full_loc(loc, manager); |
| 1017 diagnostic_.Report(full_loc, diag_derives_non_stack_allocated_) |
| 1018 << info->record() << base->info()->record(); |
| 1019 } |
| 1020 |
| 1021 void ReportDerivesStackAllocated(RecordInfo* info, BasePoint* base) { |
| 1022 SourceLocation loc = base->spec().getLocStart(); |
| 1023 SourceManager& manager = instance_.getSourceManager(); |
| 1024 FullSourceLoc full_loc(loc, manager); |
| 1025 diagnostic_.Report(full_loc, diag_derives_stack_allocated_) |
| 1026 << info->record() << base->info()->record(); |
| 1027 } |
| 1028 |
976 void NoteFieldRequiresTracing(RecordInfo* holder, FieldDecl* field) { | 1029 void NoteFieldRequiresTracing(RecordInfo* holder, FieldDecl* field) { |
977 NoteField(field, diag_field_requires_tracing_note_); | 1030 NoteField(field, diag_field_requires_tracing_note_); |
978 } | 1031 } |
979 | 1032 |
980 void NotePartObjectContainsGCRoot(FieldPoint* point) { | 1033 void NotePartObjectContainsGCRoot(FieldPoint* point) { |
981 FieldDecl* field = point->field(); | 1034 FieldDecl* field = point->field(); |
982 SourceLocation loc = field->getLocStart(); | 1035 SourceLocation loc = field->getLocStart(); |
983 SourceManager& manager = instance_.getSourceManager(); | 1036 SourceManager& manager = instance_.getSourceManager(); |
984 FullSourceLoc full_loc(loc, manager); | 1037 FullSourceLoc full_loc(loc, manager); |
985 diagnostic_.Report(full_loc, diag_part_object_contains_gc_root_note_) | 1038 diagnostic_.Report(full_loc, diag_part_object_contains_gc_root_note_) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 unsigned diag_fields_require_tracing_; | 1082 unsigned diag_fields_require_tracing_; |
1030 unsigned diag_class_contains_invalid_fields_; | 1083 unsigned diag_class_contains_invalid_fields_; |
1031 unsigned diag_class_contains_gc_root_; | 1084 unsigned diag_class_contains_gc_root_; |
1032 unsigned diag_class_requires_finalization_; | 1085 unsigned diag_class_requires_finalization_; |
1033 unsigned diag_finalizer_accesses_finalized_field_; | 1086 unsigned diag_finalizer_accesses_finalized_field_; |
1034 unsigned diag_overridden_non_virtual_trace_; | 1087 unsigned diag_overridden_non_virtual_trace_; |
1035 unsigned diag_virtual_and_manual_dispatch_; | 1088 unsigned diag_virtual_and_manual_dispatch_; |
1036 unsigned diag_missing_trace_dispatch_; | 1089 unsigned diag_missing_trace_dispatch_; |
1037 unsigned diag_missing_finalize_; | 1090 unsigned diag_missing_finalize_; |
1038 unsigned diag_missing_finalize_dispatch_; | 1091 unsigned diag_missing_finalize_dispatch_; |
| 1092 unsigned diag_derives_non_stack_allocated_; |
| 1093 unsigned diag_derives_stack_allocated_; |
1039 | 1094 |
1040 unsigned diag_field_requires_tracing_note_; | 1095 unsigned diag_field_requires_tracing_note_; |
1041 unsigned diag_raw_ptr_to_gc_managed_class_note_; | 1096 unsigned diag_raw_ptr_to_gc_managed_class_note_; |
1042 unsigned diag_ref_ptr_to_gc_managed_class_note_; | 1097 unsigned diag_ref_ptr_to_gc_managed_class_note_; |
1043 unsigned diag_own_ptr_to_gc_managed_class_note_; | 1098 unsigned diag_own_ptr_to_gc_managed_class_note_; |
| 1099 unsigned diag_stack_allocated_field_note_; |
1044 unsigned diag_part_object_contains_gc_root_note_; | 1100 unsigned diag_part_object_contains_gc_root_note_; |
1045 unsigned diag_field_contains_gc_root_note_; | 1101 unsigned diag_field_contains_gc_root_note_; |
1046 unsigned diag_finalized_field_note_; | 1102 unsigned diag_finalized_field_note_; |
1047 unsigned diag_user_declared_destructor_note_; | 1103 unsigned diag_user_declared_destructor_note_; |
1048 unsigned diag_base_requires_finalization_note_; | 1104 unsigned diag_base_requires_finalization_note_; |
1049 unsigned diag_field_requires_finalization_note_; | 1105 unsigned diag_field_requires_finalization_note_; |
1050 unsigned diag_overridden_non_virtual_trace_note_; | 1106 unsigned diag_overridden_non_virtual_trace_note_; |
1051 | 1107 |
1052 CompilerInstance& instance_; | 1108 CompilerInstance& instance_; |
1053 DiagnosticsEngine& diagnostic_; | 1109 DiagnosticsEngine& diagnostic_; |
(...skipping 30 matching lines...) Expand all Loading... |
1084 | 1140 |
1085 private: | 1141 private: |
1086 BlinkGCPluginOptions options_; | 1142 BlinkGCPluginOptions options_; |
1087 }; | 1143 }; |
1088 | 1144 |
1089 } // namespace | 1145 } // namespace |
1090 | 1146 |
1091 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( | 1147 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( |
1092 "blink-gc-plugin", | 1148 "blink-gc-plugin", |
1093 "Check Blink GC invariants"); | 1149 "Check Blink GC invariants"); |
OLD | NEW |