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