1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "DiagnosticsReporter.h" 6 7 using namespace clang; 8 9 namespace { 10 11 const char kClassMustLeftMostlyDeriveGC[] = 12 "[blink-gc] Class %0 must derive its GC base in the left-most position."; 13 14 const char kClassRequiresTraceMethod[] = 15 "[blink-gc] Class %0 requires a trace method."; 16 17 const char kBaseRequiresTracing[] = 18 "[blink-gc] Base class %0 of derived class %1 requires tracing."; 19 20 const char kBaseRequiresTracingNote[] = 21 "[blink-gc] Untraced base class %0 declared here:"; 22 23 const char kFieldsRequireTracing[] = 24 "[blink-gc] Class %0 has untraced fields that require tracing."; 25 26 const char kFieldsImproperlyTraced[] = 27 "[blink-gc] Class %0 has untraced or not traceable fields."; 28 29 const char kFieldRequiresTracingNote[] = 30 "[blink-gc] Untraced field %0 declared here:"; 31 32 const char kFieldShouldNotBeTracedNote[] = 33 "[blink-gc] Untraceable field %0 declared here:"; 34 35 const char kClassContainsInvalidFields[] = 36 "[blink-gc] Class %0 contains invalid fields."; 37 38 const char kClassContainsGCRoot[] = 39 "[blink-gc] Class %0 contains GC root in field %1."; 40 41 const char kClassRequiresFinalization[] = 42 "[blink-gc] Class %0 requires finalization."; 43 44 const char kClassDoesNotRequireFinalization[] = 45 "[blink-gc] Class %0 may not require finalization."; 46 47 const char kFinalizerAccessesFinalizedField[] = 48 "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; 49 50 const char kFinalizerAccessesEagerlyFinalizedField[] = 51 "[blink-gc] Finalizer %0 accesses eagerly finalized field %1."; 52 53 const char kRawPtrToGCManagedClassNote[] = 54 "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; 55 56 const char kRefPtrToGCManagedClassNote[] = 57 "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; 58 59 const char kReferencePtrToGCManagedClassNote[] = 60 "[blink-gc] Reference pointer field %0 to a GC managed class" 61 " declared here:"; 62 63 const char kOwnPtrToGCManagedClassNote[] = 64 "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; 65 66 const char kUniquePtrToGCManagedClassNote[] = 67 "[blink-gc] std::unique_ptr field %0 to a GC managed class declared here:"; 68 69 const char kMemberToGCUnmanagedClassNote[] = 70 "[blink-gc] Member field %0 to non-GC managed class declared here:"; 71 72 const char kStackAllocatedFieldNote[] = 73 "[blink-gc] Stack-allocated field %0 declared here:"; 74 75 const char kMemberInUnmanagedClassNote[] = 76 "[blink-gc] Member field %0 in unmanaged class declared here:"; 77 78 const char kPartObjectToGCDerivedClassNote[] = 79 "[blink-gc] Part-object field %0 to a GC derived class declared here:"; 80 81 const char kPartObjectContainsGCRootNote[] = 82 "[blink-gc] Field %0 with embedded GC root in %1 declared here:"; 83 84 const char kFieldContainsGCRootNote[] = 85 "[blink-gc] Field %0 defining a GC root declared here:"; 86 87 const char kOverriddenNonVirtualTrace[] = 88 "[blink-gc] Class %0 overrides non-virtual trace of base class %1."; 89 90 const char kOverriddenNonVirtualTraceNote[] = 91 "[blink-gc] Non-virtual trace method declared here:"; 92 93 const char kMissingTraceDispatchMethod[] = 94 "[blink-gc] Class %0 is missing manual trace dispatch."; 95 96 const char kMissingFinalizeDispatchMethod[] = 97 "[blink-gc] Class %0 is missing manual finalize dispatch."; 98 99 const char kVirtualAndManualDispatch[] = 100 "[blink-gc] Class %0 contains or inherits virtual methods" 101 " but implements manual dispatching."; 102 103 const char kMissingTraceDispatch[] = 104 "[blink-gc] Missing dispatch to class %0 in manual trace dispatch."; 105 106 const char kMissingFinalizeDispatch[] = 107 "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch."; 108 109 const char kFinalizedFieldNote[] = 110 "[blink-gc] Potentially finalized field %0 declared here:"; 111 112 const char kEagerlyFinalizedFieldNote[] = 113 "[blink-gc] Field %0 having eagerly finalized value, declared here:"; 114 115 const char kUserDeclaredDestructorNote[] = 116 "[blink-gc] User-declared destructor declared here:"; 117 118 const char kUserDeclaredFinalizerNote[] = 119 "[blink-gc] User-declared finalizer declared here:"; 120 121 const char kBaseRequiresFinalizationNote[] = 122 "[blink-gc] Base class %0 requiring finalization declared here:"; 123 124 const char kFieldRequiresFinalizationNote[] = 125 "[blink-gc] Field %0 requiring finalization declared here:"; 126 127 const char kManualDispatchMethodNote[] = 128 "[blink-gc] Manual dispatch %0 declared here:"; 129 130 const char kStackAllocatedDerivesGarbageCollected[] = 131 "[blink-gc] Stack-allocated class %0 derives class %1" 132 " which is garbage collected."; 133 134 const char kClassOverridesNew[] = 135 "[blink-gc] Garbage collected class %0" 136 " is not permitted to override its new operator."; 137 138 const char kClassDeclaresPureVirtualTrace[] = 139 "[blink-gc] Garbage collected class %0" 140 " is not permitted to declare a pure-virtual trace method."; 141 142 const char kLeftMostBaseMustBePolymorphic[] = 143 "[blink-gc] Left-most base class %0 of derived class %1" 144 " must be polymorphic."; 145 146 const char kBaseClassMustDeclareVirtualTrace[] = 147 "[blink-gc] Left-most base class %0 of derived class %1" 148 " must define a virtual trace method."; 149 150 } // namespace 151 152 DiagnosticBuilder DiagnosticsReporter::ReportDiagnostic( 153 SourceLocation location, 154 unsigned diag_id) { 155 SourceManager& manager = instance_.getSourceManager(); 156 FullSourceLoc full_loc(location, manager); 157 return diagnostic_.Report(full_loc, diag_id); 158 } 159 160 DiagnosticsReporter::DiagnosticsReporter( 161 clang::CompilerInstance& instance) 162 : instance_(instance), 163 diagnostic_(instance.getDiagnostics()) 164 { 165 // Register warning/error messages. 166 diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID( 167 getErrorLevel(), kClassMustLeftMostlyDeriveGC); 168 diag_class_requires_trace_method_ = 169 diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod); 170 diag_base_requires_tracing_ = 171 diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing); 172 diag_fields_require_tracing_ = 173 diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing); 174 diag_fields_improperly_traced_ = 175 diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsImproperlyTraced); 176 diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID( 177 getErrorLevel(), kClassContainsInvalidFields); 178 diag_class_contains_gc_root_ = 179 diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); 180 diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( 181 getErrorLevel(), kClassRequiresFinalization); 182 diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID( 183 DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization); 184 diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( 185 getErrorLevel(), kFinalizerAccessesFinalizedField); 186 diag_finalizer_eagerly_finalized_field_ = diagnostic_.getCustomDiagID( 187 getErrorLevel(), kFinalizerAccessesEagerlyFinalizedField); 188 diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( 189 getErrorLevel(), kOverriddenNonVirtualTrace); 190 diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( 191 getErrorLevel(), kMissingTraceDispatchMethod); 192 diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( 193 getErrorLevel(), kMissingFinalizeDispatchMethod); 194 diag_virtual_and_manual_dispatch_ = 195 diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); 196 diag_missing_trace_dispatch_ = 197 diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch); 198 diag_missing_finalize_dispatch_ = 199 diagnostic_.getCustomDiagID(getErrorLevel(), kMissingFinalizeDispatch); 200 diag_stack_allocated_derives_gc_ = diagnostic_.getCustomDiagID( 201 getErrorLevel(), kStackAllocatedDerivesGarbageCollected); 202 diag_class_overrides_new_ = 203 diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew); 204 diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID( 205 getErrorLevel(), kClassDeclaresPureVirtualTrace); 206 diag_left_most_base_must_be_polymorphic_ = diagnostic_.getCustomDiagID( 207 getErrorLevel(), kLeftMostBaseMustBePolymorphic); 208 diag_base_class_must_declare_virtual_trace_ = diagnostic_.getCustomDiagID( 209 getErrorLevel(), kBaseClassMustDeclareVirtualTrace); 210 211 // Register note messages. 212 diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID( 213 DiagnosticsEngine::Note, kBaseRequiresTracingNote); 214 diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( 215 DiagnosticsEngine::Note, kFieldRequiresTracingNote); 216 diag_field_should_not_be_traced_note_ = diagnostic_.getCustomDiagID( 217 DiagnosticsEngine::Note, kFieldShouldNotBeTracedNote); 218 diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( 219 DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); 220 diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( 221 DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); 222 diag_reference_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( 223 DiagnosticsEngine::Note, kReferencePtrToGCManagedClassNote); 224 diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( 225 DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); 226 diag_unique_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( 227 DiagnosticsEngine::Note, kUniquePtrToGCManagedClassNote); 228 diag_member_to_gc_unmanaged_class_note_ = diagnostic_.getCustomDiagID( 229 DiagnosticsEngine::Note, kMemberToGCUnmanagedClassNote); 230 diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID( 231 DiagnosticsEngine::Note, kStackAllocatedFieldNote); 232 diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( 233 DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); 234 diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( 235 DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); 236 diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( 237 DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); 238 diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( 239 DiagnosticsEngine::Note, kFieldContainsGCRootNote); 240 diag_finalized_field_note_ = diagnostic_.getCustomDiagID( 241 DiagnosticsEngine::Note, kFinalizedFieldNote); 242 diag_eagerly_finalized_field_note_ = diagnostic_.getCustomDiagID( 243 DiagnosticsEngine::Note, kEagerlyFinalizedFieldNote); 244 diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( 245 DiagnosticsEngine::Note, kUserDeclaredDestructorNote); 246 diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( 247 DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); 248 diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( 249 DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); 250 diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID( 251 DiagnosticsEngine::Note, kFieldRequiresFinalizationNote); 252 diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID( 253 DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote); 254 diag_manual_dispatch_method_note_ = diagnostic_.getCustomDiagID( 255 DiagnosticsEngine::Note, kManualDispatchMethodNote); 256 } 257 258 bool DiagnosticsReporter::hasErrorOccurred() const 259 { 260 return diagnostic_.hasErrorOccurred(); 261 } 262 263 DiagnosticsEngine::Level DiagnosticsReporter::getErrorLevel() const { 264 return diagnostic_.getWarningsAsErrors() ? DiagnosticsEngine::Error 265 : DiagnosticsEngine::Warning; 266 } 267 268 void DiagnosticsReporter::ClassMustLeftMostlyDeriveGC( 269 RecordInfo* info) { 270 ReportDiagnostic(info->record()->getInnerLocStart(), 271 diag_class_must_left_mostly_derive_gc_) 272 << info->record(); 273 } 274 275 void DiagnosticsReporter::ClassRequiresTraceMethod(RecordInfo* info) { 276 ReportDiagnostic(info->record()->getInnerLocStart(), 277 diag_class_requires_trace_method_) 278 << info->record(); 279 280 for (auto& base : info->GetBases()) 281 if (base.second.NeedsTracing().IsNeeded()) 282 NoteBaseRequiresTracing(&base.second); 283 284 for (auto& field : info->GetFields()) 285 if (!field.second.IsProperlyTraced()) 286 NoteFieldRequiresTracing(info, field.first); 287 } 288 289 void DiagnosticsReporter::BaseRequiresTracing( 290 RecordInfo* derived, 291 CXXMethodDecl* trace, 292 CXXRecordDecl* base) { 293 ReportDiagnostic(trace->getLocStart(), diag_base_requires_tracing_) 294 << base << derived->record(); 295 } 296 297 void DiagnosticsReporter::FieldsImproperlyTraced( 298 RecordInfo* info, 299 CXXMethodDecl* trace) { 300 // Only mention untraceable in header diagnostic if they appear. 301 unsigned diag = diag_fields_require_tracing_; 302 for (auto& field : info->GetFields()) { 303 if (field.second.IsInproperlyTraced()) { 304 diag = diag_fields_improperly_traced_; 305 break; 306 } 307 } 308 ReportDiagnostic(trace->getLocStart(), diag) 309 << info->record(); 310 for (auto& field : info->GetFields()) { 311 if (!field.second.IsProperlyTraced()) 312 NoteFieldRequiresTracing(info, field.first); 313 if (field.second.IsInproperlyTraced()) 314 NoteFieldShouldNotBeTraced(info, field.first); 315 } 316 } 317 318 void DiagnosticsReporter::ClassContainsInvalidFields( 319 RecordInfo* info, 320 const CheckFieldsVisitor::Errors& errors) { 321 322 ReportDiagnostic(info->record()->getLocStart(), 323 diag_class_contains_invalid_fields_) 324 << info->record(); 325 326 for (auto& error : errors) { 327 unsigned note; 328 if (error.second == CheckFieldsVisitor::kRawPtrToGCManaged) { 329 note = diag_raw_ptr_to_gc_managed_class_note_; 330 } else if (error.second == CheckFieldsVisitor::kRefPtrToGCManaged) { 331 note = diag_ref_ptr_to_gc_managed_class_note_; 332 } else if (error.second == CheckFieldsVisitor::kReferencePtrToGCManaged) { 333 note = diag_reference_ptr_to_gc_managed_class_note_; 334 } else if (error.second == CheckFieldsVisitor::kOwnPtrToGCManaged) { 335 note = diag_own_ptr_to_gc_managed_class_note_; 336 } else if (error.second == CheckFieldsVisitor::kUniquePtrToGCManaged) { 337 note = diag_unique_ptr_to_gc_managed_class_note_; 338 } else if (error.second == CheckFieldsVisitor::kMemberToGCUnmanaged) { 339 note = diag_member_to_gc_unmanaged_class_note_; 340 } else if (error.second == CheckFieldsVisitor::kMemberInUnmanaged) { 341 note = diag_member_in_unmanaged_class_note_; 342 } else if (error.second == CheckFieldsVisitor::kPtrFromHeapToStack) { 343 note = diag_stack_allocated_field_note_; 344 } else if (error.second == CheckFieldsVisitor::kGCDerivedPartObject) { 345 note = diag_part_object_to_gc_derived_class_note_; 346 } else { 347 assert(false && "Unknown field error"); 348 } 349 NoteField(error.first, note); 350 } 351 } 352 353 void DiagnosticsReporter::ClassContainsGCRoots( 354 RecordInfo* info, 355 const CheckGCRootsVisitor::Errors& errors) { 356 for (auto& error : errors) { 357 FieldPoint* point = nullptr; 358 for (FieldPoint* path : error) { 359 if (!point) { 360 point = path; 361 ReportDiagnostic(info->record()->getLocStart(), 362 diag_class_contains_gc_root_) 363 << info->record() << point->field(); 364 continue; 365 } 366 NotePartObjectContainsGCRoot(point); 367 point = path; 368 } 369 NoteFieldContainsGCRoot(point); 370 } 371 } 372 373 void DiagnosticsReporter::FinalizerAccessesFinalizedFields( 374 CXXMethodDecl* dtor, 375 const CheckFinalizerVisitor::Errors& errors) { 376 for (auto& error : errors) { 377 bool as_eagerly_finalized = error.as_eagerly_finalized; 378 unsigned diag_error = as_eagerly_finalized ? 379 diag_finalizer_eagerly_finalized_field_ : 380 diag_finalizer_accesses_finalized_field_; 381 unsigned diag_note = as_eagerly_finalized ? 382 diag_eagerly_finalized_field_note_ : 383 diag_finalized_field_note_; 384 ReportDiagnostic(error.member->getLocStart(), diag_error) 385 << dtor << error.field->field(); 386 NoteField(error.field, diag_note); 387 } 388 } 389 390 void DiagnosticsReporter::ClassRequiresFinalization(RecordInfo* info) { 391 ReportDiagnostic(info->record()->getInnerLocStart(), 392 diag_class_requires_finalization_) 393 << info->record(); 394 } 395 396 void DiagnosticsReporter::ClassDoesNotRequireFinalization( 397 RecordInfo* info) { 398 ReportDiagnostic(info->record()->getInnerLocStart(), 399 diag_class_does_not_require_finalization_) 400 << info->record(); 401 } 402 403 void DiagnosticsReporter::OverriddenNonVirtualTrace( 404 RecordInfo* info, 405 CXXMethodDecl* trace, 406 CXXMethodDecl* overridden) { 407 ReportDiagnostic(trace->getLocStart(), diag_overridden_non_virtual_trace_) 408 << info->record() << overridden->getParent(); 409 NoteOverriddenNonVirtualTrace(overridden); 410 } 411 412 void DiagnosticsReporter::MissingTraceDispatchMethod(RecordInfo* info) { 413 ReportMissingDispatchMethod(info, diag_missing_trace_dispatch_method_); 414 } 415 416 void DiagnosticsReporter::MissingFinalizeDispatchMethod( 417 RecordInfo* info) { 418 ReportMissingDispatchMethod(info, diag_missing_finalize_dispatch_method_); 419 } 420 421 void DiagnosticsReporter::ReportMissingDispatchMethod( 422 RecordInfo* info, 423 unsigned error) { 424 ReportDiagnostic(info->record()->getInnerLocStart(), error) 425 << info->record(); 426 } 427 428 void DiagnosticsReporter::VirtualAndManualDispatch( 429 RecordInfo* info, 430 CXXMethodDecl* dispatch) { 431 ReportDiagnostic(info->record()->getInnerLocStart(), 432 diag_virtual_and_manual_dispatch_) 433 << info->record(); 434 NoteManualDispatchMethod(dispatch); 435 } 436 437 void DiagnosticsReporter::MissingTraceDispatch( 438 const FunctionDecl* dispatch, 439 RecordInfo* receiver) { 440 ReportMissingDispatch(dispatch, receiver, diag_missing_trace_dispatch_); 441 } 442 443 void DiagnosticsReporter::MissingFinalizeDispatch( 444 const FunctionDecl* dispatch, 445 RecordInfo* receiver) { 446 ReportMissingDispatch(dispatch, receiver, diag_missing_finalize_dispatch_); 447 } 448 449 void DiagnosticsReporter::ReportMissingDispatch( 450 const FunctionDecl* dispatch, 451 RecordInfo* receiver, 452 unsigned error) { 453 ReportDiagnostic(dispatch->getLocStart(), error) << receiver->record(); 454 } 455 456 void DiagnosticsReporter::StackAllocatedDerivesGarbageCollected( 457 RecordInfo* info, 458 BasePoint* base) { 459 ReportDiagnostic(base->spec().getLocStart(), 460 diag_stack_allocated_derives_gc_) 461 << info->record() << base->info()->record(); 462 } 463 464 void DiagnosticsReporter::ClassOverridesNew( 465 RecordInfo* info, 466 CXXMethodDecl* newop) { 467 ReportDiagnostic(newop->getLocStart(), diag_class_overrides_new_) 468 << info->record(); 469 } 470 471 void DiagnosticsReporter::ClassDeclaresPureVirtualTrace( 472 RecordInfo* info, 473 CXXMethodDecl* trace) { 474 ReportDiagnostic(trace->getLocStart(), 475 diag_class_declares_pure_virtual_trace_) 476 << info->record(); 477 } 478 479 void DiagnosticsReporter::LeftMostBaseMustBePolymorphic( 480 RecordInfo* derived, 481 CXXRecordDecl* base) { 482 ReportDiagnostic(base->getLocStart(), 483 diag_left_most_base_must_be_polymorphic_) 484 << base << derived->record(); 485 } 486 487 void DiagnosticsReporter::BaseClassMustDeclareVirtualTrace( 488 RecordInfo* derived, 489 CXXRecordDecl* base) { 490 ReportDiagnostic(base->getLocStart(), 491 diag_base_class_must_declare_virtual_trace_) 492 << base << derived->record(); 493 } 494 495 void DiagnosticsReporter::NoteManualDispatchMethod(CXXMethodDecl* dispatch) { 496 ReportDiagnostic(dispatch->getLocStart(), 497 diag_manual_dispatch_method_note_) 498 << dispatch; 499 } 500 501 void DiagnosticsReporter::NoteBaseRequiresTracing(BasePoint* base) { 502 ReportDiagnostic(base->spec().getLocStart(), 503 diag_base_requires_tracing_note_) 504 << base->info()->record(); 505 } 506 507 void DiagnosticsReporter::NoteFieldRequiresTracing( 508 RecordInfo* holder, 509 FieldDecl* field) { 510 NoteField(field, diag_field_requires_tracing_note_); 511 } 512 513 void DiagnosticsReporter::NoteFieldShouldNotBeTraced( 514 RecordInfo* holder, 515 FieldDecl* field) { 516 NoteField(field, diag_field_should_not_be_traced_note_); 517 } 518 519 void DiagnosticsReporter::NotePartObjectContainsGCRoot(FieldPoint* point) { 520 FieldDecl* field = point->field(); 521 ReportDiagnostic(field->getLocStart(), 522 diag_part_object_contains_gc_root_note_) 523 << field << field->getParent(); 524 } 525 526 void DiagnosticsReporter::NoteFieldContainsGCRoot(FieldPoint* point) { 527 NoteField(point, diag_field_contains_gc_root_note_); 528 } 529 530 void DiagnosticsReporter::NoteUserDeclaredDestructor(CXXMethodDecl* dtor) { 531 ReportDiagnostic(dtor->getLocStart(), diag_user_declared_destructor_note_); 532 } 533 534 void DiagnosticsReporter::NoteUserDeclaredFinalizer(CXXMethodDecl* dtor) { 535 ReportDiagnostic(dtor->getLocStart(), diag_user_declared_finalizer_note_); 536 } 537 538 void DiagnosticsReporter::NoteBaseRequiresFinalization(BasePoint* base) { 539 ReportDiagnostic(base->spec().getLocStart(), 540 diag_base_requires_finalization_note_) 541 << base->info()->record(); 542 } 543 544 void DiagnosticsReporter::NoteFieldRequiresFinalization(FieldPoint* point) { 545 NoteField(point, diag_field_requires_finalization_note_); 546 } 547 548 void DiagnosticsReporter::NoteField(FieldPoint* point, unsigned note) { 549 NoteField(point->field(), note); 550 } 551 552 void DiagnosticsReporter::NoteField(FieldDecl* field, unsigned note) { 553 ReportDiagnostic(field->getLocStart(), note) << field; 554 } 555 556 void DiagnosticsReporter::NoteOverriddenNonVirtualTrace( 557 CXXMethodDecl* overridden) { 558 ReportDiagnostic(overridden->getLocStart(), 559 diag_overridden_non_virtual_trace_note_) 560 << overridden; 561 } 562