DiagnosticsReporter.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  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. #include "DiagnosticsReporter.h"
  5. #include "llvm/Support/ErrorHandling.h"
  6. using namespace clang;
  7. namespace {
  8. const char kClassMustLeftMostlyDeriveGC[] =
  9. "[blink-gc] Class %0 must derive from GarbageCollected in the left-most position.";
  10. const char kClassRequiresTraceMethod[] =
  11. "[blink-gc] Class %0 requires a trace method.";
  12. const char kBaseRequiresTracing[] =
  13. "[blink-gc] Base class %0 of derived class %1 requires tracing.";
  14. const char kBaseRequiresTracingNote[] =
  15. "[blink-gc] Untraced base class %0 declared here:";
  16. const char kFieldsRequireTracing[] =
  17. "[blink-gc] Class %0 has untraced fields that require tracing.";
  18. const char kFieldsImproperlyTraced[] =
  19. "[blink-gc] Class %0 has untraced or not traceable fields.";
  20. const char kFieldRequiresTracingNote[] =
  21. "[blink-gc] Untraced field %0 declared here:";
  22. const char kFieldShouldNotBeTracedNote[] =
  23. "[blink-gc] Untraceable field %0 declared here:";
  24. const char kClassContainsInvalidFields[] =
  25. "[blink-gc] Class %0 contains invalid fields.";
  26. const char kClassContainsGCRoot[] =
  27. "[blink-gc] Class %0 contains GC root in field %1.";
  28. const char kFinalizerAccessesFinalizedField[] =
  29. "[blink-gc] Finalizer %0 accesses potentially finalized field %1.";
  30. const char kRawPtrToGCManagedClassNote[] =
  31. "[blink-gc] Raw pointer field %0 to a GC managed class declared here:";
  32. const char kRefPtrToGCManagedClassNote[] =
  33. "[blink-gc] scoped_refptr field %0 to a GC managed class declared here:";
  34. const char kWeakPtrToGCManagedClassNote[] =
  35. "[blink-gc] WeakPtr field %0 to a GC managed class declared here:";
  36. const char kReferencePtrToGCManagedClassNote[] =
  37. "[blink-gc] Reference pointer field %0 to a GC managed class"
  38. " declared here:";
  39. const char kUniquePtrToGCManagedClassNote[] =
  40. "[blink-gc] std::unique_ptr field %0 to a GC managed class declared here:";
  41. const char kMemberToGCUnmanagedClassNote[] =
  42. "[blink-gc] Member field %0 to non-GC managed class declared here:";
  43. const char kStackAllocatedFieldNote[] =
  44. "[blink-gc] Stack-allocated field %0 declared here:";
  45. const char kMemberInUnmanagedClassNote[] =
  46. "[blink-gc] Member field %0 in unmanaged class declared here:";
  47. const char kPartObjectToGCDerivedClassNote[] =
  48. "[blink-gc] Part-object field %0 to a GC derived class declared here:";
  49. const char kPartObjectContainsGCRootNote[] =
  50. "[blink-gc] Field %0 with embedded GC root in %1 declared here:";
  51. const char kFieldContainsGCRootNote[] =
  52. "[blink-gc] Field %0 defining a GC root declared here:";
  53. const char kOverriddenNonVirtualTrace[] =
  54. "[blink-gc] Class %0 overrides non-virtual trace of base class %1.";
  55. const char kOverriddenNonVirtualTraceNote[] =
  56. "[blink-gc] Non-virtual trace method declared here:";
  57. const char kMissingTraceDispatchMethod[] =
  58. "[blink-gc] Class %0 is missing manual trace dispatch.";
  59. const char kVirtualAndManualDispatch[] =
  60. "[blink-gc] Class %0 contains or inherits virtual methods"
  61. " but implements manual dispatching.";
  62. const char kMissingTraceDispatch[] =
  63. "[blink-gc] Missing dispatch to class %0 in manual trace dispatch.";
  64. const char kMissingFinalizeDispatch[] =
  65. "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch.";
  66. const char kFinalizedFieldNote[] =
  67. "[blink-gc] Potentially finalized field %0 declared here:";
  68. const char kManualDispatchMethodNote[] =
  69. "[blink-gc] Manual dispatch %0 declared here:";
  70. const char kStackAllocatedDerivesGarbageCollected[] =
  71. "[blink-gc] Stack-allocated class %0 derives class %1"
  72. " which is garbage collected.";
  73. const char kClassOverridesNew[] =
  74. "[blink-gc] Garbage collected class %0"
  75. " is not permitted to override its new operator.";
  76. const char kClassDeclaresPureVirtualTrace[] =
  77. "[blink-gc] Garbage collected class %0"
  78. " is not permitted to declare a pure-virtual trace method.";
  79. const char kLeftMostBaseMustBePolymorphic[] =
  80. "[blink-gc] Left-most base class %0 of derived class %1"
  81. " must be polymorphic.";
  82. const char kBaseClassMustDeclareVirtualTrace[] =
  83. "[blink-gc] Left-most base class %0 of derived class %1"
  84. " must define a virtual trace method.";
  85. const char kClassMustCRTPItself[] =
  86. "[blink-gc] GC base class %0 must be specialized with the derived class "
  87. "%1.";
  88. const char kIteratorToGCManagedCollectionNote[] =
  89. "[blink-gc] Iterator field %0 to a GC managed collection declared here:";
  90. const char kTraceMethodOfStackAllocatedParentNote[] =
  91. "[blink-gc] The stack allocated class %0 provides an unnecessary "
  92. "trace method:";
  93. const char kMemberInStackAllocated[] =
  94. "[blink-gc] Member field %0 in stack allocated class declared here (use "
  95. "raw pointer or reference instead):";
  96. const char kMemberOnStack[] =
  97. "[blink-gc] Member variable %0 declared on stack here (use raw pointer or "
  98. "reference instead):";
  99. const char kUniquePtrUsedWithGC[] =
  100. "[blink-gc] Disallowed use of %0 found; %1 is a garbage-collected type. "
  101. "std::unique_ptr cannot hold garbage-collected objects.";
  102. const char kOptionalFieldUsedWithGC[] =
  103. "[blink-gc] Disallowed optional field of %0 found; %1 is a "
  104. "garbage-collected "
  105. "type. Optional fields cannot hold garbage-collected objects.";
  106. const char kOptionalNewExprUsedWithGC[] =
  107. "[blink-gc] Disallowed new-expression of %0 found; %1 is a "
  108. "garbage-collected "
  109. "type. GCed types cannot be created with new.";
  110. const char kVariantUsedWithGC[] =
  111. "[blink-gc] Disallowed construction of %0 found; %1 is a garbage-collected "
  112. "type. absl::variant cannot hold garbage-collected objects.";
  113. } // namespace
  114. DiagnosticBuilder DiagnosticsReporter::ReportDiagnostic(
  115. SourceLocation location,
  116. unsigned diag_id) {
  117. SourceManager& manager = instance_.getSourceManager();
  118. FullSourceLoc full_loc(location, manager);
  119. return diagnostic_.Report(full_loc, diag_id);
  120. }
  121. DiagnosticsReporter::DiagnosticsReporter(
  122. clang::CompilerInstance& instance)
  123. : instance_(instance),
  124. diagnostic_(instance.getDiagnostics())
  125. {
  126. // Register warning/error messages.
  127. diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID(
  128. getErrorLevel(), kClassMustLeftMostlyDeriveGC);
  129. diag_class_requires_trace_method_ =
  130. diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod);
  131. diag_base_requires_tracing_ =
  132. diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing);
  133. diag_fields_require_tracing_ =
  134. diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing);
  135. diag_fields_improperly_traced_ =
  136. diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsImproperlyTraced);
  137. diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID(
  138. getErrorLevel(), kClassContainsInvalidFields);
  139. diag_class_contains_gc_root_ =
  140. diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot);
  141. diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID(
  142. getErrorLevel(), kFinalizerAccessesFinalizedField);
  143. diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID(
  144. getErrorLevel(), kOverriddenNonVirtualTrace);
  145. diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID(
  146. getErrorLevel(), kMissingTraceDispatchMethod);
  147. diag_virtual_and_manual_dispatch_ =
  148. diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch);
  149. diag_missing_trace_dispatch_ =
  150. diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch);
  151. diag_missing_finalize_dispatch_ =
  152. diagnostic_.getCustomDiagID(getErrorLevel(), kMissingFinalizeDispatch);
  153. diag_stack_allocated_derives_gc_ = diagnostic_.getCustomDiagID(
  154. getErrorLevel(), kStackAllocatedDerivesGarbageCollected);
  155. diag_class_overrides_new_ =
  156. diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew);
  157. diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID(
  158. getErrorLevel(), kClassDeclaresPureVirtualTrace);
  159. diag_left_most_base_must_be_polymorphic_ = diagnostic_.getCustomDiagID(
  160. getErrorLevel(), kLeftMostBaseMustBePolymorphic);
  161. diag_base_class_must_declare_virtual_trace_ = diagnostic_.getCustomDiagID(
  162. getErrorLevel(), kBaseClassMustDeclareVirtualTrace);
  163. diag_class_must_crtp_itself_ =
  164. diagnostic_.getCustomDiagID(getErrorLevel(), kClassMustCRTPItself);
  165. diag_iterator_to_gc_managed_collection_note_ = diagnostic_.getCustomDiagID(
  166. getErrorLevel(), kIteratorToGCManagedCollectionNote);
  167. diag_trace_method_of_stack_allocated_parent_ = diagnostic_.getCustomDiagID(
  168. getErrorLevel(), kTraceMethodOfStackAllocatedParentNote);
  169. diag_member_in_stack_allocated_class_ =
  170. diagnostic_.getCustomDiagID(getErrorLevel(), kMemberInStackAllocated);
  171. diag_member_on_stack_ =
  172. diagnostic_.getCustomDiagID(getErrorLevel(), kMemberOnStack);
  173. // Register note messages.
  174. diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID(
  175. DiagnosticsEngine::Note, kBaseRequiresTracingNote);
  176. diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID(
  177. DiagnosticsEngine::Note, kFieldRequiresTracingNote);
  178. diag_field_should_not_be_traced_note_ = diagnostic_.getCustomDiagID(
  179. DiagnosticsEngine::Note, kFieldShouldNotBeTracedNote);
  180. diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
  181. DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote);
  182. diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
  183. DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote);
  184. diag_weak_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
  185. DiagnosticsEngine::Note, kWeakPtrToGCManagedClassNote);
  186. diag_reference_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
  187. DiagnosticsEngine::Note, kReferencePtrToGCManagedClassNote);
  188. diag_unique_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
  189. DiagnosticsEngine::Note, kUniquePtrToGCManagedClassNote);
  190. diag_member_to_gc_unmanaged_class_note_ = diagnostic_.getCustomDiagID(
  191. DiagnosticsEngine::Note, kMemberToGCUnmanagedClassNote);
  192. diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID(
  193. DiagnosticsEngine::Note, kStackAllocatedFieldNote);
  194. diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID(
  195. DiagnosticsEngine::Note, kMemberInUnmanagedClassNote);
  196. diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID(
  197. DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote);
  198. diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID(
  199. DiagnosticsEngine::Note, kPartObjectContainsGCRootNote);
  200. diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID(
  201. DiagnosticsEngine::Note, kFieldContainsGCRootNote);
  202. diag_finalized_field_note_ = diagnostic_.getCustomDiagID(
  203. DiagnosticsEngine::Note, kFinalizedFieldNote);
  204. diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID(
  205. DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote);
  206. diag_manual_dispatch_method_note_ = diagnostic_.getCustomDiagID(
  207. DiagnosticsEngine::Note, kManualDispatchMethodNote);
  208. diag_unique_ptr_used_with_gc_ =
  209. diagnostic_.getCustomDiagID(getErrorLevel(), kUniquePtrUsedWithGC);
  210. diag_optional_field_used_with_gc_ =
  211. diagnostic_.getCustomDiagID(getErrorLevel(), kOptionalFieldUsedWithGC);
  212. diag_optional_new_expr_used_with_gc_ =
  213. diagnostic_.getCustomDiagID(getErrorLevel(), kOptionalNewExprUsedWithGC);
  214. diag_variant_used_with_gc_ =
  215. diagnostic_.getCustomDiagID(getErrorLevel(), kVariantUsedWithGC);
  216. }
  217. bool DiagnosticsReporter::hasErrorOccurred() const
  218. {
  219. return diagnostic_.hasErrorOccurred();
  220. }
  221. DiagnosticsEngine::Level DiagnosticsReporter::getErrorLevel() const {
  222. return diagnostic_.getWarningsAsErrors() ? DiagnosticsEngine::Error
  223. : DiagnosticsEngine::Warning;
  224. }
  225. void DiagnosticsReporter::ClassMustLeftMostlyDeriveGC(
  226. RecordInfo* info) {
  227. ReportDiagnostic(info->record()->getInnerLocStart(),
  228. diag_class_must_left_mostly_derive_gc_)
  229. << info->record();
  230. }
  231. void DiagnosticsReporter::ClassRequiresTraceMethod(RecordInfo* info) {
  232. ReportDiagnostic(info->record()->getInnerLocStart(),
  233. diag_class_requires_trace_method_)
  234. << info->record();
  235. for (auto& base : info->GetBases())
  236. if (base.second.NeedsTracing().IsNeeded())
  237. NoteBaseRequiresTracing(&base.second);
  238. for (auto& field : info->GetFields())
  239. if (!field.second.IsProperlyTraced())
  240. NoteFieldRequiresTracing(info, field.first);
  241. }
  242. void DiagnosticsReporter::BaseRequiresTracing(
  243. RecordInfo* derived,
  244. CXXMethodDecl* trace,
  245. CXXRecordDecl* base) {
  246. ReportDiagnostic(trace->getBeginLoc(), diag_base_requires_tracing_)
  247. << base << derived->record();
  248. }
  249. void DiagnosticsReporter::FieldsImproperlyTraced(
  250. RecordInfo* info,
  251. CXXMethodDecl* trace) {
  252. // Only mention untraceable in header diagnostic if they appear.
  253. unsigned diag = diag_fields_require_tracing_;
  254. for (auto& field : info->GetFields()) {
  255. if (field.second.IsInproperlyTraced()) {
  256. diag = diag_fields_improperly_traced_;
  257. break;
  258. }
  259. }
  260. ReportDiagnostic(trace->getBeginLoc(), diag) << info->record();
  261. for (auto& field : info->GetFields()) {
  262. if (!field.second.IsProperlyTraced())
  263. NoteFieldRequiresTracing(info, field.first);
  264. if (field.second.IsInproperlyTraced())
  265. NoteFieldShouldNotBeTraced(info, field.first);
  266. }
  267. }
  268. void DiagnosticsReporter::ClassContainsInvalidFields(
  269. RecordInfo* info,
  270. const CheckFieldsVisitor::Errors& errors) {
  271. ReportDiagnostic(info->record()->getBeginLoc(),
  272. diag_class_contains_invalid_fields_)
  273. << info->record();
  274. for (auto& error : errors) {
  275. unsigned note;
  276. if (error.second == CheckFieldsVisitor::kRawPtrToGCManaged) {
  277. note = diag_raw_ptr_to_gc_managed_class_note_;
  278. } else if (error.second == CheckFieldsVisitor::kRefPtrToGCManaged) {
  279. note = diag_ref_ptr_to_gc_managed_class_note_;
  280. } else if (error.second == CheckFieldsVisitor::kWeakPtrToGCManaged) {
  281. note = diag_weak_ptr_to_gc_managed_class_note_;
  282. } else if (error.second == CheckFieldsVisitor::kReferencePtrToGCManaged) {
  283. note = diag_reference_ptr_to_gc_managed_class_note_;
  284. } else if (error.second == CheckFieldsVisitor::kUniquePtrToGCManaged) {
  285. note = diag_unique_ptr_to_gc_managed_class_note_;
  286. } else if (error.second == CheckFieldsVisitor::kMemberToGCUnmanaged) {
  287. note = diag_member_to_gc_unmanaged_class_note_;
  288. } else if (error.second == CheckFieldsVisitor::kMemberInUnmanaged) {
  289. note = diag_member_in_unmanaged_class_note_;
  290. } else if (error.second == CheckFieldsVisitor::kPtrFromHeapToStack) {
  291. note = diag_stack_allocated_field_note_;
  292. } else if (error.second == CheckFieldsVisitor::kGCDerivedPartObject) {
  293. note = diag_part_object_to_gc_derived_class_note_;
  294. } else if (error.second == CheckFieldsVisitor::kIteratorToGCManaged) {
  295. note = diag_iterator_to_gc_managed_collection_note_;
  296. } else if (error.second == CheckFieldsVisitor::kMemberInStackAllocated) {
  297. note = diag_member_in_stack_allocated_class_;
  298. } else {
  299. llvm_unreachable("Unknown field error.");
  300. }
  301. NoteField(error.first, note);
  302. }
  303. }
  304. void DiagnosticsReporter::ClassContainsGCRoots(
  305. RecordInfo* info,
  306. const CheckGCRootsVisitor::Errors& errors) {
  307. for (auto& error : errors) {
  308. FieldPoint* point = nullptr;
  309. for (FieldPoint* path : error) {
  310. if (!point) {
  311. point = path;
  312. ReportDiagnostic(info->record()->getBeginLoc(),
  313. diag_class_contains_gc_root_)
  314. << info->record() << point->field();
  315. continue;
  316. }
  317. NotePartObjectContainsGCRoot(point);
  318. point = path;
  319. }
  320. NoteFieldContainsGCRoot(point);
  321. }
  322. }
  323. void DiagnosticsReporter::FinalizerAccessesFinalizedFields(
  324. CXXMethodDecl* dtor,
  325. const CheckFinalizerVisitor::Errors& errors) {
  326. for (auto& error : errors) {
  327. ReportDiagnostic(error.member->getBeginLoc(),
  328. diag_finalizer_accesses_finalized_field_)
  329. << dtor << error.field->field();
  330. NoteField(error.field, diag_finalized_field_note_);
  331. }
  332. }
  333. void DiagnosticsReporter::OverriddenNonVirtualTrace(
  334. RecordInfo* info,
  335. CXXMethodDecl* trace,
  336. CXXMethodDecl* overridden) {
  337. ReportDiagnostic(trace->getBeginLoc(), diag_overridden_non_virtual_trace_)
  338. << info->record() << overridden->getParent();
  339. NoteOverriddenNonVirtualTrace(overridden);
  340. }
  341. void DiagnosticsReporter::MissingTraceDispatchMethod(RecordInfo* info) {
  342. ReportMissingDispatchMethod(info, diag_missing_trace_dispatch_method_);
  343. }
  344. void DiagnosticsReporter::ReportMissingDispatchMethod(
  345. RecordInfo* info,
  346. unsigned error) {
  347. ReportDiagnostic(info->record()->getInnerLocStart(), error)
  348. << info->record();
  349. }
  350. void DiagnosticsReporter::VirtualAndManualDispatch(
  351. RecordInfo* info,
  352. CXXMethodDecl* dispatch) {
  353. ReportDiagnostic(info->record()->getInnerLocStart(),
  354. diag_virtual_and_manual_dispatch_)
  355. << info->record();
  356. NoteManualDispatchMethod(dispatch);
  357. }
  358. void DiagnosticsReporter::MissingTraceDispatch(
  359. const FunctionDecl* dispatch,
  360. RecordInfo* receiver) {
  361. ReportMissingDispatch(dispatch, receiver, diag_missing_trace_dispatch_);
  362. }
  363. void DiagnosticsReporter::MissingFinalizeDispatch(
  364. const FunctionDecl* dispatch,
  365. RecordInfo* receiver) {
  366. ReportMissingDispatch(dispatch, receiver, diag_missing_finalize_dispatch_);
  367. }
  368. void DiagnosticsReporter::ReportMissingDispatch(
  369. const FunctionDecl* dispatch,
  370. RecordInfo* receiver,
  371. unsigned error) {
  372. ReportDiagnostic(dispatch->getBeginLoc(), error) << receiver->record();
  373. }
  374. void DiagnosticsReporter::StackAllocatedDerivesGarbageCollected(
  375. RecordInfo* info,
  376. BasePoint* base) {
  377. ReportDiagnostic(base->spec().getBeginLoc(), diag_stack_allocated_derives_gc_)
  378. << info->record() << base->info()->record();
  379. }
  380. void DiagnosticsReporter::ClassOverridesNew(
  381. RecordInfo* info,
  382. CXXMethodDecl* newop) {
  383. ReportDiagnostic(newop->getBeginLoc(), diag_class_overrides_new_)
  384. << info->record();
  385. }
  386. void DiagnosticsReporter::ClassDeclaresPureVirtualTrace(
  387. RecordInfo* info,
  388. CXXMethodDecl* trace) {
  389. ReportDiagnostic(trace->getBeginLoc(),
  390. diag_class_declares_pure_virtual_trace_)
  391. << info->record();
  392. }
  393. void DiagnosticsReporter::LeftMostBaseMustBePolymorphic(
  394. RecordInfo* derived,
  395. CXXRecordDecl* base) {
  396. ReportDiagnostic(base->getBeginLoc(),
  397. diag_left_most_base_must_be_polymorphic_)
  398. << base << derived->record();
  399. }
  400. void DiagnosticsReporter::BaseClassMustDeclareVirtualTrace(
  401. RecordInfo* derived,
  402. CXXRecordDecl* base) {
  403. ReportDiagnostic(base->getBeginLoc(),
  404. diag_base_class_must_declare_virtual_trace_)
  405. << base << derived->record();
  406. }
  407. void DiagnosticsReporter::ClassMustCRTPItself(
  408. const RecordInfo* derived,
  409. const CXXRecordDecl* base,
  410. const CXXBaseSpecifier* base_spec) {
  411. ReportDiagnostic(base_spec->getBeginLoc(), diag_class_must_crtp_itself_)
  412. << base << derived->record();
  413. }
  414. void DiagnosticsReporter::TraceMethodForStackAllocatedClass(
  415. RecordInfo* info,
  416. CXXMethodDecl* trace) {
  417. ReportDiagnostic(trace->getBeginLoc(),
  418. diag_trace_method_of_stack_allocated_parent_)
  419. << info->record();
  420. }
  421. void DiagnosticsReporter::NoteManualDispatchMethod(CXXMethodDecl* dispatch) {
  422. ReportDiagnostic(dispatch->getBeginLoc(), diag_manual_dispatch_method_note_)
  423. << dispatch;
  424. }
  425. void DiagnosticsReporter::NoteBaseRequiresTracing(BasePoint* base) {
  426. ReportDiagnostic(base->spec().getBeginLoc(), diag_base_requires_tracing_note_)
  427. << base->info()->record();
  428. }
  429. void DiagnosticsReporter::NoteFieldRequiresTracing(
  430. RecordInfo* holder,
  431. FieldDecl* field) {
  432. NoteField(field, diag_field_requires_tracing_note_);
  433. }
  434. void DiagnosticsReporter::NoteFieldShouldNotBeTraced(
  435. RecordInfo* holder,
  436. FieldDecl* field) {
  437. NoteField(field, diag_field_should_not_be_traced_note_);
  438. }
  439. void DiagnosticsReporter::NotePartObjectContainsGCRoot(FieldPoint* point) {
  440. FieldDecl* field = point->field();
  441. ReportDiagnostic(field->getBeginLoc(),
  442. diag_part_object_contains_gc_root_note_)
  443. << field << field->getParent();
  444. }
  445. void DiagnosticsReporter::NoteFieldContainsGCRoot(FieldPoint* point) {
  446. NoteField(point, diag_field_contains_gc_root_note_);
  447. }
  448. void DiagnosticsReporter::NoteField(FieldPoint* point, unsigned note) {
  449. NoteField(point->field(), note);
  450. }
  451. void DiagnosticsReporter::NoteField(FieldDecl* field, unsigned note) {
  452. ReportDiagnostic(field->getBeginLoc(), note) << field;
  453. }
  454. void DiagnosticsReporter::NoteOverriddenNonVirtualTrace(
  455. CXXMethodDecl* overridden) {
  456. ReportDiagnostic(overridden->getBeginLoc(),
  457. diag_overridden_non_virtual_trace_note_)
  458. << overridden;
  459. }
  460. void DiagnosticsReporter::UniquePtrUsedWithGC(
  461. const clang::Expr* expr,
  462. const clang::FunctionDecl* bad_function,
  463. const clang::CXXRecordDecl* gc_type) {
  464. ReportDiagnostic(expr->getBeginLoc(), diag_unique_ptr_used_with_gc_)
  465. << bad_function << gc_type << expr->getSourceRange();
  466. }
  467. void DiagnosticsReporter::OptionalFieldUsedWithGC(
  468. const clang::FieldDecl* field,
  469. const clang::CXXRecordDecl* optional,
  470. const clang::CXXRecordDecl* gc_type) {
  471. ReportDiagnostic(field->getBeginLoc(), diag_optional_field_used_with_gc_)
  472. << optional << gc_type << field->getSourceRange();
  473. }
  474. void DiagnosticsReporter::OptionalNewExprUsedWithGC(
  475. const clang::Expr* expr,
  476. const clang::CXXRecordDecl* optional,
  477. const clang::CXXRecordDecl* gc_type) {
  478. ReportDiagnostic(expr->getBeginLoc(), diag_optional_new_expr_used_with_gc_)
  479. << optional << gc_type << expr->getSourceRange();
  480. }
  481. void DiagnosticsReporter::VariantUsedWithGC(
  482. const clang::Expr* expr,
  483. const clang::CXXRecordDecl* variant,
  484. const clang::CXXRecordDecl* gc_type) {
  485. ReportDiagnostic(expr->getBeginLoc(), diag_variant_used_with_gc_)
  486. << variant << gc_type << expr->getSourceRange();
  487. }
  488. void DiagnosticsReporter::MemberOnStack(const clang::VarDecl* var) {
  489. ReportDiagnostic(var->getBeginLoc(), diag_member_on_stack_)
  490. << var->getName() << var->getSourceRange();
  491. }