| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 52 | 52 | 
| 53 const char kClassRequiresFinalization[] = | 53 const char kClassRequiresFinalization[] = | 
| 54     "[blink-gc] Class %0 requires finalization."; | 54     "[blink-gc] Class %0 requires finalization."; | 
| 55 | 55 | 
| 56 const char kClassDoesNotRequireFinalization[] = | 56 const char kClassDoesNotRequireFinalization[] = | 
| 57     "[blink-gc] Class %0 may not require finalization."; | 57     "[blink-gc] Class %0 may not require finalization."; | 
| 58 | 58 | 
| 59 const char kFinalizerAccessesFinalizedField[] = | 59 const char kFinalizerAccessesFinalizedField[] = | 
| 60     "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; | 60     "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; | 
| 61 | 61 | 
|  | 62 const char kFinalizerAccessesEagerlyFinalizedField[] = | 
|  | 63     "[blink-gc] Finalizer %0 accesses eagerly finalized field %1."; | 
|  | 64 | 
| 62 const char kRawPtrToGCManagedClassNote[] = | 65 const char kRawPtrToGCManagedClassNote[] = | 
| 63     "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; | 66     "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; | 
| 64 | 67 | 
| 65 const char kRefPtrToGCManagedClassNote[] = | 68 const char kRefPtrToGCManagedClassNote[] = | 
| 66     "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; | 69     "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; | 
| 67 | 70 | 
| 68 const char kOwnPtrToGCManagedClassNote[] = | 71 const char kOwnPtrToGCManagedClassNote[] = | 
| 69     "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; | 72     "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; | 
| 70 | 73 | 
| 71 const char kStackAllocatedFieldNote[] = | 74 const char kStackAllocatedFieldNote[] = | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 101 | 104 | 
| 102 const char kMissingTraceDispatch[] = | 105 const char kMissingTraceDispatch[] = | 
| 103     "[blink-gc] Missing dispatch to class %0 in manual trace dispatch."; | 106     "[blink-gc] Missing dispatch to class %0 in manual trace dispatch."; | 
| 104 | 107 | 
| 105 const char kMissingFinalizeDispatch[] = | 108 const char kMissingFinalizeDispatch[] = | 
| 106     "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch."; | 109     "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch."; | 
| 107 | 110 | 
| 108 const char kFinalizedFieldNote[] = | 111 const char kFinalizedFieldNote[] = | 
| 109     "[blink-gc] Potentially finalized field %0 declared here:"; | 112     "[blink-gc] Potentially finalized field %0 declared here:"; | 
| 110 | 113 | 
|  | 114 const char kEagerlyFinalizedFieldNote[] = | 
|  | 115     "[blink-gc] Field %0 having eagerly finalized value, declared here:"; | 
|  | 116 | 
| 111 const char kUserDeclaredDestructorNote[] = | 117 const char kUserDeclaredDestructorNote[] = | 
| 112     "[blink-gc] User-declared destructor declared here:"; | 118     "[blink-gc] User-declared destructor declared here:"; | 
| 113 | 119 | 
| 114 const char kUserDeclaredFinalizerNote[] = | 120 const char kUserDeclaredFinalizerNote[] = | 
| 115     "[blink-gc] User-declared finalizer declared here:"; | 121     "[blink-gc] User-declared finalizer declared here:"; | 
| 116 | 122 | 
| 117 const char kBaseRequiresFinalizationNote[] = | 123 const char kBaseRequiresFinalizationNote[] = | 
| 118     "[blink-gc] Base class %0 requiring finalization declared here:"; | 124     "[blink-gc] Base class %0 requiring finalization declared here:"; | 
| 119 | 125 | 
| 120 const char kFieldRequiresFinalizationNote[] = | 126 const char kFieldRequiresFinalizationNote[] = | 
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 236 // either a Member, a heap-allocated collection or an off-heap collection that | 242 // either a Member, a heap-allocated collection or an off-heap collection that | 
| 237 // contains Members.  Invalid uses are currently identified as passing the field | 243 // contains Members.  Invalid uses are currently identified as passing the field | 
| 238 // as the argument of a procedure call or using the -> or [] operators on it. | 244 // as the argument of a procedure call or using the -> or [] operators on it. | 
| 239 class CheckFinalizerVisitor | 245 class CheckFinalizerVisitor | 
| 240     : public RecursiveASTVisitor<CheckFinalizerVisitor> { | 246     : public RecursiveASTVisitor<CheckFinalizerVisitor> { | 
| 241  private: | 247  private: | 
| 242   // Simple visitor to determine if the content of a field might be collected | 248   // Simple visitor to determine if the content of a field might be collected | 
| 243   // during finalization. | 249   // during finalization. | 
| 244   class MightBeCollectedVisitor : public EdgeVisitor { | 250   class MightBeCollectedVisitor : public EdgeVisitor { | 
| 245    public: | 251    public: | 
| 246     MightBeCollectedVisitor() : might_be_collected_(false) {} | 252     MightBeCollectedVisitor(bool is_eagerly_finalized) | 
|  | 253         : might_be_collected_(false) | 
|  | 254         , is_eagerly_finalized_(is_eagerly_finalized) | 
|  | 255         , as_eagerly_finalized_(false) {} | 
| 247     bool might_be_collected() { return might_be_collected_; } | 256     bool might_be_collected() { return might_be_collected_; } | 
| 248     void VisitMember(Member* edge) override { might_be_collected_ = true; } | 257     bool as_eagerly_finalized() { return as_eagerly_finalized_; } | 
|  | 258     void VisitMember(Member* edge) override { | 
|  | 259       if (is_eagerly_finalized_) { | 
|  | 260         if (edge->ptr()->IsValue()) { | 
|  | 261           Value* member = static_cast<Value*>(edge->ptr()); | 
|  | 262           if (member->value()->IsEagerlyFinalized()) { | 
|  | 263             might_be_collected_ = true; | 
|  | 264             as_eagerly_finalized_ = true; | 
|  | 265           } | 
|  | 266         } | 
|  | 267         return; | 
|  | 268       } | 
|  | 269       might_be_collected_ = true; | 
|  | 270     } | 
| 249     void VisitCollection(Collection* edge) override { | 271     void VisitCollection(Collection* edge) override { | 
| 250       if (edge->on_heap()) { | 272       if (edge->on_heap() && !is_eagerly_finalized_) { | 
| 251         might_be_collected_ = !edge->is_root(); | 273         might_be_collected_ = !edge->is_root(); | 
| 252       } else { | 274       } else { | 
| 253         edge->AcceptMembers(this); | 275         edge->AcceptMembers(this); | 
| 254       } | 276       } | 
| 255     } | 277     } | 
| 256 | 278 | 
| 257    private: | 279    private: | 
| 258     bool might_be_collected_; | 280     bool might_be_collected_; | 
|  | 281     bool is_eagerly_finalized_; | 
|  | 282     bool as_eagerly_finalized_; | 
| 259   }; | 283   }; | 
| 260 | 284 | 
| 261  public: | 285  public: | 
| 262   typedef std::vector<std::pair<MemberExpr*, FieldPoint*> > Errors; | 286   class Error { | 
|  | 287   public: | 
|  | 288     Error(MemberExpr *member, | 
|  | 289           bool as_eagerly_finalized, | 
|  | 290           FieldPoint* field) | 
|  | 291         : member_(member) | 
|  | 292         , as_eagerly_finalized_(as_eagerly_finalized) | 
|  | 293         , field_(field) {} | 
| 263 | 294 | 
| 264   CheckFinalizerVisitor(RecordCache* cache) | 295     MemberExpr* member_; | 
| 265       : blacklist_context_(false), cache_(cache) {} | 296     bool as_eagerly_finalized_; | 
|  | 297     FieldPoint* field_; | 
|  | 298   }; | 
|  | 299 | 
|  | 300   typedef std::vector<Error> Errors; | 
|  | 301 | 
|  | 302   CheckFinalizerVisitor(RecordCache* cache, bool is_eagerly_finalized) | 
|  | 303       : blacklist_context_(false) | 
|  | 304       , cache_(cache) | 
|  | 305       , is_eagerly_finalized_(is_eagerly_finalized) {} | 
| 266 | 306 | 
| 267   Errors& finalized_fields() { return finalized_fields_; } | 307   Errors& finalized_fields() { return finalized_fields_; } | 
| 268 | 308 | 
| 269   bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr* expr) { | 309   bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr* expr) { | 
| 270     // Only continue the walk-up if the operator is a blacklisted one. | 310     // Only continue the walk-up if the operator is a blacklisted one. | 
| 271     switch (expr->getOperator()) { | 311     switch (expr->getOperator()) { | 
| 272       case OO_Arrow: | 312       case OO_Arrow: | 
| 273       case OO_Subscript: | 313       case OO_Subscript: | 
| 274         this->WalkUpFromCallExpr(expr); | 314         this->WalkUpFromCallExpr(expr); | 
| 275       default: | 315       default: | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 293       return true; | 333       return true; | 
| 294 | 334 | 
| 295     RecordInfo* info = cache_->Lookup(field->getParent()); | 335     RecordInfo* info = cache_->Lookup(field->getParent()); | 
| 296     if (!info) | 336     if (!info) | 
| 297       return true; | 337       return true; | 
| 298 | 338 | 
| 299     RecordInfo::Fields::iterator it = info->GetFields().find(field); | 339     RecordInfo::Fields::iterator it = info->GetFields().find(field); | 
| 300     if (it == info->GetFields().end()) | 340     if (it == info->GetFields().end()) | 
| 301       return true; | 341       return true; | 
| 302 | 342 | 
| 303     if (blacklist_context_ && MightBeCollected(&it->second)) | 343     if (seen_members_.find(member) != seen_members_.end()) | 
| 304       finalized_fields_.push_back(std::make_pair(member, &it->second)); | 344       return true; | 
|  | 345 | 
|  | 346     bool as_eagerly_finalized = false; | 
|  | 347     if (blacklist_context_ && | 
|  | 348         MightBeCollected(&it->second, as_eagerly_finalized)) { | 
|  | 349       finalized_fields_.push_back( | 
|  | 350           Error(member, as_eagerly_finalized, &it->second)); | 
|  | 351       seen_members_.insert(member); | 
|  | 352     } | 
| 305     return true; | 353     return true; | 
| 306   } | 354   } | 
| 307 | 355 | 
| 308   bool MightBeCollected(FieldPoint* point) { | 356   bool MightBeCollected(FieldPoint* point, bool& as_eagerly_finalized) { | 
| 309     MightBeCollectedVisitor visitor; | 357     MightBeCollectedVisitor visitor(is_eagerly_finalized_); | 
| 310     point->edge()->Accept(&visitor); | 358     point->edge()->Accept(&visitor); | 
|  | 359     as_eagerly_finalized = visitor.as_eagerly_finalized(); | 
| 311     return visitor.might_be_collected(); | 360     return visitor.might_be_collected(); | 
| 312   } | 361   } | 
| 313 | 362 | 
| 314  private: | 363  private: | 
| 315   bool blacklist_context_; | 364   bool blacklist_context_; | 
| 316   Errors finalized_fields_; | 365   Errors finalized_fields_; | 
|  | 366   std::set<MemberExpr*> seen_members_; | 
| 317   RecordCache* cache_; | 367   RecordCache* cache_; | 
|  | 368   bool is_eagerly_finalized_; | 
| 318 }; | 369 }; | 
| 319 | 370 | 
| 320 // This visitor checks that a method contains within its body, a call to a | 371 // This visitor checks that a method contains within its body, a call to a | 
| 321 // method on the provided receiver class. This is used to check manual | 372 // method on the provided receiver class. This is used to check manual | 
| 322 // dispatching for trace and finalize methods. | 373 // dispatching for trace and finalize methods. | 
| 323 class CheckDispatchVisitor : public RecursiveASTVisitor<CheckDispatchVisitor> { | 374 class CheckDispatchVisitor : public RecursiveASTVisitor<CheckDispatchVisitor> { | 
| 324  public: | 375  public: | 
| 325   CheckDispatchVisitor(RecordInfo* receiver) | 376   CheckDispatchVisitor(RecordInfo* receiver) | 
| 326       : receiver_(receiver), dispatched_to_receiver_(false) {} | 377       : receiver_(receiver), dispatched_to_receiver_(false) {} | 
| 327 | 378 | 
| (...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 962     diag_class_contains_invalid_fields_warning_ = diagnostic_.getCustomDiagID( | 1013     diag_class_contains_invalid_fields_warning_ = diagnostic_.getCustomDiagID( | 
| 963         DiagnosticsEngine::Warning, kClassContainsInvalidFields); | 1014         DiagnosticsEngine::Warning, kClassContainsInvalidFields); | 
| 964     diag_class_contains_gc_root_ = | 1015     diag_class_contains_gc_root_ = | 
| 965         diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); | 1016         diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); | 
| 966     diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( | 1017     diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( | 
| 967         getErrorLevel(), kClassRequiresFinalization); | 1018         getErrorLevel(), kClassRequiresFinalization); | 
| 968     diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID( | 1019     diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID( | 
| 969         DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization); | 1020         DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization); | 
| 970     diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( | 1021     diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( | 
| 971         getErrorLevel(), kFinalizerAccessesFinalizedField); | 1022         getErrorLevel(), kFinalizerAccessesFinalizedField); | 
|  | 1023     diag_finalizer_eagerly_finalized_field_ = diagnostic_.getCustomDiagID( | 
|  | 1024         getErrorLevel(), kFinalizerAccessesEagerlyFinalizedField); | 
| 972     diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( | 1025     diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( | 
| 973         getErrorLevel(), kOverriddenNonVirtualTrace); | 1026         getErrorLevel(), kOverriddenNonVirtualTrace); | 
| 974     diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( | 1027     diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( | 
| 975         getErrorLevel(), kMissingTraceDispatchMethod); | 1028         getErrorLevel(), kMissingTraceDispatchMethod); | 
| 976     diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( | 1029     diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( | 
| 977         getErrorLevel(), kMissingFinalizeDispatchMethod); | 1030         getErrorLevel(), kMissingFinalizeDispatchMethod); | 
| 978     diag_virtual_and_manual_dispatch_ = | 1031     diag_virtual_and_manual_dispatch_ = | 
| 979         diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); | 1032         diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); | 
| 980     diag_missing_trace_dispatch_ = | 1033     diag_missing_trace_dispatch_ = | 
| 981         diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch); | 1034         diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 1011     diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( | 1064     diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( | 
| 1012         DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); | 1065         DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); | 
| 1013     diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( | 1066     diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( | 
| 1014         DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); | 1067         DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); | 
| 1015     diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 1068     diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 
| 1016         DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); | 1069         DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); | 
| 1017     diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 1070     diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 
| 1018         DiagnosticsEngine::Note, kFieldContainsGCRootNote); | 1071         DiagnosticsEngine::Note, kFieldContainsGCRootNote); | 
| 1019     diag_finalized_field_note_ = diagnostic_.getCustomDiagID( | 1072     diag_finalized_field_note_ = diagnostic_.getCustomDiagID( | 
| 1020         DiagnosticsEngine::Note, kFinalizedFieldNote); | 1073         DiagnosticsEngine::Note, kFinalizedFieldNote); | 
|  | 1074     diag_eagerly_finalized_field_note_ = diagnostic_.getCustomDiagID( | 
|  | 1075         DiagnosticsEngine::Note, kEagerlyFinalizedFieldNote); | 
| 1021     diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( | 1076     diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( | 
| 1022         DiagnosticsEngine::Note, kUserDeclaredDestructorNote); | 1077         DiagnosticsEngine::Note, kUserDeclaredDestructorNote); | 
| 1023     diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( | 1078     diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( | 
| 1024         DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); | 1079         DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); | 
| 1025     diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( | 1080     diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( | 
| 1026         DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); | 1081         DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); | 
| 1027     diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID( | 1082     diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID( | 
| 1028         DiagnosticsEngine::Note, kFieldRequiresFinalizationNote); | 1083         DiagnosticsEngine::Note, kFieldRequiresFinalizationNote); | 
| 1029     diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID( | 1084     diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID( | 
| 1030         DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote); | 1085         DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote); | 
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1380     } | 1435     } | 
| 1381   } | 1436   } | 
| 1382 | 1437 | 
| 1383   // TODO: Should we collect destructors similar to trace methods? | 1438   // TODO: Should we collect destructors similar to trace methods? | 
| 1384   void CheckFinalization(RecordInfo* info) { | 1439   void CheckFinalization(RecordInfo* info) { | 
| 1385     CXXDestructorDecl* dtor = info->record()->getDestructor(); | 1440     CXXDestructorDecl* dtor = info->record()->getDestructor(); | 
| 1386 | 1441 | 
| 1387     // For finalized classes, check the finalization method if possible. | 1442     // For finalized classes, check the finalization method if possible. | 
| 1388     if (info->IsGCFinalized()) { | 1443     if (info->IsGCFinalized()) { | 
| 1389       if (dtor && dtor->hasBody()) { | 1444       if (dtor && dtor->hasBody()) { | 
| 1390         CheckFinalizerVisitor visitor(&cache_); | 1445         CheckFinalizerVisitor visitor(&cache_, info->IsEagerlyFinalized()); | 
| 1391         visitor.TraverseCXXMethodDecl(dtor); | 1446         visitor.TraverseCXXMethodDecl(dtor); | 
| 1392         if (!visitor.finalized_fields().empty()) { | 1447         if (!visitor.finalized_fields().empty()) { | 
| 1393           ReportFinalizerAccessesFinalizedFields( | 1448           ReportFinalizerAccessesFinalizedFields( | 
| 1394               dtor, &visitor.finalized_fields()); | 1449               dtor, &visitor.finalized_fields()); | 
| 1395         } | 1450         } | 
| 1396       } | 1451       } | 
| 1397       return; | 1452       return; | 
| 1398     } | 1453     } | 
| 1399 | 1454 | 
| 1400     // Don't require finalization of a mixin that has not yet been "mixed in". | 1455     // Don't require finalization of a mixin that has not yet been "mixed in". | 
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1809       NoteFieldContainsGCRoot(point); | 1864       NoteFieldContainsGCRoot(point); | 
| 1810     } | 1865     } | 
| 1811   } | 1866   } | 
| 1812 | 1867 | 
| 1813   void ReportFinalizerAccessesFinalizedFields( | 1868   void ReportFinalizerAccessesFinalizedFields( | 
| 1814       CXXMethodDecl* dtor, | 1869       CXXMethodDecl* dtor, | 
| 1815       CheckFinalizerVisitor::Errors* fields) { | 1870       CheckFinalizerVisitor::Errors* fields) { | 
| 1816     for (CheckFinalizerVisitor::Errors::iterator it = fields->begin(); | 1871     for (CheckFinalizerVisitor::Errors::iterator it = fields->begin(); | 
| 1817          it != fields->end(); | 1872          it != fields->end(); | 
| 1818          ++it) { | 1873          ++it) { | 
| 1819       SourceLocation loc = it->first->getLocStart(); | 1874       SourceLocation loc = it->member_->getLocStart(); | 
| 1820       SourceManager& manager = instance_.getSourceManager(); | 1875       SourceManager& manager = instance_.getSourceManager(); | 
|  | 1876       bool as_eagerly_finalized = it->as_eagerly_finalized_; | 
|  | 1877       unsigned diag_error = as_eagerly_finalized ? | 
|  | 1878           diag_finalizer_eagerly_finalized_field_ : | 
|  | 1879           diag_finalizer_accesses_finalized_field_; | 
|  | 1880       unsigned diag_note = as_eagerly_finalized ? | 
|  | 1881           diag_eagerly_finalized_field_note_ : | 
|  | 1882           diag_finalized_field_note_; | 
| 1821       FullSourceLoc full_loc(loc, manager); | 1883       FullSourceLoc full_loc(loc, manager); | 
| 1822       diagnostic_.Report(full_loc, diag_finalizer_accesses_finalized_field_) | 1884       diagnostic_.Report(full_loc, diag_error) | 
| 1823           << dtor << it->second->field(); | 1885           << dtor << it->field_->field(); | 
| 1824       NoteField(it->second, diag_finalized_field_note_); | 1886       NoteField(it->field_, diag_note); | 
| 1825     } | 1887     } | 
| 1826   } | 1888   } | 
| 1827 | 1889 | 
| 1828   void ReportClassRequiresFinalization(RecordInfo* info) { | 1890   void ReportClassRequiresFinalization(RecordInfo* info) { | 
| 1829     SourceLocation loc = info->record()->getInnerLocStart(); | 1891     SourceLocation loc = info->record()->getInnerLocStart(); | 
| 1830     SourceManager& manager = instance_.getSourceManager(); | 1892     SourceManager& manager = instance_.getSourceManager(); | 
| 1831     FullSourceLoc full_loc(loc, manager); | 1893     FullSourceLoc full_loc(loc, manager); | 
| 1832     diagnostic_.Report(full_loc, diag_class_requires_finalization_) | 1894     diagnostic_.Report(full_loc, diag_class_requires_finalization_) | 
| 1833         << info->record(); | 1895         << info->record(); | 
| 1834   } | 1896   } | 
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2023   unsigned diag_class_must_left_mostly_derive_gc_; | 2085   unsigned diag_class_must_left_mostly_derive_gc_; | 
| 2024   unsigned diag_class_requires_trace_method_; | 2086   unsigned diag_class_requires_trace_method_; | 
| 2025   unsigned diag_base_requires_tracing_; | 2087   unsigned diag_base_requires_tracing_; | 
| 2026   unsigned diag_fields_require_tracing_; | 2088   unsigned diag_fields_require_tracing_; | 
| 2027   unsigned diag_class_contains_invalid_fields_; | 2089   unsigned diag_class_contains_invalid_fields_; | 
| 2028   unsigned diag_class_contains_invalid_fields_warning_; | 2090   unsigned diag_class_contains_invalid_fields_warning_; | 
| 2029   unsigned diag_class_contains_gc_root_; | 2091   unsigned diag_class_contains_gc_root_; | 
| 2030   unsigned diag_class_requires_finalization_; | 2092   unsigned diag_class_requires_finalization_; | 
| 2031   unsigned diag_class_does_not_require_finalization_; | 2093   unsigned diag_class_does_not_require_finalization_; | 
| 2032   unsigned diag_finalizer_accesses_finalized_field_; | 2094   unsigned diag_finalizer_accesses_finalized_field_; | 
|  | 2095   unsigned diag_finalizer_eagerly_finalized_field_; | 
| 2033   unsigned diag_overridden_non_virtual_trace_; | 2096   unsigned diag_overridden_non_virtual_trace_; | 
| 2034   unsigned diag_missing_trace_dispatch_method_; | 2097   unsigned diag_missing_trace_dispatch_method_; | 
| 2035   unsigned diag_missing_finalize_dispatch_method_; | 2098   unsigned diag_missing_finalize_dispatch_method_; | 
| 2036   unsigned diag_virtual_and_manual_dispatch_; | 2099   unsigned diag_virtual_and_manual_dispatch_; | 
| 2037   unsigned diag_missing_trace_dispatch_; | 2100   unsigned diag_missing_trace_dispatch_; | 
| 2038   unsigned diag_missing_finalize_dispatch_; | 2101   unsigned diag_missing_finalize_dispatch_; | 
| 2039   unsigned diag_derives_non_stack_allocated_; | 2102   unsigned diag_derives_non_stack_allocated_; | 
| 2040   unsigned diag_class_overrides_new_; | 2103   unsigned diag_class_overrides_new_; | 
| 2041   unsigned diag_class_declares_pure_virtual_trace_; | 2104   unsigned diag_class_declares_pure_virtual_trace_; | 
| 2042   unsigned diag_left_most_base_must_be_polymorphic_; | 2105   unsigned diag_left_most_base_must_be_polymorphic_; | 
| 2043   unsigned diag_base_class_must_declare_virtual_trace_; | 2106   unsigned diag_base_class_must_declare_virtual_trace_; | 
| 2044   unsigned diag_class_must_declare_gc_mixin_trace_method_; | 2107   unsigned diag_class_must_declare_gc_mixin_trace_method_; | 
| 2045 | 2108 | 
| 2046   unsigned diag_base_requires_tracing_note_; | 2109   unsigned diag_base_requires_tracing_note_; | 
| 2047   unsigned diag_field_requires_tracing_note_; | 2110   unsigned diag_field_requires_tracing_note_; | 
|  | 2111   unsigned diag_field_illegally_traced_note_; | 
| 2048   unsigned diag_raw_ptr_to_gc_managed_class_note_; | 2112   unsigned diag_raw_ptr_to_gc_managed_class_note_; | 
| 2049   unsigned diag_ref_ptr_to_gc_managed_class_note_; | 2113   unsigned diag_ref_ptr_to_gc_managed_class_note_; | 
| 2050   unsigned diag_own_ptr_to_gc_managed_class_note_; | 2114   unsigned diag_own_ptr_to_gc_managed_class_note_; | 
| 2051   unsigned diag_stack_allocated_field_note_; | 2115   unsigned diag_stack_allocated_field_note_; | 
| 2052   unsigned diag_member_in_unmanaged_class_note_; | 2116   unsigned diag_member_in_unmanaged_class_note_; | 
| 2053   unsigned diag_part_object_to_gc_derived_class_note_; | 2117   unsigned diag_part_object_to_gc_derived_class_note_; | 
| 2054   unsigned diag_part_object_contains_gc_root_note_; | 2118   unsigned diag_part_object_contains_gc_root_note_; | 
| 2055   unsigned diag_field_contains_gc_root_note_; | 2119   unsigned diag_field_contains_gc_root_note_; | 
| 2056   unsigned diag_finalized_field_note_; | 2120   unsigned diag_finalized_field_note_; | 
|  | 2121   unsigned diag_eagerly_finalized_field_note_; | 
| 2057   unsigned diag_user_declared_destructor_note_; | 2122   unsigned diag_user_declared_destructor_note_; | 
| 2058   unsigned diag_user_declared_finalizer_note_; | 2123   unsigned diag_user_declared_finalizer_note_; | 
| 2059   unsigned diag_base_requires_finalization_note_; | 2124   unsigned diag_base_requires_finalization_note_; | 
| 2060   unsigned diag_field_requires_finalization_note_; | 2125   unsigned diag_field_requires_finalization_note_; | 
| 2061   unsigned diag_overridden_non_virtual_trace_note_; | 2126   unsigned diag_overridden_non_virtual_trace_note_; | 
| 2062   unsigned diag_manual_dispatch_method_note_; | 2127   unsigned diag_manual_dispatch_method_note_; | 
| 2063 | 2128 | 
| 2064   CompilerInstance& instance_; | 2129   CompilerInstance& instance_; | 
| 2065   DiagnosticsEngine& diagnostic_; | 2130   DiagnosticsEngine& diagnostic_; | 
| 2066   BlinkGCPluginOptions options_; | 2131   BlinkGCPluginOptions options_; | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2104 | 2169 | 
| 2105  private: | 2170  private: | 
| 2106   BlinkGCPluginOptions options_; | 2171   BlinkGCPluginOptions options_; | 
| 2107 }; | 2172 }; | 
| 2108 | 2173 | 
| 2109 }  // namespace | 2174 }  // namespace | 
| 2110 | 2175 | 
| 2111 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( | 2176 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( | 
| 2112     "blink-gc-plugin", | 2177     "blink-gc-plugin", | 
| 2113     "Check Blink GC invariants"); | 2178     "Check Blink GC invariants"); | 
| OLD | NEW | 
|---|