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 | 8 |
8 using namespace clang; | 9 using namespace clang; |
9 using std::string; | 10 using std::string; |
10 | 11 |
11 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) | 12 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) |
12 : cache_(cache), | 13 : cache_(cache), |
13 record_(record), | 14 record_(record), |
14 name_(record->getName()), | 15 name_(record->getName()), |
15 fields_need_tracing_(TracingStatus::Unknown()), | 16 fields_need_tracing_(TracingStatus::Unknown()), |
16 bases_(0), | 17 bases_(0), |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 if (it->second.info()->NeedsTracing(option).IsNeeded()) | 550 if (it->second.info()->NeedsTracing(option).IsNeeded()) |
550 return TracingStatus::Needed(); | 551 return TracingStatus::Needed(); |
551 } | 552 } |
552 | 553 |
553 if (option == Edge::kRecursive) | 554 if (option == Edge::kRecursive) |
554 GetFields(); | 555 GetFields(); |
555 | 556 |
556 return fields_need_tracing_; | 557 return fields_need_tracing_; |
557 } | 558 } |
558 | 559 |
| 560 static bool isInStdNamespace(clang::Sema& sema, NamespaceDecl* ns) |
| 561 { |
| 562 while (ns) { |
| 563 if (sema.getStdNamespace()->InEnclosingNamespaceSetOf(ns)) |
| 564 return true; |
| 565 ns = dyn_cast<NamespaceDecl>(ns->getParent()); |
| 566 } |
| 567 return false; |
| 568 } |
| 569 |
559 Edge* RecordInfo::CreateEdge(const Type* type) { | 570 Edge* RecordInfo::CreateEdge(const Type* type) { |
560 if (!type) { | 571 if (!type) { |
561 return 0; | 572 return 0; |
562 } | 573 } |
563 | 574 |
564 if (type->isPointerType() || type->isReferenceType()) { | 575 if (type->isPointerType() || type->isReferenceType()) { |
565 if (Edge* ptr = CreateEdge(type->getPointeeType().getTypePtrOrNull())) | 576 if (Edge* ptr = CreateEdge(type->getPointeeType().getTypePtrOrNull())) |
566 return new RawPtr(ptr, type->isReferenceType()); | 577 return new RawPtr(ptr, type->isReferenceType()); |
567 return 0; | 578 return 0; |
568 } | 579 } |
(...skipping 12 matching lines...) Expand all Loading... |
581 return new RefPtr(ptr); | 592 return new RefPtr(ptr); |
582 return 0; | 593 return 0; |
583 } | 594 } |
584 | 595 |
585 if (Config::IsOwnPtr(info->name()) && info->GetTemplateArgs(1, &args)) { | 596 if (Config::IsOwnPtr(info->name()) && info->GetTemplateArgs(1, &args)) { |
586 if (Edge* ptr = CreateEdge(args[0])) | 597 if (Edge* ptr = CreateEdge(args[0])) |
587 return new OwnPtr(ptr); | 598 return new OwnPtr(ptr); |
588 return 0; | 599 return 0; |
589 } | 600 } |
590 | 601 |
| 602 if (Config::IsUniquePtr(info->name()) && info->GetTemplateArgs(1, &args)) { |
| 603 // Check that this is std::unique_ptr |
| 604 NamespaceDecl* ns = |
| 605 dyn_cast<NamespaceDecl>(info->record()->getDeclContext()); |
| 606 clang::Sema& sema = cache_->instance().getSema(); |
| 607 if (!isInStdNamespace(sema, ns)) |
| 608 return 0; |
| 609 if (Edge* ptr = CreateEdge(args[0])) |
| 610 return new UniquePtr(ptr); |
| 611 return 0; |
| 612 } |
| 613 |
591 if (Config::IsMember(info->name()) && info->GetTemplateArgs(1, &args)) { | 614 if (Config::IsMember(info->name()) && info->GetTemplateArgs(1, &args)) { |
592 if (Edge* ptr = CreateEdge(args[0])) | 615 if (Edge* ptr = CreateEdge(args[0])) |
593 return new Member(ptr); | 616 return new Member(ptr); |
594 return 0; | 617 return 0; |
595 } | 618 } |
596 | 619 |
597 if (Config::IsWeakMember(info->name()) && info->GetTemplateArgs(1, &args)) { | 620 if (Config::IsWeakMember(info->name()) && info->GetTemplateArgs(1, &args)) { |
598 if (Edge* ptr = CreateEdge(args[0])) | 621 if (Edge* ptr = CreateEdge(args[0])) |
599 return new WeakMember(ptr); | 622 return new WeakMember(ptr); |
600 return 0; | 623 return 0; |
601 } | 624 } |
602 | 625 |
603 if (Config::IsPersistent(info->name())) { | 626 bool is_persistent = Config::IsPersistent(info->name()); |
| 627 if (is_persistent || Config::IsCrossThreadPersistent(info->name())) { |
604 // Persistent might refer to v8::Persistent, so check the name space. | 628 // Persistent might refer to v8::Persistent, so check the name space. |
605 // TODO: Consider using a more canonical identification than names. | 629 // TODO: Consider using a more canonical identification than names. |
606 NamespaceDecl* ns = | 630 NamespaceDecl* ns = |
607 dyn_cast<NamespaceDecl>(info->record()->getDeclContext()); | 631 dyn_cast<NamespaceDecl>(info->record()->getDeclContext()); |
608 if (!ns || ns->getName() != "blink") | 632 if (!ns || ns->getName() != "blink") |
609 return 0; | 633 return 0; |
610 if (!info->GetTemplateArgs(1, &args)) | 634 if (!info->GetTemplateArgs(1, &args)) |
611 return 0; | 635 return 0; |
612 if (Edge* ptr = CreateEdge(args[0])) | 636 if (Edge* ptr = CreateEdge(args[0])) { |
613 return new Persistent(ptr); | 637 if (is_persistent) |
| 638 return new Persistent(ptr); |
| 639 else |
| 640 return new CrossThreadPersistent(ptr); |
| 641 } |
614 return 0; | 642 return 0; |
615 } | 643 } |
616 | 644 |
617 if (Config::IsGCCollection(info->name()) || | 645 if (Config::IsGCCollection(info->name()) || |
618 Config::IsWTFCollection(info->name())) { | 646 Config::IsWTFCollection(info->name())) { |
619 bool is_root = Config::IsPersistentGCCollection(info->name()); | 647 bool is_root = Config::IsPersistentGCCollection(info->name()); |
620 bool on_heap = is_root || info->IsHeapAllocatedCollection(); | 648 bool on_heap = is_root || info->IsHeapAllocatedCollection(); |
621 size_t count = Config::CollectionDimension(info->name()); | 649 size_t count = Config::CollectionDimension(info->name()); |
622 if (!info->GetTemplateArgs(count, &args)) | 650 if (!info->GetTemplateArgs(count, &args)) |
623 return 0; | 651 return 0; |
624 Collection* edge = new Collection(info, on_heap, is_root); | 652 Collection* edge = new Collection(info, on_heap, is_root); |
625 for (TemplateArgs::iterator it = args.begin(); it != args.end(); ++it) { | 653 for (TemplateArgs::iterator it = args.begin(); it != args.end(); ++it) { |
626 if (Edge* member = CreateEdge(*it)) { | 654 if (Edge* member = CreateEdge(*it)) { |
627 edge->members().push_back(member); | 655 edge->members().push_back(member); |
628 } | 656 } |
629 // TODO: Handle the case where we fail to create an edge (eg, if the | 657 // TODO: Handle the case where we fail to create an edge (eg, if the |
630 // argument is a primitive type or just not fully known yet). | 658 // argument is a primitive type or just not fully known yet). |
631 } | 659 } |
632 return edge; | 660 return edge; |
633 } | 661 } |
634 | 662 |
635 return new Value(info); | 663 return new Value(info); |
636 } | 664 } |
OLD | NEW |