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 26 matching lines...) Expand all Loading... |
95 | 98 |
96 const char kBaseRequiresFinalizationNote[] = | 99 const char kBaseRequiresFinalizationNote[] = |
97 "[blink-gc] Base class %0 requiring finalization declared here:"; | 100 "[blink-gc] Base class %0 requiring finalization declared here:"; |
98 | 101 |
99 const char kFieldRequiresFinalizationNote[] = | 102 const char kFieldRequiresFinalizationNote[] = |
100 "[blink-gc] Field %0 requiring finalization declared here:"; | 103 "[blink-gc] Field %0 requiring finalization declared here:"; |
101 | 104 |
102 const char kManualDispatchMethodNote[] = | 105 const char kManualDispatchMethodNote[] = |
103 "[blink-gc] Manual dispatch %0 declared here:"; | 106 "[blink-gc] Manual dispatch %0 declared here:"; |
104 | 107 |
| 108 const char kDerivesNonStackAllocated[] = |
| 109 "[blink-gc] Stack-allocated class %0 derives class %1" |
| 110 " which is not stack allocated."; |
| 111 |
105 struct BlinkGCPluginOptions { | 112 struct BlinkGCPluginOptions { |
106 BlinkGCPluginOptions() : enable_oilpan(false) {} | 113 BlinkGCPluginOptions() : enable_oilpan(false) {} |
107 bool enable_oilpan; | 114 bool enable_oilpan; |
108 std::set<std::string> ignored_classes; | 115 std::set<std::string> ignored_classes; |
109 std::set<std::string> checked_namespaces; | 116 std::set<std::string> checked_namespaces; |
110 std::vector<std::string> ignored_directories; | 117 std::vector<std::string> ignored_directories; |
111 }; | 118 }; |
112 | 119 |
113 typedef std::vector<CXXRecordDecl*> RecordVector; | 120 typedef std::vector<CXXRecordDecl*> RecordVector; |
114 typedef std::vector<CXXMethodDecl*> MethodVector; | 121 typedef std::vector<CXXMethodDecl*> MethodVector; |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 }; | 424 }; |
418 | 425 |
419 // This visitor checks that the fields of a class are "well formed". | 426 // This visitor checks that the fields of a class are "well formed". |
420 // - OwnPtr, RefPtr and RawPtr must not point to a GC derived types. | 427 // - OwnPtr, RefPtr and RawPtr must not point to a GC derived types. |
421 // - An on-heap class must never contain GC roots. | 428 // - An on-heap class must never contain GC roots. |
422 class CheckFieldsVisitor : public RecursiveEdgeVisitor { | 429 class CheckFieldsVisitor : public RecursiveEdgeVisitor { |
423 public: | 430 public: |
424 typedef std::vector<std::pair<FieldPoint*, Edge*> > Errors; | 431 typedef std::vector<std::pair<FieldPoint*, Edge*> > Errors; |
425 | 432 |
426 CheckFieldsVisitor(const BlinkGCPluginOptions& options) | 433 CheckFieldsVisitor(const BlinkGCPluginOptions& options) |
427 : options_(options), current_(0) {} | 434 : options_(options), current_(0), stack_allocated_host_(false) {} |
428 | 435 |
429 Errors& invalid_fields() { return invalid_fields_; } | 436 Errors& invalid_fields() { return invalid_fields_; } |
430 | 437 |
431 bool ContainsInvalidFields(RecordInfo* info) { | 438 bool ContainsInvalidFields(RecordInfo* info) { |
| 439 stack_allocated_host_ = info->IsStackAllocated(); |
432 for (RecordInfo::Fields::iterator it = info->GetFields().begin(); | 440 for (RecordInfo::Fields::iterator it = info->GetFields().begin(); |
433 it != info->GetFields().end(); | 441 it != info->GetFields().end(); |
434 ++it) { | 442 ++it) { |
435 context().clear(); | 443 context().clear(); |
436 current_ = &it->second; | 444 current_ = &it->second; |
437 current_->edge()->Accept(this); | 445 current_->edge()->Accept(this); |
438 } | 446 } |
439 return !invalid_fields_.empty(); | 447 return !invalid_fields_.empty(); |
440 } | 448 } |
441 | 449 |
442 void VisitValue(Value* edge) { | 450 void VisitValue(Value* edge) { |
443 // TODO: what should we do to check unions? | 451 // TODO: what should we do to check unions? |
444 if (edge->value()->record()->isUnion()) | 452 if (edge->value()->record()->isUnion()) |
445 return; | 453 return; |
446 | 454 |
| 455 if (!stack_allocated_host_ && edge->value()->IsStackAllocated()) |
| 456 invalid_fields_.push_back(std::make_pair(current_, edge)); |
| 457 |
447 if (!Parent() || !edge->value()->IsGCAllocated()) | 458 if (!Parent() || !edge->value()->IsGCAllocated()) |
448 return; | 459 return; |
449 | 460 |
450 if (Parent()->IsOwnPtr()) | 461 if (Parent()->IsOwnPtr()) |
451 invalid_fields_.push_back(std::make_pair(current_, Parent())); | 462 invalid_fields_.push_back(std::make_pair(current_, Parent())); |
452 | 463 |
453 // Don't check raw and ref pointers in transition mode. | 464 // Don't check raw and ref pointers in transition mode. |
454 if (options_.enable_oilpan) | 465 if (options_.enable_oilpan) |
455 return; | 466 return; |
456 | 467 |
457 if (Parent()->IsRawPtr() || Parent()->IsRefPtr()) | 468 if ((!stack_allocated_host_ && Parent()->IsRawPtr()) || |
| 469 Parent()->IsRefPtr()) |
458 invalid_fields_.push_back(std::make_pair(current_, Parent())); | 470 invalid_fields_.push_back(std::make_pair(current_, Parent())); |
459 } | 471 } |
460 | 472 |
461 private: | 473 private: |
462 const BlinkGCPluginOptions& options_; | 474 const BlinkGCPluginOptions& options_; |
463 FieldPoint* current_; | 475 FieldPoint* current_; |
| 476 bool stack_allocated_host_; |
464 Errors invalid_fields_; | 477 Errors invalid_fields_; |
465 }; | 478 }; |
466 | 479 |
467 // Main class containing checks for various invariants of the Blink | 480 // Main class containing checks for various invariants of the Blink |
468 // garbage collection infrastructure. | 481 // garbage collection infrastructure. |
469 class BlinkGCPluginConsumer : public ASTConsumer { | 482 class BlinkGCPluginConsumer : public ASTConsumer { |
470 public: | 483 public: |
471 BlinkGCPluginConsumer(CompilerInstance& instance, | 484 BlinkGCPluginConsumer(CompilerInstance& instance, |
472 const BlinkGCPluginOptions& options) | 485 const BlinkGCPluginOptions& options) |
473 : instance_(instance), | 486 : instance_(instance), |
(...skipping 29 matching lines...) Expand all Loading... |
503 diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( | 516 diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( |
504 getErrorLevel(), kMissingTraceDispatchMethod); | 517 getErrorLevel(), kMissingTraceDispatchMethod); |
505 diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( | 518 diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( |
506 getErrorLevel(), kMissingFinalizeDispatchMethod); | 519 getErrorLevel(), kMissingFinalizeDispatchMethod); |
507 diag_virtual_and_manual_dispatch_ = diagnostic_.getCustomDiagID( | 520 diag_virtual_and_manual_dispatch_ = diagnostic_.getCustomDiagID( |
508 getErrorLevel(), kVirtualAndManualDispatch); | 521 getErrorLevel(), kVirtualAndManualDispatch); |
509 diag_missing_trace_dispatch_ = diagnostic_.getCustomDiagID( | 522 diag_missing_trace_dispatch_ = diagnostic_.getCustomDiagID( |
510 getErrorLevel(), kMissingTraceDispatch); | 523 getErrorLevel(), kMissingTraceDispatch); |
511 diag_missing_finalize_dispatch_ = diagnostic_.getCustomDiagID( | 524 diag_missing_finalize_dispatch_ = diagnostic_.getCustomDiagID( |
512 getErrorLevel(), kMissingFinalizeDispatch); | 525 getErrorLevel(), kMissingFinalizeDispatch); |
| 526 diag_derives_non_stack_allocated_ = diagnostic_.getCustomDiagID( |
| 527 getErrorLevel(), kDerivesNonStackAllocated); |
513 | 528 |
514 // Register note messages. | 529 // Register note messages. |
515 diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( | 530 diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( |
516 DiagnosticsEngine::Note, kFieldRequiresTracingNote); | 531 DiagnosticsEngine::Note, kFieldRequiresTracingNote); |
517 diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( | 532 diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( |
518 DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); | 533 DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); |
519 diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( | 534 diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( |
520 DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); | 535 DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); |
521 diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( | 536 diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( |
522 DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); | 537 DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); |
| 538 diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID( |
| 539 DiagnosticsEngine::Note, kStackAllocatedFieldNote); |
523 diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 540 diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( |
524 DiagnosticsEngine::Note, kPartObjectContainsGCRoot); | 541 DiagnosticsEngine::Note, kPartObjectContainsGCRoot); |
525 diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 542 diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( |
526 DiagnosticsEngine::Note, kFieldContainsGCRoot); | 543 DiagnosticsEngine::Note, kFieldContainsGCRoot); |
527 diag_finalized_field_note_ = diagnostic_.getCustomDiagID( | 544 diag_finalized_field_note_ = diagnostic_.getCustomDiagID( |
528 DiagnosticsEngine::Note, kFinalizedFieldNote); | 545 DiagnosticsEngine::Note, kFinalizedFieldNote); |
529 diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( | 546 diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( |
530 DiagnosticsEngine::Note, kUserDeclaredDestructorNote); | 547 DiagnosticsEngine::Note, kUserDeclaredDestructorNote); |
531 diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( | 548 diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( |
532 DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); | 549 DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 CheckClass(cache_.Lookup(*it)); | 595 CheckClass(cache_.Lookup(*it)); |
579 } | 596 } |
580 return; | 597 return; |
581 } | 598 } |
582 | 599 |
583 CheckClass(info); | 600 CheckClass(info); |
584 } | 601 } |
585 | 602 |
586 // Check a class-like object (eg, class, specialization, instantiation). | 603 // Check a class-like object (eg, class, specialization, instantiation). |
587 void CheckClass(RecordInfo* info) { | 604 void CheckClass(RecordInfo* info) { |
588 // Don't enforce tracing of stack allocated objects. | 605 if (!info) |
589 if (!info || info->IsStackAllocated()) | |
590 return; | 606 return; |
591 | 607 |
| 608 // Check consistency of stack-allocated hierarchies. |
| 609 if (info->IsStackAllocated()) { |
| 610 for (RecordInfo::Bases::iterator it = info->GetBases().begin(); |
| 611 it != info->GetBases().end(); |
| 612 ++it) { |
| 613 if (!it->second.info()->IsStackAllocated()) |
| 614 ReportDerivesNonStackAllocated(info, &it->second); |
| 615 } |
| 616 } |
| 617 |
592 if (info->RequiresTraceMethod() && !info->GetTraceMethod()) | 618 if (info->RequiresTraceMethod() && !info->GetTraceMethod()) |
593 ReportClassRequiresTraceMethod(info); | 619 ReportClassRequiresTraceMethod(info); |
594 | 620 |
595 CheckDispatch(info); | 621 CheckDispatch(info); |
596 | 622 |
597 { | 623 { |
598 CheckFieldsVisitor visitor(options_); | 624 CheckFieldsVisitor visitor(options_); |
599 if (visitor.ContainsInvalidFields(info)) | 625 if (visitor.ContainsInvalidFields(info)) |
600 ReportClassContainsInvalidFields(info, &visitor.invalid_fields()); | 626 ReportClassContainsInvalidFields(info, &visitor.invalid_fields()); |
601 } | 627 } |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 << info->record(); | 913 << info->record(); |
888 for (CheckFieldsVisitor::Errors::iterator it = errors->begin(); | 914 for (CheckFieldsVisitor::Errors::iterator it = errors->begin(); |
889 it != errors->end(); | 915 it != errors->end(); |
890 ++it) { | 916 ++it) { |
891 if (it->second->IsRawPtr()) { | 917 if (it->second->IsRawPtr()) { |
892 NoteField(it->first, diag_raw_ptr_to_gc_managed_class_note_); | 918 NoteField(it->first, diag_raw_ptr_to_gc_managed_class_note_); |
893 } else if (it->second->IsRefPtr()) { | 919 } else if (it->second->IsRefPtr()) { |
894 NoteField(it->first, diag_ref_ptr_to_gc_managed_class_note_); | 920 NoteField(it->first, diag_ref_ptr_to_gc_managed_class_note_); |
895 } else if (it->second->IsOwnPtr()) { | 921 } else if (it->second->IsOwnPtr()) { |
896 NoteField(it->first, diag_own_ptr_to_gc_managed_class_note_); | 922 NoteField(it->first, diag_own_ptr_to_gc_managed_class_note_); |
| 923 } else if (it->second->IsValue()) { |
| 924 NoteField(it->first, diag_stack_allocated_field_note_); |
897 } | 925 } |
898 } | 926 } |
899 } | 927 } |
900 | 928 |
901 void ReportClassContainsGCRoots(RecordInfo* info, | 929 void ReportClassContainsGCRoots(RecordInfo* info, |
902 CheckGCRootsVisitor::Errors* errors) { | 930 CheckGCRootsVisitor::Errors* errors) { |
903 SourceLocation loc = info->record()->getLocStart(); | 931 SourceLocation loc = info->record()->getLocStart(); |
904 SourceManager& manager = instance_.getSourceManager(); | 932 SourceManager& manager = instance_.getSourceManager(); |
905 FullSourceLoc full_loc(loc, manager); | 933 FullSourceLoc full_loc(loc, manager); |
906 for (CheckGCRootsVisitor::Errors::iterator it = errors->begin(); | 934 for (CheckGCRootsVisitor::Errors::iterator it = errors->begin(); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 | 1018 |
991 void ReportMissingDispatch(const FunctionDecl* dispatch, | 1019 void ReportMissingDispatch(const FunctionDecl* dispatch, |
992 RecordInfo* receiver, | 1020 RecordInfo* receiver, |
993 unsigned error) { | 1021 unsigned error) { |
994 SourceLocation loc = dispatch->getLocStart(); | 1022 SourceLocation loc = dispatch->getLocStart(); |
995 SourceManager& manager = instance_.getSourceManager(); | 1023 SourceManager& manager = instance_.getSourceManager(); |
996 FullSourceLoc full_loc(loc, manager); | 1024 FullSourceLoc full_loc(loc, manager); |
997 diagnostic_.Report(full_loc, error) << receiver->record(); | 1025 diagnostic_.Report(full_loc, error) << receiver->record(); |
998 } | 1026 } |
999 | 1027 |
| 1028 void ReportDerivesNonStackAllocated(RecordInfo* info, BasePoint* base) { |
| 1029 SourceLocation loc = base->spec().getLocStart(); |
| 1030 SourceManager& manager = instance_.getSourceManager(); |
| 1031 FullSourceLoc full_loc(loc, manager); |
| 1032 diagnostic_.Report(full_loc, diag_derives_non_stack_allocated_) |
| 1033 << info->record() << base->info()->record(); |
| 1034 } |
| 1035 |
1000 void NoteManualDispatchMethod(CXXMethodDecl* dispatch) { | 1036 void NoteManualDispatchMethod(CXXMethodDecl* dispatch) { |
1001 SourceLocation loc = dispatch->getLocStart(); | 1037 SourceLocation loc = dispatch->getLocStart(); |
1002 SourceManager& manager = instance_.getSourceManager(); | 1038 SourceManager& manager = instance_.getSourceManager(); |
1003 FullSourceLoc full_loc(loc, manager); | 1039 FullSourceLoc full_loc(loc, manager); |
1004 diagnostic_.Report(full_loc, diag_manual_dispatch_method_note_) << dispatch; | 1040 diagnostic_.Report(full_loc, diag_manual_dispatch_method_note_) << dispatch; |
1005 } | 1041 } |
1006 | 1042 |
1007 void NoteFieldRequiresTracing(RecordInfo* holder, FieldDecl* field) { | 1043 void NoteFieldRequiresTracing(RecordInfo* holder, FieldDecl* field) { |
1008 NoteField(field, diag_field_requires_tracing_note_); | 1044 NoteField(field, diag_field_requires_tracing_note_); |
1009 } | 1045 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 unsigned diag_class_contains_invalid_fields_; | 1104 unsigned diag_class_contains_invalid_fields_; |
1069 unsigned diag_class_contains_gc_root_; | 1105 unsigned diag_class_contains_gc_root_; |
1070 unsigned diag_class_requires_finalization_; | 1106 unsigned diag_class_requires_finalization_; |
1071 unsigned diag_finalizer_accesses_finalized_field_; | 1107 unsigned diag_finalizer_accesses_finalized_field_; |
1072 unsigned diag_overridden_non_virtual_trace_; | 1108 unsigned diag_overridden_non_virtual_trace_; |
1073 unsigned diag_missing_trace_dispatch_method_; | 1109 unsigned diag_missing_trace_dispatch_method_; |
1074 unsigned diag_missing_finalize_dispatch_method_; | 1110 unsigned diag_missing_finalize_dispatch_method_; |
1075 unsigned diag_virtual_and_manual_dispatch_; | 1111 unsigned diag_virtual_and_manual_dispatch_; |
1076 unsigned diag_missing_trace_dispatch_; | 1112 unsigned diag_missing_trace_dispatch_; |
1077 unsigned diag_missing_finalize_dispatch_; | 1113 unsigned diag_missing_finalize_dispatch_; |
| 1114 unsigned diag_derives_non_stack_allocated_; |
1078 | 1115 |
1079 unsigned diag_field_requires_tracing_note_; | 1116 unsigned diag_field_requires_tracing_note_; |
1080 unsigned diag_raw_ptr_to_gc_managed_class_note_; | 1117 unsigned diag_raw_ptr_to_gc_managed_class_note_; |
1081 unsigned diag_ref_ptr_to_gc_managed_class_note_; | 1118 unsigned diag_ref_ptr_to_gc_managed_class_note_; |
1082 unsigned diag_own_ptr_to_gc_managed_class_note_; | 1119 unsigned diag_own_ptr_to_gc_managed_class_note_; |
| 1120 unsigned diag_stack_allocated_field_note_; |
1083 unsigned diag_part_object_contains_gc_root_note_; | 1121 unsigned diag_part_object_contains_gc_root_note_; |
1084 unsigned diag_field_contains_gc_root_note_; | 1122 unsigned diag_field_contains_gc_root_note_; |
1085 unsigned diag_finalized_field_note_; | 1123 unsigned diag_finalized_field_note_; |
1086 unsigned diag_user_declared_destructor_note_; | 1124 unsigned diag_user_declared_destructor_note_; |
1087 unsigned diag_user_declared_finalizer_note_; | 1125 unsigned diag_user_declared_finalizer_note_; |
1088 unsigned diag_base_requires_finalization_note_; | 1126 unsigned diag_base_requires_finalization_note_; |
1089 unsigned diag_field_requires_finalization_note_; | 1127 unsigned diag_field_requires_finalization_note_; |
1090 unsigned diag_overridden_non_virtual_trace_note_; | 1128 unsigned diag_overridden_non_virtual_trace_note_; |
1091 unsigned diag_manual_dispatch_method_note_; | 1129 unsigned diag_manual_dispatch_method_note_; |
1092 | 1130 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 | 1163 |
1126 private: | 1164 private: |
1127 BlinkGCPluginOptions options_; | 1165 BlinkGCPluginOptions options_; |
1128 }; | 1166 }; |
1129 | 1167 |
1130 } // namespace | 1168 } // namespace |
1131 | 1169 |
1132 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( | 1170 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( |
1133 "blink-gc-plugin", | 1171 "blink-gc-plugin", |
1134 "Check Blink GC invariants"); | 1172 "Check Blink GC invariants"); |
OLD | NEW |