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 #include "Config.h" | 5 #include "Config.h" |
6 #include "RecordInfo.h" | 6 #include "RecordInfo.h" |
7 | 7 |
8 using namespace clang; | 8 using namespace clang; |
9 using std::string; | 9 using std::string; |
10 | 10 |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 return fields; | 420 return fields; |
421 } | 421 } |
422 | 422 |
423 void RecordInfo::DetermineTracingMethods() { | 423 void RecordInfo::DetermineTracingMethods() { |
424 if (determined_trace_methods_) | 424 if (determined_trace_methods_) |
425 return; | 425 return; |
426 determined_trace_methods_ = true; | 426 determined_trace_methods_ = true; |
427 if (Config::IsGCBase(name_)) | 427 if (Config::IsGCBase(name_)) |
428 return; | 428 return; |
429 CXXMethodDecl* trace = nullptr; | 429 CXXMethodDecl* trace = nullptr; |
| 430 CXXMethodDecl* trace_impl = nullptr; |
430 CXXMethodDecl* trace_after_dispatch = nullptr; | 431 CXXMethodDecl* trace_after_dispatch = nullptr; |
431 bool has_adjust_and_mark = false; | 432 bool has_adjust_and_mark = false; |
432 bool has_is_heap_object_alive = false; | 433 bool has_is_heap_object_alive = false; |
433 for (CXXRecordDecl::method_iterator it = record_->method_begin(); | 434 for (Decl* decl : record_->decls()) { |
434 it != record_->method_end(); | 435 CXXMethodDecl* method = dyn_cast<CXXMethodDecl>(decl); |
435 ++it) { | 436 if (!method) { |
436 switch (Config::GetTraceMethodType(*it)) { | 437 if (FunctionTemplateDecl* func_template = |
| 438 dyn_cast<FunctionTemplateDecl>(decl)) |
| 439 method = dyn_cast<CXXMethodDecl>(func_template->getTemplatedDecl()); |
| 440 } |
| 441 if (!method) |
| 442 continue; |
| 443 |
| 444 switch (Config::GetTraceMethodType(method)) { |
437 case Config::TRACE_METHOD: | 445 case Config::TRACE_METHOD: |
438 trace = *it; | 446 trace = method; |
439 break; | 447 break; |
440 case Config::TRACE_AFTER_DISPATCH_METHOD: | 448 case Config::TRACE_AFTER_DISPATCH_METHOD: |
441 trace_after_dispatch = *it; | 449 trace_after_dispatch = method; |
442 break; | 450 break; |
443 case Config::TRACE_IMPL_METHOD: | 451 case Config::TRACE_IMPL_METHOD: |
| 452 trace_impl = method; |
| 453 break; |
444 case Config::TRACE_AFTER_DISPATCH_IMPL_METHOD: | 454 case Config::TRACE_AFTER_DISPATCH_IMPL_METHOD: |
445 break; | 455 break; |
446 case Config::NOT_TRACE_METHOD: | 456 case Config::NOT_TRACE_METHOD: |
447 if (it->getNameAsString() == kFinalizeName) { | 457 if (method->getNameAsString() == kFinalizeName) { |
448 finalize_dispatch_method_ = *it; | 458 finalize_dispatch_method_ = method; |
449 } else if (it->getNameAsString() == kAdjustAndMarkName) { | 459 } else if (method->getNameAsString() == kAdjustAndMarkName) { |
450 has_adjust_and_mark = true; | 460 has_adjust_and_mark = true; |
451 } else if (it->getNameAsString() == kIsHeapObjectAliveName) { | 461 } else if (method->getNameAsString() == kIsHeapObjectAliveName) { |
452 has_is_heap_object_alive = true; | 462 has_is_heap_object_alive = true; |
453 } | 463 } |
454 break; | 464 break; |
455 } | 465 } |
456 } | 466 } |
| 467 |
457 // Record if class defines the two GCMixin methods. | 468 // Record if class defines the two GCMixin methods. |
458 has_gc_mixin_methods_ = | 469 has_gc_mixin_methods_ = |
459 has_adjust_and_mark && has_is_heap_object_alive ? kTrue : kFalse; | 470 has_adjust_and_mark && has_is_heap_object_alive ? kTrue : kFalse; |
460 if (trace_after_dispatch) { | 471 if (trace_after_dispatch) { |
461 trace_method_ = trace_after_dispatch; | 472 trace_method_ = trace_after_dispatch; |
462 trace_dispatch_method_ = trace; | 473 trace_dispatch_method_ = trace_impl ? trace_impl : trace; |
463 } else { | 474 } else { |
464 // TODO: Can we never have a dispatch method called trace without the same | 475 // TODO: Can we never have a dispatch method called trace without the same |
465 // class defining a traceAfterDispatch method? | 476 // class defining a traceAfterDispatch method? |
466 trace_method_ = trace; | 477 trace_method_ = trace; |
467 trace_dispatch_method_ = nullptr; | 478 trace_dispatch_method_ = nullptr; |
468 } | 479 } |
469 if (trace_dispatch_method_ && finalize_dispatch_method_) | 480 if (trace_dispatch_method_ && finalize_dispatch_method_) |
470 return; | 481 return; |
471 // If this class does not define dispatching methods inherit them. | 482 // If this class does not define dispatching methods inherit them. |
472 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { | 483 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 edge->members().push_back(member); | 642 edge->members().push_back(member); |
632 } | 643 } |
633 // TODO: Handle the case where we fail to create an edge (eg, if the | 644 // TODO: Handle the case where we fail to create an edge (eg, if the |
634 // argument is a primitive type or just not fully known yet). | 645 // argument is a primitive type or just not fully known yet). |
635 } | 646 } |
636 return edge; | 647 return edge; |
637 } | 648 } |
638 | 649 |
639 return new Value(info); | 650 return new Value(info); |
640 } | 651 } |
OLD | NEW |