Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(652)

Side by Side Diff: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp

Issue 206123004: Add checks for stack-allocated types and their uses in fields. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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");
OLDNEW
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/RecordInfo.h » ('j') | tools/clang/blink_gc_plugin/RecordInfo.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698