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 #include "clang/Sema/Sema.h" | 7 #include "clang/Sema/Sema.h" |
8 | 8 |
9 using namespace clang; | 9 using namespace clang; |
10 using std::string; | 10 using std::string; |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 return fields; | 431 return fields; |
432 } | 432 } |
433 | 433 |
434 void RecordInfo::DetermineTracingMethods() { | 434 void RecordInfo::DetermineTracingMethods() { |
435 if (determined_trace_methods_) | 435 if (determined_trace_methods_) |
436 return; | 436 return; |
437 determined_trace_methods_ = true; | 437 determined_trace_methods_ = true; |
438 if (Config::IsGCBase(name_)) | 438 if (Config::IsGCBase(name_)) |
439 return; | 439 return; |
440 CXXMethodDecl* trace = nullptr; | 440 CXXMethodDecl* trace = nullptr; |
441 CXXMethodDecl* trace_impl = nullptr; | |
442 CXXMethodDecl* trace_after_dispatch = nullptr; | 441 CXXMethodDecl* trace_after_dispatch = nullptr; |
443 bool has_adjust_and_mark = false; | 442 bool has_adjust_and_mark = false; |
444 bool has_is_heap_object_alive = false; | 443 bool has_is_heap_object_alive = false; |
445 for (Decl* decl : record_->decls()) { | 444 for (Decl* decl : record_->decls()) { |
446 CXXMethodDecl* method = dyn_cast<CXXMethodDecl>(decl); | 445 CXXMethodDecl* method = dyn_cast<CXXMethodDecl>(decl); |
447 if (!method) { | 446 if (!method) { |
448 if (FunctionTemplateDecl* func_template = | 447 if (FunctionTemplateDecl* func_template = |
449 dyn_cast<FunctionTemplateDecl>(decl)) | 448 dyn_cast<FunctionTemplateDecl>(decl)) |
450 method = dyn_cast<CXXMethodDecl>(func_template->getTemplatedDecl()); | 449 method = dyn_cast<CXXMethodDecl>(func_template->getTemplatedDecl()); |
451 } | 450 } |
452 if (!method) | 451 if (!method) |
453 continue; | 452 continue; |
454 | 453 |
455 switch (Config::GetTraceMethodType(method)) { | 454 switch (Config::GetTraceMethodType(method)) { |
456 case Config::TRACE_METHOD: | 455 case Config::TRACE_METHOD: |
457 trace = method; | 456 trace = method; |
458 break; | 457 break; |
459 case Config::TRACE_AFTER_DISPATCH_METHOD: | 458 case Config::TRACE_AFTER_DISPATCH_METHOD: |
460 trace_after_dispatch = method; | 459 trace_after_dispatch = method; |
461 break; | 460 break; |
462 case Config::TRACE_IMPL_METHOD: | |
463 trace_impl = method; | |
464 break; | |
465 case Config::TRACE_AFTER_DISPATCH_IMPL_METHOD: | |
466 break; | |
467 case Config::NOT_TRACE_METHOD: | 461 case Config::NOT_TRACE_METHOD: |
468 if (method->getNameAsString() == kFinalizeName) { | 462 if (method->getNameAsString() == kFinalizeName) { |
469 finalize_dispatch_method_ = method; | 463 finalize_dispatch_method_ = method; |
470 } else if (method->getNameAsString() == kAdjustAndMarkName) { | 464 } else if (method->getNameAsString() == kAdjustAndMarkName) { |
471 has_adjust_and_mark = true; | 465 has_adjust_and_mark = true; |
472 } else if (method->getNameAsString() == kIsHeapObjectAliveName) { | 466 } else if (method->getNameAsString() == kIsHeapObjectAliveName) { |
473 has_is_heap_object_alive = true; | 467 has_is_heap_object_alive = true; |
474 } | 468 } |
475 break; | 469 break; |
476 } | 470 } |
477 } | 471 } |
478 | 472 |
479 // Record if class defines the two GCMixin methods. | 473 // Record if class defines the two GCMixin methods. |
480 has_gc_mixin_methods_ = | 474 has_gc_mixin_methods_ = |
481 has_adjust_and_mark && has_is_heap_object_alive ? kTrue : kFalse; | 475 has_adjust_and_mark && has_is_heap_object_alive ? kTrue : kFalse; |
482 if (trace_after_dispatch) { | 476 if (trace_after_dispatch) { |
483 trace_method_ = trace_after_dispatch; | 477 trace_method_ = trace_after_dispatch; |
484 trace_dispatch_method_ = trace_impl ? trace_impl : trace; | 478 trace_dispatch_method_ = trace; |
485 } else { | 479 } else { |
486 // TODO: Can we never have a dispatch method called trace without the same | 480 // TODO: Can we never have a dispatch method called trace without the same |
487 // class defining a traceAfterDispatch method? | 481 // class defining a traceAfterDispatch method? |
488 trace_method_ = trace; | 482 trace_method_ = trace; |
489 trace_dispatch_method_ = nullptr; | 483 trace_dispatch_method_ = nullptr; |
490 } | 484 } |
491 if (trace_dispatch_method_ && finalize_dispatch_method_) | 485 if (trace_dispatch_method_ && finalize_dispatch_method_) |
492 return; | 486 return; |
493 // If this class does not define dispatching methods inherit them. | 487 // If this class does not define dispatching methods inherit them. |
494 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { | 488 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 edge->members().push_back(member); | 687 edge->members().push_back(member); |
694 } | 688 } |
695 // TODO: Handle the case where we fail to create an edge (eg, if the | 689 // TODO: Handle the case where we fail to create an edge (eg, if the |
696 // argument is a primitive type or just not fully known yet). | 690 // argument is a primitive type or just not fully known yet). |
697 } | 691 } |
698 return edge; | 692 return edge; |
699 } | 693 } |
700 | 694 |
701 return new Value(info); | 695 return new Value(info); |
702 } | 696 } |
OLD | NEW |