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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 bool dispatched_to_receiver() { return dispatched_to_receiver_; } | 308 bool dispatched_to_receiver() { return dispatched_to_receiver_; } |
309 | 309 |
310 bool VisitMemberExpr(MemberExpr* member) { | 310 bool VisitMemberExpr(MemberExpr* member) { |
311 if (CXXMethodDecl* fn = dyn_cast<CXXMethodDecl>(member->getMemberDecl())) { | 311 if (CXXMethodDecl* fn = dyn_cast<CXXMethodDecl>(member->getMemberDecl())) { |
312 if (fn->getParent() == receiver_->record()) | 312 if (fn->getParent() == receiver_->record()) |
313 dispatched_to_receiver_ = true; | 313 dispatched_to_receiver_ = true; |
314 } | 314 } |
315 return true; | 315 return true; |
316 } | 316 } |
317 | 317 |
| 318 bool VisitUnresolvedMemberExpr(UnresolvedMemberExpr* member) { |
| 319 for (Decl* decl : member->decls()) { |
| 320 if (CXXMethodDecl* method = dyn_cast<CXXMethodDecl>(decl)) { |
| 321 if (method->getParent() == receiver_->record() && |
| 322 Config::GetTraceMethodType(method) == |
| 323 Config::TRACE_AFTER_DISPATCH_METHOD) { |
| 324 dispatched_to_receiver_ = true; |
| 325 return true; |
| 326 } |
| 327 } |
| 328 } |
| 329 return true; |
| 330 } |
| 331 |
318 private: | 332 private: |
319 RecordInfo* receiver_; | 333 RecordInfo* receiver_; |
320 bool dispatched_to_receiver_; | 334 bool dispatched_to_receiver_; |
321 }; | 335 }; |
322 | 336 |
323 // This visitor checks a tracing method by traversing its body. | 337 // This visitor checks a tracing method by traversing its body. |
324 // - A member field is considered traced if it is referenced in the body. | 338 // - A member field is considered traced if it is referenced in the body. |
325 // - A base is traced if a base-qualified call to a trace method is found. | 339 // - A base is traced if a base-qualified call to a trace method is found. |
326 class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { | 340 class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { |
327 public: | 341 public: |
(...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 } | 1414 } |
1401 return; | 1415 return; |
1402 } | 1416 } |
1403 | 1417 |
1404 CheckTraceOrDispatchMethod(parent, method); | 1418 CheckTraceOrDispatchMethod(parent, method); |
1405 } | 1419 } |
1406 | 1420 |
1407 // Determine what type of tracing method this is (dispatch or trace). | 1421 // Determine what type of tracing method this is (dispatch or trace). |
1408 void CheckTraceOrDispatchMethod(RecordInfo* parent, CXXMethodDecl* method) { | 1422 void CheckTraceOrDispatchMethod(RecordInfo* parent, CXXMethodDecl* method) { |
1409 Config::TraceMethodType trace_type = Config::GetTraceMethodType(method); | 1423 Config::TraceMethodType trace_type = Config::GetTraceMethodType(method); |
1410 if (trace_type != Config::TRACE_METHOD || | 1424 if (trace_type == Config::TRACE_AFTER_DISPATCH_METHOD || |
| 1425 trace_type == Config::TRACE_AFTER_DISPATCH_IMPL_METHOD || |
1411 !parent->GetTraceDispatchMethod()) { | 1426 !parent->GetTraceDispatchMethod()) { |
1412 CheckTraceMethod(parent, method, trace_type); | 1427 CheckTraceMethod(parent, method, trace_type); |
1413 } | 1428 } |
1414 // Dispatch methods are checked when we identify subclasses. | 1429 // Dispatch methods are checked when we identify subclasses. |
1415 } | 1430 } |
1416 | 1431 |
1417 // Check an actual trace method. | 1432 // Check an actual trace method. |
1418 void CheckTraceMethod(RecordInfo* parent, | 1433 void CheckTraceMethod(RecordInfo* parent, |
1419 CXXMethodDecl* trace, | 1434 CXXMethodDecl* trace, |
1420 Config::TraceMethodType trace_type) { | 1435 Config::TraceMethodType trace_type) { |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2032 | 2047 |
2033 private: | 2048 private: |
2034 BlinkGCPluginOptions options_; | 2049 BlinkGCPluginOptions options_; |
2035 }; | 2050 }; |
2036 | 2051 |
2037 } // namespace | 2052 } // namespace |
2038 | 2053 |
2039 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( | 2054 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( |
2040 "blink-gc-plugin", | 2055 "blink-gc-plugin", |
2041 "Check Blink GC invariants"); | 2056 "Check Blink GC invariants"); |
OLD | NEW |