| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "BlinkGCPluginConsumer.h" | 5 #include "BlinkGCPluginConsumer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "CheckDispatchVisitor.h" | 10 #include "CheckDispatchVisitor.h" |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 " is not permitted to declare a pure-virtual trace method."; | 142 " is not permitted to declare a pure-virtual trace method."; |
| 143 | 143 |
| 144 const char kLeftMostBaseMustBePolymorphic[] = | 144 const char kLeftMostBaseMustBePolymorphic[] = |
| 145 "[blink-gc] Left-most base class %0 of derived class %1" | 145 "[blink-gc] Left-most base class %0 of derived class %1" |
| 146 " must be polymorphic."; | 146 " must be polymorphic."; |
| 147 | 147 |
| 148 const char kBaseClassMustDeclareVirtualTrace[] = | 148 const char kBaseClassMustDeclareVirtualTrace[] = |
| 149 "[blink-gc] Left-most base class %0 of derived class %1" | 149 "[blink-gc] Left-most base class %0 of derived class %1" |
| 150 " must define a virtual trace method."; | 150 " must define a virtual trace method."; |
| 151 | 151 |
| 152 const char kClassMustDeclareGCMixinTraceMethod[] = | |
| 153 "[blink-gc] Class %0 which inherits from GarbageCollectedMixin must" | |
| 154 " locally declare and override trace(Visitor*)"; | |
| 155 | |
| 156 // Use a local RAV implementation to simply collect all FunctionDecls marked for | 152 // Use a local RAV implementation to simply collect all FunctionDecls marked for |
| 157 // late template parsing. This happens with the flag -fdelayed-template-parsing, | 153 // late template parsing. This happens with the flag -fdelayed-template-parsing, |
| 158 // which is on by default in MSVC-compatible mode. | 154 // which is on by default in MSVC-compatible mode. |
| 159 std::set<FunctionDecl*> GetLateParsedFunctionDecls(TranslationUnitDecl* decl) { | 155 std::set<FunctionDecl*> GetLateParsedFunctionDecls(TranslationUnitDecl* decl) { |
| 160 struct Visitor : public RecursiveASTVisitor<Visitor> { | 156 struct Visitor : public RecursiveASTVisitor<Visitor> { |
| 161 bool VisitFunctionDecl(FunctionDecl* function_decl) { | 157 bool VisitFunctionDecl(FunctionDecl* function_decl) { |
| 162 if (function_decl->isLateTemplateParsed()) | 158 if (function_decl->isLateTemplateParsed()) |
| 163 late_parsed_decls.insert(function_decl); | 159 late_parsed_decls.insert(function_decl); |
| 164 return true; | 160 return true; |
| 165 } | 161 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 diag_derives_non_stack_allocated_ = | 240 diag_derives_non_stack_allocated_ = |
| 245 diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated); | 241 diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated); |
| 246 diag_class_overrides_new_ = | 242 diag_class_overrides_new_ = |
| 247 diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew); | 243 diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew); |
| 248 diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID( | 244 diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID( |
| 249 getErrorLevel(), kClassDeclaresPureVirtualTrace); | 245 getErrorLevel(), kClassDeclaresPureVirtualTrace); |
| 250 diag_left_most_base_must_be_polymorphic_ = diagnostic_.getCustomDiagID( | 246 diag_left_most_base_must_be_polymorphic_ = diagnostic_.getCustomDiagID( |
| 251 getErrorLevel(), kLeftMostBaseMustBePolymorphic); | 247 getErrorLevel(), kLeftMostBaseMustBePolymorphic); |
| 252 diag_base_class_must_declare_virtual_trace_ = diagnostic_.getCustomDiagID( | 248 diag_base_class_must_declare_virtual_trace_ = diagnostic_.getCustomDiagID( |
| 253 getErrorLevel(), kBaseClassMustDeclareVirtualTrace); | 249 getErrorLevel(), kBaseClassMustDeclareVirtualTrace); |
| 254 diag_class_must_declare_gc_mixin_trace_method_ = | |
| 255 diagnostic_.getCustomDiagID(getErrorLevel(), | |
| 256 kClassMustDeclareGCMixinTraceMethod); | |
| 257 | 250 |
| 258 // Register note messages. | 251 // Register note messages. |
| 259 diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID( | 252 diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID( |
| 260 DiagnosticsEngine::Note, kBaseRequiresTracingNote); | 253 DiagnosticsEngine::Note, kBaseRequiresTracingNote); |
| 261 diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( | 254 diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( |
| 262 DiagnosticsEngine::Note, kFieldRequiresTracingNote); | 255 DiagnosticsEngine::Note, kFieldRequiresTracingNote); |
| 263 diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( | 256 diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( |
| 264 DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); | 257 DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); |
| 265 diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( | 258 diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( |
| 266 DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); | 259 DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 ReportClassContainsInvalidFields(info, &visitor.invalid_fields()); | 430 ReportClassContainsInvalidFields(info, &visitor.invalid_fields()); |
| 438 } | 431 } |
| 439 | 432 |
| 440 if (info->IsGCDerived()) { | 433 if (info->IsGCDerived()) { |
| 441 if (!info->IsGCMixin()) { | 434 if (!info->IsGCMixin()) { |
| 442 CheckLeftMostDerived(info); | 435 CheckLeftMostDerived(info); |
| 443 CheckDispatch(info); | 436 CheckDispatch(info); |
| 444 if (CXXMethodDecl* newop = info->DeclaresNewOperator()) | 437 if (CXXMethodDecl* newop = info->DeclaresNewOperator()) |
| 445 if (!Config::IsIgnoreAnnotated(newop)) | 438 if (!Config::IsIgnoreAnnotated(newop)) |
| 446 ReportClassOverridesNew(info, newop); | 439 ReportClassOverridesNew(info, newop); |
| 447 if (info->IsGCMixinInstance()) { | |
| 448 // Require that declared GCMixin implementations | |
| 449 // also provide a trace() override. | |
| 450 if (info->DeclaresGCMixinMethods() | |
| 451 && !info->DeclaresLocalTraceMethod()) | |
| 452 ReportClassMustDeclareGCMixinTraceMethod(info); | |
| 453 } | |
| 454 } | 440 } |
| 455 | 441 |
| 456 { | 442 { |
| 457 CheckGCRootsVisitor visitor; | 443 CheckGCRootsVisitor visitor; |
| 458 if (visitor.ContainsGCRoots(info)) | 444 if (visitor.ContainsGCRoots(info)) |
| 459 ReportClassContainsGCRoots(info, &visitor.gc_roots()); | 445 ReportClassContainsGCRoots(info, &visitor.gc_roots()); |
| 460 } | 446 } |
| 461 | 447 |
| 462 if (info->NeedsFinalization()) | 448 if (info->NeedsFinalization()) |
| 463 CheckFinalization(info); | 449 CheckFinalization(info); |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 << info->record(); | 1096 << info->record(); |
| 1111 } | 1097 } |
| 1112 | 1098 |
| 1113 void BlinkGCPluginConsumer::ReportClassDoesNotRequireFinalization( | 1099 void BlinkGCPluginConsumer::ReportClassDoesNotRequireFinalization( |
| 1114 RecordInfo* info) { | 1100 RecordInfo* info) { |
| 1115 ReportDiagnostic(info->record()->getInnerLocStart(), | 1101 ReportDiagnostic(info->record()->getInnerLocStart(), |
| 1116 diag_class_does_not_require_finalization_) | 1102 diag_class_does_not_require_finalization_) |
| 1117 << info->record(); | 1103 << info->record(); |
| 1118 } | 1104 } |
| 1119 | 1105 |
| 1120 void BlinkGCPluginConsumer::ReportClassMustDeclareGCMixinTraceMethod( | |
| 1121 RecordInfo* info) { | |
| 1122 ReportDiagnostic(info->record()->getInnerLocStart(), | |
| 1123 diag_class_must_declare_gc_mixin_trace_method_) | |
| 1124 << info->record(); | |
| 1125 } | |
| 1126 | |
| 1127 void BlinkGCPluginConsumer::ReportOverriddenNonVirtualTrace( | 1106 void BlinkGCPluginConsumer::ReportOverriddenNonVirtualTrace( |
| 1128 RecordInfo* info, | 1107 RecordInfo* info, |
| 1129 CXXMethodDecl* trace, | 1108 CXXMethodDecl* trace, |
| 1130 CXXMethodDecl* overridden) { | 1109 CXXMethodDecl* overridden) { |
| 1131 ReportDiagnostic(trace->getLocStart(), diag_overridden_non_virtual_trace_) | 1110 ReportDiagnostic(trace->getLocStart(), diag_overridden_non_virtual_trace_) |
| 1132 << info->record() << overridden->getParent(); | 1111 << info->record() << overridden->getParent(); |
| 1133 NoteOverriddenNonVirtualTrace(overridden); | 1112 NoteOverriddenNonVirtualTrace(overridden); |
| 1134 } | 1113 } |
| 1135 | 1114 |
| 1136 void BlinkGCPluginConsumer::ReportMissingTraceDispatchMethod(RecordInfo* info) { | 1115 void BlinkGCPluginConsumer::ReportMissingTraceDispatchMethod(RecordInfo* info) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 void BlinkGCPluginConsumer::NoteField(FieldDecl* field, unsigned note) { | 1245 void BlinkGCPluginConsumer::NoteField(FieldDecl* field, unsigned note) { |
| 1267 ReportDiagnostic(field->getLocStart(), note) << field; | 1246 ReportDiagnostic(field->getLocStart(), note) << field; |
| 1268 } | 1247 } |
| 1269 | 1248 |
| 1270 void BlinkGCPluginConsumer::NoteOverriddenNonVirtualTrace( | 1249 void BlinkGCPluginConsumer::NoteOverriddenNonVirtualTrace( |
| 1271 CXXMethodDecl* overridden) { | 1250 CXXMethodDecl* overridden) { |
| 1272 ReportDiagnostic(overridden->getLocStart(), | 1251 ReportDiagnostic(overridden->getLocStart(), |
| 1273 diag_overridden_non_virtual_trace_note_) | 1252 diag_overridden_non_virtual_trace_note_) |
| 1274 << overridden; | 1253 << overridden; |
| 1275 } | 1254 } |
| OLD | NEW |