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

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

Issue 551343002: Blink GC plugin: Add plugin flags for generating raw-pointer errors and unneeded-finalizer warnings. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: presubmit Created 6 years, 3 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
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/tests/class_does_not_require_finalization.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 43
44 const char kClassContainsInvalidFields[] = 44 const char kClassContainsInvalidFields[] =
45 "[blink-gc] Class %0 contains invalid fields."; 45 "[blink-gc] Class %0 contains invalid fields.";
46 46
47 const char kClassContainsGCRoot[] = 47 const char kClassContainsGCRoot[] =
48 "[blink-gc] Class %0 contains GC root in field %1."; 48 "[blink-gc] Class %0 contains GC root in field %1.";
49 49
50 const char kClassRequiresFinalization[] = 50 const char kClassRequiresFinalization[] =
51 "[blink-gc] Class %0 requires finalization."; 51 "[blink-gc] Class %0 requires finalization.";
52 52
53 const char kClassDoesNotRequireFinalization[] =
54 "[blink-gc] Class %0 may not require finalization.";
55
53 const char kFinalizerAccessesFinalizedField[] = 56 const char kFinalizerAccessesFinalizedField[] =
54 "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; 57 "[blink-gc] Finalizer %0 accesses potentially finalized field %1.";
55 58
56 const char kRawPtrToGCManagedClassNote[] = 59 const char kRawPtrToGCManagedClassNote[] =
57 "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; 60 "[blink-gc] Raw pointer field %0 to a GC managed class declared here:";
58 61
59 const char kRefPtrToGCManagedClassNote[] = 62 const char kRefPtrToGCManagedClassNote[] =
60 "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; 63 "[blink-gc] RefPtr field %0 to a GC managed class declared here:";
61 64
62 const char kOwnPtrToGCManagedClassNote[] = 65 const char kOwnPtrToGCManagedClassNote[] =
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 134
132 const char kLeftMostBaseMustBePolymorphic[] = 135 const char kLeftMostBaseMustBePolymorphic[] =
133 "[blink-gc] Left-most base class %0 of derived class %1" 136 "[blink-gc] Left-most base class %0 of derived class %1"
134 " must be polymorphic."; 137 " must be polymorphic.";
135 138
136 const char kBaseClassMustDeclareVirtualTrace[] = 139 const char kBaseClassMustDeclareVirtualTrace[] =
137 "[blink-gc] Left-most base class %0 of derived class %1" 140 "[blink-gc] Left-most base class %0 of derived class %1"
138 " must define a virtual trace method."; 141 " must define a virtual trace method.";
139 142
140 struct BlinkGCPluginOptions { 143 struct BlinkGCPluginOptions {
141 BlinkGCPluginOptions() : enable_oilpan(false), dump_graph(false) {} 144 BlinkGCPluginOptions()
145 : enable_oilpan(false)
146 , dump_graph(false)
147 , warn_raw_ptr(false)
148 , warn_unneeded_finalizer(false) {}
142 bool enable_oilpan; 149 bool enable_oilpan;
143 bool dump_graph; 150 bool dump_graph;
151 bool warn_raw_ptr;
152 bool warn_unneeded_finalizer;
144 std::set<std::string> ignored_classes; 153 std::set<std::string> ignored_classes;
145 std::set<std::string> checked_namespaces; 154 std::set<std::string> checked_namespaces;
146 std::vector<std::string> ignored_directories; 155 std::vector<std::string> ignored_directories;
147 }; 156 };
148 157
149 typedef std::vector<CXXRecordDecl*> RecordVector; 158 typedef std::vector<CXXRecordDecl*> RecordVector;
150 typedef std::vector<CXXMethodDecl*> MethodVector; 159 typedef std::vector<CXXMethodDecl*> MethodVector;
151 160
152 // Test if a template specialization is an instantiation. 161 // Test if a template specialization is an instantiation.
153 static bool IsTemplateInstantiation(CXXRecordDecl* record) { 162 static bool IsTemplateInstantiation(CXXRecordDecl* record) {
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 // This visitor checks that the fields of a class are "well formed". 621 // This visitor checks that the fields of a class are "well formed".
613 // - OwnPtr, RefPtr and RawPtr must not point to a GC derived types. 622 // - OwnPtr, RefPtr and RawPtr must not point to a GC derived types.
614 // - Part objects must not be GC derived types. 623 // - Part objects must not be GC derived types.
615 // - An on-heap class must never contain GC roots. 624 // - An on-heap class must never contain GC roots.
616 // - Only stack-allocated types may point to stack-allocated types. 625 // - Only stack-allocated types may point to stack-allocated types.
617 class CheckFieldsVisitor : public RecursiveEdgeVisitor { 626 class CheckFieldsVisitor : public RecursiveEdgeVisitor {
618 public: 627 public:
619 628
620 enum Error { 629 enum Error {
621 kRawPtrToGCManaged, 630 kRawPtrToGCManaged,
631 kRawPtrToGCManagedWarning,
622 kRefPtrToGCManaged, 632 kRefPtrToGCManaged,
623 kOwnPtrToGCManaged, 633 kOwnPtrToGCManaged,
624 kMemberInUnmanaged, 634 kMemberInUnmanaged,
625 kPtrFromHeapToStack, 635 kPtrFromHeapToStack,
626 kGCDerivedPartObject 636 kGCDerivedPartObject
627 }; 637 };
628 638
629 typedef std::vector<std::pair<FieldPoint*, Error> > Errors; 639 typedef std::vector<std::pair<FieldPoint*, Error> > Errors;
630 640
631 CheckFieldsVisitor(const BlinkGCPluginOptions& options) 641 CheckFieldsVisitor(const BlinkGCPluginOptions& options)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 // In transition mode, disallow OwnPtr<T>, RawPtr<T> to GC allocated T's, 695 // In transition mode, disallow OwnPtr<T>, RawPtr<T> to GC allocated T's,
686 // also disallow T* in stack-allocated types. 696 // also disallow T* in stack-allocated types.
687 if (options_.enable_oilpan) { 697 if (options_.enable_oilpan) {
688 if (Parent()->IsOwnPtr() || 698 if (Parent()->IsOwnPtr() ||
689 Parent()->IsRawPtrClass() || 699 Parent()->IsRawPtrClass() ||
690 (stack_allocated_host_ && Parent()->IsRawPtr())) { 700 (stack_allocated_host_ && Parent()->IsRawPtr())) {
691 invalid_fields_.push_back(std::make_pair( 701 invalid_fields_.push_back(std::make_pair(
692 current_, InvalidSmartPtr(Parent()))); 702 current_, InvalidSmartPtr(Parent())));
693 return; 703 return;
694 } 704 }
695 705 if (options_.warn_raw_ptr && Parent()->IsRawPtr()) {
706 invalid_fields_.push_back(std::make_pair(
707 current_, kRawPtrToGCManagedWarning));
708 }
696 return; 709 return;
697 } 710 }
698 711
699 if (Parent()->IsRawPtr() || Parent()->IsRefPtr() || Parent()->IsOwnPtr()) { 712 if (Parent()->IsRawPtr() || Parent()->IsRefPtr() || Parent()->IsOwnPtr()) {
700 invalid_fields_.push_back(std::make_pair( 713 invalid_fields_.push_back(std::make_pair(
701 current_, InvalidSmartPtr(Parent()))); 714 current_, InvalidSmartPtr(Parent())));
702 return; 715 return;
703 } 716 }
704 } 717 }
705 718
(...skipping 13 matching lines...) Expand all
719 assert(false && "Unknown smart pointer kind"); 732 assert(false && "Unknown smart pointer kind");
720 } 733 }
721 734
722 const BlinkGCPluginOptions& options_; 735 const BlinkGCPluginOptions& options_;
723 FieldPoint* current_; 736 FieldPoint* current_;
724 bool stack_allocated_host_; 737 bool stack_allocated_host_;
725 bool managed_host_; 738 bool managed_host_;
726 Errors invalid_fields_; 739 Errors invalid_fields_;
727 }; 740 };
728 741
742 class EmptyStmtVisitor
743 : public RecursiveASTVisitor<EmptyStmtVisitor> {
744 public:
745 static bool isEmpty(Stmt* stmt) {
746 EmptyStmtVisitor visitor;
747 visitor.TraverseStmt(stmt);
748 return visitor.empty_;
749 }
750
751 bool WalkUpFromCompoundStmt(CompoundStmt* stmt) {
752 empty_ = stmt->body_empty();
753 return false;
754 }
755 bool VisitStmt(Stmt*) {
756 empty_ = false;
757 return false;
758 }
759 private:
760 EmptyStmtVisitor() : empty_(true) {}
761 bool empty_;
762 };
763
729 // Main class containing checks for various invariants of the Blink 764 // Main class containing checks for various invariants of the Blink
730 // garbage collection infrastructure. 765 // garbage collection infrastructure.
731 class BlinkGCPluginConsumer : public ASTConsumer { 766 class BlinkGCPluginConsumer : public ASTConsumer {
732 public: 767 public:
733 BlinkGCPluginConsumer(CompilerInstance& instance, 768 BlinkGCPluginConsumer(CompilerInstance& instance,
734 const BlinkGCPluginOptions& options) 769 const BlinkGCPluginOptions& options)
735 : instance_(instance), 770 : instance_(instance),
736 diagnostic_(instance.getDiagnostics()), 771 diagnostic_(instance.getDiagnostics()),
737 options_(options), 772 options_(options),
738 json_(0) { 773 json_(0) {
739 774
740 // Only check structures in the blink and WebKit namespaces. 775 // Only check structures in the blink and WebKit namespaces.
741 options_.checked_namespaces.insert("blink"); 776 options_.checked_namespaces.insert("blink");
742 options_.checked_namespaces.insert("WebKit"); 777 options_.checked_namespaces.insert("WebKit");
743 778
744 // Ignore GC implementation files. 779 // Ignore GC implementation files.
745 options_.ignored_directories.push_back("/heap/"); 780 options_.ignored_directories.push_back("/heap/");
746 781
747 // Register warning/error messages. 782 // Register warning/error messages.
748 diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID( 783 diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID(
749 getErrorLevel(), kClassMustLeftMostlyDeriveGC); 784 getErrorLevel(), kClassMustLeftMostlyDeriveGC);
750 diag_class_requires_trace_method_ = 785 diag_class_requires_trace_method_ =
751 diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod); 786 diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod);
752 diag_base_requires_tracing_ = 787 diag_base_requires_tracing_ =
753 diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing); 788 diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing);
754 diag_fields_require_tracing_ = 789 diag_fields_require_tracing_ =
755 diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing); 790 diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing);
756 diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID( 791 diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID(
757 getErrorLevel(), kClassContainsInvalidFields); 792 getErrorLevel(), kClassContainsInvalidFields);
793 diag_class_contains_invalid_fields_warning_ = diagnostic_.getCustomDiagID(
794 DiagnosticsEngine::Warning, kClassContainsInvalidFields);
758 diag_class_contains_gc_root_ = 795 diag_class_contains_gc_root_ =
759 diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); 796 diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot);
760 diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( 797 diag_class_requires_finalization_ = diagnostic_.getCustomDiagID(
761 getErrorLevel(), kClassRequiresFinalization); 798 getErrorLevel(), kClassRequiresFinalization);
799 diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID(
800 DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization);
762 diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( 801 diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID(
763 getErrorLevel(), kFinalizerAccessesFinalizedField); 802 getErrorLevel(), kFinalizerAccessesFinalizedField);
764 diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( 803 diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID(
765 getErrorLevel(), kOverriddenNonVirtualTrace); 804 getErrorLevel(), kOverriddenNonVirtualTrace);
766 diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( 805 diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID(
767 getErrorLevel(), kMissingTraceDispatchMethod); 806 getErrorLevel(), kMissingTraceDispatchMethod);
768 diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( 807 diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID(
769 getErrorLevel(), kMissingFinalizeDispatchMethod); 808 getErrorLevel(), kMissingFinalizeDispatchMethod);
770 diag_virtual_and_manual_dispatch_ = 809 diag_virtual_and_manual_dispatch_ =
771 diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); 810 diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 } 973 }
935 974
936 { 975 {
937 CheckGCRootsVisitor visitor; 976 CheckGCRootsVisitor visitor;
938 if (visitor.ContainsGCRoots(info)) 977 if (visitor.ContainsGCRoots(info))
939 ReportClassContainsGCRoots(info, &visitor.gc_roots()); 978 ReportClassContainsGCRoots(info, &visitor.gc_roots());
940 } 979 }
941 980
942 if (info->NeedsFinalization()) 981 if (info->NeedsFinalization())
943 CheckFinalization(info); 982 CheckFinalization(info);
983
984 if (options_.warn_unneeded_finalizer && info->IsGCFinalized())
985 CheckUnneededFinalization(info);
944 } 986 }
945 987
946 DumpClass(info); 988 DumpClass(info);
947 } 989 }
948 990
949 CXXRecordDecl* GetDependentTemplatedDecl(const Type& type) { 991 CXXRecordDecl* GetDependentTemplatedDecl(const Type& type) {
950 const TemplateSpecializationType* tmpl_type = 992 const TemplateSpecializationType* tmpl_type =
951 type.getAs<TemplateSpecializationType>(); 993 type.getAs<TemplateSpecializationType>();
952 if (!tmpl_type) 994 if (!tmpl_type)
953 return 0; 995 return 0;
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 } 1200 }
1159 1201
1160 for (RecordInfo::Fields::iterator it = info->GetFields().begin(); 1202 for (RecordInfo::Fields::iterator it = info->GetFields().begin();
1161 it != info->GetFields().end(); 1203 it != info->GetFields().end();
1162 ++it) { 1204 ++it) {
1163 if (it->second.edge()->NeedsFinalization()) 1205 if (it->second.edge()->NeedsFinalization())
1164 NoteField(&it->second, diag_field_requires_finalization_note_); 1206 NoteField(&it->second, diag_field_requires_finalization_note_);
1165 } 1207 }
1166 } 1208 }
1167 1209
1210 void CheckUnneededFinalization(RecordInfo* info) {
1211 if (!HasNonEmptyFinalizer(info))
1212 ReportClassDoesNotRequireFinalization(info);
1213 }
1214
1215 bool HasNonEmptyFinalizer(RecordInfo* info) {
1216 CXXDestructorDecl* dtor = info->record()->getDestructor();
1217 if (dtor && dtor->isUserProvided()) {
1218 if (!dtor->hasBody() || !EmptyStmtVisitor::isEmpty(dtor->getBody()))
1219 return true;
1220 }
1221 for (RecordInfo::Bases::iterator it = info->GetBases().begin();
1222 it != info->GetBases().end();
1223 ++it) {
1224 if (HasNonEmptyFinalizer(it->second.info()))
1225 return true;
1226 }
1227 for (RecordInfo::Fields::iterator it = info->GetFields().begin();
1228 it != info->GetFields().end();
1229 ++it) {
1230 if (it->second.edge()->NeedsFinalization())
1231 return true;
1232 }
1233 return false;
1234 }
1235
1168 // This is the main entry for tracing method definitions. 1236 // This is the main entry for tracing method definitions.
1169 void CheckTracingMethod(CXXMethodDecl* method) { 1237 void CheckTracingMethod(CXXMethodDecl* method) {
1170 RecordInfo* parent = cache_.Lookup(method->getParent()); 1238 RecordInfo* parent = cache_.Lookup(method->getParent());
1171 if (IsIgnored(parent)) 1239 if (IsIgnored(parent))
1172 return; 1240 return;
1173 1241
1174 // Check templated tracing methods by checking the template instantiations. 1242 // Check templated tracing methods by checking the template instantiations.
1175 // Specialized templates are handled as ordinary classes. 1243 // Specialized templates are handled as ordinary classes.
1176 if (ClassTemplateDecl* tmpl = 1244 if (ClassTemplateDecl* tmpl =
1177 parent->record()->getDescribedClassTemplate()) { 1245 parent->record()->getDescribedClassTemplate()) {
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 if (!it->second.IsProperlyTraced()) 1523 if (!it->second.IsProperlyTraced())
1456 NoteFieldRequiresTracing(info, it->first); 1524 NoteFieldRequiresTracing(info, it->first);
1457 } 1525 }
1458 } 1526 }
1459 1527
1460 void ReportClassContainsInvalidFields(RecordInfo* info, 1528 void ReportClassContainsInvalidFields(RecordInfo* info,
1461 CheckFieldsVisitor::Errors* errors) { 1529 CheckFieldsVisitor::Errors* errors) {
1462 SourceLocation loc = info->record()->getLocStart(); 1530 SourceLocation loc = info->record()->getLocStart();
1463 SourceManager& manager = instance_.getSourceManager(); 1531 SourceManager& manager = instance_.getSourceManager();
1464 FullSourceLoc full_loc(loc, manager); 1532 FullSourceLoc full_loc(loc, manager);
1465 diagnostic_.Report(full_loc, diag_class_contains_invalid_fields_) 1533 bool only_warnings = options_.warn_raw_ptr;
1534 for (CheckFieldsVisitor::Errors::iterator it = errors->begin();
1535 only_warnings && it != errors->end();
1536 ++it) {
1537 if (it->second != CheckFieldsVisitor::kRawPtrToGCManagedWarning)
1538 only_warnings = false;
1539 }
1540 diagnostic_.Report(full_loc, only_warnings ?
1541 diag_class_contains_invalid_fields_warning_ :
1542 diag_class_contains_invalid_fields_)
1466 << info->record(); 1543 << info->record();
1467 for (CheckFieldsVisitor::Errors::iterator it = errors->begin(); 1544 for (CheckFieldsVisitor::Errors::iterator it = errors->begin();
1468 it != errors->end(); 1545 it != errors->end();
1469 ++it) { 1546 ++it) {
1470 unsigned error; 1547 unsigned error;
1471 if (it->second == CheckFieldsVisitor::kRawPtrToGCManaged) { 1548 if (it->second == CheckFieldsVisitor::kRawPtrToGCManaged ||
1549 it->second == CheckFieldsVisitor::kRawPtrToGCManagedWarning) {
1472 error = diag_raw_ptr_to_gc_managed_class_note_; 1550 error = diag_raw_ptr_to_gc_managed_class_note_;
1473 } else if (it->second == CheckFieldsVisitor::kRefPtrToGCManaged) { 1551 } else if (it->second == CheckFieldsVisitor::kRefPtrToGCManaged) {
1474 error = diag_ref_ptr_to_gc_managed_class_note_; 1552 error = diag_ref_ptr_to_gc_managed_class_note_;
1475 } else if (it->second == CheckFieldsVisitor::kOwnPtrToGCManaged) { 1553 } else if (it->second == CheckFieldsVisitor::kOwnPtrToGCManaged) {
1476 error = diag_own_ptr_to_gc_managed_class_note_; 1554 error = diag_own_ptr_to_gc_managed_class_note_;
1477 } else if (it->second == CheckFieldsVisitor::kMemberInUnmanaged) { 1555 } else if (it->second == CheckFieldsVisitor::kMemberInUnmanaged) {
1478 error = diag_member_in_unmanaged_class_note_; 1556 error = diag_member_in_unmanaged_class_note_;
1479 } else if (it->second == CheckFieldsVisitor::kPtrFromHeapToStack) { 1557 } else if (it->second == CheckFieldsVisitor::kPtrFromHeapToStack) {
1480 error = diag_stack_allocated_field_note_; 1558 error = diag_stack_allocated_field_note_;
1481 } else if (it->second == CheckFieldsVisitor::kGCDerivedPartObject) { 1559 } else if (it->second == CheckFieldsVisitor::kGCDerivedPartObject) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 } 1601 }
1524 1602
1525 void ReportClassRequiresFinalization(RecordInfo* info) { 1603 void ReportClassRequiresFinalization(RecordInfo* info) {
1526 SourceLocation loc = info->record()->getInnerLocStart(); 1604 SourceLocation loc = info->record()->getInnerLocStart();
1527 SourceManager& manager = instance_.getSourceManager(); 1605 SourceManager& manager = instance_.getSourceManager();
1528 FullSourceLoc full_loc(loc, manager); 1606 FullSourceLoc full_loc(loc, manager);
1529 diagnostic_.Report(full_loc, diag_class_requires_finalization_) 1607 diagnostic_.Report(full_loc, diag_class_requires_finalization_)
1530 << info->record(); 1608 << info->record();
1531 } 1609 }
1532 1610
1611 void ReportClassDoesNotRequireFinalization(RecordInfo* info) {
1612 SourceLocation loc = info->record()->getInnerLocStart();
1613 SourceManager& manager = instance_.getSourceManager();
1614 FullSourceLoc full_loc(loc, manager);
1615 diagnostic_.Report(full_loc, diag_class_does_not_require_finalization_)
1616 << info->record();
1617 }
1618
1533 void ReportOverriddenNonVirtualTrace(RecordInfo* info, 1619 void ReportOverriddenNonVirtualTrace(RecordInfo* info,
1534 CXXMethodDecl* trace, 1620 CXXMethodDecl* trace,
1535 CXXMethodDecl* overridden) { 1621 CXXMethodDecl* overridden) {
1536 SourceLocation loc = trace->getLocStart(); 1622 SourceLocation loc = trace->getLocStart();
1537 SourceManager& manager = instance_.getSourceManager(); 1623 SourceManager& manager = instance_.getSourceManager();
1538 FullSourceLoc full_loc(loc, manager); 1624 FullSourceLoc full_loc(loc, manager);
1539 diagnostic_.Report(full_loc, diag_overridden_non_virtual_trace_) 1625 diagnostic_.Report(full_loc, diag_overridden_non_virtual_trace_)
1540 << info->record() << overridden->getParent(); 1626 << info->record() << overridden->getParent();
1541 NoteOverriddenNonVirtualTrace(overridden); 1627 NoteOverriddenNonVirtualTrace(overridden);
1542 } 1628 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 FullSourceLoc full_loc(loc, manager); 1784 FullSourceLoc full_loc(loc, manager);
1699 diagnostic_.Report(full_loc, diag_overridden_non_virtual_trace_note_) 1785 diagnostic_.Report(full_loc, diag_overridden_non_virtual_trace_note_)
1700 << overridden; 1786 << overridden;
1701 } 1787 }
1702 1788
1703 unsigned diag_class_must_left_mostly_derive_gc_; 1789 unsigned diag_class_must_left_mostly_derive_gc_;
1704 unsigned diag_class_requires_trace_method_; 1790 unsigned diag_class_requires_trace_method_;
1705 unsigned diag_base_requires_tracing_; 1791 unsigned diag_base_requires_tracing_;
1706 unsigned diag_fields_require_tracing_; 1792 unsigned diag_fields_require_tracing_;
1707 unsigned diag_class_contains_invalid_fields_; 1793 unsigned diag_class_contains_invalid_fields_;
1794 unsigned diag_class_contains_invalid_fields_warning_;
1708 unsigned diag_class_contains_gc_root_; 1795 unsigned diag_class_contains_gc_root_;
1709 unsigned diag_class_requires_finalization_; 1796 unsigned diag_class_requires_finalization_;
1797 unsigned diag_class_does_not_require_finalization_;
1710 unsigned diag_finalizer_accesses_finalized_field_; 1798 unsigned diag_finalizer_accesses_finalized_field_;
1711 unsigned diag_overridden_non_virtual_trace_; 1799 unsigned diag_overridden_non_virtual_trace_;
1712 unsigned diag_missing_trace_dispatch_method_; 1800 unsigned diag_missing_trace_dispatch_method_;
1713 unsigned diag_missing_finalize_dispatch_method_; 1801 unsigned diag_missing_finalize_dispatch_method_;
1714 unsigned diag_virtual_and_manual_dispatch_; 1802 unsigned diag_virtual_and_manual_dispatch_;
1715 unsigned diag_missing_trace_dispatch_; 1803 unsigned diag_missing_trace_dispatch_;
1716 unsigned diag_missing_finalize_dispatch_; 1804 unsigned diag_missing_finalize_dispatch_;
1717 unsigned diag_derives_non_stack_allocated_; 1805 unsigned diag_derives_non_stack_allocated_;
1718 unsigned diag_class_overrides_new_; 1806 unsigned diag_class_overrides_new_;
1719 unsigned diag_class_declares_pure_virtual_trace_; 1807 unsigned diag_class_declares_pure_virtual_trace_;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1758 1846
1759 virtual bool ParseArgs(const CompilerInstance& instance, 1847 virtual bool ParseArgs(const CompilerInstance& instance,
1760 const std::vector<string>& args) { 1848 const std::vector<string>& args) {
1761 bool parsed = true; 1849 bool parsed = true;
1762 1850
1763 for (size_t i = 0; i < args.size() && parsed; ++i) { 1851 for (size_t i = 0; i < args.size() && parsed; ++i) {
1764 if (args[i] == "enable-oilpan") { 1852 if (args[i] == "enable-oilpan") {
1765 options_.enable_oilpan = true; 1853 options_.enable_oilpan = true;
1766 } else if (args[i] == "dump-graph") { 1854 } else if (args[i] == "dump-graph") {
1767 options_.dump_graph = true; 1855 options_.dump_graph = true;
1856 } else if (args[i] == "warn-raw-ptr") {
1857 options_.warn_raw_ptr = true;
1858 } else if (args[i] == "warn-unneeded-finalizer") {
1859 options_.warn_unneeded_finalizer = true;
1768 } else { 1860 } else {
1769 parsed = false; 1861 parsed = false;
1770 llvm::errs() << "Unknown blink-gc-plugin argument: " << args[i] << "\n"; 1862 llvm::errs() << "Unknown blink-gc-plugin argument: " << args[i] << "\n";
1771 } 1863 }
1772 } 1864 }
1773 1865
1774 return parsed; 1866 return parsed;
1775 } 1867 }
1776 1868
1777 private: 1869 private:
1778 BlinkGCPluginOptions options_; 1870 BlinkGCPluginOptions options_;
1779 }; 1871 };
1780 1872
1781 } // namespace 1873 } // namespace
1782 1874
1783 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( 1875 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X(
1784 "blink-gc-plugin", 1876 "blink-gc-plugin",
1785 "Check Blink GC invariants"); 1877 "Check Blink GC invariants");
OLDNEW
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/tests/class_does_not_require_finalization.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698